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 * Prints state in a string buffer. Must only be called from the context of 246 * the main CHRE thread. 247 * 248 * @param debugDump The debug dump wrapper where a string can be printed 249 * into one of the buffers. 250 */ 251 void logStateToBuffer(DebugDumpWrapper &debugDump) const; 252 253 /** 254 * Releases the sensor data event back to the platform. Also removes any 255 * requests for a one-shot sensor if the sensor type corresponds to a one-shot 256 * sensor. 257 * 258 * @param eventType the sensor event type that was sent and now needs to be 259 * released. 260 * @param eventData the event data to be released back to the platform. 261 */ 262 void releaseSensorDataEvent(uint16_t eventType, void *eventData); 263 264 /** 265 * Releases the bias data back to the platform. 266 * 267 * @param biasData the bias data to be released back to the platform. 268 */ releaseBiasData(void * biasData)269 void releaseBiasData(void *biasData) { 270 mPlatformSensorManager.releaseBiasEvent(biasData); 271 } 272 273 /** 274 * Releases the sampling status updated back to the platform. 275 * 276 * @param status the status to be released back to the platform. 277 */ releaseSamplingStatusUpdate(struct chreSensorSamplingStatus * status)278 void releaseSamplingStatusUpdate(struct chreSensorSamplingStatus *status) { 279 mPlatformSensorManager.releaseSamplingStatusUpdate(status); 280 } 281 282 /** 283 * Disables all active sensor requests for the given nanoapp. 284 * 285 * The bias requests are automatically disabled together with the main 286 * request. 287 * 288 * @param nanoapp A non-null pointer to the nanoapp. 289 * 290 * @return The number of subscriptions disabled. 291 */ 292 uint32_t disableAllSubscriptions(Nanoapp *nanoapp); 293 294 private: 295 //! An internal structure to store incoming sensor flush requests 296 struct FlushRequest { FlushRequestFlushRequest297 FlushRequest(uint32_t handle, uint16_t id, const void *cookiePtr) { 298 sensorHandle = handle; 299 nanoappInstanceId = id; 300 cookie = cookiePtr; 301 } 302 303 //! The timestamp at which this request should complete. 304 Nanoseconds deadlineTimestamp = 305 SystemTime::getMonotonicTime() + 306 Nanoseconds(CHRE_SENSOR_FLUSH_COMPLETE_TIMEOUT_NS); 307 //! The sensor handle this flush request is for. 308 uint32_t sensorHandle; 309 //! The opaque pointer provided in flushAsync(). 310 const void *cookie; 311 //! The ID of the nanoapp that requested the flush. 312 uint16_t nanoappInstanceId; 313 //! True if this flush request is active and is pending completion. 314 bool isActive = false; 315 }; 316 317 //! An internal structure to store sensor request logs 318 struct SensorRequestLog { SensorRequestLogSensorRequestLog319 SensorRequestLog(Nanoseconds timestampIn, uint16_t instanceIdIn, 320 uint32_t sensorHandleIn, SensorMode modeIn, 321 Nanoseconds intervalIn, Nanoseconds latencyIn) 322 : timestamp(timestampIn), 323 interval(intervalIn), 324 latency(latencyIn), 325 sensorHandle(sensorHandleIn), 326 instanceId(instanceIdIn), 327 mode(modeIn) {} 328 329 Nanoseconds timestamp; 330 Nanoseconds interval; 331 Nanoseconds latency; 332 uint32_t sensorHandle; 333 uint16_t instanceId; 334 SensorMode mode; 335 }; 336 337 //! The list of all sensors 338 DynamicVector<Sensor> mSensors; 339 340 //! The list of logged sensor requests 341 static constexpr size_t kMaxSensorRequestLogs = 15; 342 ArrayQueue<SensorRequestLog, kMaxSensorRequestLogs> mSensorRequestLogs; 343 344 //! A queue of flush requests made by nanoapps. 345 static constexpr size_t kMaxFlushRequests = 16; 346 FixedSizeVector<FlushRequest, kMaxFlushRequests> mFlushRequestQueue; 347 348 PlatformSensorManager mPlatformSensorManager; 349 350 /** 351 * Makes a specified flush request, and sets the timeout timer appropriately. 352 * If there already is a pending flush request for the sensor specified in 353 * the request, then this method does nothing. 354 * 355 * @param request the request to make 356 * 357 * @return An error code from enum chreError 358 */ 359 uint8_t makeFlushRequest(FlushRequest &request); 360 361 /** 362 * Make a flush request through PlatformSensorManager. 363 * 364 * @param sensor The sensor to flush. 365 * @return true if the flush request was successfully made. 366 */ 367 bool doMakeFlushRequest(Sensor &sensor); 368 369 /** 370 * Removes all requests and consolidates all the maximal request changes 371 * into one sensor configuration update. 372 * 373 * @param sensor The sensor to clear all requests for. 374 * @return true if all the requests have been removed and sensor 375 * configuration successfully updated. 376 */ 377 bool removeAllRequests(Sensor &sensor); 378 379 /** 380 * Removes a sensor request from the given lists of requests. The provided 381 * index must fall in the range of the sensor requests available. 382 * 383 * @param sensor The sensor to remove the request from. 384 * @param removeIndex The index to remove the request from. 385 * @param requestChanged A non-null pointer to a bool to indicate that the 386 * net request made to the sensor has changed. This boolean is always 387 * assigned to the status of the request changing (true or false). 388 * @return true if the remove operation was successful. 389 */ 390 bool removeRequest(Sensor &sensor, size_t removeIndex, bool *requestChanged); 391 392 /** 393 * Adds a new sensor request to the given list of requests. 394 * 395 * @param sensor The sensor to add the request to. 396 * @param request The request to add to the multiplexer. 397 * @param requestChanged A non-null pointer to a bool to indicate that the 398 * net request made to the sensor has changed. This boolean is always 399 * assigned to the status of the request changing (true or false). 400 * @return true if the add operation was successful. 401 */ 402 bool addRequest(Sensor &sensor, const SensorRequest &request, 403 bool *requestChanged); 404 405 /** 406 * Updates a sensor request in the given list of requests. The provided index 407 * must fall in range of the sensor requests managed by the multiplexer. 408 * 409 * @param sensor The sensor that will be updated. 410 * @param updateIndex The index to update the request at. 411 * @param request The new sensor request to replace the existing request 412 * with. 413 * @param requestChanged A non-null pointer to a bool to indicate that the 414 * net request made to the sensor has changed. This boolean is always 415 * assigned to the status of the request changing (true or false). 416 * @return true if the update operation was successful. 417 */ 418 bool updateRequest(Sensor &sensor, size_t updateIndex, 419 const SensorRequest &request, bool *requestChanged); 420 421 /** 422 * Posts an event to a nanoapp indicating the completion of a flush request. 423 * 424 * @param sensorHandle The handle of the sensor for this event. 425 * @param errorCode An error code from enum chreError 426 * @param request The corresponding FlushRequest. 427 */ 428 void postFlushCompleteEvent(uint32_t sensorHandle, uint8_t errorCode, 429 const FlushRequest &request); 430 431 /** 432 * Completes a flush request at the specified index by posting a 433 * CHRE_EVENT_SENSOR_FLUSH_COMPLETE event with the specified errorCode, 434 * removing the request from the queue, cleaning up states as necessary. 435 * 436 * @param index The index of the flush request. 437 * @param errorCode The error code to send the completion event with. 438 */ 439 void completeFlushRequestAtIndex(size_t index, uint8_t errorCode); 440 441 /** 442 * Dispatches the next flush request for the given sensor. If there are no 443 * more pending flush requests, this method does nothing. 444 * 445 * @param sensorHandle The handle of the sensor to dispatch a new flush 446 * request for. 447 */ 448 void dispatchNextFlushRequest(uint32_t sensorHandle); 449 450 /** 451 * A method that is called whenever a flush request times out. 452 * 453 * @param sensorHandle The sensor handle of the flush request. 454 */ 455 void onFlushTimeout(uint32_t sensorHandle); 456 457 /** 458 * Handles a complete event for a sensor flush requested through flushAsync. 459 * See handleFlushCompleteEvent which may be called from any thread. This 460 * method is intended to be invoked on the CHRE event loop thread. 461 * 462 * @param errorCode An error code from enum chreError 463 * @param sensorHandle The handle of the sensor that has completed the flush. 464 */ 465 void handleFlushCompleteEventSync(uint8_t errorCode, uint32_t sensorHandle); 466 467 /** 468 * Cancels all pending flush requests for a given sensor and nanoapp. 469 * 470 * @param sensorHandle The sensor handle indicating the sensor to cancel flush 471 * requests for. 472 * @param nanoappInstanceId The ID of the nanoapp to cancel requests for, 473 * kSystemInstanceId to remove requests for all nanoapps. 474 */ 475 void cancelFlushRequests(uint32_t sensorHandle, 476 uint32_t nanoappInstanceId = kSystemInstanceId); 477 478 /** 479 * Adds a request log to the list of logs possibly pushing latest log 480 * off if full. 481 * 482 * @param nanoappInstanceId Instance ID of the nanoapp that made the request. 483 * @param sensorHandle The sensor handle for the sensor request being added. 484 * @param sensorRequest The SensorRequest object holding params about 485 * request. 486 */ 487 void addSensorRequestLog(uint16_t nanoappInstanceId, uint32_t sensorHandle, 488 const SensorRequest &sensorRequest); 489 490 /** 491 * Helper function to make a sensor's maximal request to the platform, and 492 * reset the last event if an on-change sensor is successfully turned off. 493 * 494 * If either bias update configuration or sensor data configuration fails, 495 * this entire method will fail. When this method fails, any previous 496 * configuration will be restored on a best-effort basis. 497 * 498 * @param sensor The sensor that will be configured. 499 * @param prevSensorRequest The previous sensor request that was made for the 500 * given sensor. 501 * @return true if both configuring the platform for bias updates and for 502 * sensor data succeeded. 503 */ 504 bool configurePlatformSensor(Sensor &sensor, 505 const SensorRequest &prevSensorRequest); 506 507 /** 508 * @param nanoappInstanceId The instance ID of the nanoapp to check. 509 * @param sensorType The sensor type. 510 * 511 * @return the target group masks that are actively enabled for this nanoapp 512 * and the sensor type. 513 */ 514 uint16_t getActiveTargetGroupMask(uint16_t nanoappInstanceId, 515 uint8_t sensorType); 516 }; 517 518 } // namespace chre 519 520 #endif // CHRE_SENSORS_SUPPORT_ENABLED 521 522 #endif // CHRE_CORE_SENSOR_REQUEST_MANAGER_H_ 523