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