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