xref: /aosp_15_r20/system/chre/core/include/chre/core/sensor_request_manager.h (revision 84e339476a462649f82315436d70fd732297a399)
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