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