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