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