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