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_H_
18 #define CHRE_CORE_SENSOR_H_
19 
20 #include "chre/core/sensor_request_multiplexer.h"
21 #include "chre/core/sensor_type_helpers.h"
22 #include "chre/core/timer_pool.h"
23 #include "chre/platform/atomic.h"
24 #include "chre/platform/platform_sensor.h"
25 #include "chre/util/optional.h"
26 
27 namespace chre {
28 
29 /**
30  * Represents a sensor in the system that is exposed to nanoapps in CHRE.
31  *
32  * Note that like chre::Nanoapp, this class uses inheritance to separate the
33  * common code (Sensor) from common interface with platform-specific
34  * implementation (PlatformSensor). However, this inheritance relationship does
35  * *not* imply polymorphism, and this object must only be referred to via the
36  * most-derived type, i.e. chre::Sensor.
37  */
38 class Sensor : public PlatformSensor {
39  public:
40   /**
41    * Constructs a sensor in an unspecified state. Should not be called directly
42    * by common code, as platform-specific initialization of the Sensor object is
43    * required for it to be usable.
44    *
45    * @see PlatformSensorManager::getSensors
46    */
Sensor()47   Sensor() : mFlushRequestPending(false) {}
48 
49   Sensor(Sensor &&other);
50   Sensor &operator=(Sensor &&other);
51 
52   ~Sensor();
53 
54   /**
55    * Initializes various Sensor class state. The platform implementation is
56    * responsible for invoking this after any base class state necessary for
57    * PlatformSensor methods to work is set up.
58    */
59   void init();
60 
61   /**
62    * @return true if the sensor is currently enabled.
63    */
isSensorEnabled()64   bool isSensorEnabled() const {
65     return !mSensorRequests.getRequests().empty();
66   }
67 
68   /**
69    * @return true if the sensor has bias updates enabled.
70    */
biasEventsEnabled()71   bool biasEventsEnabled() const {
72     return mSensorRequests.getCurrentMaximalRequest().getBiasUpdatesRequested();
73   }
74 
75   /**
76    * @return A const reference to the maximal request.
77    */
getMaximalRequest()78   const SensorRequest &getMaximalRequest() const {
79     return mSensorRequests.getCurrentMaximalRequest();
80   }
81 
82   /**
83    * @return A reference to the list of all active requests for this sensor.
84    */
getRequests()85   const DynamicVector<SensorRequest> &getRequests() const {
86     return mSensorRequests.getRequests();
87   }
88 
89   /**
90    * @return A reference to the multiplexer for all active requests for this
91    *     sensor.
92    */
getRequestMultiplexer()93   SensorRequestMultiplexer &getRequestMultiplexer() {
94     return mSensorRequests;
95   }
96 
97   /**
98    * @return Whether this sensor is a one-shot sensor.
99    */
isOneShot()100   bool isOneShot() const {
101     return SensorTypeHelpers::isOneShot(getSensorType());
102   }
103 
104   /**
105    * @return Whether this sensor is an on-change sensor.
106    */
isOnChange()107   bool isOnChange() const {
108     return SensorTypeHelpers::isOnChange(getSensorType());
109   }
110 
111   /**
112    * @return Whether this sensor is a continuous sensor.
113    */
isContinuous()114   bool isContinuous() const {
115     return SensorTypeHelpers::isContinuous(getSensorType());
116   }
117 
118   /**
119    * @return Whether this sensor is calibrated.
120    */
isCalibrated()121   bool isCalibrated() const {
122     return SensorTypeHelpers::isCalibrated(getSensorType());
123   }
124 
125   /**
126    * @param eventType A non-null pointer to the event type to populate
127    * @return true if this sensor has a bias event type.
128    */
getBiasEventType(uint16_t * eventType)129   bool getBiasEventType(uint16_t *eventType) const {
130     return SensorTypeHelpers::getBiasEventType(getSensorType(), eventType);
131   }
132 
133   /**
134    * Gets the sensor info of this sensor in the CHRE API format.
135    *
136    * @param info A non-null pointer to the chreSensor info to populate.
137    * @param targetApiVersion CHRE_API_VERSION_ value corresponding to the API
138    *     that the info struct should be populated for.
139    */
140   void populateSensorInfo(struct chreSensorInfo *info,
141                           uint32_t targetApiVersion) const;
142 
143   /**
144    * Clears any states (e.g. timeout timer and relevant flags) associated
145    * with a pending flush request.
146    */
147   void clearPendingFlushRequest();
148 
149   /**
150    * Cancels the pending timeout timer associated with a flush request.
151    */
152   void cancelPendingFlushRequestTimer();
153 
154   /**
155    * Sets the timer handle used to time out an active flush request for this
156    * sensor.
157    *
158    * @param handle Timer handle for the current flush request.
159    */
setFlushRequestTimerHandle(TimerHandle handle)160   void setFlushRequestTimerHandle(TimerHandle handle) {
161     mFlushRequestTimerHandle = handle;
162   }
163 
164   /**
165    * Sets whether a flush request is pending or not.
166    *
167    * @param pending bool indicating whether a flush is pending.
168    */
setFlushRequestPending(bool pending)169   void setFlushRequestPending(bool pending) {
170     mFlushRequestPending = pending;
171   }
172 
173   /**
174    * @return true if a flush is pending.
175    */
isFlushRequestPending()176   bool isFlushRequestPending() const {
177     return mFlushRequestPending;
178   }
179 
180   /**
181    * @return Pointer to this sensor's last data event. It returns a nullptr if
182    *         the sensor doesn't provide it.
183    */
getLastEvent()184   ChreSensorData *getLastEvent() const {
185     return mLastEventValid ? mLastEvent : nullptr;
186   }
187 
188   /**
189    * Extracts the last sample from the supplied event to the sensor's last event
190    * memory and marks last event valid. This method must be invoked within the
191    * CHRE thread before the event containing the sensor data is delivered to
192    * nanoapps.
193    *
194    * @param event The pointer to the event to update from. If nullptr, the last
195    *      event is marked invalid.
196    */
197   void setLastEvent(ChreSensorData *event);
198 
199   /**
200    * Marks the last event invalid.
201    */
clearLastEvent()202   void clearLastEvent() {
203     mLastEventValid = false;
204   }
205 
206   /**
207    * Gets the current status of this sensor in the CHRE API format.
208    *
209    * @param status A non-null pointer to chreSensorSamplingStatus to populate
210    * @return true if the sampling status has been successfully obtained.
211    */
212   bool getSamplingStatus(struct chreSensorSamplingStatus *status) const;
213 
214   /**
215    * Sets the current status of this sensor in the CHRE API format.
216    *
217    * Note: This method is called on a thread other than the main event loop.
218    *
219    * @param status The current sampling status.
220    */
221   void setSamplingStatus(const struct chreSensorSamplingStatus &status);
222 
getSensorTypeName()223   const char *getSensorTypeName() const {
224     return SensorTypeHelpers::getSensorTypeName(getSensorType());
225   }
226 
227  private:
getLastEventSize()228   size_t getLastEventSize() {
229     return SensorTypeHelpers::getLastEventSize(getSensorType());
230   }
231 
232   //! Mutex used to lock setting / getting the sampling status information for
233   //! sensors. Share it among all sensors since nanoapps can only request a
234   //! single sensor status at a time.
235   static Mutex mSamplingStatusMutex;
236 
237   //! The latest sampling status provided by the sensor.
238   struct chreSensorSamplingStatus mSamplingStatus = {};
239 
240   //! Set to true only when this sensor is currently active and we have a copy
241   //! of the most recent event in lastEvent.
242   bool mLastEventValid = false;
243 
244   //! The most recent event received for this sensor. Only enough memory is
245   //! allocated to store the sensor data for this particular sensor (a.k.a.
246   //! don't attempt to use other fields in this union).
247   ChreSensorData *mLastEvent = nullptr;
248 
249   //! The multiplexer for all requests for this sensor.
250   SensorRequestMultiplexer mSensorRequests;
251 
252   //! The timeout timer handle for the current flush request.
253   TimerHandle mFlushRequestTimerHandle = CHRE_TIMER_INVALID;
254 
255   //! True if a flush request is pending for this sensor.
256   AtomicBool mFlushRequestPending;
257 };
258 
259 }  // namespace chre
260 
261 #endif  // CHRE_CORE_SENSOR_H_
262