1e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/*
2e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Copyright (C) 2016 The Android Open Source Project
3e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *
4e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Licensed under the Apache License, Version 2.0 (the "License");
5e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * you may not use this file except in compliance with the License.
6e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * You may obtain a copy of the License at
7e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *
8e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *      http://www.apache.org/licenses/LICENSE-2.0
9e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie *
10e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * Unless required by applicable law or agreed to in writing, software
11e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * distributed under the License is distributed on an "AS IS" BASIS,
12e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * See the License for the specific language governing permissions and
14e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie * limitations under the License.
15e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */
16e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
17e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#ifndef CHRE_CORE_EVENT_LOOP_H_
18e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#define CHRE_CORE_EVENT_LOOP_H_
19e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
20e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/event.h"
21e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/core/nanoapp.h"
22fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol#include "chre/core/timer_pool.h"
23977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie#include "chre/platform/mutex.h"
242de17c9c5c541d72248f8371dfb4d7e402dc93e8Andrew Rossignol#include "chre/platform/platform_nanoapp.h"
25ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro#include "chre/platform/power_control_manager.h"
26c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol#include "chre/util/dynamic_vector.h"
27022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol#include "chre/util/fixed_size_blocking_queue.h"
28e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#include "chre/util/non_copyable.h"
29a1d5686c7513f6b8a436efd9f554d8c2227a2291Brian Duddie#include "chre/util/synchronized_memory_pool.h"
302de17c9c5c541d72248f8371dfb4d7e402dc93e8Andrew Rossignol#include "chre/util/unique_ptr.h"
3162f187d9d736346275492e916f6001576b68bb00Brian Duddie#include "chre_api/chre/event.h"
32e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
33cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung// These default values can be overridden in the variant-specific makefile.
34cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#ifndef CHRE_MAX_EVENT_COUNT
35cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#define CHRE_MAX_EVENT_COUNT 96
36cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#endif
37cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung
38cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#ifndef CHRE_MAX_UNSCHEDULED_EVENT_COUNT
39cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#define CHRE_MAX_UNSCHEDULED_EVENT_COUNT 96
40cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung#endif
41cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung
42e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddienamespace chre {
43e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
44e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie/**
45977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * The EventLoop represents a single thread of execution that is shared among
46977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * zero or more nanoapps. As the name implies, the EventLoop is built around a
47977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie * loop that delivers events to the nanoapps managed within for processing.
48e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie */
49e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddieclass EventLoop : public NonCopyable {
50e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie public:
51fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol  /**
52a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * Synchronous callback used with forEachNanoapp
53a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   */
54a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie  typedef void (NanoappCallbackFunction)(const Nanoapp *nanoapp, void *data);
55a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie
56a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie  /**
57977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * Searches the set of nanoapps managed by this EventLoop for one with the
58977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * given app ID. If found, provides its instance ID, which can be used to send
59977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * events to the app.
60977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   *
61977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * This function is safe to call from any thread.
62977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   *
63977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * @param appId The nanoapp identifier to search for.
64977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * @param instanceId If this function returns true, will be populated with the
65977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   *        instanceId associated with the given appId; otherwise unmodified.
66977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   *        Must not be null.
67977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * @return true if the given app ID was found and instanceId was populated
68977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   */
692fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie  bool findNanoappInstanceIdByAppId(uint64_t appId, uint32_t *instanceId) const;
70e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
71e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  /**
72a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * Iterates over the list of Nanoapps managed by this EventLoop, and invokes
73a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * the supplied callback for each one. This holds a lock if necessary, so it
74a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * is safe to call from any thread.
75a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   *
76a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * @param callback Function to invoke on each Nanoapp (synchronously)
77a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * @param data Arbitrary data to pass to the callback
78a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   */
79a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie  void forEachNanoapp(NanoappCallbackFunction *callback, void *data);
80a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie
81a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie  /**
8209a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * Invokes a message to host free callback supplied by the given nanoapp
8309a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * (identified by app ID). Ensures that the calling context is updated
8409a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * appropriately.
8509a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   *
8609a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * @param appId Identifies the nanoapp that sent this message and supplied the
8709a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   *        free callback
8809a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * @param freeFunction The non-null message free callback given by the nanoapp
8909a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * @param message Pointer to the message data
9009a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * @param messageSize Size of the message
9109a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   */
9209a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie  void invokeMessageFreeFunction(
9309a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie      uint64_t appId, chreMessageFreeFunction *freeFunction, void *message,
9409a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie      size_t messageSize);
9509a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie
9609a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie  /**
979d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   * Invokes the Nanoapp's start callback, and if successful, adds it to the
989d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   * set of Nanoapps managed by this EventLoop. This function must only be
999d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   * called from the context of the thread that runs this event loop (i.e. from
1009d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   * the same thread that will call run() or from a callback invoked within
1019d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   * run()).
102e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   *
1039d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   * @param nanoapp The nanoapp that will be started. Upon success, this
1049d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   *        UniquePtr will become invalid, as the underlying Nanoapp instance
1059d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   *        will have been transferred to be managed by this EventLoop.
1069d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie   * @return true if the app was started successfully
107e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   */
1089d5b500a223ef73560f0dce38f50b809bde5dd0dBrian Duddie  bool startNanoapp(UniquePtr<Nanoapp>& nanoapp);
109e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
110e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  /**
11199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * Stops and unloads a nanoapp identified by its instance ID. The end entry
11299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * point will be invoked, and the chre::Nanoapp instance will be destroyed.
11399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * After this function returns, all references to the Nanoapp instance are
11499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * invalidated.
115e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   *
11699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * @param instanceId The nanoapp's unique instance identifier
11799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * @param allowSystemNanoappUnload If false, this function will reject
11899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   *        attempts to unload a system nanoapp
11999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   *
12099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * @return true if the nanoapp with the given instance ID was found & unloaded
121e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   */
12299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  bool unloadNanoapp(uint32_t instanceId, bool allowSystemNanoappUnload);
123e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
124e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  /**
125977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * Executes the loop that blocks on the event queue and delivers received
126977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * events to nanoapps. Only returns after stop() is called (from another
127977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * context).
128e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   */
129e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  void run();
130e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
131e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  /**
132e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   * Signals the event loop currently executing in run() to exit gracefully at
133f80ea015d077330cfdbd619680b250915ffcf1d2Brian Duddie   * the next available opportunity. This function is thread-safe.
134e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   */
135e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  void stop();
136e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
1374927ee586656424c827920876673228fbdcf27c3Andrew Rossignol  /**
1384927ee586656424c827920876673228fbdcf27c3Andrew Rossignol   * Posts an event to a nanoapp that is currently running (or all nanoapps if
1393c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol   * the target instance ID is kBroadcastInstanceId). If the senderInstanceId is
1403c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol   * kSystemInstanceId and the event fails to post, this is considered a fatal
1413c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol   * error.
142042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie   *
143042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie   * This function is safe to call from any thread.
1444927ee586656424c827920876673228fbdcf27c3Andrew Rossignol   *
1455d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * @param eventType The type of data being posted.
1465d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * @param eventData The data being posted.
1475d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * @param freeCallback The callback to invoke when the event is no longer
1485d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   *        needed.
1495d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * @param senderInstanceId The instance ID of the sender of this event.
1505d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * @param targetInstanceId The instance ID of the destination of this event.
1514927ee586656424c827920876673228fbdcf27c3Andrew Rossignol   *
152a12d05f5b1b8bd8d953a328758426b7ca8b5e6deBrian Duddie   * @return true if the event was successfully added to the queue. Note that
153a12d05f5b1b8bd8d953a328758426b7ca8b5e6deBrian Duddie   *         unlike chreSendEvent, this does *not* invoke the free callback if
154a12d05f5b1b8bd8d953a328758426b7ca8b5e6deBrian Duddie   *         it failed to post the event.
1555d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   *
1565d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * @see chreSendEvent
1574927ee586656424c827920876673228fbdcf27c3Andrew Rossignol   */
158042f73e3b7f019c818f69b2c097c4b6f9db839b5Brian Duddie  bool postEvent(uint16_t eventType, void *eventData,
1594927ee586656424c827920876673228fbdcf27c3Andrew Rossignol                 chreEventCompleteFunction *freeCallback,
1604927ee586656424c827920876673228fbdcf27c3Andrew Rossignol                 uint32_t senderInstanceId = kSystemInstanceId,
1614927ee586656424c827920876673228fbdcf27c3Andrew Rossignol                 uint32_t targetInstanceId = kBroadcastInstanceId);
162e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
163e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  /**
16453bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   * Post an event to a nanoapp. If it fails, free the event with freeCallback.
16553bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   *
16653bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   * @see postEvent
16753bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   */
16853bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung  bool postEventOrFree(uint16_t eventType, void *eventData,
16953bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung                       chreEventCompleteFunction *freeCallback,
17053bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung                       uint32_t senderInstanceId = kSystemInstanceId,
17153bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung                       uint32_t targetInstanceId = kBroadcastInstanceId);
17253bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung
17353bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung  /**
174e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   * Returns a pointer to the currently executing Nanoapp, or nullptr if none is
175977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * currently executing. Must only be called from within the thread context
176977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * associated with this EventLoop.
177e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   *
178977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * @return the currently executing nanoapp, or nullptr
179e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie   */
180b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol  Nanoapp *getCurrentNanoapp() const {
181b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol    return mCurrentApp;
182b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol  }
183e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
184e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  /**
185a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * Gets the number of nanoapps currently associated with this event loop. Must
186a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * only be called within the context of this EventLoop.
187a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   *
188a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   * @return The number of nanoapps managed by this event loop
189a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie   */
190b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol  size_t getNanoappCount() const {
191b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol    return mNanoapps.size();
192b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol  }
193a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie
194a2f5add27054c406f36528cf8a5cbc6d4c79d246Brian Duddie  /**
195725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol   * Obtains the TimerPool associated with this event loop.
196725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol   *
197725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol   * @return The timer pool owned by this event loop.
198725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol   */
199b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol  TimerPool& getTimerPool() {
200b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol    return mTimerPool;
201b75315a3e185b4559d73c69eea3b30679239fac1Andrew Rossignol  }
202725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol
20330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol  /**
20430f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   * Searches the set of nanoapps managed by this EventLoop for one with the
20530f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   * given instance ID.
20630f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   *
20730f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   * This function is safe to call from any thread.
20830f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   *
20930f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   * @param instanceId The nanoapp instance ID to search for.
21030f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   * @return a pointer to the found nanoapp or nullptr if no match was found.
21130f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol   */
2122fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie  Nanoapp *findNanoappByInstanceId(uint32_t instanceId) const;
21330f18903edc1dfe46e12b9989760ef7a56cb31d3Andrew Rossignol
21499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  /**
21562f187d9d736346275492e916f6001576b68bb00Brian Duddie   * Looks for an app with the given ID and if found, populates info with its
21662f187d9d736346275492e916f6001576b68bb00Brian Duddie   * metadata. Safe to call from any thread.
21762f187d9d736346275492e916f6001576b68bb00Brian Duddie   *
21862f187d9d736346275492e916f6001576b68bb00Brian Duddie   * @see chreGetNanoappInfoByAppId
21962f187d9d736346275492e916f6001576b68bb00Brian Duddie   */
22062f187d9d736346275492e916f6001576b68bb00Brian Duddie  bool populateNanoappInfoForAppId(uint64_t appId,
22162f187d9d736346275492e916f6001576b68bb00Brian Duddie                                   struct chreNanoappInfo *info) const;
22262f187d9d736346275492e916f6001576b68bb00Brian Duddie
22362f187d9d736346275492e916f6001576b68bb00Brian Duddie  /**
22462f187d9d736346275492e916f6001576b68bb00Brian Duddie   * Looks for an app with the given instance ID and if found, populates info
22562f187d9d736346275492e916f6001576b68bb00Brian Duddie   * with its metadata. Safe to call from any thread.
22662f187d9d736346275492e916f6001576b68bb00Brian Duddie   *
22762f187d9d736346275492e916f6001576b68bb00Brian Duddie   * @see chreGetNanoappInfoByInstanceId
22862f187d9d736346275492e916f6001576b68bb00Brian Duddie   */
22962f187d9d736346275492e916f6001576b68bb00Brian Duddie  bool populateNanoappInfoForInstanceId(uint32_t instanceId,
23062f187d9d736346275492e916f6001576b68bb00Brian Duddie                                        struct chreNanoappInfo *info) const;
23162f187d9d736346275492e916f6001576b68bb00Brian Duddie
23262f187d9d736346275492e916f6001576b68bb00Brian Duddie  /**
23399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * @return true if the current Nanoapp (or entire CHRE) is being unloaded, and
23499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   *         therefore it should not be allowed to send events or messages, etc.
23599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   */
2362fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie  bool currentNanoappIsStopping() const;
23799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
238d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro  /**
239d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   * Prints state in a string buffer. Must only be called from the context of
240d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   * the main CHRE thread.
241d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   *
242d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   * @param buffer Pointer to the start of the buffer.
243d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   * @param bufferPos Pointer to buffer position to start the print (in-out).
244d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   * @param size Size of the buffer in bytes.
245d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   *
246d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   * @return true if entire log printed, false if overflow or error.
247d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro   */
248d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro  bool logStateToBuffer(char *buffer, size_t *bufferPos,
249d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro                        size_t bufferSize) const;
250d0530f420d8bdaee755ec2834af407424de195e0Arthur Ishiguro
251ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro
252ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro  /**
253ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro   * Returns a reference to the power control manager. This allows power
254ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro   * controls from subsystems outside the event loops.
255ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro   */
256ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro  PowerControlManager& getPowerControlManager() {
257ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro    return mPowerControlManager;
258ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro  }
259ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro
260e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie private:
2614927ee586656424c827920876673228fbdcf27c3Andrew Rossignol  //! The maximum number of events that can be active in the system.
262cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung  static constexpr size_t kMaxEventCount = CHRE_MAX_EVENT_COUNT;
2634927ee586656424c827920876673228fbdcf27c3Andrew Rossignol
2643c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol  //! The minimum number of events to reserve in the event pool for system
2653c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol  //! events.
2663c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol  static constexpr size_t kMinReservedSystemEventCount = 16;
2673c8d7a9746ec61c1677ed33f9fcd25d3830392c7Andrew Rossignol
268022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol  //! The maximum number of events that are awaiting to be scheduled. These
269022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol  //! events are in a queue to be distributed to apps.
270cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung  static constexpr size_t kMaxUnscheduledEventCount =
271cbf0967e920840e21bcd6aeda67d88b70d30a558Meng-hsuan Chung      CHRE_MAX_UNSCHEDULED_EVENT_COUNT;
272022cc6c770c299bb364e35377a2661791475bbceAndrew Rossignol
2734927ee586656424c827920876673228fbdcf27c3Andrew Rossignol  //! The memory pool to allocate incoming events from.
274f7914d0fbadf2644c0c4096380c741bee2a026e0Andrew Rossignol  SynchronizedMemoryPool<Event, kMaxEventCount> mEventPool;
2754927ee586656424c827920876673228fbdcf27c3Andrew Rossignol
276fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol  //! The timer used schedule timed events for tasks running in this event loop.
277fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol  TimerPool mTimerPool;
278fbb213b072fec0a14f437ad55685c4d95eec829eAndrew Rossignol
279c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol  //! The list of nanoapps managed by this event loop.
2802de17c9c5c541d72248f8371dfb4d7e402dc93e8Andrew Rossignol  DynamicVector<UniquePtr<Nanoapp>> mNanoapps;
281725bef45ca127971b3ea798cd1f4e4b2c0d8fe9dAndrew Rossignol
282977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  //! This lock *must* be held whenever we:
283977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  //!   (1) make changes to the mNanoapps vector, or
284977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  //!   (2) read the mNanoapps vector from a thread other than the one
285977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  //!       associated with this EventLoop
286977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  //! It is not necessary to acquire the lock when reading mNanoapps from within
287977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  //! the thread context of this EventLoop.
2882fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie  mutable Mutex mNanoappsLock;
289977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie
290c03d7df169f13195652de29f4452830130a0c53fAndrew Rossignol  //! The blocking queue of incoming events from the system that have not been
29199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  //! distributed out to apps yet.
2921795db1e2282dac8454cf59d23314f70b6930f7bAndrew Rossignol  FixedSizeBlockingQueue<Event *, kMaxUnscheduledEventCount> mEvents;
293e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
294977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  // TODO: should probably be atomic to be fully correct
2958c56d08e149720fcb99e6ddc71289ebb5ee594e6Brian Duddie  volatile bool mRunning = true;
296e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
29799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  //! The nanoapp that is currently executing - must be set any time we call
29899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  //! into the nanoapp's entry points or callbacks
299e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  Nanoapp *mCurrentApp = nullptr;
300e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
30199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  //! Set to the nanoapp we are in the process of unloading in unloadNanoapp()
30299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  Nanoapp *mStoppingNanoapp = nullptr;
30399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
304ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro  //! The object which manages power related controls.
305ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro  PowerControlManager mPowerControlManager;
306ff1c1a2ab3ff2614bb6cea1f1d6f6e9c44a87464Arthur Ishiguro
30788f21c7ca23d96f6ef568a06c98f3a5c4538140fAndrew Rossignol  //! The maximum number of events ever waiting in the event pool.
30888f21c7ca23d96f6ef568a06c98f3a5c4538140fAndrew Rossignol  size_t mMaxEventPoolUsage = 0;
30988f21c7ca23d96f6ef568a06c98f3a5c4538140fAndrew Rossignol
31099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  /**
31153bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   * Allolcates an event from the event pool and post it.
31253bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   *
31353bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   * @return true if the event has been successfully allocated and posted.
31453bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   *
31553bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   * @see postEvent and postEventOrFree
31653bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung   */
31753bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung  bool allocateAndPostEvent(uint16_t eventType, void *eventData,
31853bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung    chreEventCompleteFunction *freeCallback, uint32_t senderInstanceId,
31953bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung    uint32_t targetInstanceId);
32053bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung
32153bc18a9e15f478ea0332a733b77c718114a8610Meng-hsuan Chung  /**
32299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * Do one round of Nanoapp event delivery, only considering events in
32399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * Nanoapps' own queues (not mEvents).
32499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   *
32599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * @return true if there are more events pending in Nanoapps' own queues
32699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   */
32799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  bool deliverEvents();
32899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
329977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  /**
3305d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * Delivers the next event pending in the Nanoapp's queue, and takes care of
3315d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * freeing events once they have been delivered to all nanoapps. Must only be
3325d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * called after confirming that the app has at least 1 pending event.
3335d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   *
3345d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   * @return true if the nanoapp has another event pending in its queue
3355d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   */
3365d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie  bool deliverNextEvent(const UniquePtr<Nanoapp>& app);
3375d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie
3385d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie  /**
33999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * Given an event pulled from the main incoming event queue (mEvents), deliver
34099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * it to all Nanoapps that should receive the event, or free the event if
34199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * there are no valid recipients.
34299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   *
34399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * @param event The Event to distribute to Nanoapps
34499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   */
34599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  void distributeEvent(Event *event);
34699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
34799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  /**
34899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * Distribute all events pending in the inbound event queue. Note that this
34999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * function only guarantees that any events in the inbound queue at the time
35099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * it is called will be distributed to Nanoapp event queues - new events may
35199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * still be posted during or after this function call from other threads as
35299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * long as postEvent() will accept them.
35399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   */
35499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  void flushInboundEventQueue();
35599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
35699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  /**
35799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * Delivers events pending in Nanoapps' own queues until they are all empty.
35899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   */
35999f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  void flushNanoappEventQueues();
36099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie
36199f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  /**
362977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * Call after when an Event has been delivered to all intended recipients.
363977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * Invokes the event's free callback (if given) and releases resources.
364977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   *
365977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * @param event The event to be freed
366977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   */
367e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie  void freeEvent(Event *event);
368e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
369977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie  /**
37009a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * Finds a Nanoapp with the given 64-bit appId.
37109a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   *
3722fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie   * Only safe to call within this EventLoop's thread, or if mNanoappsLock is
3732fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie   * held.
37409a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   *
37509a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * @param appId Nanoapp ID
37609a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   * @return Pointer to Nanoapp instance in this EventLoop with the given app
37709a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   *         ID, or nullptr if not found
37809a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie   */
3792fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie  Nanoapp *lookupAppByAppId(uint64_t appId) const;
38009a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie
38109a4783208b5ba1e14d0f0102eb31e688caca28dBrian Duddie  /**
382977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * Finds a Nanoapp with the given instanceId.
383977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   *
3842fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie   * Only safe to call within this EventLoop's thread, or if mNanoappsLock is
3852fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie   * held.
386977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   *
387977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * @param instanceId Nanoapp instance identifier
388977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   * @return Nanoapp with the given instanceId, or nullptr if not found
389977321d9ad051d4d6519a5fa8c2ca914f4d1424fBrian Duddie   */
3902fce52a25d14fcdcba888f8ff7892dffe3f55abaBrian Duddie  Nanoapp *lookupAppByInstanceId(uint32_t instanceId) const;
3915d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie
3925d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie  /**
39365d679851a2c062c26f685afb450f17bce177d29Brian Duddie   * Sends an event with payload struct chreNanoappInfo populated from the given
39465d679851a2c062c26f685afb450f17bce177d29Brian Duddie   * Nanoapp instance to inform other nanoapps about it starting/stopping.
39565d679851a2c062c26f685afb450f17bce177d29Brian Duddie   *
39665d679851a2c062c26f685afb450f17bce177d29Brian Duddie   * @param eventType Should be one of CHRE_EVENT_NANOAPP_{STARTED, STOPPED}
39765d679851a2c062c26f685afb450f17bce177d29Brian Duddie   * @param nanoapp The nanoapp instance whose status has changed
39865d679851a2c062c26f685afb450f17bce177d29Brian Duddie   */
39965d679851a2c062c26f685afb450f17bce177d29Brian Duddie  void notifyAppStatusChange(uint16_t eventType, const Nanoapp& nanoapp);
40065d679851a2c062c26f685afb450f17bce177d29Brian Duddie
40165d679851a2c062c26f685afb450f17bce177d29Brian Duddie  /**
40299f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * Stops and unloads the Nanoapp at the given index in mNanoapps.
40399f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   *
40499f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * IMPORTANT: prior to calling this function, the event queues must be in a
40599f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * safe condition for removal of this nanoapp. This means that there must not
40699f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * be any pending events in this nanoapp's queue, and there must not be any
40799f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * outstanding events sent by this nanoapp, as they may reference the
40899f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie   * nanoapp's own memory (even if there is no free callback).
4095d9b2d68940f7dac47bf2fbad6f6069ed3b2faaaBrian Duddie   */
41099f01ac9bd6e351538cb8922ef15d9e838e7339aBrian Duddie  void unloadNanoappAtIndex(size_t index);
411e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie};
412e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
413e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie}  // namespace chre
414e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie
415e64f180233e64c40b56993cfea3696c5b4b16395Brian Duddie#endif  // CHRE_CORE_EVENT_LOOP_H_
416