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