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