xref: /aosp_15_r20/system/chre/host/common/include/chre_host/daemon_base.h (revision 84e339476a462649f82315436d70fd732297a399)
1 /*
2  * Copyright (C) 2010 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_DAEMON_H_
18 #define CHRE_DAEMON_H_
19 
20 /**
21  * @file daemon_base.h
22  * This header defines the CHRE daemon base class, off of which all supported
23  * CHRE daemon variants are expected to derive from. The goal is to provide
24  * common (abstract or implemented) interfaces that all CHRE daemons must
25  * implement.
26  */
27 
28 #include <atomic>
29 #include <csignal>
30 #include <cstdint>
31 #include <map>
32 #include <mutex>
33 #include <queue>
34 #include <string>
35 #include <thread>
36 
37 #include "chre_host/host_protocol_host.h"
38 #include "chre_host/log_message_parser.h"
39 #include "chre_host/socket_server.h"
40 
41 #ifdef CHRE_DAEMON_METRIC_ENABLED
42 #include <aidl/android/frameworks/stats/IStats.h>
43 #include <android/binder_manager.h>
44 
45 #include "chre_host/metrics_reporter.h"
46 #endif  // CHRE_DAEMON_METRIC_ENABLED
47 
48 namespace android {
49 namespace chre {
50 
51 class ChreDaemonBase {
52  public:
53   ChreDaemonBase();
~ChreDaemonBase()54   virtual ~ChreDaemonBase() {
55     if (mSignalHandlerThread.joinable()) {
56       std::raise(SIGINT);
57       mSignalHandlerThread.join();
58     }
59   }
60 
61   /**
62    * Initialize the CHRE daemon. We're expected to fail here and not start
63    * the daemon if we don't get all the resources we're hoping to.
64    * Any resources claimed by this function should be released in the
65    * destructor
66    *
67    * @return true on successful initialization
68    */
69   virtual bool init() = 0;
70 
71   /**
72    * Start the CHRE Daemon. This method must be called after @ref init() has
73    * been called.
74    */
75   virtual void run() = 0;
76 
77   /**
78    * Send a message to CHRE
79    *
80    * @param clientId The client ID that this message originates from.
81    * @param data The data to pass down.
82    * @param length The size of the data to send.
83    * @return true if successful, false otherwise.
84    */
85   virtual bool sendMessageToChre(uint16_t clientId, void *data,
86                                  size_t dataLen) = 0;
87 
88   /**
89    * Function to be invoked on a shutdown request (eg: from a signal handler)
90    * to initiate a graceful shutdown of the daemon.
91    */
onShutdown()92   virtual void onShutdown() {
93     setShutdownRequested(true);
94     mServer.shutdownServer();
95   }
96 
97   /**
98    * Function to query if a graceful shutdown of CHRE was requested
99    *
100    * @return true if a graceful shutdown was requested
101    */
wasShutdownRequested()102   bool wasShutdownRequested() const {
103     return mChreShutdownRequested;
104   }
105 
106  protected:
107   //! The host ID to use when preloading nanoapps. This is used before the
108   //! server is started and is sufficiently high enough so as to not collide
109   //! with any clients after the server starts.
110   static constexpr uint16_t kHostClientIdDaemon = UINT16_MAX;
111 
112   //! Contains the transaction ID and app ID used to preload nanoapps.
113   struct Transaction {
114     uint32_t transactionId;
115     uint64_t nanoappId;
116   };
117 
setShutdownRequested(bool request)118   void setShutdownRequested(bool request) {
119     mChreShutdownRequested = request;
120   }
121 
122   /**
123    * Attempts to load all preloaded nanoapps from a config file. The config file
124    * is expected to be valid JSON with the following structure:
125    *
126    * { "nanoapps": [
127    *     "/path/to/nanoapp_1",
128    *     "/path/to/nanoapp_2"
129    * ]}
130    *
131    * The napp_header and so files will both be loaded. All errors are logged.
132    */
133   void loadPreloadedNanoapps();
134 
135   /**
136    * Loads a preloaded nanoapp given a filename to load from. Allows the
137    * transaction to complete before the nanoapp starts so the server can start
138    * serving requests as soon as possible.
139    *
140    * @param directory The directory to load the nanoapp from.
141    * @param name The filename of the nanoapp to load.
142    * @param transactionId The transaction ID to use when loading the app.
143    */
144   virtual void loadPreloadedNanoapp(const std::string &directory,
145                                     const std::string &name,
146                                     uint32_t transactionId);
147 
148   /**
149    * Sends a preloaded nanoapp filename / metadata to CHRE.
150    *
151    * @param header The nanoapp header binary blob.
152    * @param nanoappName The filename of the nanoapp to be loaded.
153    * @param transactionId The transaction ID to use when loading the app.
154    * @return true if successful, false otherwise.
155    */
156   bool loadNanoapp(const std::vector<uint8_t> &header,
157                    const std::string &nanoappName, uint32_t transactionId);
158 
159   /**
160    * Loads a nanoapp by sending the nanoapp filename to the CHRE framework. This
161    * method will return after sending the request so no guarantee is made that
162    * the nanoapp is loaded until after the response is received.
163    *
164    * @param appId The ID of the nanoapp to load.
165    * @param appVersion The version of the nanoapp to load.
166    * @param appTargetApiVersion The version of the CHRE API that the app
167    * targets.
168    * @param appBinaryName The name of the binary as stored in the filesystem.
169    * This will be used to load the nanoapp into CHRE.
170    * @param transactionId The transaction ID to use when loading.
171    * @return true if a request was successfully sent, false otherwise.
172    */
173   virtual bool sendNanoappLoad(uint64_t appId, uint32_t appVersion,
174                                uint32_t appTargetApiVersion,
175                                const std::string &appBinaryName,
176                                uint32_t transactionId) = 0;
177 
178   /**
179    * Send a time sync message to CHRE
180    *
181    * @param logOnError If true, logs an error message on failure.
182    *
183    * @return true if the time sync message was successfully sent to CHRE.
184    */
185   virtual bool sendTimeSync(bool logOnError) = 0;
186 
187   /**
188    * Computes and returns the clock drift between the system clock
189    * and the processor timer registers
190    *
191    * @return offset in nanoseconds
192    */
193   virtual int64_t getTimeOffset(bool *success) = 0;
194 
195   /**
196    * Sends a time sync message to CHRE, retrying a specified time until success.
197    *
198    * @param maxNumRetries The number of times to retry sending the message
199    *
200    * @return true if the time sync message was successfully sent to CHRE.
201    */
202   bool sendTimeSyncWithRetry(size_t numRetries, useconds_t retryDelayUs,
203                              bool logOnError);
204 
205   /**
206    * Interface to a callback that is called when the Daemon receives a message.
207    *
208    * @param message A buffer containing the message
209    * @param messageLen size of the message buffer in bytes
210    */
211   virtual void onMessageReceived(const unsigned char *message,
212                                  size_t messageLen) = 0;
213 
214   /**
215    * Handles a message that is directed towards the daemon.
216    *
217    * @param message The message sent to the daemon.
218    */
219   virtual void handleDaemonMessage(const uint8_t *message) = 0;
220 
221   /**
222    * Enables or disables LPMA (low power microphone access).
223    */
224   virtual void configureLpma(bool enabled) = 0;
225 
226 #ifdef CHRE_DAEMON_METRIC_ENABLED
227   /**
228    * Handles a metric log message sent from CHRE
229    *
230    */
231   virtual void handleMetricLog(const ::chre::fbs::MetricLogT *metric_msg);
232 
233 #ifdef CHRE_LOG_ATOM_EXTENSION_ENABLED
234   /**
235    * Handles additional metrics that aren't logged by the common CHRE code.
236    */
237   virtual void handleVendorMetricLog(
238       const ::chre::fbs::MetricLogT *metric_msg) = 0;
239 #endif  // CHRE_LOG_ATOM_EXTENSION_ENABLED
240 
241   /**
242    * Create and report CHRE vendor atom and send it to stats_client.
243    *
244    * @param atom the vendor atom to be reported.
245    */
246   void reportMetric(const aidl::android::frameworks::stats::VendorAtom &atom);
247 #endif  // CHRE_DAEMON_METRIC_ENABLED
248 
249   /**
250    * Handles a NAN configuration request sent from CHRE.
251    *
252    * @param request NAN configuration request.
253    */
254   virtual void handleNanConfigurationRequest(
255       const ::chre::fbs::NanConfigurationRequestT *request);
256 
257   /**
258    * Returns the CHRE log message parser instance.
259    * @return log message parser instance.
260    */
getLogger()261   LogMessageParser &getLogger() {
262     return mLogger;
263   }
264 
265   //! Server used to communicate with daemon clients
266   SocketServer mServer;
267 
268 #ifdef CHRE_DAEMON_METRIC_ENABLED
269   android::chre::MetricsReporter mMetricsReporter;
270 #endif  // CHRE_DAEMON_METRIC_ENABLED
271 
272  private:
273   LogMessageParser mLogger;
274 
275   std::thread mSignalHandlerThread;
276 
277   //! Set to true when we request a graceful shutdown of CHRE
278   std::atomic<bool> mChreShutdownRequested;
279 };
280 
281 }  // namespace chre
282 }  // namespace android
283 
284 #endif  // CHRE_DAEMON_H
285