Enforce sensible resolution for accel / gyro / mag
Since there's no guarantee that devices provide a resolution value for a
given sensor if they were developed before Android R, stop crashing for
resolution values of 0 and skip requantization.
Instead, override the resolution value for accel, gyro, and mag if the
given resolution value claims it supports more than 24 bits of
resolution. This should be more than enough to cover current and future
devices.
Bug: 162957913
Test: Verify device with resolution value lower than this has its value
changed and if the value is within the appropriate range, it's left
alone.
Change-Id: I9616062ca238c433d51f905be950927bbe2770af
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index e355594..2810bff 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -145,13 +145,7 @@
convertToSensor(convertToOldSensorInfo(list[i]), &sensor);
if (sensor.type < static_cast<int>(SensorType::DEVICE_PRIVATE_BASE)) {
- if(sensor.resolution == 0) {
- // Don't crash here or the device will go into a crashloop.
- ALOGW("%s must have a non-zero resolution", sensor.name);
- // For simple algos, map their resolution to 1 if it's not specified
- sensor.resolution =
- SensorDeviceUtils::defaultResolutionForType(sensor.type);
- }
+ sensor.resolution = SensorDeviceUtils::resolutionForSensor(sensor);
// Some sensors don't have a default resolution and will be left at 0.
// Don't crash in this case since CTS will verify that devices don't go to
@@ -165,6 +159,9 @@
SensorDeviceUtils::quantizeValue(
&sensor.maxRange, promotedResolution);
}
+ } else {
+ // Don't crash here or the device will go into a crashloop.
+ ALOGW("%s should have a non-zero resolution", sensor.name);
}
}
diff --git a/services/sensorservice/SensorDeviceUtils.cpp b/services/sensorservice/SensorDeviceUtils.cpp
index 52213cf..5aa283e 100644
--- a/services/sensorservice/SensorDeviceUtils.cpp
+++ b/services/sensorservice/SensorDeviceUtils.cpp
@@ -31,7 +31,6 @@
namespace SensorDeviceUtils {
void quantizeSensorEventValues(sensors_event_t *event, float resolution) {
- LOG_FATAL_IF(resolution == 0, "Resolution must be specified for all sensors!");
if (resolution == 0) {
return;
}
@@ -79,8 +78,26 @@
}
}
-float defaultResolutionForType(int type) {
- switch ((SensorTypeV2_1)type) {
+float resolutionForSensor(const sensor_t &sensor) {
+ switch ((SensorTypeV2_1)sensor.type) {
+ case SensorTypeV2_1::ACCELEROMETER:
+ case SensorTypeV2_1::MAGNETIC_FIELD:
+ case SensorTypeV2_1::GYROSCOPE:
+ case SensorTypeV2_1::MAGNETIC_FIELD_UNCALIBRATED:
+ case SensorTypeV2_1::GYROSCOPE_UNCALIBRATED:
+ case SensorTypeV2_1::ACCELEROMETER_UNCALIBRATED: {
+ if (sensor.maxRange == 0) {
+ ALOGE("No max range for sensor type %d, can't determine appropriate resolution",
+ sensor.type);
+ return sensor.resolution;
+ }
+ // Accel, gyro, and mag shouldn't have more than 24 bits of resolution on the most
+ // advanced devices.
+ double lowerBound = 2.0 * sensor.maxRange / std::pow(2, 24);
+
+ // No need to check the upper bound as that's already enforced through CTS.
+ return std::max(sensor.resolution, static_cast<float>(lowerBound));
+ }
case SensorTypeV2_1::SIGNIFICANT_MOTION:
case SensorTypeV2_1::STEP_DETECTOR:
case SensorTypeV2_1::STEP_COUNTER:
@@ -91,12 +108,14 @@
case SensorTypeV2_1::WRIST_TILT_GESTURE:
case SensorTypeV2_1::STATIONARY_DETECT:
case SensorTypeV2_1::MOTION_DETECT:
+ // Ignore input resolution as all of these sensors are required to have a resolution of
+ // 1.
return 1.0f;
default:
- // fall through and return 0 for all other types
+ // fall through and return the current resolution for all other types
break;
}
- return 0.0f;
+ return sensor.resolution;
}
HidlServiceRegistrationWaiter::HidlServiceRegistrationWaiter() {
diff --git a/services/sensorservice/SensorDeviceUtils.h b/services/sensorservice/SensorDeviceUtils.h
index c232f0b..1309971 100644
--- a/services/sensorservice/SensorDeviceUtils.h
+++ b/services/sensorservice/SensorDeviceUtils.h
@@ -19,6 +19,7 @@
#include <android/hidl/manager/1.0/IServiceNotification.h>
#include <hardware/sensors.h>
+#include <utils/Log.h>
#include <cmath>
#include <condition_variable>
@@ -33,6 +34,10 @@
// Quantizes a single value using a sensor's resolution.
inline void quantizeValue(float *value, double resolution) {
+ if (resolution == 0) {
+ return;
+ }
+
// Increase the value of the sensor's nominal resolution to ensure that
// sensor accuracy improvements, like runtime calibration, are not masked
// during requantization.
@@ -43,8 +48,8 @@
// Ensures a sensor event doesn't provide values finer grained than its sensor resolution allows.
void quantizeSensorEventValues(sensors_event_t *event, float resolution);
-// Provides a default resolution for simple sensor types if one wasn't provided by the HAL.
-float defaultResolutionForType(int type);
+// Returns the expected resolution value for the given sensor
+float resolutionForSensor(const sensor_t &sensor);
class HidlServiceRegistrationWaiter : public IServiceNotification {
public: