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