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 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