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