• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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