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