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

Commit 77fb68e6 authored by Fiona Campbell's avatar Fiona Campbell
Browse files

Add ambientLightHorizon to DDC

Add ambientLightHorizonLong and ambientLightHorizonShort to the
DisplayDeviceConfig. These values were previously hardcoded, we can now
adjust them per display. The fallback is still the original hardcoded
value.

Bug: 204251622
Test: adb shell dumpsys display | grep -i horizon
Test: atest AutomaticBrightnessControllerTest

Change-Id: Id6960c8117c4c981f74f883af35b2f8fbf171367
parent e62cb766
Loading
Loading
Loading
Loading
+48 −26
Original line number Diff line number Diff line
@@ -70,13 +70,6 @@ class AutomaticBrightnessController {
    private static final int MSG_UPDATE_FOREGROUND_APP_SYNC = 5;
    private static final int MSG_RUN_UPDATE = 6;

    // Length of the ambient light horizon used to calculate the long term estimate of ambient
    // light.
    private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;

    // Length of the ambient light horizon used to calculate short-term estimate of ambient light.
    private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;

    // Callbacks for requesting updates to the display's power state
    private final Callbacks mCallbacks;

@@ -121,8 +114,10 @@ class AutomaticBrightnessController {
    // and only then decide whether to change brightness.
    private final boolean mResetAmbientLuxAfterWarmUpConfig;

    // Period of time in which to consider light samples in milliseconds.
    private final int mAmbientLightHorizon;
    // Period of time in which to consider light samples for a short/long-term estimate of ambient
    // light in milliseconds.
    private final int mAmbientLightHorizonLong;
    private final int mAmbientLightHorizonShort;

    // The intercept used for the weighting calculation. This is used in order to keep all possible
    // weighting values positive.
@@ -215,6 +210,7 @@ class AutomaticBrightnessController {
    private PackageManager mPackageManager;
    private Context mContext;

    private Clock mClock;
    private final Injector mInjector;

    AutomaticBrightnessController(Callbacks callbacks, Looper looper,
@@ -226,14 +222,16 @@ class AutomaticBrightnessController {
            boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
            HysteresisLevels screenBrightnessThresholds, Context context,
            HighBrightnessModeController hbmController,
            BrightnessMappingStrategy idleModeBrightnessMapper) {
            BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
            int ambientLightHorizonLong) {
        this(new Injector(), callbacks, looper, sensorManager, lightSensor,
                interactiveModeBrightnessMapper,
                lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
                lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
                darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
                ambientBrightnessThresholds, screenBrightnessThresholds, context,
                hbmController, idleModeBrightnessMapper
                hbmController, idleModeBrightnessMapper, ambientLightHorizonShort,
                ambientLightHorizonLong
        );
    }

@@ -247,8 +245,10 @@ class AutomaticBrightnessController {
            boolean resetAmbientLuxAfterWarmUpConfig, HysteresisLevels ambientBrightnessThresholds,
            HysteresisLevels screenBrightnessThresholds, Context context,
            HighBrightnessModeController hbmController,
            BrightnessMappingStrategy idleModeBrightnessMapper) {
            BrightnessMappingStrategy idleModeBrightnessMapper, int ambientLightHorizonShort,
            int ambientLightHorizonLong) {
        mInjector = injector;
        mClock = injector.createClock();
        mContext = context;
        mCallbacks = callbacks;
        mSensorManager = sensorManager;
@@ -263,15 +263,16 @@ class AutomaticBrightnessController {
        mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
        mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
        mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
        mAmbientLightHorizon = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
        mWeightingIntercept = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
        mAmbientLightHorizonLong = ambientLightHorizonLong;
        mAmbientLightHorizonShort = ambientLightHorizonShort;
        mWeightingIntercept = ambientLightHorizonLong;
        mAmbientBrightnessThresholds = ambientBrightnessThresholds;
        mScreenBrightnessThresholds = screenBrightnessThresholds;
        mShortTermModelValid = true;
        mShortTermModelAnchor = -1;
        mHandler = new AutomaticBrightnessHandler(looper);
        mAmbientLightRingBuffer =
            new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizon);
            new AmbientLightRingBuffer(mNormalLightSensorRate, mAmbientLightHorizonLong, mClock);

        if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
            mLightSensor = lightSensor;
@@ -390,6 +391,11 @@ class AutomaticBrightnessController {
        mHandler.sendEmptyMessage(MSG_RUN_UPDATE);
    }

    @VisibleForTesting
    float getAmbientLux() {
        return mAmbientLux;
    }

    private boolean setDisplayPolicy(int policy) {
        if (mDisplayPolicy == policy) {
            return false;
@@ -468,7 +474,8 @@ class AutomaticBrightnessController {
        pw.println("  mBrighteningLightDebounceConfig=" + mBrighteningLightDebounceConfig);
        pw.println("  mDarkeningLightDebounceConfig=" + mDarkeningLightDebounceConfig);
        pw.println("  mResetAmbientLuxAfterWarmUpConfig=" + mResetAmbientLuxAfterWarmUpConfig);
        pw.println("  mAmbientLightHorizon=" + mAmbientLightHorizon);
        pw.println("  mAmbientLightHorizonLong=" + mAmbientLightHorizonLong);
        pw.println("  mAmbientLightHorizonShort=" + mAmbientLightHorizonShort);
        pw.println("  mWeightingIntercept=" + mWeightingIntercept);

        pw.println();
@@ -524,7 +531,7 @@ class AutomaticBrightnessController {
        if (enable) {
            if (!mLightSensorEnabled) {
                mLightSensorEnabled = true;
                mLightSensorEnableTime = SystemClock.uptimeMillis();
                mLightSensorEnableTime = mClock.uptimeMillis();
                mCurrentLightSensorRate = mInitialLightSensorRate;
                registerForegroundAppUpdater();
                mSensorManager.registerListener(mLightSensorListener, mLightSensor,
@@ -559,7 +566,7 @@ class AutomaticBrightnessController {

    private void applyLightSensorMeasurement(long time, float lux) {
        mRecentLightSamples++;
        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
        mAmbientLightRingBuffer.push(time, lux);

        // Remember this sample value.
@@ -700,8 +707,8 @@ class AutomaticBrightnessController {
    }

    private void updateAmbientLux() {
        long time = SystemClock.uptimeMillis();
        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizon);
        long time = mClock.uptimeMillis();
        mAmbientLightRingBuffer.prune(time - mAmbientLightHorizonLong);
        updateAmbientLux(time);
    }

@@ -721,7 +728,7 @@ class AutomaticBrightnessController {
                        timeWhenSensorWarmedUp);
                return;
            }
            setAmbientLux(calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS));
            setAmbientLux(calculateAmbientLux(time, mAmbientLightHorizonShort));
            mAmbientLuxValid = true;
            if (mLoggingEnabled) {
                Slog.d(TAG, "updateAmbientLux: Initializing: " +
@@ -741,8 +748,8 @@ class AutomaticBrightnessController {
        // proposed ambient light value since the slow value might be sufficiently far enough away
        // from the fast value to cause a recalculation while its actually just converging on
        // the fast value still.
        float slowAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_LONG_HORIZON_MILLIS);
        float fastAmbientLux = calculateAmbientLux(time, AMBIENT_LIGHT_SHORT_HORIZON_MILLIS);
        float slowAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonLong);
        float fastAmbientLux = calculateAmbientLux(time, mAmbientLightHorizonShort);

        if ((slowAmbientLux >= mAmbientBrighteningThreshold
                && fastAmbientLux >= mAmbientBrighteningThreshold
@@ -1023,7 +1030,7 @@ class AutomaticBrightnessController {
        @Override
        public void onSensorChanged(SensorEvent event) {
            if (mLightSensorEnabled) {
                final long time = SystemClock.uptimeMillis();
                final long time = mClock.uptimeMillis();
                final float lux = event.values[0];
                handleLightSensorEvent(time, lux);
            }
@@ -1049,6 +1056,15 @@ class AutomaticBrightnessController {
        void updateBrightness();
    }

    /** Functional interface for providing time. */
    @VisibleForTesting
    interface Clock {
        /**
         * Returns current time in milliseconds since boot, not counting time spent in deep sleep.
         */
        long uptimeMillis();
    }

    /**
     * A ring buffer of ambient light measurements sorted by time.
     *
@@ -1068,14 +1084,16 @@ class AutomaticBrightnessController {
        private int mStart;
        private int mEnd;
        private int mCount;
        Clock mClock;

        public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon) {
        public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon, Clock clock) {
            if (lightSensorRate <= 0) {
                throw new IllegalArgumentException("lightSensorRate must be above 0");
            }
            mCapacity = (int) Math.ceil(ambientLightHorizon * BUFFER_SLACK / lightSensorRate);
            mRingLux = new float[mCapacity];
            mRingTime = new long[mCapacity];
            mClock = clock;
        }

        public float getLux(int index) {
@@ -1160,7 +1178,7 @@ class AutomaticBrightnessController {
            StringBuilder buf = new StringBuilder();
            buf.append('[');
            for (int i = 0; i < mCount; i++) {
                final long next = i + 1 < mCount ? getTime(i + 1) : SystemClock.uptimeMillis();
                final long next = i + 1 < mCount ? getTime(i + 1) : mClock.uptimeMillis();
                if (i != 0) {
                    buf.append(", ");
                }
@@ -1189,5 +1207,9 @@ class AutomaticBrightnessController {
        public Handler getBackgroundThreadHandler() {
            return BackgroundThread.getHandler();
        }

        Clock createClock() {
            return SystemClock::uptimeMillis;
        }
    }
}
+32 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -86,6 +87,13 @@ public class DisplayDeviceConfig {

    private static final float NITS_INVALID = -1;

    // Length of the ambient light horizon used to calculate the long term estimate of ambient
    // light.
    private static final int AMBIENT_LIGHT_LONG_HORIZON_MILLIS = 10000;

    // Length of the ambient light horizon used to calculate short-term estimate of ambient light.
    private static final int AMBIENT_LIGHT_SHORT_HORIZON_MILLIS = 2000;

    private final Context mContext;

    // The details of the ambient light sensor associated with this display.
@@ -120,6 +128,8 @@ public class DisplayDeviceConfig {
    private float mBrightnessRampFastIncrease = Float.NaN;
    private float mBrightnessRampSlowDecrease = Float.NaN;
    private float mBrightnessRampSlowIncrease = Float.NaN;
    private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
    private int mAmbientHorizonShort = AMBIENT_LIGHT_SHORT_HORIZON_MILLIS;
    private Spline mBrightnessToBacklightSpline;
    private Spline mBacklightToBrightnessSpline;
    private Spline mBacklightToNitsSpline;
@@ -346,6 +356,14 @@ public class DisplayDeviceConfig {
        return mBrightnessRampSlowIncrease;
    }

    public int getAmbientHorizonLong() {
        return mAmbientHorizonLong;
    }

    public int getAmbientHorizonShort() {
        return mAmbientHorizonShort;
    }

    SensorData getAmbientLightSensor() {
        return mAmbientLightSensor;
    }
@@ -405,6 +423,8 @@ public class DisplayDeviceConfig {
                + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
                + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
                + ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
                + ", mAmbientHorizonLong=" + mAmbientHorizonLong
                + ", mAmbientHorizonShort=" + mAmbientHorizonShort
                + ", mAmbientLightSensor=" + mAmbientLightSensor
                + ", mProximitySensor=" + mProximitySensor
                + ", mRefreshRateLimitations= " + Arrays.toString(mRefreshRateLimitations.toArray())
@@ -461,6 +481,7 @@ public class DisplayDeviceConfig {
                loadBrightnessRamps(config);
                loadAmbientLightSensorFromDdc(config);
                loadProxSensorFromDdc(config);
                loadAmbientHorizonFromDdc(config);
            } else {
                Slog.w(TAG, "DisplayDeviceConfig file is null");
            }
@@ -869,6 +890,17 @@ public class DisplayDeviceConfig {
        }
    }

    private void loadAmbientHorizonFromDdc(DisplayConfiguration config) {
        final BigInteger configLongHorizon = config.getAmbientLightHorizonLong();
        if (configLongHorizon != null) {
            mAmbientHorizonLong = configLongHorizon.intValue();
        }
        final BigInteger configShortHorizon = config.getAmbientLightHorizonShort();
        if (configShortHorizon != null) {
            mAmbientHorizonShort = configShortHorizon.intValue();
        }
    }

    static class SensorData {
        public String type;
        public String name;
+3 −1
Original line number Diff line number Diff line
@@ -946,7 +946,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                    lightSensorRate, initialLightSensorRate, brighteningLightDebounce,
                    darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp,
                    ambientBrightnessThresholds, screenBrightnessThresholds, mContext,
                    mHbmController, mIdleModeBrightnessMapper);
                    mHbmController, mIdleModeBrightnessMapper,
                    mDisplayDeviceConfig.getAmbientHorizonShort(),
                    mDisplayDeviceConfig.getAmbientHorizonLong());
        } else {
            mUseSoftwareAutoBrightnessConfig = false;
        }
+9 −0
Original line number Diff line number Diff line
@@ -58,6 +58,15 @@
                <xs:element type="sensorDetails" name="proxSensor">
                    <xs:annotation name="final"/>
                </xs:element>

                <!-- Length of the ambient light horizon used to calculate the long & short term
                estimates of ambient light in milliseconds.-->
                <xs:element type="xs:nonNegativeInteger" name="ambientLightHorizonLong">
                    <xs:annotation name="final"/>
                </xs:element>
                <xs:element type="xs:nonNegativeInteger" name="ambientLightHorizonShort">
                    <xs:annotation name="final"/>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
+4 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.display.config {

  public class DisplayConfiguration {
    ctor public DisplayConfiguration();
    method public final java.math.BigInteger getAmbientLightHorizonLong();
    method public final java.math.BigInteger getAmbientLightHorizonShort();
    method @Nullable public final com.android.server.display.config.DensityMap getDensityMap();
    method public com.android.server.display.config.HighBrightnessMode getHighBrightnessMode();
    method public final com.android.server.display.config.SensorDetails getLightSensor();
@@ -29,6 +31,8 @@ package com.android.server.display.config {
    method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease();
    method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
    method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
    method public final void setAmbientLightHorizonLong(java.math.BigInteger);
    method public final void setAmbientLightHorizonShort(java.math.BigInteger);
    method public final void setDensityMap(@Nullable com.android.server.display.config.DensityMap);
    method public void setHighBrightnessMode(com.android.server.display.config.HighBrightnessMode);
    method public final void setLightSensor(com.android.server.display.config.SensorDetails);
Loading