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_H_
18 #define CHRE_CORE_SENSOR_REQUEST_H_
19 
20 #include <cstdint>
21 
22 #include "chre_api/chre/sensor.h"
23 #include "chre/core/nanoapp.h"
24 #include "chre/util/time.h"
25 
26 namespace chre {
27 
28 // TODO: Move SensorType and related functions to a new file called
29 // sensor_type.h and include it here. This will allow using this logic in util
30 // code withput pulling in the entire SensorRequest class which is only intended
31 // to be used by the CHRE implementation.
32 
33 //! The union of possible CHRE sensor data event type with one sample.
34 union ChreSensorData {
35   struct chreSensorThreeAxisData threeAxisData;
36   struct chreSensorOccurrenceData occurrenceData;
37   struct chreSensorFloatData floatData;
38   struct chreSensorByteData byteData;
39 };
40 
41 /**
42  * This SensorType is designed to wrap constants provided by the CHRE API
43  * to improve type-safety. In addition, an unknown sensor type is provided
44  * for dealing with sensors that are not defined as per the CHRE API
45  * specification. The details of these sensors are left to the CHRE API
46  * sensor definitions.
47  */
48 enum class SensorType {
49   Unknown,
50   Accelerometer,
51   InstantMotion,
52   StationaryDetect,
53   Gyroscope,
54   GeomagneticField,
55   Pressure,
56   Light,
57   Proximity,
58   AccelerometerTemperature,
59   GyroscopeTemperature,
60   UncalibratedAccelerometer,
61   UncalibratedGyroscope,
62   UncalibratedGeomagneticField,
63 
64   // Note to future developers: don't forget to update the implementation of
65   // 1) getSensorTypeName,
66   // 2) getSensorTypeFromUnsignedInt,
67   // 3) getUnsignedIntFromSensorType,
68   // 4) getSensorSampleTypeFromSensorType
69   // 5) sensorTypeIsOneShot
70   // 6) sensorTypeIsOnChange
71   // when adding or removing a new entry here :)
72   // Have a nice day.
73 
74   //! The number of sensor types including unknown. This entry must be last.
75   SENSOR_TYPE_COUNT,
76 };
77 
78 /**
79  * This SensorSampleType is designed to help classify SensorType's data type in
80  * event handling.
81  */
82 enum class SensorSampleType {
83   Byte,
84   Float,
85   Occurrence,
86   ThreeAxis,
87   Unknown,
88 };
89 
90 /**
91  * Returns a string representation of the given sensor type.
92  *
93  * @param sensorType The sensor type to obtain a string for.
94  * @return A string representation of the sensor type.
95  */
96 const char *getSensorTypeName(SensorType sensorType);
97 
98 /**
99  * Returns a sensor sample event type for a given sensor type. The sensor type
100  * must not be SensorType::Unknown. This is a fatal error.
101  *
102  * @param sensorType The type of the sensor.
103  * @return The event type for a sensor sample of the given sensor type.
104  */
105 uint16_t getSampleEventTypeForSensorType(SensorType sensorType);
106 
107 /**
108  * Returns a sensor type for a given sensor sample event type.
109  *
110  * @param eventType The event type for a sensor sample.
111  * @return The type of the sensor.
112  */
113 SensorType getSensorTypeForSampleEventType(uint16_t eventType);
114 
115 /**
116  * @return An index into an array for a given sensor type. This is useful to map
117  * sensor type to array index quickly. The range returned corresponds to any
118  * SensorType except for Unknown starting from zero to the maximum value sensor
119  * with no gaps.
120  */
121 constexpr size_t getSensorTypeArrayIndex(SensorType sensorType);
122 
123 /**
124  * @return The number of valid sensor types in the SensorType enum.
125  */
126 constexpr size_t getSensorTypeCount();
127 
128 /**
129  * Translates an unsigned integer as provided by a CHRE-compliant nanoapp to a
130  * SensorType. If the integer sensor type does not match one of the internal
131  * sensor types, SensorType::Unknown is returned.
132  *
133  * @param sensorType The integer sensor type.
134  * @return The strongly-typed sensor if a match is found or SensorType::Unknown.
135  */
136 SensorType getSensorTypeFromUnsignedInt(uint8_t sensorType);
137 
138 /**
139  * Translates a SensorType to an unsigned integer as provided by CHRE API. If
140  * the sensor type is SensorType::Unknown, 0 is returned.
141  *
142  * @param sensorType The strongly-typed sensor.
143  * @return The integer sensor type if sensorType is not SensorType::Unknown.
144  */
145 uint8_t getUnsignedIntFromSensorType(SensorType sensorType);
146 
147 /**
148  * Provides a stable handle for a CHRE sensor type. This handle is exposed to
149  * CHRE nanoapps as a way to refer to sensors that they are subscribing to. This
150  * API is not expected to be called with SensorType::Unknown as nanoapps are not
151  * able to subscribe to the Unknown sensor type.
152  *
153  * @param sensorType The type of the sensor to obtain a handle for.
154  * @return The handle for a given sensor.
155  */
156 constexpr uint32_t getSensorHandleFromSensorType(SensorType sensorType);
157 
158 /**
159  * Maps a sensor handle to a SensorType or returns SensorType::Unknown if the
160  * provided handle is invalid.
161  *
162  * @param handle The sensor handle for a sensor.
163  * @return The sensor type for a given handle.
164  */
165 constexpr SensorType getSensorTypeFromSensorHandle(uint32_t handle);
166 
167 /**
168  * Maps a sensorType to its SensorSampleType.
169  *
170  * @param sensorType The type of the sensor to obtain its SensorSampleType for.
171  * @return The SensorSampleType of the sensorType.
172  */
173 SensorSampleType getSensorSampleTypeFromSensorType(SensorType sensorType);
174 
175 /**
176  * This SensorMode is designed to wrap constants provided by the CHRE API to
177  * imrpove type-safety. The details of these modes are left to the CHRE API mode
178  * definitions contained in the chreSensorConfigureMode enum.
179  */
180 enum class SensorMode {
181   Off,
182   ActiveContinuous,
183   ActiveOneShot,
184   PassiveContinuous,
185   PassiveOneShot,
186 };
187 
188 /**
189  * @return true if the sensor mode is considered to be active and would cause a
190  * sensor to be powered on in order to get sensor data.
191  */
192 constexpr bool sensorModeIsActive(SensorMode sensorMode);
193 
194 /**
195  * @return true if the sensor mode is considered to be contunuous.
196  */
197 constexpr bool sensorModeIsContinuous(SensorMode sensorMode);
198 
199 /**
200  * @return true if the sensor mode is considered to be one-shot.
201  */
202 constexpr bool sensorModeIsOneShot(SensorMode sensorMode);
203 
204 /**
205  * Translates a CHRE API enum sensor mode to a SensorMode. This function also
206  * performs input validation and will default to SensorMode::Off if the provided
207  * value is not a valid enum value.
208  *
209  * @param enumSensorMode A potentially unsafe CHRE API enum sensor mode.
210  * @return Returns a SensorMode given a CHRE API enum sensor mode.
211  */
212 SensorMode getSensorModeFromEnum(enum chreSensorConfigureMode enumSensorMode);
213 
214 /**
215  * Indicates whether the sensor type is a one-shot sensor.
216  *
217  * @param sensorType The sensor type of the sensor.
218  * @return true if the sensor is a one-shot sensor.
219  */
220 bool sensorTypeIsOneShot(SensorType sensorType);
221 
222 /**
223  * Indicates whether the sensor type is an on-change sensor.
224  *
225  * @param sensorType The sensor type of the sensor.
226  * @return true if the sensor is an on-change sensor.
227  */
228 bool sensorTypeIsOnChange(SensorType sensorType);
229 
230 /**
231  * Models a request for sensor data. This class implements the API set forth by
232  * the RequestMultiplexer container.
233  */
234 class SensorRequest {
235  public:
236   /**
237    * Default constructs a sensor request to the minimal possible configuration.
238    * The sensor is disabled and the interval and latency are both set to zero.
239    */
240   SensorRequest();
241 
242   /**
243    * Constructs a sensor request given a mode, interval and latency.
244    *
245    * @param mode The mode of the sensor request.
246    * @param interval The interval between samples.
247    * @param latency The maximum amount of time to batch samples before
248    *        delivering to a client.
249    */
250   SensorRequest(SensorMode mode, Nanoseconds interval, Nanoseconds latency);
251 
252   /**
253    * Constructs a sensor request given an owning nanoapp, mode, interval and
254    * latency.
255    *
256    * @param nanoapp The nanoapp that made this request.
257    * @param mode The mode of the sensor request.
258    * @param interval The interval between samples.
259    * @param latency The maximum amount of time to batch samples before
260    *        delivering to a client.
261    */
262   SensorRequest(Nanoapp *nanoapp, SensorMode mode, Nanoseconds interval,
263                 Nanoseconds latency);
264 
265   /**
266    * Performs an equivalency comparison of two sensor requests. This determines
267    * if the effective request for sensor data is the same as another.
268    *
269    * @param request The request to compare against.
270    * @return Returns true if this request is equivalent to another.
271    */
272   bool isEquivalentTo(const SensorRequest& request) const;
273 
274   /**
275    * Assigns the current request to the maximal superset of the mode, rate
276    * and latency of the other request.
277    *
278    * @param request The other request to compare the attributes of.
279    * @return true if any of the attributes of this request changed.
280    */
281   bool mergeWith(const SensorRequest& request);
282 
283   /**
284    * @return Returns the interval of samples for this request.
285    */
286   Nanoseconds getInterval() const;
287 
288   /**
289    * @return Returns the maximum amount of time samples can be batched prior to
290    * dispatching to the client.
291    */
292   Nanoseconds getLatency() const;
293 
294   /**
295    * @return The mode of this request.
296    */
297   SensorMode getMode() const;
298 
299   /**
300    * @return The nanoapp that owns this sensor request.
301    */
302   Nanoapp *getNanoapp() const;
303 
304  private:
305   //! The nanoapp that made this request. This will be nullptr when returned by
306   //! the generateIntersectionOf method.
307   Nanoapp *mNanoapp = nullptr;
308 
309   //! The interval between samples for this request.
310   Nanoseconds mInterval;
311 
312   //! The maximum amount of time samples can be batched prior to dispatching to
313   //! the client
314   Nanoseconds mLatency;
315 
316   //! The mode of this request.
317   SensorMode mMode;
318 };
319 
320 }  // namespace chre
321 
322 #include "chre/core/sensor_request_impl.h"
323 
324 #endif  // CHRE_CORE_SENSOR_REQUEST_H_
325