Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5945eb3b authored by Anthony Stange's avatar Anthony Stange
Browse files

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
parent 14195920
Loading
Loading
Loading
Loading
+4 −7
Original line number Diff line number Diff line
@@ -145,13 +145,7 @@ void SensorDevice::initializeSensorList() {
                    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 @@ void SensorDevice::initializeSensorList() {
                                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);
                        }
                    }

+24 −5
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ namespace android {
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 @@ void quantizeSensorEventValues(sensors_event_t *event, float resolution) {
    }
}

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 @@ float defaultResolutionForType(int type) {
        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() {
+7 −2
Original line number Diff line number Diff line
@@ -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 @@ namespace SensorDeviceUtils {

// 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 @@ inline void quantizeValue(float *value, double resolution) {
// 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: