1 /* 2 * Copyright (C) 2016 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_CORE_SENSOR_REQUEST_MANAGER_H_ 18 #define CHRE_CORE_SENSOR_REQUEST_MANAGER_H_ 19 20 #include "chre/core/sensor.h" 21 #include "chre/core/sensor_request.h" 22 #include "chre/core/sensor_request_multiplexer.h" 23 #include "chre/platform/fatal_error.h" 24 #include "chre/platform/platform_sensor_manager.h" 25 #include "chre/platform/system_time.h" 26 #include "chre/platform/system_timer.h" 27 #include "chre/util/non_copyable.h" 28 #include "chre/util/optional.h" 29 #include "chre/util/system/debug_dump.h" 30 31 namespace chre { 32 33 /** 34 * Handles requests from nanoapps for sensor data and information. This includes 35 * multiplexing multiple requests into one for the platform to handle. 36 * 37 * This class is effectively a singleton as there can only be one instance of 38 * the PlatformSensorManager instance. 39 */ 40 class SensorRequestManager : public NonCopyable { 41 public: 42 /** 43 * Destructs the sensor request manager and releases platform sensor resources 44 * if requested. 45 */ 46 ~SensorRequestManager(); 47 48 /** 49 * Initializes the underlying platform-specific sensors. Must be called 50 * prior to invoking any other methods in this class. 51 */ 52 void init(); 53 54 /** 55 * Determines whether the runtime is aware of a given sensor type. The 56 * supplied sensorHandle is only populated if the sensor type is known. 57 * 58 * @param sensorType The type of the sensor. 59 * @param sensorIndex The index of the sensor. 60 * @param targetGroupId The target group ID that must be covered by the 61 * matching sensor. 62 * @param sensorHandle A non-null pointer to a uint32_t to use as a sensor 63 * handle for nanoapps. 64 * @return true if the supplied sensor type is available for use. 65 */ 66 bool getSensorHandle(uint8_t sensorType, uint8_t sensorIndex, 67 uint16_t targetGroupId, uint32_t *sensorHandle) const; 68 69 /** 70 * Same as getSensorHandle(), but the targetGroupId is derived based on the 71 * nanoapp's characteristics. 72 */ getSensorHandleForNanoapp(uint8_t sensorType,uint8_t sensorIndex,const Nanoapp & nanoapp,uint32_t * sensorHandle)73 bool getSensorHandleForNanoapp(uint8_t sensorType, uint8_t sensorIndex, 74 const Nanoapp &nanoapp, 75 uint32_t *sensorHandle) const { 76 return getSensorHandle(sensorType, sensorIndex, 77 mPlatformSensorManager.getTargetGroupId(nanoapp), 78 sensorHandle); 79 } 80 81 /** 82 * Same as getSensorHandle(), but 0 is used for both the sensorIndex and 83 * targetGroupId so that the first sensor matching the type is used. This is 84 * useful when dealing with one-shot sensors that must only have a single 85 * instance. 86 */ getDefaultSensorHandle(uint8_t sensorType,uint32_t * sensorHandle)87 bool getDefaultSensorHandle(uint8_t sensorType, 88 uint32_t *sensorHandle) const { 89 return getSensorHandle(sensorType, 0 /* sensorIndex */, 90 0 /* targetGroupId */, sensorHandle); 91 } 92 93 /** 94 * Sets a sensor request for the given nanoapp for the provided sensor handle. 95 * If the nanoapp has made a previous request, it is replaced by this request. 96 * If the request changes the mode to SensorMode::Off the request is removed. 97 * 98 * @param nanoapp A non-null pointer to the nanoapp requesting this change. 99 * @param sensorHandle The sensor handle for which this sensor request is 100 * directed at. 101 * @param request The new sensor request for this nanoapp. 102 * @return true if the request was set successfully. If the sensorHandle is 103 * out of range or the platform sensor fails to update to the new 104 * request false will be returned. 105 */ 106 bool setSensorRequest(Nanoapp *nanoapp, uint32_t sensorHandle, 107 const SensorRequest &sensorRequest); 108 109 /** 110 * Populates the supplied info struct if the sensor handle exists. 111 * 112 * @param sensorHandle The handle of the sensor. 113 * @param nanoapp The nanoapp requesting this change. 114 * @param info A non-null pointer to a chreSensorInfo struct. 115 * @return true if the supplied sensor handle exists. 116 */ 117 bool getSensorInfo(uint32_t sensorHandle, const Nanoapp &nanoapp, 118 struct chreSensorInfo *info) const; 119 /* 120 * Removes all requests of a sensorType and unregisters all nanoapps for its 121 * events. 122 * 123 * @param sensorHandle The handle of the sensor. 124 * @return true if all requests of the sensor type have been successfully 125 * removed. 126 */ 127 bool removeAllRequests(uint32_t sensorHandle); 128 129 /** 130 * Obtains a pointer to the Sensor of the specified sensorHandle. 131 * 132 * NOTE: Some platform implementations invoke this method from different 133 * threads assuming the underlying list of sensors doesn't change after 134 * initialization. 135 * 136 * @param sensorHandle The sensor handle corresponding to the sensor. 137 * @return A pointer to the Sensor, or nullptr if sensorHandle is invalid. 138 */ 139 Sensor *getSensor(uint32_t sensorHandle); 140 141 /** 142 * Populates the supplied sampling status struct if the sensor handle exists. 143 * 144 * @param sensorHandle The handle of the sensor. 145 * @param status A non-null pointer to a chreSensorSamplingStatus struct. 146 * @return true if the supplied sensor handle exists. 147 */ 148 bool getSensorSamplingStatus(uint32_t sensorHandle, 149 struct chreSensorSamplingStatus *status) const; 150 151 /** 152 * Obtains the list of open requests of the specified sensor handle. 153 * 154 * @param sensorHandle The handle of the sensor. 155 * @return The list of open requests of this sensor in a DynamicVector. 156 */ 157 const DynamicVector<SensorRequest> &getRequests(uint32_t sensorHandle) const; 158 159 /** 160 * Configures a nanoapp to receive bias events. 161 * 162 * @param nanoapp A non-null pointer to the nanoapp making this request. 163 * @param sensorHandle The handle of the sensor to receive bias events for. 164 * @param enable true to enable bias event reporting. 165 * 166 * @return true if the configuration was successful. 167 */ 168 bool configureBiasEvents(Nanoapp *nanoapp, uint32_t sensorHandle, 169 bool enable); 170 171 /** 172 * Synchronously retrieves the current bias for a sensor that supports 173 * data in the chreSensorThreeAxisData format. 174 * 175 * @param sensorHandle The handle of the sensor to retrieve bias data for. 176 * @param bias A non-null pointer to store the current bias data. 177 * 178 * @return false if the sensor handle was invalid or the sensor does not 179 * report bias data in the chreSensorThreeAxisData format. 180 */ 181 bool getThreeAxisBias(uint32_t sensorHandle, 182 struct chreSensorThreeAxisData *bias) const; 183 184 /** 185 * Makes a sensor flush request for a nanoapp asynchronously. 186 * 187 * @param nanoapp A non-null pointer to the nanoapp requesting this change. 188 * @param sensorHandle The sensor handle for which this sensor request is 189 * directed at. 190 * @param cookie An opaque pointer to data that will be used in the 191 * chreSensorFlushCompleteEvent. 192 * 193 * @return true if the request was accepted, false otherwise 194 */ 195 bool flushAsync(Nanoapp *nanoapp, uint32_t sensorHandle, const void *cookie); 196 197 /** 198 * Invoked by the PlatformSensorManager when a flush complete event is 199 * received for a given sensor for a request done through flushAsync(). This 200 * method can be invoked from any thread, and defers processing the event to 201 * the main CHRE event loop. 202 * 203 * @param sensorHandle The sensor handle that completed flushing. 204 * @param flushRequestId The ID of the flush request that completed. Should 205 * be set to UINT32_MAX if request IDs are not supported by the platform. 206 * @param errorCode An error code from enum chreError 207 */ 208 void handleFlushCompleteEvent(uint32_t sensorHandle, uint32_t flushRequestId, 209 uint8_t errorCode); 210 211 /** 212 * Invoked by the PlatformSensorManager when a sensor event is received for a 213 * given sensor. This method should be invoked from the same thread. 214 * 215 * @param sensorHandle The sensor handle this data event is from. 216 * @param event the event data formatted as one of the chreSensorXXXData 217 * defined in the CHRE API, implicitly specified by sensorHandle. 218 */ 219 void handleSensorDataEvent(uint32_t sensorHandle, void *event); 220 221 /** 222 * Invoked by the PlatformSensorManager when a sensor's sampling status 223 * changes. This method can be invoked from any thread. 224 * 225 * @param sensorHandle The handle that corresponds to the sensor this update 226 * is for. 227 * @param status The status update for the given sensor. 228 */ 229 void handleSamplingStatusUpdate(uint32_t sensorHandle, 230 struct chreSensorSamplingStatus *status); 231 232 /** 233 * Invoked by the PlatformSensorManager when a bias update has been received 234 * for a sensor. This method can be invoked from any thread. 235 * 236 * @param sensorHandle The handle that corresponds to the sensor this update 237 * is for. 238 * @param bias The bias update for the given sensor. 239 */ 240 void handleBiasEvent(uint32_t sensorHandle, void *biasData); 241 242 /** 243 * Prints state in a string buffer. Must only be called from the context of 244 * the main CHRE thread. 245 * 246 * @param debugDump The debug dump wrapper where a string can be printed 247 * into one of the buffers. 248 */ 249 void logStateToBuffer(DebugDumpWrapper &debugDump) const; 250 251 /** 252 * Releases the sensor data event back to the platform. Also removes any 253 * requests for a one-shot sensor if the sensor type corresponds to a one-shot 254 * sensor. 255 * 256 * @param eventType the sensor event type that was sent and now needs to be 257 * released. 258 * @param eventData the event data to be released back to the platform. 259 */ 260 void releaseSensorDataEvent(uint16_t eventType, void *eventData); 261 262 /** 263 * Releases the bias data back to the platform. 264 * 265 * @param biasData the bias data to be released back to the platform. 266 */ releaseBiasData(void * biasData)267 void releaseBiasData(void *biasData) { 268 mPlatformSensorManager.releaseBiasEvent(biasData); 269 } 270 271 /** 272 * Releases the sampling status updated back to the platform. 273 * 274 * @param status the status to be released back to the platform. 275 */ releaseSamplingStatusUpdate(struct chreSensorSamplingStatus * status)276 void releaseSamplingStatusUpdate(struct chreSensorSamplingStatus *status) { 277 mPlatformSensorManager.releaseSamplingStatusUpdate(status); 278 } 279 280 private: 281 //! An internal structure to store incoming sensor flush requests 282 struct FlushRequest { FlushRequestFlushRequest283 FlushRequest(uint32_t handle, uint32_t id, const void *cookiePtr) { 284 sensorHandle = handle; 285 nanoappInstanceId = id; 286 cookie = cookiePtr; 287 } 288 289 //! The timestamp at which this request should complete. 290 Nanoseconds deadlineTimestamp = 291 SystemTime::getMonotonicTime() + 292 Nanoseconds(CHRE_SENSOR_FLUSH_COMPLETE_TIMEOUT_NS); 293 //! The sensor handle this flush request is for. 294 uint32_t sensorHandle; 295 //! The ID of the nanoapp that requested the flush. 296 uint32_t nanoappInstanceId; 297 //! The opaque pointer provided in flushAsync(). 298 const void *cookie; 299 //! True if this flush request is active and is pending completion. 300 bool isActive = false; 301 }; 302 303 //! An internal structure to store sensor request logs 304 struct SensorRequestLog { SensorRequestLogSensorRequestLog305 SensorRequestLog(Nanoseconds timestampIn, uint32_t instanceIdIn, 306 uint32_t sensorHandleIn, SensorMode modeIn, 307 Nanoseconds intervalIn, Nanoseconds latencyIn) 308 : timestamp(timestampIn), 309 interval(intervalIn), 310 latency(latencyIn), 311 instanceId(instanceIdIn), 312 sensorHandle(sensorHandleIn), 313 mode(modeIn) {} 314 315 Nanoseconds timestamp; 316 Nanoseconds interval; 317 Nanoseconds latency; 318 uint32_t instanceId; 319 uint32_t sensorHandle; 320 SensorMode mode; 321 }; 322 323 //! The list of all sensors 324 DynamicVector<Sensor> mSensors; 325 326 //! The list of logged sensor requests 327 static constexpr size_t kMaxSensorRequestLogs = 15; 328 ArrayQueue<SensorRequestLog, kMaxSensorRequestLogs> mSensorRequestLogs; 329 330 //! A queue of flush requests made by nanoapps. 331 static constexpr size_t kMaxFlushRequests = 16; 332 FixedSizeVector<FlushRequest, kMaxFlushRequests> mFlushRequestQueue; 333 334 PlatformSensorManager mPlatformSensorManager; 335 336 /** 337 * Makes a specified flush request, and sets the timeout timer appropriately. 338 * If there already is a pending flush request for the sensor specified in 339 * the request, then this method does nothing. 340 * 341 * @param request the request to make 342 * 343 * @return An error code from enum chreError 344 */ 345 uint8_t makeFlushRequest(FlushRequest &request); 346 347 /** 348 * Make a flush request through PlatformSensorManager. 349 * 350 * @param sensor The sensor to flush. 351 * @return true if the flush request was successfully made. 352 */ 353 bool doMakeFlushRequest(Sensor &sensor); 354 355 /** 356 * Removes all requests and consolidates all the maximal request changes 357 * into one sensor configuration update. 358 * 359 * @param sensor The sensor to clear all requests for. 360 * @return true if all the requests have been removed and sensor 361 * configuration successfully updated. 362 */ 363 bool removeAllRequests(Sensor &sensor); 364 365 /** 366 * Removes a sensor request from the given lists of requests. The provided 367 * index must fall in the range of the sensor requests available. 368 * 369 * @param sensor The sensor to remove the request from. 370 * @param removeIndex The index to remove the request from. 371 * @param requestChanged A non-null pointer to a bool to indicate that the 372 * net request made to the sensor has changed. This boolean is always 373 * assigned to the status of the request changing (true or false). 374 * @return true if the remove operation was successful. 375 */ 376 bool removeRequest(Sensor &sensor, size_t removeIndex, bool *requestChanged); 377 378 /** 379 * Adds a new sensor request to the given list of requests. 380 * 381 * @param sensor The sensor to add the request to. 382 * @param request The request to add to the multiplexer. 383 * @param requestChanged A non-null pointer to a bool to indicate that the 384 * net request made to the sensor has changed. This boolean is always 385 * assigned to the status of the request changing (true or false). 386 * @return true if the add operation was successful. 387 */ 388 bool addRequest(Sensor &sensor, const SensorRequest &request, 389 bool *requestChanged); 390 391 /** 392 * Updates a sensor request in the given list of requests. The provided index 393 * must fall in range of the sensor requests managed by the multiplexer. 394 * 395 * @param sensor The sensor that will be updated. 396 * @param updateIndex The index to update the request at. 397 * @param request The new sensor request to replace the existing request 398 * with. 399 * @param requestChanged A non-null pointer to a bool to indicate that the 400 * net request made to the sensor has changed. This boolean is always 401 * assigned to the status of the request changing (true or false). 402 * @return true if the update operation was successful. 403 */ 404 bool updateRequest(Sensor &sensor, size_t updateIndex, 405 const SensorRequest &request, bool *requestChanged); 406 407 /** 408 * Posts an event to a nanoapp indicating the completion of a flush request. 409 * 410 * @param sensorHandle The handle of the sensor for this event. 411 * @param errorCode An error code from enum chreError 412 * @param request The corresponding FlushRequest. 413 */ 414 void postFlushCompleteEvent(uint32_t sensorHandle, uint8_t errorCode, 415 const FlushRequest &request); 416 417 /** 418 * Completes a flush request at the specified index by posting a 419 * CHRE_EVENT_SENSOR_FLUSH_COMPLETE event with the specified errorCode, 420 * removing the request from the queue, cleaning up states as necessary. 421 * 422 * @param index The index of the flush request. 423 * @param errorCode The error code to send the completion event with. 424 */ 425 void completeFlushRequestAtIndex(size_t index, uint8_t errorCode); 426 427 /** 428 * Dispatches the next flush request for the given sensor. If there are no 429 * more pending flush requests, this method does nothing. 430 * 431 * @param sensorHandle The handle of the sensor to dispatch a new flush 432 * request for. 433 */ 434 void dispatchNextFlushRequest(uint32_t sensorHandle); 435 436 /** 437 * A method that is called whenever a flush request times out. 438 * 439 * @param sensorHandle The sensor handle of the flush request. 440 */ 441 void onFlushTimeout(uint32_t sensorHandle); 442 443 /** 444 * Handles a complete event for a sensor flush requested through flushAsync. 445 * See handleFlushCompleteEvent which may be called from any thread. This 446 * method is intended to be invoked on the CHRE event loop thread. 447 * 448 * @param errorCode An error code from enum chreError 449 * @param sensorHandle The handle of the sensor that has completed the flush. 450 */ 451 void handleFlushCompleteEventSync(uint8_t errorCode, uint32_t sensorHandle); 452 453 /** 454 * Cancels all pending flush requests for a given sensor and nanoapp. 455 * 456 * @param sensorHandle The sensor handle indicating the sensor to cancel flush 457 * requests for. 458 * @param nanoappInstanceId The ID of the nanoapp to cancel requests for, 459 * kSystemInstanceId to remove requests for all nanoapps. 460 */ 461 void cancelFlushRequests(uint32_t sensorHandle, 462 uint32_t nanoappInstanceId = kSystemInstanceId); 463 464 /** 465 * Adds a request log to the list of logs possibly pushing latest log 466 * off if full. 467 * 468 * @param nanoappInstanceId Instance ID of the nanoapp that made the request. 469 * @param sensorHandle The sensor handle for the sensor request being added. 470 * @param sensorRequest The SensorRequest object holding params about 471 * request. 472 */ 473 void addSensorRequestLog(uint32_t nanoappInstanceId, uint32_t sensorHandle, 474 const SensorRequest &sensorRequest); 475 476 /** 477 * Helper function to make a sensor's maximal request to the platform, and 478 * reset the last event if an on-change sensor is successfully turned off. 479 * 480 * If either bias update configuration or sensor data configuration fails, 481 * this entire method will fail. When this method fails, any previous 482 * configuration will be restored on a best-effort basis. 483 * 484 * @param sensor The sensor that will be configured. 485 * @param prevSensorRequest The previous sensor request that was made for the 486 * given sensor. 487 * @return true if both configuring the platform for bias updates and for 488 * sensor data succeeded. 489 */ 490 bool configurePlatformSensor(Sensor &sensor, 491 const SensorRequest &prevSensorRequest); 492 493 /** 494 * @param nanoappInstanceId The instance ID of the nanoapp to check. 495 * @param sensorType The sensor type. 496 * 497 * @return the target group masks that are actively enabled for this nanoapp 498 * and the sensor type. 499 */ 500 uint16_t getActiveTargetGroupMask(uint32_t nanoappInstanceId, 501 uint8_t sensorType); 502 }; 503 504 } // namespace chre 505 506 #endif // CHRE_CORE_SENSOR_REQUEST_MANAGER_H_ 507