1 /* 2 * Copyright (C) 2020 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 CHRE_PLATFORM_LOG_BUFFER_MANAGER_BUFFER_H_ 18 #define CHRE_PLATFORM_LOG_BUFFER_MANAGER_BUFFER_H_ 19 20 #include "chre/platform/assert.h" 21 #include "chre/platform/condition_variable.h" 22 #include "chre/platform/mutex.h" 23 #include "chre/platform/shared/bt_snoop_log.h" 24 #include "chre/platform/shared/generated/host_messages_generated.h" 25 #include "chre/platform/shared/log_buffer.h" 26 #include "chre/util/singleton.h" 27 #include "chre_api/chre/re.h" 28 29 #ifndef CHRE_LOG_BUFFER_DATA_SIZE 30 #define CHRE_LOG_BUFFER_DATA_SIZE CHRE_MESSAGE_TO_HOST_MAX_SIZE 31 #endif 32 33 namespace chre { 34 35 using LogType = fbs::LogType; 36 37 /** 38 * A log buffer manager that platform code can use to buffer logs when the host 39 * is not available and then send them off when the host becomes available. Uses 40 * the LogBuffer API to buffer the logs in memory. 41 * 42 * The manager uses two LogBuffer objects to handle flushing logs to the host at 43 * the same time as handling more incoming logs. Incoming logs are always put 44 * into the primary buffer first. The secondary buffer takes all the logs 45 * currently in the primary buffer before the logs are sent off to the host 46 * because the secondary buffer is the memory location passed to the 47 * HostLink::sendLogs API. Logs are also flushed to the secondary buffer from 48 * the primary buffer when the primary buffer fills up. 49 * 50 * When implementing this class in platform code. Use the singleton defined 51 * after this class and pass logs to the log or logVa methods. Initialize the 52 * singleton before using it. Call the onLogsSentToHost callback immediately 53 * after sending logs to the host. 54 */ 55 class LogBufferManager : public LogBufferCallbackInterface { 56 public: LogBufferManager(uint8_t * primaryBufferData,uint8_t * secondaryBufferData,size_t bufferSize)57 LogBufferManager(uint8_t *primaryBufferData, uint8_t *secondaryBufferData, 58 size_t bufferSize) 59 : mPrimaryLogBuffer(this, primaryBufferData, bufferSize), 60 mSecondaryLogBuffer(nullptr /* callback */, secondaryBufferData, 61 bufferSize) {} 62 63 ~LogBufferManager() = default; 64 65 /** 66 * Logs message with printf-style arguments. No trailing newline is required 67 * for this method. 68 */ 69 void log(chreLogLevel logLevel, const char *formatStr, ...); 70 71 /** 72 * Similar as log() but with a log buffer and a log size argument instead 73 * of a printf-style arguments. 74 * 75 * @param logs Pointer to the buffer containing the encoded log message. 76 * @param logSize Size of the encoded logs. 77 */ 78 void logEncoded(chreLogLevel logLevel, const uint8_t *encodedLog, 79 size_t encodedLogSize); 80 81 /** 82 * Log via the pigweed tokenized logging format for nanoapps. The log message 83 * message is tokenized and will be decoded into printf style strings at the 84 * receiver. 85 * 86 * @param level Logging level. 87 * @param instanceId The instance ID of the nanoapp which sends the log. 88 * @param msg A byte buffer containing the tokenized log message. 89 * @param msgSize Size of the tokenized log message buffer. 90 */ 91 void logNanoappTokenized(chreLogLevel logLevel, uint16_t instanceID, 92 const uint8_t *msg, size_t msgSize); 93 94 /** 95 * Logs message with printf-style arguments. No trailing newline is required 96 * for this method. Uses va_list parameter instead of ... 97 */ 98 void logVa(chreLogLevel logLevel, const char *formatStr, va_list args); 99 100 /** 101 * Logs BT commands and events. These logs will not be displayed on logcat. 102 * The BT events will be handled with a bt snoop log parser. 103 */ 104 void logBtSnoop(BtSnoopDirection direction, const uint8_t *buffer, 105 size_t size); 106 107 /** 108 * Overrides required method from LogBufferCallbackInterface. 109 */ 110 void onLogsReady() final; 111 112 /** 113 * Flush any logs that might be in the default log buffer. 114 */ 115 void flushLogs(); 116 117 /** 118 * The platform code should call this method after the logs have been sent to 119 * the host to signal that more logs can be sent to the host when ready. The 120 * caller must indicate whether the platform could successfully deliver the 121 * logs as well. 122 * 123 * @param success true if the logs were sent through to host successfully. 124 */ 125 void onLogsSentToHost(bool success); 126 127 /** 128 * Loop that waits on the conditions for sending logs to host to be met and 129 * sends the logs to the host if so. This method never exits. Should be called 130 * by a platform thread. 131 */ 132 void startSendLogsToHostLoop(); 133 134 private: 135 /* 136 * @return The LogBuffer log level for the given CHRE log level. 137 */ 138 LogBufferLogLevel chreToLogBufferLogLevel(chreLogLevel chreLogLevel); 139 140 /** 141 * Perform any setup needed by the plaform before the secondary buffer is 142 * used. 143 * 144 * Implemented by the platform. 145 */ 146 void preSecondaryBufferUse() const; 147 148 /** 149 * Same as onLogsSentToHost, but without locking. The calling code should have 150 * the flush logs mutex locked before calling this method. 151 * 152 * @param success true if the logs were successfully delivered to the host. 153 */ 154 void onLogsSentToHostLocked(bool success); 155 156 uint32_t getTimestampMs(); 157 158 void bufferOverflowGuard(size_t logSize, LogType type); 159 160 LogBuffer mPrimaryLogBuffer; 161 LogBuffer mSecondaryLogBuffer; 162 163 size_t mNumLogsDroppedTotal = 0; 164 165 ConditionVariable mSendLogsToHostCondition; 166 bool mLogFlushToHostPending = false; 167 bool mLogsBecameReadyWhileFlushPending = false; 168 Mutex mFlushLogsMutex; 169 }; 170 171 //! Provides an alias to the LogBufferManager singleton. 172 typedef Singleton<LogBufferManager> LogBufferManagerSingleton; 173 174 //! Extern the explicit LogBufferManagerSingleton to force non-inline calls. 175 //! This reduces codesize considerably. 176 extern template class Singleton<LogBufferManager>; 177 178 } // namespace chre 179 180 #endif // CHRE_PLATFORM_LOG_BUFFER_MANAGER_H_ 181