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