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