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

Commit 3dd8502a authored by Brian Duddie's avatar Brian Duddie
Browse files

Only requantize sensor max range if significant

The previous computation that decided whether to adjust the sensor's
reported maximum range if not a multiple of the resolution was
susceptible to floating point error (e.g. considering 5.0 as not a
multiple of 0.1), so rework this to only update the maximum range and
print a warning log if the maximum range would be changed significantly
after requantization. We define significant here as resolution/8 (i.e.
the target quantization level).

Also, make the reported power clamping log more helpful.

Fixes: 182828004
Test: compare SensorService startup logs before & after change
Change-Id: I44e399a7aca6fe8ff02bd2840525c95798cda1f4
parent 5a7ea516
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -132,8 +132,6 @@ SensorDevice::SensorDevice()
}

void SensorDevice::initializeSensorList() {
    float minPowerMa = 0.001; // 1 microAmp

    checkReturn(mSensors->getSensorsList(
            [&](const auto &list) {
                const size_t count = list.size();
@@ -151,13 +149,18 @@ void SensorDevice::initializeSensorList() {
                        // Don't crash in this case since CTS will verify that devices don't go to
                        // production with a resolution of 0.
                        if (sensor.resolution != 0) {
                            double promotedResolution = sensor.resolution;
                            double promotedMaxRange = sensor.maxRange;
                            if (fmod(promotedMaxRange, promotedResolution) != 0) {
                                ALOGW("%s's max range %f is not a multiple of the resolution %f",
                                        sensor.name, sensor.maxRange, sensor.resolution);
                            float quantizedRange = sensor.maxRange;
                            SensorDeviceUtils::quantizeValue(
                                        &sensor.maxRange, promotedResolution);
                                    &quantizedRange, sensor.resolution, /*factor=*/ 1);
                            // Only rewrite maxRange if the requantization produced a "significant"
                            // change, which is fairly arbitrarily defined as resolution / 8.
                            // Smaller deltas are permitted, as they may simply be due to floating
                            // point representation error, etc.
                            if (fabsf(sensor.maxRange - quantizedRange) > sensor.resolution / 8) {
                                ALOGW("%s's max range %.12f is not a multiple of the resolution "
                                      "%.12f - updated to %.12f", sensor.name, sensor.maxRange,
                                      sensor.resolution, quantizedRange);
                                sensor.maxRange = quantizedRange;
                            }
                        } else {
                            // Don't crash here or the device will go into a crashloop.
@@ -166,10 +169,11 @@ void SensorDevice::initializeSensorList() {
                    }

                    // Sanity check and clamp power if it is 0 (or close)
                    if (sensor.power < minPowerMa) {
                        ALOGI("Reported power %f not deemed sane, clamping to %f",
                              sensor.power, minPowerMa);
                        sensor.power = minPowerMa;
                    constexpr float MIN_POWER_MA = 0.001; // 1 microAmp
                    if (sensor.power < MIN_POWER_MA) {
                        ALOGI("%s's reported power %f invalid, clamped to %f",
                              sensor.name, sensor.power, MIN_POWER_MA);
                        sensor.power = MIN_POWER_MA;
                    }
                    mSensorList.push_back(sensor);

+5 −6
Original line number Diff line number Diff line
@@ -32,16 +32,15 @@ using ::android::hidl::manager::V1_0::IServiceNotification;
namespace android {
namespace SensorDeviceUtils {

// Quantizes a single value using a sensor's resolution.
inline void quantizeValue(float *value, double resolution) {
// Quantizes a single value to (a fractional factor of) a sensor's resolution. Typically we
// increase the value of the sensor's nominal resolution to ensure that sensor accuracy
// improvements, like runtime calibration, are not masked during requantization.
inline void quantizeValue(float *value, double resolution, double factor = 0.125) {
    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.
    double incRes = 0.125 * resolution;
    double incRes = factor * resolution;
    *value = round(static_cast<double>(*value) / incRes) * incRes;
}