1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ANDROID_MEDIA_NBLOG_EVENTS_H
18 #define ANDROID_MEDIA_NBLOG_EVENTS_H
19
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <system/audio.h>
23 #include <type_traits>
24
25 namespace android {
26 namespace NBLog {
27
28 // TODO have a comment somewhere explaining the whole process for adding a new EVENT_
29
30 // NBLog Event types. The Events are named to provide contextual meaning for what is logged.
31 // If adding a new standalone Event here, update the event-to-type mapping by adding a
32 // MAP_EVENT_TO_TYPE statement below.
33 // XXX Note that as of the current design, Events should not be renumbered (i.e. reordered)
34 // if they ever leave memory (for example, written to file, uploaded to cloud, etc.).
35 // TODO make some sort of interface to keep these "contract" constants.
36 enum Event : uint8_t {
37 EVENT_RESERVED,
38 EVENT_STRING, // ASCII string, not NUL-terminated
39 // TODO: make timestamp optional
40 EVENT_TIMESTAMP, // clock_gettime(CLOCK_MONOTONIC)
41
42 // Types for Format Entry, i.e. formatted entry
43 EVENT_FMT_START, // logFormat start event: entry includes format string,
44 // following entries contain format arguments
45 // format arguments
46 EVENT_FMT_AUTHOR, // author index (present in merged logs) tracks entry's
47 // original log
48 EVENT_FMT_FLOAT, // floating point value entry
49 EVENT_FMT_HASH, // unique HASH of log origin, originates from hash of file name
50 // and line number
51 EVENT_FMT_INTEGER, // integer value entry
52 EVENT_FMT_PID, // process ID and process name
53 EVENT_FMT_STRING, // string value entry
54 EVENT_FMT_TIMESTAMP, // timestamp value entry
55 // end of format arguments
56 EVENT_FMT_END, // end of logFormat argument list
57
58 // Types for wakeup timestamp histograms
59 EVENT_AUDIO_STATE, // audio on/off event: logged on FastMixer::onStateChange call
60 EVENT_HISTOGRAM_ENTRY_TS, // single datum for timestamp histogram
61
62 // Types representing audio performance metrics
63 EVENT_LATENCY, // difference between frames presented by HAL and frames
64 // written to HAL output sink, divided by sample rate.
65 EVENT_OVERRUN, // predicted thread overrun event timestamp
66 EVENT_THREAD_INFO, // see thread_info_t below
67 EVENT_UNDERRUN, // predicted thread underrun event timestamp
68 EVENT_WARMUP_TIME, // thread warmup time
69 EVENT_WORK_TIME, // the time a thread takes to do work, e.g. read, write, etc.
70 EVENT_THREAD_PARAMS, // see thread_params_t below
71
72 EVENT_UPPER_BOUND, // to check for invalid events
73 };
74
75 // NBLog custom-defined structs. Some NBLog Event types map to these structs.
76
77 using log_hash_t = uint64_t;
78
79 // used for EVENT_HISTOGRAM_ENTRY_TS (not mapped)
80 struct HistTsEntry {
81 log_hash_t hash;
82 int64_t ts;
83 }; //TODO __attribute__((packed));
84
85 // used for EVENT_HISTOGRAM_ENTRY_TS (not mapped)
86 struct HistTsEntryWithAuthor {
87 log_hash_t hash;
88 int64_t ts;
89 int author;
90 }; //TODO __attribute__((packed));
91
92 enum ThreadType {
93 UNKNOWN,
94 MIXER,
95 CAPTURE,
96 FASTMIXER,
97 FASTCAPTURE,
98 };
99
threadTypeToString(ThreadType type)100 inline const char *threadTypeToString(ThreadType type) {
101 switch (type) {
102 case MIXER:
103 return "MIXER";
104 case CAPTURE:
105 return "CAPTURE";
106 case FASTMIXER:
107 return "FASTMIXER";
108 case FASTCAPTURE:
109 return "FASTCAPTURE";
110 case UNKNOWN:
111 default:
112 return "UNKNOWN";
113 }
114 }
115
116 // mapped from EVENT_THREAD_INFO
117 // These fields always stay the same throughout a thread's lifetime and
118 // should only need to be logged once upon thread initialization.
119 // There is currently no recovery mechanism if the log event corresponding
120 // to this type is lost.
121 // TODO add this information when adding a reader to MediaLogService?
122 struct thread_info_t {
123 audio_io_handle_t id = -1; // Thread I/O handle
124 ThreadType type = UNKNOWN; // See enum ThreadType above
125 };
126
127 // mapped from EVENT_THREAD_PARAMS
128 // These fields are not necessarily constant throughout a thread's lifetime and
129 // can be logged whenever a thread receives new configurations or parameters.
130 struct thread_params_t {
131 size_t frameCount = 0; // number of frames per read or write buffer
132 unsigned sampleRate = 0; // in frames per second
133 };
134
135 template <Event E> struct get_mapped;
136 #define MAP_EVENT_TO_TYPE(E, T) \
137 template<> struct get_mapped<E> { \
138 static_assert(std::is_trivially_copyable<T>::value \
139 && !std::is_pointer<T>::value, \
140 "NBLog::Event must map to trivially copyable, non-pointer type."); \
141 typedef T type; \
142 }
143
144 // Maps an NBLog Event type to a C++ POD type.
145 MAP_EVENT_TO_TYPE(EVENT_LATENCY, double);
146 MAP_EVENT_TO_TYPE(EVENT_OVERRUN, int64_t);
147 MAP_EVENT_TO_TYPE(EVENT_THREAD_INFO, thread_info_t);
148 MAP_EVENT_TO_TYPE(EVENT_UNDERRUN, int64_t);
149 MAP_EVENT_TO_TYPE(EVENT_WARMUP_TIME, double);
150 MAP_EVENT_TO_TYPE(EVENT_WORK_TIME, int64_t);
151 MAP_EVENT_TO_TYPE(EVENT_THREAD_PARAMS, thread_params_t);
152
153 } // namespace NBLog
154 } // namespace android
155
156 #endif // ANDROID_MEDIA_NBLOG_EVENTS_H
157