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