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