• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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_CORE_EVENT_LOOP_MANAGER_H_
18 #define CHRE_CORE_EVENT_LOOP_MANAGER_H_
19 
20 #include "chre/core/debug_dump_manager.h"
21 #include "chre/core/event_loop.h"
22 #include "chre/core/event_loop_common.h"
23 #include "chre/core/host_comms_manager.h"
24 #include "chre/core/host_endpoint_manager.h"
25 #include "chre/core/settings.h"
26 #include "chre/core/system_health_monitor.h"
27 #include "chre/platform/atomic.h"
28 #include "chre/platform/memory_manager.h"
29 #include "chre/platform/mutex.h"
30 #include "chre/util/always_false.h"
31 #include "chre/util/fixed_size_vector.h"
32 #include "chre/util/non_copyable.h"
33 #include "chre/util/singleton.h"
34 #include "chre/util/unique_ptr.h"
35 #include "chre_api/chre/event.h"
36 
37 #ifdef CHRE_AUDIO_SUPPORT_ENABLED
38 #include "chre/core/audio_request_manager.h"
39 #endif  // CHRE_AUDIO_SUPPORT_ENABLED
40 
41 #ifdef CHRE_BLE_SUPPORT_ENABLED
42 #include "chre/core/ble_request_manager.h"
43 #endif  // CHRE_BLE_SUPPORT_ENABLED
44 
45 #ifdef CHRE_GNSS_SUPPORT_ENABLED
46 #include "chre/core/gnss_manager.h"
47 #endif  // CHRE_GNSS_SUPPORT_ENABLED
48 
49 #ifdef CHRE_SENSORS_SUPPORT_ENABLED
50 #include "chre/core/sensor_request_manager.h"
51 #endif  // CHRE_SENSORS_SUPPORT_ENABLED
52 
53 #ifdef CHRE_WIFI_SUPPORT_ENABLED
54 #include "chre/core/wifi_request_manager.h"
55 #endif  // CHRE_WIFI_SUPPORT_ENABLED
56 
57 #ifdef CHRE_WWAN_SUPPORT_ENABLED
58 #include "chre/core/wwan_request_manager.h"
59 #endif  // CHRE_WWAN_SUPPORT_ENABLED
60 
61 #ifdef CHRE_TELEMETRY_SUPPORT_ENABLED
62 #include "chre/core/telemetry_manager.h"
63 #endif  // CHRE_TELEMETRY_SUPPORT_ENABLED
64 
65 #include <cstddef>
66 
67 namespace chre {
68 
69 template <typename T>
70 using TypedSystemEventCallbackFunction = void(SystemCallbackType type,
71                                               UniquePtr<T> &&data);
72 
73 /**
74  * A class that keeps track of all event loops in the system. This class
75  * represents the top-level object in CHRE. It will own all resources that are
76  * shared by all event loops.
77  */
78 class EventLoopManager : public NonCopyable {
79  public:
80   /**
81    * Validates that a CHRE API is invoked from a valid nanoapp context and
82    * returns a pointer to the currently executing nanoapp. This should be
83    * called by most CHRE API methods that require accessing details about the
84    * event loop or the nanoapp itself. If the current event loop or nanoapp are
85    * null, this is an assertion error.
86    *
87    * @param functionName The name of the CHRE API. This should be __func__.
88    * @param eventLoop Optional output parameter, which will be populated with
89    *        the EventLoop that is currently executing if this function is
90    *        successful
91    * @return A pointer to the currently executing nanoapp or null if outside
92    *         the context of a nanoapp.
93    */
94   static Nanoapp *validateChreApiCall(const char *functionName);
95 
96   /**
97    * Leverages the event queue mechanism to schedule a CHRE system callback to
98    * be invoked at some point in the future from within the context of the
99    * "main" EventLoop. Which EventLoop is considered to be the "main" one is
100    * currently not specified, but it is required to be exactly one EventLoop
101    * that does not change at runtime.
102    *
103    * This function is safe to call from any thread.
104    *
105    * @param type An identifier for the callback, which is passed through to the
106    *        callback as a uint16_t, and can also be useful for debugging
107    * @param data Arbitrary data to provide to the callback
108    * @param callback Function to invoke from within the main CHRE thread
109    * @param extraData Additional arbitrary data to provide to the callback
110    * @return If true, the callback was deferred successfully; false otherwise.
111    */
112   bool deferCallback(SystemCallbackType type, void *data,
113                      SystemEventCallbackFunction *callback,
114                      void *extraData = nullptr) {
115     return mEventLoop.postSystemEvent(static_cast<uint16_t>(type), data,
116                                       callback, extraData);
117   }
118 
119   /**
120    * Alternative version of deferCallback which accepts a UniquePtr for the data
121    * passed to the callback. This overload helps ensure that type continuity is
122    * maintained with the callback, and also helps to ensure that the memory is
123    * not leaked, including when CHRE is shutting down.
124    *
125    * Safe to call from any thread.
126    *
127    * @param type An identifier for the callback, which is passed through as
128    *        uint16_t, and can also be useful for debugging
129    * @param data Pointer to arbitrary data to provide to the callback
130    * @param callback Function to invoke from within the main CHRE thread
131    * @return If true, the callback was deferred successfully; false otherwise.
132    */
133   template <typename T>
deferCallback(SystemCallbackType type,UniquePtr<T> && data,TypedSystemEventCallbackFunction<T> * callback)134   bool deferCallback(SystemCallbackType type, UniquePtr<T> &&data,
135                      TypedSystemEventCallbackFunction<T> *callback) {
136     auto outerCallback = [](uint16_t callbackType, void *eventData,
137                             void *extraData) {
138       // Re-wrap eventData in UniquePtr so its destructor will get called and
139       // the memory will be freed once we leave this scope
140       UniquePtr<T> dataWrapped = UniquePtr<T>(static_cast<T *>(eventData));
141       auto *innerCallback =
142           reinterpret_cast<TypedSystemEventCallbackFunction<T> *>(extraData);
143       innerCallback(static_cast<SystemCallbackType>(callbackType),
144                     std::move(dataWrapped));
145     };
146     // Pass the "inner" callback (the caller's callback) through to the "outer"
147     // callback using the extraData parameter. Note that we're leveraging the
148     // C++11 ability to cast a function pointer to void*
149     bool status = mEventLoop.postSystemEvent(
150         static_cast<uint16_t>(type), data.get(), outerCallback,
151         reinterpret_cast<void *>(callback));
152     if (status) {
153       data.release();
154     }
155     return status;
156   }
157 
158   //! Override that allows passing a lambda for the callback
159   template <typename T, typename LambdaT>
deferCallback(SystemCallbackType type,UniquePtr<T> && data,LambdaT callback)160   bool deferCallback(SystemCallbackType type, UniquePtr<T> &&data,
161                      LambdaT callback) {
162     return deferCallback(
163         type, std::move(data),
164         static_cast<TypedSystemEventCallbackFunction<T> *>(callback));
165   }
166 
167   //! Disallows passing a null callback, as we don't include a null check in the
168   //! outer callback to reduce code size. Note that this doesn't prevent the
169   //! caller from passing a variable which is set to nullptr at runtime, but
170   //! generally the callback is always known at compile time.
171   template <typename T>
deferCallback(SystemCallbackType,UniquePtr<T> &&,std::nullptr_t)172   void deferCallback(SystemCallbackType /*type*/, UniquePtr<T> && /*data*/,
173                      std::nullptr_t /*callback*/) {
174     static_assert(AlwaysFalse<T>::value,
175                   "deferCallback(SystemCallbackType, UniquePtr<T>, nullptr) is "
176                   "not allowed");
177   }
178 
179   /**
180    * Schedules a CHRE system callback to be invoked at some point in the future
181    * after a specified amount of time, in the context of the "main" CHRE
182    * EventLoop.
183    *
184    * This function is safe to call from any thread.
185    *
186    * @param type An identifier for the callback, which is passed through to the
187    *        callback as a uint16_t, and can also be useful for debugging
188    * @param data Arbitrary data to provide to the callback
189    * @param callback Function to invoke from within the main CHRE event loop -
190    *        note that extraData is always passed back as nullptr
191    * @param delay The delay to postpone posting the event
192    * @return TimerHandle of the requested timer.
193    *
194    * @see deferCallback
195    */
setDelayedCallback(SystemCallbackType type,void * data,SystemEventCallbackFunction * callback,Nanoseconds delay)196   TimerHandle setDelayedCallback(SystemCallbackType type, void *data,
197                                  SystemEventCallbackFunction *callback,
198                                  Nanoseconds delay) {
199     return mEventLoop.getTimerPool().setSystemTimer(delay, callback, type,
200                                                     data);
201   }
202 
203   /**
204    * Cancels a delayed callback previously scheduled by setDelayedCallback.
205    *
206    * This function is safe to call from any thread.
207    *
208    * @param timerHandle The TimerHandle returned by setDelayedCallback
209    *
210    * @return true if the callback was successfully cancelled
211    */
cancelDelayedCallback(TimerHandle timerHandle)212   bool cancelDelayedCallback(TimerHandle timerHandle) {
213     return mEventLoop.getTimerPool().cancelSystemTimer(timerHandle);
214   }
215 
216   /**
217    * Returns a guaranteed unique instance identifier to associate with a newly
218    * constructed nanoapp.
219    *
220    * @return a unique instance ID
221    */
222   uint16_t getNextInstanceId();
223 
224 #ifdef CHRE_AUDIO_SUPPORT_ENABLED
225   /**
226    * @return A reference to the audio request manager. This allows interacting
227    *         with the audio subsystem and manages requests from various
228    *         nanoapps.
229    */
getAudioRequestManager()230   AudioRequestManager &getAudioRequestManager() {
231     return mAudioRequestManager;
232   }
233 #endif  // CHRE_AUDIO_SUPPORT_ENABLED
234 
235 #ifdef CHRE_BLE_SUPPORT_ENABLED
236   /**
237    * @return A reference to the ble request manager. This allows interacting
238    *         with the ble subsystem and manages requests from various
239    *         nanoapps.
240    */
getBleRequestManager()241   BleRequestManager &getBleRequestManager() {
242     return mBleRequestManager;
243   }
244 #endif  // CHRE_BLE_SUPPORT_ENABLED
245 
246   /**
247    * @return The event loop managed by this event loop manager.
248    */
getEventLoop()249   EventLoop &getEventLoop() {
250     return mEventLoop;
251   }
252 
253 #ifdef CHRE_GNSS_SUPPORT_ENABLED
254   /**
255    * @return A reference to the GNSS request manager. This allows interacting
256    *         with the platform GNSS subsystem and manages requests from various
257    *         nanoapps.
258    */
getGnssManager()259   GnssManager &getGnssManager() {
260     return mGnssManager;
261   }
262 #endif  // CHRE_GNSS_SUPPORT_ENABLED
263 
264   /**
265    * @return A reference to the host communications manager that enables
266    *         transferring arbitrary data between the host processor and CHRE.
267    */
getHostCommsManager()268   HostCommsManager &getHostCommsManager() {
269     return mHostCommsManager;
270   }
271 
getHostEndpointManager()272   HostEndpointManager &getHostEndpointManager() {
273     return mHostEndpointManager;
274   }
275 
276 #ifdef CHRE_SENSORS_SUPPORT_ENABLED
277   /**
278    * @return Returns a reference to the sensor request manager. This allows
279    *         interacting with the platform sensors and managing requests from
280    *         various nanoapps.
281    */
getSensorRequestManager()282   SensorRequestManager &getSensorRequestManager() {
283     return mSensorRequestManager;
284   }
285 #endif  // CHRE_SENSORS_SUPPORT_ENABLED
286 
287 #ifdef CHRE_WIFI_SUPPORT_ENABLED
288   /**
289    * @return Returns a reference to the wifi request manager. This allows
290    *         interacting with the platform wifi subsystem and manages the
291    *         requests from various nanoapps.
292    */
getWifiRequestManager()293   WifiRequestManager &getWifiRequestManager() {
294     return mWifiRequestManager;
295   }
296 #endif  // CHRE_WIFI_SUPPORT_ENABLED
297 
298 #ifdef CHRE_WWAN_SUPPORT_ENABLED
299   /**
300    * @return A reference to the WWAN request manager. This allows interacting
301    *         with the platform WWAN subsystem and manages requests from various
302    *         nanoapps.
303    */
getWwanRequestManager()304   WwanRequestManager &getWwanRequestManager() {
305     return mWwanRequestManager;
306   }
307 #endif  // CHRE_WWAN_SUPPORT_ENABLED
308 
309   /**
310    * @return A reference to the memory manager. This allows central control of
311    *         the heap space allocated by nanoapps.
312    */
getMemoryManager()313   MemoryManager &getMemoryManager() {
314     return mMemoryManager;
315   }
316 
317   /**
318    * @return A reference to the debug dump manager. This allows central control
319    *         of the debug dump process.
320    */
getDebugDumpManager()321   DebugDumpManager &getDebugDumpManager() {
322     return mDebugDumpManager;
323   }
324 
325 #ifdef CHRE_TELEMETRY_SUPPORT_ENABLED
326   /**
327    * @return A reference to the telemetry manager.
328    */
getTelemetryManager()329   TelemetryManager &getTelemetryManager() {
330     return mTelemetryManager;
331   }
332 #endif  // CHRE_TELEMETRY_SUPPORT_ENABLED
333 
334   /**
335    * @return A reference to the setting manager.
336    */
getSettingManager()337   SettingManager &getSettingManager() {
338     return mSettingManager;
339   }
340 
getSystemHealthMonitor()341   SystemHealthMonitor &getSystemHealthMonitor() {
342     return mSystemHealthMonitor;
343   }
344 
345   /**
346    * Performs second-stage initialization of things that are not necessarily
347    * required at construction time but need to be completed prior to executing
348    * any nanoapps.
349    */
350   void lateInit();
351 
352  private:
353   //! The instance ID generated by getNextInstanceId().
354   AtomicUint32 mNextInstanceId{kSystemInstanceId + 1};
355 
356 #ifdef CHRE_AUDIO_SUPPORT_ENABLED
357   //! The audio request manager handles requests for all nanoapps and manages
358   //! the state of the audio subsystem that the runtime subscribes to.
359   AudioRequestManager mAudioRequestManager;
360 #endif
361 
362 #ifdef CHRE_BLE_SUPPORT_ENABLED
363   //! The BLE request manager handles requests for all nanoapps and manages
364   //! the state of the BLE subsystem that the runtime subscribes to.
365   BleRequestManager mBleRequestManager;
366 #endif  // CHRE_BLE_SUPPORT_ENABLED
367 
368   //! The event loop managed by this event loop manager.
369   EventLoop mEventLoop;
370 
371 #ifdef CHRE_GNSS_SUPPORT_ENABLED
372   //! The GnssManager that handles requests for all nanoapps. This manages the
373   //! state of the GNSS subsystem that the runtime subscribes to.
374   GnssManager mGnssManager;
375 #endif  // CHRE_GNSS_SUPPORT_ENABLED
376 
377   //! Handles communications with the host processor.
378   HostCommsManager mHostCommsManager;
379 
380   HostEndpointManager mHostEndpointManager;
381 
382   SystemHealthMonitor mSystemHealthMonitor;
383 
384 #ifdef CHRE_SENSORS_SUPPORT_ENABLED
385   //! The SensorRequestManager that handles requests for all nanoapps. This
386   //! manages the state of all sensors that runtime subscribes to.
387   SensorRequestManager mSensorRequestManager;
388 #endif  // CHRE_SENSORS_SUPPORT_ENABLED
389 
390 #ifdef CHRE_WIFI_SUPPORT_ENABLED
391   //! The WifiRequestManager that handles requests for nanoapps. This manages
392   //! the state of the wifi subsystem that the runtime subscribes to.
393   WifiRequestManager mWifiRequestManager;
394 #endif  // CHRE_WIFI_SUPPORT_ENABLED
395 
396 #ifdef CHRE_WWAN_SUPPORT_ENABLED
397   //! The WwanRequestManager that handles requests for nanoapps. This manages
398   //! the state of the WWAN subsystem that the runtime subscribes to.
399   WwanRequestManager mWwanRequestManager;
400 #endif  // CHRE_WWAN_SUPPORT_ENABLED
401 
402   //! The MemoryManager that handles malloc/free call from nanoapps and also
403   //! controls upper limits on the heap allocation amount.
404   MemoryManager mMemoryManager;
405 
406   //! The DebugDumpManager that handles the debug dump process.
407   DebugDumpManager mDebugDumpManager;
408 
409 #ifdef CHRE_TELEMETRY_SUPPORT_ENABLED
410   //! The TelemetryManager that handles metric collection/reporting.
411   TelemetryManager mTelemetryManager;
412 #endif  // CHRE_TELEMETRY_SUPPORT_ENABLED
413 
414   //! The SettingManager that manages setting states.
415   SettingManager mSettingManager;
416 };
417 
418 //! Provide an alias to the EventLoopManager singleton.
419 typedef Singleton<EventLoopManager> EventLoopManagerSingleton;
420 
421 //! Extern the explicit EventLoopManagerSingleton to force non-inline method
422 //! calls. This reduces codesize considerably.
423 extern template class Singleton<EventLoopManager>;
424 
425 #ifdef CHRE_SENSORS_SUPPORT_ENABLED
getSensorRequestManager()426 inline SensorRequestManager &getSensorRequestManager() {
427   return EventLoopManagerSingleton::get()->getSensorRequestManager();
428 }
429 #endif  // CHRE_SENSORS_SUPPORT_ENABLED
430 
431 }  // namespace chre
432 
433 #endif  // CHRE_CORE_EVENT_LOOP_MANAGER_H_
434