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/request_multiplexer.h" 21 #include "chre/core/sensor.h" 22 #include "chre/core/sensor_request.h" 23 #include "chre/core/timer_pool.h" 24 #include "chre/platform/atomic.h" 25 #include "chre/platform/system_time.h" 26 #include "chre/platform/system_timer.h" 27 #include "chre/util/fixed_size_vector.h" 28 #include "chre/util/non_copyable.h" 29 #include "chre/util/optional.h" 30 31 namespace chre { 32 33 class SensorRequestManager : public NonCopyable { 34 public: 35 /** 36 * Performs initialization of the SensorRequestManager and populates the 37 * sensor list with platform sensors. 38 */ 39 SensorRequestManager(); 40 41 /** 42 * Destructs the sensor request manager and releases platform sensor resources 43 * if requested. 44 */ 45 ~SensorRequestManager(); 46 47 /** 48 * Initializes the underlying platform-specific sensors. Must be called 49 * prior to invoking any other methods in this class. 50 */ 51 void init(); 52 53 /** 54 * Determines whether the runtime is aware of a given sensor type. The 55 * supplied sensorHandle is only populated if the sensor type is known. 56 * 57 * @param sensorType The type of the sensor. 58 * @param sensorHandle A non-null pointer to a uint32_t to use as a sensor 59 * handle for nanoapps. 60 * @return true if the supplied sensor type is available for use. 61 */ 62 bool getSensorHandle(SensorType sensorType, uint32_t *sensorHandle) const; 63 64 /** 65 * Sets a sensor request for the given nanoapp for the provided sensor handle. 66 * If the nanoapp has made a previous request, it is replaced by this request. 67 * If the request changes the mode to SensorMode::Off the request is removed. 68 * 69 * @param nanoapp A non-null pointer to the nanoapp requesting this change. 70 * @param sensorHandle The sensor handle for which this sensor request is 71 * directed at. 72 * @param request The new sensor request for this nanoapp. 73 * @return true if the request was set successfully. If the sensorHandle is 74 * out of range or the platform sensor fails to update to the new 75 * request false will be returned. 76 */ 77 bool setSensorRequest(Nanoapp *nanoapp, uint32_t sensorHandle, 78 const SensorRequest& sensorRequest); 79 80 /** 81 * Populates the supplied info struct if the sensor handle exists. 82 * 83 * @param sensorHandle The handle of the sensor. 84 * @param nanoapp The nanoapp requesting this change. 85 * @param info A non-null pointer to a chreSensorInfo struct. 86 * @return true if the supplied sensor handle exists. 87 */ 88 bool getSensorInfo(uint32_t sensorHandle, const Nanoapp& nanoapp, 89 struct chreSensorInfo *info) const; 90 /* 91 * Removes all requests of a sensorType and unregisters all nanoapps for its 92 * events. 93 * 94 * @param sensorType The sensor type whose requests are to be removed. 95 * @return true if all requests of the sensor type have been successfully 96 * removed. 97 */ 98 bool removeAllRequests(SensorType sensorType); 99 100 /** 101 * Obtains a pointer to the Sensor of the specified sensorType. 102 * 103 * NOTE: Some platform implementations invoke this method from different 104 * threads assuming the underlying list of sensors doesn't change after 105 * initialization. 106 * 107 * @param sensorType The SensorType of the sensor. 108 * @return A pointer to the Sensor of sensorType, or nullptr if sensorType is 109 * invalid or the requested SensorType is not supported on the current 110 * platform. 111 */ 112 Sensor *getSensor(SensorType sensorType); 113 114 /** 115 * Populates the supplied sampling status struct if the sensor handle exists. 116 * 117 * @param sensorHandle The handle of the sensor. 118 * @param status A non-null pointer to a chreSensorSamplingStatus struct. 119 * @return true if the supplied sensor handle exists. 120 */ 121 bool getSensorSamplingStatus(uint32_t sensorHandle, 122 struct chreSensorSamplingStatus *status) const; 123 124 /** 125 * Obtains the list of open requests of the specified SensorType. 126 * 127 * @param sensorType The SensorType of the sensor. 128 * @return The list of open requests of this sensor in a DynamicVector. 129 */ 130 const DynamicVector<SensorRequest>& getRequests(SensorType sensorType) const; 131 132 /** 133 * Configures a nanoapp to receive bias events. 134 * 135 * @param nanoapp A non-null pointer to the nanoapp making this request. 136 * @param sensorHandle The handle of the sensor to receive bias events for. 137 * @param enable true to enable bias event reporting. 138 * 139 * @return true if the configuration was successful. 140 */ 141 bool configureBiasEvents( 142 Nanoapp *nanoapp, uint32_t sensorHandle, bool enable); 143 144 /** 145 * Synchronously retrieves the current bias for a sensor that supports 146 * data in the chreSensorThreeAxisData format. 147 * 148 * @param sensorHandle The handle of the sensor to retrieve bias data for. 149 * @param bias A non-null pointer to store the current bias data. 150 * 151 * @return false if the sensor handle was invalid or the sensor does not 152 * report bias data in the chreSensorThreeAxisData format. 153 */ 154 bool getThreeAxisBias( 155 uint32_t sensorHandle, struct chreSensorThreeAxisData *bias) const; 156 157 /** 158 * Makes a sensor flush request for a nanoapp asynchronously. 159 * 160 * @param nanoapp A non-null pointer to the nanoapp requesting this change. 161 * @param sensorHandle The sensor handle for which this sensor request is 162 * directed at. 163 * @param cookie An opaque pointer to data that will be used in the 164 * chreSensorFlushCompleteEvent. 165 * 166 * @return true if the request was accepted, false otherwise 167 */ 168 bool flushAsync(Nanoapp *nanoapp, uint32_t sensorHandle, const void *cookie); 169 170 /** 171 * Invoked by the PlatformSensor when a flush complete event is received for a 172 * given sensor for a request done through flushAsync(). This method can be 173 * invoked from any thread, and defers processing the event to the main CHRE 174 * event loop. 175 * 176 * @param errorCode An error code from enum chreError 177 * @param sensorType The SensorType of sensor that has completed the flush. 178 */ 179 void handleFlushCompleteEvent(uint8_t errorCode, SensorType sensorType); 180 181 /** 182 * Invoked by the PlatformSensor when a sensor event is received for a given 183 * sensor. This method should be invoked from the same thread. 184 * 185 * @param sensorType the type of sensor the sensor data corresponds to 186 * @param event the event data formatted as one of the chreSensorXXXData 187 * defined in the CHRE API, implicitly specified by sensorType. 188 */ 189 void handleSensorEvent(SensorType sensorType, void *event); 190 191 /** 192 * Prints state in a string buffer. Must only be called from the context of 193 * the main CHRE thread. 194 * 195 * @param buffer Pointer to the start of the buffer. 196 * @param bufferPos Pointer to buffer position to start the print (in-out). 197 * @param size Size of the buffer in bytes. 198 */ 199 void logStateToBuffer(char *buffer, size_t *bufferPos, 200 size_t bufferSize) const; 201 202 private: 203 //! An internal structure to store incoming sensor flush requests 204 struct FlushRequest { FlushRequestFlushRequest205 FlushRequest(SensorType type, uint32_t id, const void *cookiePtr) { 206 sensorType = type; 207 nanoappInstanceId = id; 208 cookie = cookiePtr; 209 } 210 211 //! The sensor type the flush request is for. 212 SensorType sensorType; 213 //! The ID of the nanoapp that requested the flush. 214 uint32_t nanoappInstanceId; 215 //! The opaque pointer provided in flushAsync(). 216 const void *cookie; 217 //! The timestamp at which this request should complete. 218 Nanoseconds deadlineTimestamp = SystemTime::getMonotonicTime() + 219 Nanoseconds(CHRE_SENSOR_FLUSH_COMPLETE_TIMEOUT_NS); 220 //! True if this flush request is active and is pending completion. 221 bool isActive = false; 222 }; 223 224 /** 225 * This allows tracking the state of a sensor with the various requests for it 226 * and can trigger a change in mode/rate/latency when required. 227 */ 228 class SensorRequests { 229 public: SensorRequests()230 SensorRequests() : mFlushRequestPending(false) {} 231 232 /** 233 * Initializes the sensor object. This method must only be invoked once 234 * when the SensorRequestManager initializes. 235 * 236 * @param sensor The sensor object to initialize with. 237 */ setSensor(Sensor && sensor)238 void setSensor(Sensor&& sensor) { 239 CHRE_ASSERT(!mSensor.has_value()); 240 mSensor = std::move(sensor); 241 } 242 243 /** 244 * @return true if the sensor is supported by the platform. 245 */ isSensorSupported()246 bool isSensorSupported() const { 247 return mSensor.has_value(); 248 } 249 250 /** 251 * @return The set of active requests for this sensor. 252 */ getRequests()253 const DynamicVector<SensorRequest>& getRequests() const { 254 return mMultiplexer.getRequests(); 255 } 256 257 /** 258 * @return true if the sensor is currently enabled. 259 */ isSensorEnabled()260 bool isSensorEnabled() const { 261 return !mMultiplexer.getRequests().empty(); 262 } 263 264 /** 265 * @return A constant reference to the sensor object. This method has an 266 * undefined behavior if isSensorSupported() is false. 267 */ getSensor()268 const Sensor& getSensor() const { 269 return mSensor.value(); 270 } 271 272 /** 273 * @return A reference to the sensor object. This method has an undefined 274 * behavior if isSensorSupported() is false. 275 */ getSensor()276 Sensor& getSensor() { 277 return mSensor.value(); 278 } 279 280 /** 281 * Gets the sensor's sampling status. The caller must ensure that 282 * isSensorSupported() is true before invoking this method. 283 * 284 * @param status A non-null pointer where the sampling status will be 285 * stored, if successful. 286 * 287 * @return true if getting the sampling status succeeded. 288 */ getSamplingStatus(struct chreSensorSamplingStatus * status)289 bool getSamplingStatus(struct chreSensorSamplingStatus *status) const { 290 CHRE_ASSERT(isSensorSupported()); 291 return isSensorSupported() ? mSensor->getSamplingStatus(status) : false; 292 } 293 294 /** 295 * Synchronously retrieves the current bias for a sensor that supports 296 * data in the chreSensorThreeAxisData format. The caller must ensure that 297 * isSensorSupported() is true before invoking this method. 298 * 299 * @param bias A non-null pointer to store the current bias data. 300 * 301 * @return false if sensor does not report bias data in the 302 * chreSensorThreeAxisData format. 303 */ getThreeAxisBias(struct chreSensorThreeAxisData * bias)304 bool getThreeAxisBias(struct chreSensorThreeAxisData *bias) const { 305 CHRE_ASSERT(isSensorSupported()); 306 return isSensorSupported() ? mSensor->getThreeAxisBias(bias) : false; 307 } 308 309 /** 310 * Searches through the list of sensor requests for a request owned by the 311 * given nanoapp. The provided non-null index pointer is populated with the 312 * index of the request if it is found. 313 * 314 * @param instanceId The instance ID of the nanoapp whose request is being 315 * searched for. 316 * @param index A non-null pointer to an index that is populated if a 317 * request for this nanoapp is found. 318 * @return A pointer to a SensorRequest that is owned by the provided 319 * nanoapp if one is found otherwise nullptr. 320 */ 321 const SensorRequest *find(uint32_t instanceId, size_t *index) const; 322 323 /** 324 * Adds a new sensor request to the request multiplexer for this sensor. 325 * 326 * @param request The request to add to the multiplexer. 327 * @param requestChanged A non-null pointer to a bool to indicate that the 328 * net request made to the sensor has changed. This boolean is always 329 * assigned to the status of the request changing (true or false). 330 * @return true if the add operation was successful. 331 */ 332 bool add(const SensorRequest& request, bool *requestChanged); 333 334 /** 335 * Removes a sensor request from the request multiplexer for this sensor. 336 * The provided index must fall in the range of the sensor requests managed 337 * by the multiplexer. 338 * 339 * @param removeIndex The index to remove the request from. 340 * @param requestChanged A non-null pointer to a bool to indicate that the 341 * net request made to the sensor has changed. This boolean is always 342 * assigned to the status of the request changing (true or false). 343 * @return true if the remove operation was successful. 344 */ 345 bool remove(size_t removeIndex, bool *requestChanged); 346 347 /** 348 * Updates a sensor request in the request multiplexer for this sensor. The 349 * provided index must fall in range of the sensor requests managed by the 350 * multiplexer. 351 * 352 * @param updateIndex The index to update the request at. 353 * @param request The new sensor request to replace the existing request 354 * with. 355 * @return true if the update operation was successful. 356 */ 357 bool update(size_t updateIndex, const SensorRequest& request, 358 bool *requestChanged); 359 360 /** 361 * Removes all requests and consolidates all the maximal request changes 362 * into one sensor configuration update. 363 * 364 * @return true if all the requests have been removed and sensor 365 * configuration successfully updated. 366 */ 367 bool removeAll(); 368 369 /** 370 * Makes a specified flush request for this sensor, and sets the timeout 371 * timer appropriately. If there already is a pending flush request, then 372 * this method does nothing. 373 * 374 * @param request the request to make 375 * 376 * @return An error code from enum chreError 377 */ 378 uint8_t makeFlushRequest(FlushRequest& request); 379 380 /** 381 * Clears any states (e.g. timeout timer and relevant flags) associated 382 * with a pending flush request. 383 */ 384 void clearPendingFlushRequest(); 385 386 /** 387 * Cancels the pending timeout timer associated with a flush request. 388 */ 389 void cancelPendingFlushRequestTimer(); 390 391 /** 392 * @return true if a flush through makeFlushRequest is pending. 393 */ isFlushRequestPending()394 inline bool isFlushRequestPending() const { 395 return mFlushRequestPending; 396 } 397 398 private: 399 //! The sensor associated with this request multiplexer. If this Optional 400 //! container does not have a value, then the platform does not support this 401 //! type of sensor. 402 Optional<Sensor> mSensor; 403 404 //! The request multiplexer for this sensor. 405 RequestMultiplexer<SensorRequest> mMultiplexer; 406 407 //! The timeout timer handle for the current flush request. 408 TimerHandle mFlushRequestTimerHandle = CHRE_TIMER_INVALID; 409 410 //! True if a flush request is pending for this sensor. 411 AtomicBool mFlushRequestPending; 412 413 /** 414 * Make a flush request through PlatformSensor. 415 * 416 * @return true if the flush request was successfully made. 417 */ 418 bool doMakeFlushRequest(); 419 }; 420 421 //! The list of sensor requests. 422 FixedSizeVector<SensorRequests, getSensorTypeCount()> mSensorRequests; 423 424 //! A queue of flush requests made by nanoapps. 425 static constexpr size_t kMaxFlushRequests = 16; 426 FixedSizeVector<FlushRequest, kMaxFlushRequests> mFlushRequestQueue; 427 428 /** 429 * Helper function to convert SensorType to SensorRequests. 430 */ getSensorRequests(SensorType sensorType)431 SensorRequests& getSensorRequests(SensorType sensorType) { 432 size_t index = getSensorTypeArrayIndex(sensorType); 433 return mSensorRequests[index]; 434 } 435 436 /** 437 * Posts an event to a nanoapp indicating the completion of a flush request. 438 * 439 * @param sensorHandle The handle of the sensor for this event. 440 * @param errorCode An error code from enum chreError 441 * @param request The corresponding FlushRequest. 442 */ 443 void postFlushCompleteEvent( 444 uint32_t sensorHandle, uint8_t errorCode, const FlushRequest& request); 445 446 /** 447 * Completes a flush request at the specified index by posting a 448 * CHRE_EVENT_SENSOR_FLUSH_COMPLETE event with the specified errorCode, 449 * removing the request from the queue, cleaning up states as necessary. 450 * 451 * @param index The index of the flush request. 452 * @param errorCode The error code to send the completion event with. 453 */ 454 void completeFlushRequestAtIndex(size_t index, uint8_t errorCode); 455 456 /** 457 * Dispatches the next flush request for the given sensor. If there are no 458 * more pending flush requests, this method does nothing. 459 * 460 * @param sensorType The corresponding sensor type. 461 */ 462 void dispatchNextFlushRequest(SensorType sensorType); 463 464 /** 465 * Handles a complete event for a sensor flush requested through flushAsync. 466 * See handleFlushCompleteEvent which may be called from any thread. This 467 * method is intended to be invoked on the CHRE event loop thread. 468 * 469 * @param errorCode An error code from enum chreError 470 * @param sensorType The SensorType of sensor that has completed the flush. 471 */ 472 void handleFlushCompleteEventSync(uint8_t errorCode, SensorType sensorType); 473 474 /** 475 * Cancels all pending flush requests for a given sensor and nanoapp. 476 * 477 * @param sensorType The type of sensor to cancel requests for. 478 * @param nanoappInstanceId The ID of the nanoapp to cancel requests for, 479 * kSystemInstanceId to remove requests for all nanoapps. 480 */ 481 void cancelFlushRequests( 482 SensorType sensorType, uint32_t nanoappInstanceId = kSystemInstanceId); 483 }; 484 485 } // namespace chre 486 487 #endif // CHRE_CORE_SENSOR_REQUEST_MANAGER_H_ 488