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

Commit d6fb3434 authored by Fiona Campbell's avatar Fiona Campbell Committed by Android (Google) Code Review
Browse files

Merge "Add idle screen brightness mapping to DPC"

parents 544739c6 f0c4a778
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -1483,6 +1483,30 @@
    <integer-array name="config_autoBrightnessLevels">
    </integer-array>

    <!-- Array of light sensor lux values to define our levels for auto backlight brightness
         support whilst in idle mode.
         The N entries of this array define N + 1 control points as follows:
         (1-based arrays)

         Point 1:            (0, value[1]):             lux <= 0
         Point 2:     (level[1], value[2]):  0        < lux <= level[1]
         Point 3:     (level[2], value[3]):  level[2] < lux <= level[3]
         ...
         Point N+1: (level[N], value[N+1]):  level[N] < lux

         The control points must be strictly increasing. Each control point
         corresponds to an entry in the brightness backlight values arrays.
         For example, if lux == level[1] (first element of the levels array)
         then the brightness will be determined by value[2] (second element
         of the brightness values array).

         Spline interpolation is used to determine the auto-brightness
         backlight values for lux levels between these control points.

         Must be overridden in platform specific overlays -->
    <integer-array name="config_autoBrightnessLevelsIdle">
    </integer-array>

    <!-- Timeout (in milliseconds) after which we remove the effects any user interactions might've
         had on the brightness mapping. This timeout doesn't start until we transition to a
         non-interactive display policy so that we don't reset while users are using their devices,
@@ -1506,6 +1530,10 @@
    <integer-array name="config_autoBrightnessLcdBacklightValues_doze">
    </integer-array>

    <!-- Enables idle screen brightness mode on this device.
         If this is true, config_autoBrightnessDisplayValuesNitsIdle must be defined. -->
    <bool name="config_enableIdleScreenBrightnessMode">false</bool>

    <!-- Array of desired screen brightness in nits corresponding to the lux values
         in the config_autoBrightnessLevels array. As with config_screenBrightnessMinimumNits and
         config_screenBrightnessMaximumNits, the display brightness is defined as the measured
@@ -1522,6 +1550,13 @@
    <array name="config_autoBrightnessDisplayValuesNits">
    </array>

    <!-- Array of desired screen brightness in nits for idle screen brightness mode.
         This array should meet the same requirements as config_autoBrightnessDisplayValuesNits.
         This array also corresponds to the lux values given in config_autoBrightnessLevelsIdle.
         In order to activate this mode, config_enableIdleScreenBrightnessMode must be true. -->
    <array name="config_autoBrightnessDisplayValuesNitsIdle">
    </array>

    <!-- Array of output values for button backlight corresponding to the luX values
         in the config_autoBrightnessLevels array.  This array should have size one greater
         than the size of the config_autoBrightnessLevels array.
+3 −0
Original line number Diff line number Diff line
@@ -1902,6 +1902,7 @@
  <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" />
  <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues_doze" />
  <java-symbol type="array" name="config_autoBrightnessLevels" />
  <java-symbol type="array" name="config_autoBrightnessLevelsIdle" />
  <java-symbol type="array" name="config_ambientThresholdLevels" />
  <java-symbol type="array" name="config_ambientBrighteningThresholds" />
  <java-symbol type="array" name="config_ambientDarkeningThresholds" />
@@ -3788,7 +3789,9 @@
  <java-symbol type="bool" name="config_fillMainBuiltInDisplayCutout" />
  <java-symbol type="drawable" name="ic_logout" />

  <java-symbol type="bool" name="config_enableIdleScreenBrightnessMode" />
  <java-symbol type="array" name="config_autoBrightnessDisplayValuesNits" />
  <java-symbol type="array" name="config_autoBrightnessDisplayValuesNitsIdle" />
  <java-symbol type="array" name="config_screenBrightnessBacklight" />
  <java-symbol type="array" name="config_screenBrightnessNits" />

+51 −6
Original line number Diff line number Diff line
@@ -60,17 +60,62 @@ public abstract class BrightnessMappingStrategy {

    private static final Plog PLOG = Plog.createSystemPlog(TAG);

    /**
     * Creates a BrightnessMappingStrategy for active (normal) mode.
     * @param resources
     * @param displayDeviceConfig
     * @return the BrightnessMappingStrategy
     */
    @Nullable
    public static BrightnessMappingStrategy create(Resources resources,
            DisplayDeviceConfig displayDeviceConfig) {
        return create(resources, displayDeviceConfig, /* isForIdleMode= */ false);
    }

    /**
     * Creates a BrightnessMappingStrategy for idle screen brightness mode.
     * @param resources
     * @param displayDeviceConfig
     * @return the BrightnessMappingStrategy
     */
    @Nullable
    public static BrightnessMappingStrategy createForIdleMode(Resources resources,
            DisplayDeviceConfig displayDeviceConfig) {
        return create(resources, displayDeviceConfig, /* isForIdleMode= */ true);
    }

        // Display independent values
        float[] luxLevels = getLuxLevels(resources.getIntArray(
    /**
     * Creates a BrightnessMapping strategy for either active or idle screen brightness mode.
     * We do not create a simple mapping strategy for idle mode.
     *
     * @param resources
     * @param displayDeviceConfig
     * @param isForIdleMode determines whether the configurations loaded are for idle screen
     *                      brightness mode or active screen brightness mode.
     * @return the BrightnessMappingStrategy
     */
    @Nullable
    private static BrightnessMappingStrategy create(Resources resources,
            DisplayDeviceConfig displayDeviceConfig, boolean isForIdleMode) {

        // Display independent, mode dependent values
        float[] brightnessLevelsNits;
        float[] luxLevels;
        if (isForIdleMode) {
            brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
                    com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle));
            luxLevels = getLuxLevels(resources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessLevelsIdle));
        } else {
            brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
                    com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
            luxLevels = getLuxLevels(resources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessLevels));
        }

        // Display independent, mode independent values
        int[] brightnessLevelsBacklight = resources.getIntArray(
                com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
        float[] brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
                com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
        float autoBrightnessAdjustmentMaxGamma = resources.getFraction(
                com.android.internal.R.fraction.config_autoBrightnessAdjustmentMaxGamma,
                1, 1);
@@ -91,7 +136,7 @@ public abstract class BrightnessMappingStrategy {
            builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO);
            return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange,
                    autoBrightnessAdjustmentMaxGamma);
        } else if (isValidMapping(luxLevels, brightnessLevelsBacklight)) {
        } else if (isValidMapping(luxLevels, brightnessLevelsBacklight) && !isForIdleMode) {
            return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight,
                    autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout);
        } else {
+33 −9
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.util.Slog;
import android.util.TimeUtils;
import android.view.Display;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IBatteryStats;
import com.android.internal.display.BrightnessSynchronizer;
@@ -386,8 +387,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    private Sensor mLightSensor;

    // The mapper between ambient lux, display backlight values, and display brightness.
    // This mapper holds the current one that is being used. We will switch between the idle
    // mapper and active mapper here.
    @Nullable
    private BrightnessMappingStrategy mBrightnessMapper;
    private BrightnessMappingStrategy mCurrentBrightnessMapper;

    // Mapper used for active (normal) screen brightness mode
    @Nullable
    private BrightnessMappingStrategy mInteractiveModeBrightnessMapper;
    // Mapper used for idle screen brightness mode
    @Nullable
    private BrightnessMappingStrategy mIdleModeBrightnessMapper;

    // The current brightness configuration.
    @Nullable
@@ -408,7 +418,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call

    // The temporary screen brightness. Typically set when a user is interacting with the
    // brightness slider but hasn't settled on a choice yet. Set to
    // PowerManager.BRIGHNTESS_INVALID_FLOAT when there's no temporary brightness set.
    // PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary brightness set.
    private float mTemporaryScreenBrightness;

    // The current screen brightness while in VR mode.
@@ -600,7 +610,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    }

    private void handleRbcChanged(boolean strengthChanged, boolean justActivated) {
        if (mBrightnessMapper == null) {
        if (mCurrentBrightnessMapper == null) {
            Log.w(TAG, "No brightness mapping available to recalculate splines");
            return;
        }
@@ -609,7 +619,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        for (int i = 0; i < mNitsRange.length; i++) {
            adjustedNits[i] = mCdsi.getReduceBrightColorsAdjustedBrightnessNits(mNitsRange[i]);
        }
        mBrightnessMapper.recalculateSplines(mCdsi.isReduceBrightColorsActivated(), adjustedNits);
        mCurrentBrightnessMapper.recalculateSplines(mCdsi.isReduceBrightColorsActivated(),
                adjustedNits);

        mPendingRbcOnOrChanged = strengthChanged || justActivated;

@@ -867,9 +878,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
            return;
        }

        mBrightnessMapper = BrightnessMappingStrategy.create(resources, mDisplayDeviceConfig);
        final boolean isIdleScreenBrightnessEnabled = resources.getBoolean(
                R.bool.config_enableIdleScreenBrightnessMode);
        mInteractiveModeBrightnessMapper = BrightnessMappingStrategy.create(resources,
                mDisplayDeviceConfig);
        if (isIdleScreenBrightnessEnabled) {
            mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources,
                    mDisplayDeviceConfig);
        }
        mCurrentBrightnessMapper = mInteractiveModeBrightnessMapper;

        if (mBrightnessMapper != null) {
        if (mCurrentBrightnessMapper != null) {
            final float dozeScaleFactor = resources.getFraction(
                    com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
                    1, 1);
@@ -920,7 +939,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
                mAutomaticBrightnessController.stop();
            }
            mAutomaticBrightnessController = new AutomaticBrightnessController(this,
                    handler.getLooper(), mSensorManager, mLightSensor, mBrightnessMapper,
                    handler.getLooper(), mSensorManager, mLightSensor, mCurrentBrightnessMapper,
                    lightSensorWarmUpTimeConfig, PowerManager.BRIGHTNESS_MIN,
                    PowerManager.BRIGHTNESS_MAX, dozeScaleFactor, lightSensorRate,
                    initialLightSensorRate, brighteningLightDebounce, darkeningLightDebounce,
@@ -2143,8 +2162,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
    }

    private float convertToNits(float brightness) {
        if (mBrightnessMapper != null) {
            return mBrightnessMapper.convertToNits(brightness);
        if (mCurrentBrightnessMapper != null) {
            return mCurrentBrightnessMapper.convertToNits(brightness);
        } else {
            return -1.0f;
        }
@@ -2296,6 +2315,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
        pw.println("  mReportedToPolicy=" +
                reportedToPolicyToString(mReportedScreenStateToPolicy));

        if (mIdleModeBrightnessMapper != null) {
            pw.println("  mIdleModeBrightnessMapper= ");
            mIdleModeBrightnessMapper.dump(pw);
        }

        if (mScreenBrightnessRampAnimator != null) {
            pw.println("  mScreenBrightnessRampAnimator.isAnimating()=" +
                    mScreenBrightnessRampAnimator.isAnimating());
+83 −4
Original line number Diff line number Diff line
@@ -59,6 +59,20 @@ public class BrightnessMappingStrategyTest {
        5000
    };

    private static final int[] LUX_LEVELS_IDLE = {
        0,
        10,
        40,
        80,
        200,
        655,
        1200,
        2500,
        4400,
        8000,
        10000
    };

    private static final float[] DISPLAY_LEVELS_NITS = {
        13.25f,
        54.0f,
@@ -73,6 +87,20 @@ public class BrightnessMappingStrategyTest {
        478.5f,
    };

    private static final float[] DISPLAY_LEVELS_NITS_IDLE = {
        23.25f,
        64.0f,
        88.85f,
        115.02f,
        142.7f,
        180.12f,
        222.1f,
        275.2f,
        345.8f,
        425.2f,
        468.5f,
    };

    private static final int[] DISPLAY_LEVELS_BACKLIGHT = {
        9,
        30,
@@ -88,7 +116,6 @@ public class BrightnessMappingStrategyTest {
    };

    private static final float[] DISPLAY_RANGE_NITS = { 2.685f, 478.5f };
    private static final float[] DISPLAY_LEVELS_RANGE_NITS = { 13.25f, 478.5f };
    private static final float[] BACKLIGHT_RANGE_ZERO_TO_ONE = { 0.0f, 1.0f };
    private static final float[] DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT = { 0.03149606299f, 1.0f };

@@ -118,6 +145,8 @@ public class BrightnessMappingStrategyTest {
            new float[] { 0.0f, 100.0f, 1000.0f, 2500.0f, 4000.0f, 4900.0f, 5000.0f },
            new float[] { 0.0475f, 0.0475f, 0.2225f, 0.5140f, 0.8056f, 0.9805f, 1.0f });

    private static final float TOLERANCE = 0.0001f;

    @Test
    public void testSimpleStrategyMappingAtControlPoints() {
        Resources res = createResources(LUX_LEVELS, DISPLAY_LEVELS_BACKLIGHT);
@@ -357,6 +386,27 @@ public class BrightnessMappingStrategyTest {
        assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc));
    }

    @Test
    public void testIdleModeConfigLoadsCorrectly() {
        Resources res = createResourcesIdle(LUX_LEVELS_IDLE, DISPLAY_LEVELS_NITS_IDLE);
        DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE);

        // Create an idle mode bms
        // This will fail if it tries to fetch the wrong configuration.
        BrightnessMappingStrategy bms = BrightnessMappingStrategy.createForIdleMode(res, ddc);
        assertNotNull("BrightnessMappingStrategy should not be null", bms);

        // Ensure that the config is the one we set
        // Ensure that the lux -> brightness -> nits path works. ()
        for (int i = 0; i < DISPLAY_LEVELS_NITS_IDLE.length; i++) {
            assertEquals(LUX_LEVELS_IDLE[i], bms.getDefaultConfig().getCurve().first[i], TOLERANCE);
            assertEquals(DISPLAY_LEVELS_NITS_IDLE[i], bms.getDefaultConfig().getCurve().second[i],
                    TOLERANCE);
            assertEquals(bms.convertToNits(bms.getBrightness(LUX_LEVELS_IDLE[i])),
                    DISPLAY_LEVELS_NITS_IDLE[i], TOLERANCE);
        }
    }

    private static void assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy strategy) {
        // Save out all of the initial brightness data for comparison after reset.
        float[] initialBrightnessLevels = new float[LUX_LEVELS.length];
@@ -421,14 +471,39 @@ public class BrightnessMappingStrategyTest {
                brightnessLevelsNits);
    }

    private Resources createResourcesIdle(int[] luxLevels, float[] brightnessLevelsNits) {
        return createResources(EMPTY_INT_ARRAY, EMPTY_INT_ARRAY, EMPTY_FLOAT_ARRAY,
                luxLevels, brightnessLevelsNits);
    }

    private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight,
            float[] brightnessLevelsNits) {
        return createResources(luxLevels, brightnessLevelsBacklight, brightnessLevelsNits,
                EMPTY_INT_ARRAY, EMPTY_FLOAT_ARRAY);

    }

    private Resources createResources(int[] luxLevels, int[] brightnessLevelsBacklight,
            float[] brightnessLevelsNits, int[] luxLevelsIdle, float[] brightnessLevelsNitsIdle) {

        Resources mockResources = mock(Resources.class);

        // For historical reasons, the lux levels resource implicitly defines the first point as 0,
        // so we need to chop it off of the array the mock resource object returns.
        // Don't mock if these values are not set. If we try to use them, we will fail.
        if (luxLevels.length > 0) {
            int[] luxLevelsResource = Arrays.copyOfRange(luxLevels, 1, luxLevels.length);
        when(mockResources.getIntArray(com.android.internal.R.array.config_autoBrightnessLevels))
            when(mockResources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessLevels))
                    .thenReturn(luxLevelsResource);
        }
        if (luxLevelsIdle.length > 0) {
            int[] luxLevelsIdleResource = Arrays.copyOfRange(luxLevelsIdle, 1,
                    luxLevelsIdle.length);
            when(mockResources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessLevelsIdle))
                    .thenReturn(luxLevelsIdleResource);
        }

        when(mockResources.getIntArray(
                com.android.internal.R.array.config_autoBrightnessLcdBacklightValues))
@@ -438,6 +513,10 @@ public class BrightnessMappingStrategyTest {
        when(mockResources.obtainTypedArray(
                com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
                .thenReturn(mockBrightnessLevelNits);
        TypedArray mockBrightnessLevelNitsIdle = createFloatTypedArray(brightnessLevelsNitsIdle);
        when(mockResources.obtainTypedArray(
                com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle))
                .thenReturn(mockBrightnessLevelNitsIdle);

        when(mockResources.getInteger(
                com.android.internal.R.integer.config_screenBrightnessSettingMinimum))