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_WRITER_H 18 #define ANDROID_MEDIA_NBLOG_WRITER_H 19 20 #include <stdarg.h> 21 #include <stddef.h> 22 23 #include <binder/IMemory.h> 24 #include <media/nblog/Events.h> 25 #include <utils/Mutex.h> 26 #include <utils/RefBase.h> 27 28 class audio_utils_fifo; 29 class audio_utils_fifo_writer; 30 31 namespace android { 32 33 class IMemory; 34 35 namespace NBLog { 36 37 class Entry; 38 struct Shared; 39 40 // NBLog Writer Interface 41 42 // Writer is thread-safe with respect to Reader, but not with respect to multiple threads 43 // calling Writer methods. If you need multi-thread safety for writing, use LockedWriter. 44 class Writer : public RefBase { 45 public: 46 Writer() = default; // dummy nop implementation without shared memory 47 48 // Input parameter 'size' is the desired size of the timeline in byte units. 49 // The size of the shared memory must be at least Timeline::sharedSize(size). 50 Writer(void *shared, size_t size); 51 Writer(const sp<IMemory>& iMemory, size_t size); 52 53 ~Writer() override; 54 55 // FIXME needs comments, and some should be private 56 void log(const char *string); 57 void logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); 58 void logTimestamp(); 59 void logFormat(const char *fmt, log_hash_t hash, ...); 60 void logEventHistTs(Event event, log_hash_t hash); 61 62 // Log data related to Event E. See the event-to-type mapping for the type of data 63 // corresponding to the event. For example, if you see a mapping statement: 64 // MAP_TYPE_TO_EVENT(E, T); 65 // then the usage of this method would be: 66 // T data = doComputation(); 67 // tlNBLogWriter->log<NBLog::E>(data); 68 template<Event E> log(typename get_mapped<E>::type data)69 void log(typename get_mapped<E>::type data) { 70 log(E, &data, sizeof(data)); 71 } 72 73 virtual bool isEnabled() const; 74 75 // return value for all of these is the previous isEnabled() 76 virtual bool setEnabled(bool enabled); // but won't enable if no shared memory enable()77 bool enable() { return setEnabled(true); } disable()78 bool disable() { return setEnabled(false); } 79 getIMemory()80 sp<IMemory> getIMemory() const { return mIMemory; } 81 82 // Public logging function implementations should always use one of the 83 // two log() function calls below to write to shared memory. 84 protected: 85 // Writes a single Entry to the FIFO if the writer is enabled. 86 // This is protected and virtual because LockedWriter uses a lock to protect 87 // writing to the FIFO before writing to this function. 88 virtual void log(const Entry &entry, bool trusted = false); 89 90 private: 91 // 0 <= length <= kMaxLength 92 // Log a single Entry with corresponding event, data, and length. 93 void log(Event event, const void *data, size_t length); 94 95 void logvf(const char *fmt, va_list ap); 96 97 // helper functions for logging parts of a formatted entry 98 void logStart(const char *fmt); 99 void logTimestampFormat(); 100 void logVFormat(const char *fmt, log_hash_t hash, va_list ap); 101 102 Shared* const mShared{}; // raw pointer to shared memory 103 sp<IMemory> mIMemory{}; // ref-counted version, initialized in constructor 104 // and then const 105 audio_utils_fifo * const mFifo{}; // FIFO itself, non-NULL 106 // unless constructor fails 107 // or dummy constructor used 108 audio_utils_fifo_writer * const mFifoWriter{}; // used to write to FIFO, non-NULL 109 // unless dummy constructor used 110 bool mEnabled = false; // whether to actually log 111 112 // cached pid and process name to use in %p format specifier 113 // total tag length is mPidTagSize and process name is not zero terminated 114 char *mPidTag{}; 115 size_t mPidTagSize = 0; 116 }; 117 118 // --------------------------------------------------------------------------- 119 120 // Similar to Writer, but safe for multiple threads to call concurrently 121 class LockedWriter : public Writer { 122 public: 123 LockedWriter() = default; 124 LockedWriter(void *shared, size_t size); 125 126 bool isEnabled() const override; 127 bool setEnabled(bool enabled) override; 128 129 private: 130 // Lock needs to be obtained before writing to FIFO. 131 void log(const Entry &entry, bool trusted = false) override; 132 133 mutable Mutex mLock; 134 }; 135 136 } // namespace NBLog 137 } // namespace android 138 139 #endif // ANDROID_MEDIA_NBLOG_WRITER_H 140