• 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 #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