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