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 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 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 73 SensorType getSensorTypeForSampleEventType(uint16_t eventType) { 74 return getSensorTypeFromUnsignedInt( 75 eventType - CHRE_EVENT_SENSOR_DATA_EVENT_BASE); 76 } 77 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 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 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 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 190 bool sensorTypeIsOneShot(SensorType sensorType) { 191 return (sensorType == SensorType::InstantMotion || 192 sensorType == SensorType::StationaryDetect); 193 } 194 195 bool sensorTypeIsOnChange(SensorType sensorType) { 196 return (sensorType == SensorType::Light || 197 sensorType == SensorType::Proximity); 198 } 199 200 SensorRequest::SensorRequest() 201 : SensorRequest(SensorMode::Off, 202 Nanoseconds(CHRE_SENSOR_INTERVAL_DEFAULT), 203 Nanoseconds(CHRE_SENSOR_LATENCY_DEFAULT)) {} 204 205 SensorRequest::SensorRequest(SensorMode mode, 206 Nanoseconds interval, 207 Nanoseconds latency) 208 : mInterval(interval), mLatency(latency), mMode(mode) {} 209 210 SensorRequest::SensorRequest(Nanoapp *nanoapp, SensorMode mode, 211 Nanoseconds interval, 212 Nanoseconds latency) 213 : mNanoapp(nanoapp), mInterval(interval), mLatency(latency), mMode(mode) {} 214 215 bool SensorRequest::isEquivalentTo(const SensorRequest& request) const { 216 return (mMode == request.mMode 217 && mInterval == request.mInterval 218 && mLatency == request.mLatency); 219 } 220 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 261 Nanoseconds SensorRequest::getInterval() const { 262 return mInterval; 263 } 264 265 Nanoseconds SensorRequest::getLatency() const { 266 return mLatency; 267 } 268 269 SensorMode SensorRequest::getMode() const { 270 return mMode; 271 } 272 273 Nanoapp *SensorRequest::getNanoapp() const { 274 return mNanoapp; 275 } 276 277 } // namespace chre 278