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