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