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