Merge "Add idle screen brightness mapping to DPC"
This commit is contained in:
committed by
Android (Google) Code Review
commit
d6fb34349d
@@ -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.
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
// Display independent values
|
||||
float[] luxLevels = getLuxLevels(resources.getIntArray(
|
||||
com.android.internal.R.array.config_autoBrightnessLevels));
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.
|
||||
int[] luxLevelsResource = Arrays.copyOfRange(luxLevels, 1, luxLevels.length);
|
||||
when(mockResources.getIntArray(com.android.internal.R.array.config_autoBrightnessLevels))
|
||||
.thenReturn(luxLevelsResource);
|
||||
// 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))
|
||||
.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))
|
||||
|
||||
Reference in New Issue
Block a user