• 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/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   void logEncoded(chreLogLevel logLevel, const uint8_t *encodedLog,
68                   size_t encodedLogSize);
69 
70   /**
71    * Logs message with printf-style arguments. No trailing newline is required
72    * for this method. Uses va_list parameter instead of ...
73    */
74   void logVa(chreLogLevel logLevel, const char *formatStr, va_list args);
75 
76   /**
77    * Overrides required method from LogBufferCallbackInterface.
78    */
79   void onLogsReady() final;
80 
81   /**
82    * Flush any logs that might be in the default log buffer.
83    */
84   void flushLogs();
85 
86   /**
87    * The platform code should call this method after the logs have been sent to
88    * the host to signal that more logs can be sent to the host when ready. The
89    * caller must indicate whether the platform could successfully deliver the
90    * logs as well.
91    *
92    * @param success true if the logs were sent through to host successfully.
93    */
94   void onLogsSentToHost(bool success);
95 
96   /**
97    * Loop that waits on the conditions for sending logs to host to be met and
98    * sends the logs to the host if so. This method never exits. Should be called
99    * by a platform thread.
100    */
101   void startSendLogsToHostLoop();
102 
103  private:
104   /*
105    * @return The LogBuffer log level for the given CHRE log level.
106    */
107   LogBufferLogLevel chreToLogBufferLogLevel(chreLogLevel chreLogLevel);
108 
109   /**
110    * Perform any setup needed by the plaform before the secondary buffer is
111    * used.
112    *
113    * Implemented by the platform.
114    */
115   void preSecondaryBufferUse() const;
116 
117   /**
118    * Same as onLogsSentToHost, but without locking. The calling code should have
119    * the flush logs mutex locked before calling this method.
120    *
121    * @param success true if the logs were successfully delivered to the host.
122    */
123   void onLogsSentToHostLocked(bool success);
124 
125   uint32_t getTimestampMs();
126 
127   void bufferOverflowGuard(size_t logSize);
128 
129   LogBuffer mPrimaryLogBuffer;
130   LogBuffer mSecondaryLogBuffer;
131 
132   size_t mNumLogsDroppedTotal = 0;
133 
134   ConditionVariable mSendLogsToHostCondition;
135   bool mLogFlushToHostPending = false;
136   bool mLogsBecameReadyWhileFlushPending = false;
137   Mutex mFlushLogsMutex;
138 };
139 
140 //! Provides an alias to the LogBufferManager singleton.
141 typedef Singleton<LogBufferManager> LogBufferManagerSingleton;
142 
143 //! Extern the explicit LogBufferManagerSingleton to force non-inline calls.
144 //! This reduces codesize considerably.
145 extern template class Singleton<LogBufferManager>;
146 
147 }  // namespace chre
148 
149 #endif  // CHRE_PLATFORM_LOG_BUFFER_MANAGER_H_
150