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