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