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 #include <algorithm>
18 
19 #include "chre/core/sensor_request.h"
20 #include "chre/platform/assert.h"
21 #include "chre/platform/fatal_error.h"
22 
23 namespace chre {
24 
getSensorTypeName(SensorType sensorType)25 const char *getSensorTypeName(SensorType sensorType) {
26   switch (sensorType) {
27     case SensorType::Unknown:
28       return "Unknown";
29     case SensorType::Accelerometer:
30       return "Accelerometer";
31     case SensorType::InstantMotion:
32       return "Instant Motion";
33     case SensorType::StationaryDetect:
34       return "Stationary Detect";
35     case SensorType::Gyroscope:
36       return "Gyroscope";
37     case SensorType::GeomagneticField:
38       return "Geomagnetic Field";
39     case SensorType::Pressure:
40       return "Pressure";
41     case SensorType::Light:
42       return "Light";
43     case SensorType::Proximity:
44       return "Proximity";
45     case SensorType::AccelerometerTemperature:
46       return "Accelerometer Temp";
47     case SensorType::GyroscopeTemperature:
48       return "Gyroscope Temp";
49     case SensorType::UncalibratedAccelerometer:
50       return "Uncal Accelerometer";
51     case SensorType::UncalibratedGyroscope:
52       return "Uncal Gyroscope";
53     case SensorType::UncalibratedGeomagneticField:
54       return "Uncal Geomagnetic Field";
55     default:
56       CHRE_ASSERT(false);
57       return "";
58   }
59 }
60 
getSampleEventTypeForSensorType(SensorType sensorType)61 uint16_t getSampleEventTypeForSensorType(SensorType sensorType) {
62   if (sensorType == SensorType::Unknown) {
63     FATAL_ERROR("Tried to obtain the sensor sample event index for an unknown "
64                 "sensor type");
65   }
66 
67   // The enum values of SensorType may not map to the defined values in the
68   // CHRE API.
69   uint8_t sensorTypeValue = getUnsignedIntFromSensorType(sensorType);
70   return CHRE_EVENT_SENSOR_DATA_EVENT_BASE + sensorTypeValue;
71 }
72 
getSensorTypeForSampleEventType(uint16_t eventType)73 SensorType getSensorTypeForSampleEventType(uint16_t eventType) {
74   return getSensorTypeFromUnsignedInt(
75       eventType - CHRE_EVENT_SENSOR_DATA_EVENT_BASE);
76 }
77 
getSensorTypeFromUnsignedInt(uint8_t sensorType)78 SensorType getSensorTypeFromUnsignedInt(uint8_t sensorType) {
79   switch (sensorType) {
80     case CHRE_SENSOR_TYPE_ACCELEROMETER:
81       return SensorType::Accelerometer;
82     case CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT:
83       return SensorType::InstantMotion;
84     case CHRE_SENSOR_TYPE_STATIONARY_DETECT:
85       return SensorType::StationaryDetect;
86     case CHRE_SENSOR_TYPE_GYROSCOPE:
87       return SensorType::Gyroscope;
88     case CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD:
89       return SensorType::GeomagneticField;
90     case CHRE_SENSOR_TYPE_PRESSURE:
91       return SensorType::Pressure;
92     case CHRE_SENSOR_TYPE_LIGHT:
93       return SensorType::Light;
94     case CHRE_SENSOR_TYPE_PROXIMITY:
95       return SensorType::Proximity;
96     case CHRE_SENSOR_TYPE_ACCELEROMETER_TEMPERATURE:
97       return SensorType::AccelerometerTemperature;
98     case CHRE_SENSOR_TYPE_GYROSCOPE_TEMPERATURE:
99       return SensorType::GyroscopeTemperature;
100     case CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER:
101       return SensorType::UncalibratedAccelerometer;
102     case CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE:
103       return SensorType::UncalibratedGyroscope;
104     case CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD:
105       return SensorType::UncalibratedGeomagneticField;
106     default:
107       return SensorType::Unknown;
108   }
109 }
110 
getUnsignedIntFromSensorType(SensorType sensorType)111 uint8_t getUnsignedIntFromSensorType(SensorType sensorType) {
112   switch (sensorType) {
113     case SensorType::Accelerometer:
114       return CHRE_SENSOR_TYPE_ACCELEROMETER;
115     case SensorType::InstantMotion:
116       return CHRE_SENSOR_TYPE_INSTANT_MOTION_DETECT;
117     case SensorType::StationaryDetect:
118       return CHRE_SENSOR_TYPE_STATIONARY_DETECT;
119     case SensorType::Gyroscope:
120       return CHRE_SENSOR_TYPE_GYROSCOPE;
121     case SensorType::GeomagneticField:
122       return CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD;
123     case SensorType::Pressure:
124       return CHRE_SENSOR_TYPE_PRESSURE;
125     case SensorType::Light:
126       return CHRE_SENSOR_TYPE_LIGHT;
127     case SensorType::Proximity:
128       return CHRE_SENSOR_TYPE_PROXIMITY;
129     case SensorType::AccelerometerTemperature:
130       return CHRE_SENSOR_TYPE_ACCELEROMETER_TEMPERATURE;
131     case SensorType::GyroscopeTemperature:
132       return CHRE_SENSOR_TYPE_GYROSCOPE_TEMPERATURE;
133     case SensorType::UncalibratedAccelerometer:
134       return CHRE_SENSOR_TYPE_UNCALIBRATED_ACCELEROMETER;
135     case SensorType::UncalibratedGyroscope:
136       return CHRE_SENSOR_TYPE_UNCALIBRATED_GYROSCOPE;
137     case SensorType::UncalibratedGeomagneticField:
138       return CHRE_SENSOR_TYPE_UNCALIBRATED_GEOMAGNETIC_FIELD;
139     default:
140       // Update implementation to prevent undefined or SensorType::Unknown from
141       // being used.
142       CHRE_ASSERT(false);
143       return 0;
144   }
145 }
146 
getSensorSampleTypeFromSensorType(SensorType sensorType)147 SensorSampleType getSensorSampleTypeFromSensorType(SensorType sensorType) {
148   switch (sensorType) {
149     case SensorType::Accelerometer:
150     case SensorType::Gyroscope:
151     case SensorType::GeomagneticField:
152     case SensorType::UncalibratedAccelerometer:
153     case SensorType::UncalibratedGyroscope:
154     case SensorType::UncalibratedGeomagneticField:
155       return SensorSampleType::ThreeAxis;
156     case SensorType::Pressure:
157     case SensorType::Light:
158     case SensorType::AccelerometerTemperature:
159     case SensorType::GyroscopeTemperature:
160       return SensorSampleType::Float;
161     case SensorType::InstantMotion:
162     case SensorType::StationaryDetect:
163       return SensorSampleType::Occurrence;
164     case SensorType::Proximity:
165       return SensorSampleType::Byte;
166     default:
167       CHRE_ASSERT(false);
168       return SensorSampleType::Unknown;
169   }
170 }
171 
getSensorModeFromEnum(enum chreSensorConfigureMode enumSensorMode)172 SensorMode getSensorModeFromEnum(enum chreSensorConfigureMode enumSensorMode) {
173   switch (enumSensorMode) {
174     case CHRE_SENSOR_CONFIGURE_MODE_DONE:
175       return SensorMode::Off;
176     case CHRE_SENSOR_CONFIGURE_MODE_CONTINUOUS:
177       return SensorMode::ActiveContinuous;
178     case CHRE_SENSOR_CONFIGURE_MODE_ONE_SHOT:
179       return SensorMode::ActiveOneShot;
180     case CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_CONTINUOUS:
181       return SensorMode::PassiveContinuous;
182     case CHRE_SENSOR_CONFIGURE_MODE_PASSIVE_ONE_SHOT:
183       return SensorMode::PassiveOneShot;
184     default:
185       // Default to off since it is the least harmful and has no power impact.
186       return SensorMode::Off;
187   }
188 }
189 
sensorTypeIsOneShot(SensorType sensorType)190 bool sensorTypeIsOneShot(SensorType sensorType) {
191   return (sensorType == SensorType::InstantMotion ||
192           sensorType == SensorType::StationaryDetect);
193 }
194 
sensorTypeIsOnChange(SensorType sensorType)195 bool sensorTypeIsOnChange(SensorType sensorType) {
196   return (sensorType == SensorType::Light ||
197           sensorType == SensorType::Proximity);
198 }
199 
SensorRequest()200 SensorRequest::SensorRequest()
201     : SensorRequest(SensorMode::Off,
202                     Nanoseconds(CHRE_SENSOR_INTERVAL_DEFAULT),
203                     Nanoseconds(CHRE_SENSOR_LATENCY_DEFAULT)) {}
204 
SensorRequest(SensorMode mode,Nanoseconds interval,Nanoseconds latency)205 SensorRequest::SensorRequest(SensorMode mode,
206                              Nanoseconds interval,
207                              Nanoseconds latency)
208     : mInterval(interval), mLatency(latency), mMode(mode) {}
209 
SensorRequest(Nanoapp * nanoapp,SensorMode mode,Nanoseconds interval,Nanoseconds latency)210 SensorRequest::SensorRequest(Nanoapp *nanoapp, SensorMode mode,
211                              Nanoseconds interval,
212                              Nanoseconds latency)
213     : mNanoapp(nanoapp), mInterval(interval), mLatency(latency), mMode(mode) {}
214 
isEquivalentTo(const SensorRequest & request) const215 bool SensorRequest::isEquivalentTo(const SensorRequest& request) const {
216   return (mMode == request.mMode
217       && mInterval == request.mInterval
218       && mLatency == request.mLatency);
219 }
220 
mergeWith(const SensorRequest & request)221 bool SensorRequest::mergeWith(const SensorRequest& request) {
222   bool attributesChanged = false;
223 
224   if (request.mInterval < mInterval) {
225     mInterval = request.mInterval;
226     attributesChanged = true;
227   }
228 
229   if (request.mLatency < mLatency) {
230     mLatency = request.mLatency;
231     attributesChanged = true;
232   }
233 
234   // Compute the highest priority mode. Active continuous is the highest
235   // priority and passive one-shot is the lowest.
236   SensorMode maximalSensorMode = SensorMode::Off;
237   if (mMode == SensorMode::ActiveContinuous
238       || request.mMode == SensorMode::ActiveContinuous) {
239     maximalSensorMode = SensorMode::ActiveContinuous;
240   } else if (mMode == SensorMode::ActiveOneShot
241       || request.mMode == SensorMode::ActiveOneShot) {
242     maximalSensorMode = SensorMode::ActiveOneShot;
243   } else if (mMode == SensorMode::PassiveContinuous
244       || request.mMode == SensorMode::PassiveContinuous) {
245     maximalSensorMode = SensorMode::PassiveContinuous;
246   } else if (mMode == SensorMode::PassiveOneShot
247       || request.mMode == SensorMode::PassiveOneShot) {
248     maximalSensorMode = SensorMode::PassiveOneShot;
249   } else {
250     CHRE_ASSERT(false);
251   }
252 
253   if (mMode != maximalSensorMode) {
254     mMode = maximalSensorMode;
255     attributesChanged = true;
256   }
257 
258   return attributesChanged;
259 }
260 
getInterval() const261 Nanoseconds SensorRequest::getInterval() const {
262   return mInterval;
263 }
264 
getLatency() const265 Nanoseconds SensorRequest::getLatency() const {
266   return mLatency;
267 }
268 
getMode() const269 SensorMode SensorRequest::getMode() const {
270   return mMode;
271 }
272 
getNanoapp() const273 Nanoapp *SensorRequest::getNanoapp() const {
274   return mNanoapp;
275 }
276 
277 }  // namespace chre
278