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