Home | History | Annotate | Download | only in nblog
      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