diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ffb602d93b0f2..16511a678760d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6346,4 +6346,8 @@
true
true
+
+
+ false
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 92dc5694ff2c9..6974bd29e5488 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2229,6 +2229,7 @@
+
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 592daa61f36c9..720ea99da93d2 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -50,7 +50,12 @@ import com.android.server.display.brightness.BrightnessEvent;
import java.io.PrintWriter;
-class AutomaticBrightnessController {
+/**
+ * Manages the associated display brightness when in auto-brightness mode. This is also
+ * responsible for managing the brightness lux-nits mapping strategies. Internally also listens to
+ * the LightSensor and adjusts the system brightness in case of changes in the surrounding lux.
+ */
+public class AutomaticBrightnessController {
private static final String TAG = "AutomaticBrightnessController";
private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
@@ -1140,7 +1145,7 @@ class AutomaticBrightnessController {
if (mCurrentBrightnessMapper != null) {
return mCurrentBrightnessMapper.convertToFloatScale(nits);
} else {
- return -1.0f;
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
}
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index d7c1529aedc4e..d0471837d79b3 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -322,9 +322,10 @@ public abstract class BrightnessMappingStrategy {
public abstract float convertToNits(float brightness);
/**
- * Converts the provided nits value to a float value if possible.
+ * Converts the provided nit value to a float scale value if possible.
*
- * Returns -1.0f if there's no available mapping for the nits to float.
+ * Returns {@link PowerManager.BRIGHTNESS_INVALID_FLOAT} if there's no available mapping for
+ * the nits to float scale.
*/
public abstract float convertToFloatScale(float nits);
@@ -679,7 +680,7 @@ public abstract class BrightnessMappingStrategy {
@Override
public float convertToFloatScale(float nits) {
- return -1.0f;
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
@Override
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java
index 4a9b562be697c..de42370e6d847 100644
--- a/services/core/java/com/android/server/display/BrightnessSetting.java
+++ b/services/core/java/com/android/server/display/BrightnessSetting.java
@@ -121,6 +121,23 @@ public class BrightnessSetting {
}
}
+ /**
+ * @return The brightness for the default display in nits. Used when the underlying display
+ * device has changed but we want to persist the nit value.
+ */
+ public float getBrightnessNitsForDefaultDisplay() {
+ return mPersistentDataStore.getBrightnessNitsForDefaultDisplay();
+ }
+
+ /**
+ * Set brightness in nits for the default display. Used when we want to persist the nit value
+ * even if the underlying display device changes.
+ * @param nits The brightness value in nits
+ */
+ public void setBrightnessNitsForDefaultDisplay(float nits) {
+ mPersistentDataStore.setBrightnessNitsForDefaultDisplay(nits);
+ }
+
private void notifyListeners(float brightness) {
for (BrightnessSettingListener l : mListeners) {
l.onBrightnessChanged(brightness);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 84fe8f21b7648..055ca37d9a3f4 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -233,6 +233,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// True if should use light sensor to automatically determine doze screen brightness.
private final boolean mAllowAutoBrightnessWhileDozingConfig;
+ // True if we want to persist the brightness value in nits even if the underlying display
+ // device changes.
+ private final boolean mPersistBrightnessNitsForDefaultDisplay;
+
// True if the brightness config has changed and the short-term model needs to be reset
private boolean mShouldResetShortTermModel;
@@ -590,6 +594,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
+ mPersistBrightnessNitsForDefaultDisplay = resources.getBoolean(
+ com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay);
+
mDisplayDeviceConfig = logicalDisplay.getPrimaryDisplayDeviceLocked()
.getDisplayDeviceConfig();
@@ -658,7 +665,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
loadProximitySensor();
- mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
+ loadNitBasedBrightnessSetting();
mBrightnessToFollow = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
@@ -745,10 +752,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
mHbmController.onAmbientLuxChange(ambientLux);
- if (mAutomaticBrightnessController == null || nits < 0) {
+ if (nits < 0) {
mBrightnessToFollow = leadDisplayBrightness;
} else {
- float brightness = mAutomaticBrightnessController.convertToFloatScale(nits);
+ float brightness = convertToFloatScale(nits);
if (isValidBrightnessValue(brightness)) {
mBrightnessToFollow = brightness;
} else {
@@ -895,6 +902,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mDisplayDeviceConfig = config;
mBrightnessThrottlingDataId = brightnessThrottlingDataId;
loadFromDisplayDeviceConfig(token, info, hbmMetadata);
+ loadNitBasedBrightnessSetting();
/// Since the underlying display-device changed, we really don't know the
// last command that was sent to change it's state. Lets assume it is unknown so
@@ -2563,11 +2571,34 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return clampAbsoluteBrightness(brightness);
}
+ private void loadNitBasedBrightnessSetting() {
+ if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
+ float brightnessNitsForDefaultDisplay =
+ mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
+ if (brightnessNitsForDefaultDisplay >= 0) {
+ float brightnessForDefaultDisplay = convertToFloatScale(
+ brightnessNitsForDefaultDisplay);
+ if (isValidBrightnessValue(brightnessForDefaultDisplay)) {
+ mBrightnessSetting.setBrightness(brightnessForDefaultDisplay);
+ mCurrentScreenBrightnessSetting = brightnessForDefaultDisplay;
+ return;
+ }
+ }
+ }
+ mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
+ }
+
@Override
public void setBrightness(float brightnessValue) {
// Update the setting, which will eventually call back into DPC to have us actually update
// the display with the new value.
mBrightnessSetting.setBrightness(brightnessValue);
+ if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
+ float nits = convertToNits(brightnessValue);
+ if (nits >= 0) {
+ mBrightnessSetting.setBrightnessNitsForDefaultDisplay(nits);
+ }
+ }
}
@Override
@@ -2582,7 +2613,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return;
}
setCurrentScreenBrightness(brightnessValue);
- mBrightnessSetting.setBrightness(brightnessValue);
+ setBrightness(brightnessValue);
}
private void setCurrentScreenBrightness(float brightnessValue) {
@@ -2661,6 +2692,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return mAutomaticBrightnessController.convertToNits(brightness);
}
+ private float convertToFloatScale(float nits) {
+ if (mAutomaticBrightnessController == null) {
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+ return mAutomaticBrightnessController.convertToFloatScale(nits);
+ }
+
@GuardedBy("mLock")
private void updatePendingProximityRequestsLocked() {
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
@@ -2759,6 +2797,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
pw.println(" mAllowAutoBrightnessWhileDozingConfig="
+ mAllowAutoBrightnessWhileDozingConfig);
+ pw.println(" mPersistBrightnessNitsForDefaultDisplay="
+ + mPersistBrightnessNitsForDefaultDisplay);
pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp);
pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
pw.println(" mColorFadeEnabled=" + mColorFadeEnabled);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 297a6f8a52e5b..3c937e82a2fa5 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -861,7 +861,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
noteScreenBrightness(mPowerState.getScreenBrightness());
// Initialize all of the brightness tracking state
- final float brightness = convertToNits(mPowerState.getScreenBrightness());
+ final float brightness = mDisplayBrightnessController.convertToNits(
+ mPowerState.getScreenBrightness());
if (mBrightnessTracker != null && brightness >= PowerManager.BRIGHTNESS_MIN) {
mBrightnessTracker.start(brightness);
}
@@ -1024,6 +1025,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper,
mDisplayDeviceConfig.getAmbientHorizonShort(),
mDisplayDeviceConfig.getAmbientHorizonLong(), userLux, userBrightness);
+ mDisplayBrightnessController.setAutomaticBrightnessController(
+ mAutomaticBrightnessController);
mBrightnessEventRingBuffer =
new RingBuffer<>(BrightnessEvent.class, RINGBUFFER_MAX);
@@ -1389,7 +1392,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
: mAutomaticBrightnessController.getAmbientLux();
for (int i = 0; i < displayBrightnessFollowers.size(); i++) {
DisplayPowerControllerInterface follower = displayBrightnessFollowers.valueAt(i);
- follower.setBrightnessToFollow(rawBrightnessState, convertToNits(rawBrightnessState),
+ follower.setBrightnessToFollow(rawBrightnessState,
+ mDisplayBrightnessController.convertToNits(rawBrightnessState),
ambientLux);
}
@@ -2191,10 +2195,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
@Override
public void setBrightnessToFollow(float leadDisplayBrightness, float nits, float ambientLux) {
mHbmController.onAmbientLuxChange(ambientLux);
- if (mAutomaticBrightnessController == null || nits < 0) {
+ if (nits < 0) {
mDisplayBrightnessController.setBrightnessToFollow(leadDisplayBrightness);
} else {
- float brightness = mAutomaticBrightnessController.convertToFloatScale(nits);
+ float brightness = mDisplayBrightnessController.convertToFloatScale(nits);
if (BrightnessUtils.isValidBrightnessValue(brightness)) {
mDisplayBrightnessController.setBrightnessToFollow(brightness);
} else {
@@ -2230,7 +2234,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
boolean wasShortTermModelActive) {
- final float brightnessInNits = convertToNits(brightness);
+ final float brightnessInNits = mDisplayBrightnessController.convertToNits(brightness);
if (mUseAutoBrightness && brightnessInNits >= 0.0f
&& mAutomaticBrightnessController != null && mBrightnessTracker != null) {
// We only want to track changes on devices that can actually map the display backlight
@@ -2247,13 +2251,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
}
}
- private float convertToNits(float brightness) {
- if (mAutomaticBrightnessController == null) {
- return -1f;
- }
- return mAutomaticBrightnessController.convertToNits(brightness);
- }
-
@Override
public void addDisplayBrightnessFollower(DisplayPowerControllerInterface follower) {
synchronized (mLock) {
@@ -2513,17 +2510,17 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
int appliedRbcStrength = event.isRbcEnabled() ? event.getRbcStrength() : -1;
float appliedHbmMaxNits =
event.getHbmMode() == BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF
- ? -1f : convertToNits(event.getHbmMax());
+ ? -1f : mDisplayBrightnessController.convertToNits(event.getHbmMax());
// thermalCapNits set to -1 if not currently capping max brightness
float appliedThermalCapNits =
event.getThermalMax() == PowerManager.BRIGHTNESS_MAX
- ? -1f : convertToNits(event.getThermalMax());
+ ? -1f : mDisplayBrightnessController.convertToNits(event.getThermalMax());
if (mLogicalDisplay.getPrimaryDisplayDeviceLocked() != null
&& mLogicalDisplay.getPrimaryDisplayDeviceLocked()
.getDisplayDeviceInfoLocked().type == Display.TYPE_INTERNAL) {
FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_BRIGHTNESS_CHANGED,
- convertToNits(event.getInitialBrightness()),
- convertToNits(event.getBrightness()),
+ mDisplayBrightnessController.convertToNits(event.getInitialBrightness()),
+ mDisplayBrightnessController.convertToNits(event.getBrightness()),
event.getLux(),
event.getPhysicalDisplayId(),
event.wasShortTermModelActive(),
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index e7601bcd8f3ad..ec70c8966736c 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -94,6 +94,7 @@ import java.util.Objects;
* </brightness-curve>
* </brightness-configuration>
* </brightness-configurations>
+ * <brightness-nits-for-default-display>600</brightness-nits-for-default-display>
* </display-manager-state>
*
*
@@ -130,6 +131,9 @@ final class PersistentDataStore {
private static final String TAG_RESOLUTION_HEIGHT = "resolution-height";
private static final String TAG_REFRESH_RATE = "refresh-rate";
+ private static final String TAG_BRIGHTNESS_NITS_FOR_DEFAULT_DISPLAY =
+ "brightness-nits-for-default-display";
+
// Remembered Wifi display devices.
private ArrayList mRememberedWifiDisplays = new ArrayList();
@@ -137,6 +141,8 @@ final class PersistentDataStore {
private final HashMap mDisplayStates =
new HashMap();
+ private float mBrightnessNitsForDefaultDisplay = -1;
+
// Display values which should be stable across the device's lifetime.
private final StableDeviceValues mStableDeviceValues = new StableDeviceValues();
@@ -312,6 +318,19 @@ final class PersistentDataStore {
return false;
}
+ public float getBrightnessNitsForDefaultDisplay() {
+ return mBrightnessNitsForDefaultDisplay;
+ }
+
+ public boolean setBrightnessNitsForDefaultDisplay(float nits) {
+ if (nits != mBrightnessNitsForDefaultDisplay) {
+ mBrightnessNitsForDefaultDisplay = nits;
+ setDirty();
+ return true;
+ }
+ return false;
+ }
+
public boolean setUserPreferredRefreshRate(DisplayDevice displayDevice, float refreshRate) {
final String displayDeviceUniqueId = displayDevice.getUniqueId();
if (!displayDevice.hasStableUniqueId() || displayDeviceUniqueId == null) {
@@ -513,6 +532,10 @@ final class PersistentDataStore {
if (parser.getName().equals(TAG_BRIGHTNESS_CONFIGURATIONS)) {
mGlobalBrightnessConfigurations.loadFromXml(parser);
}
+ if (parser.getName().equals(TAG_BRIGHTNESS_NITS_FOR_DEFAULT_DISPLAY)) {
+ String value = parser.nextText();
+ mBrightnessNitsForDefaultDisplay = Float.parseFloat(value);
+ }
}
}
@@ -592,6 +615,9 @@ final class PersistentDataStore {
serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
mGlobalBrightnessConfigurations.saveToXml(serializer);
serializer.endTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
+ serializer.startTag(null, TAG_BRIGHTNESS_NITS_FOR_DEFAULT_DISPLAY);
+ serializer.text(Float.toString(mBrightnessNitsForDefaultDisplay));
+ serializer.endTag(null, TAG_BRIGHTNESS_NITS_FOR_DEFAULT_DISPLAY);
serializer.endTag(null, TAG_DISPLAY_MANAGER_STATE);
serializer.endDocument();
}
@@ -615,6 +641,7 @@ final class PersistentDataStore {
mStableDeviceValues.dump(pw, " ");
pw.println(" GlobalBrightnessConfigurations:");
mGlobalBrightnessConfigurations.dump(pw, " ");
+ pw.println(" mBrightnessNitsForDefaultDisplay=" + mBrightnessNitsForDefaultDisplay);
}
private static final class DisplayState {
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
index 68758caa808ab..2916fefefe1b1 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -16,14 +16,17 @@
package com.android.server.display.brightness;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.display.DisplayManagerInternal;
import android.os.HandlerExecutor;
import android.os.PowerManager;
import android.util.IndentingPrintWriter;
+import android.view.Display;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.AutomaticBrightnessController;
import com.android.server.display.BrightnessSetting;
import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy;
@@ -84,6 +87,15 @@ public final class DisplayBrightnessController {
// callback is not executed in sync and is not blocking the thread from which it is called.
private final HandlerExecutor mBrightnessChangeExecutor;
+ // True if we want to persist the brightness value in nits even if the underlying display
+ // device changes.
+ private final boolean mPersistBrightnessNitsForDefaultDisplay;
+
+ // The controller for the automatic brightness level.
+ // TODO(b/265415257): Move to the automatic brightness strategy
+ @Nullable
+ private AutomaticBrightnessController mAutomaticBrightnessController;
+
/**
* The constructor of DisplayBrightnessController.
*/
@@ -103,6 +115,8 @@ public final class DisplayBrightnessController {
mDisplayBrightnessStrategySelector = injector.getDisplayBrightnessStrategySelector(context,
displayId);
mBrightnessChangeExecutor = brightnessChangeExecutor;
+ mPersistBrightnessNitsForDefaultDisplay = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay);
}
/**
@@ -263,6 +277,12 @@ public final class DisplayBrightnessController {
// Update the setting, which will eventually call back into DPC to have us actually
// update the display with the new value.
mBrightnessSetting.setBrightness(brightnessValue);
+ if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
+ float nits = convertToNits(brightnessValue);
+ if (nits >= 0) {
+ mBrightnessSetting.setBrightnessNitsForDefaultDisplay(nits);
+ }
+ }
}
/**
@@ -280,6 +300,42 @@ public final class DisplayBrightnessController {
setBrightness(brightnessValue);
}
+ /**
+ * Set the {@link AutomaticBrightnessController} which is needed to perform nit-to-float-scale
+ * conversion.
+ * @param automaticBrightnessController The ABC
+ */
+ public void setAutomaticBrightnessController(
+ AutomaticBrightnessController automaticBrightnessController) {
+ mAutomaticBrightnessController = automaticBrightnessController;
+ loadNitBasedBrightnessSetting();
+ }
+
+ /**
+ * Convert a brightness float scale value to a nit value.
+ * @param brightness The float scale value
+ * @return The nit value or -1f if no conversion is possible.
+ */
+ public float convertToNits(float brightness) {
+ if (mAutomaticBrightnessController == null) {
+ return -1f;
+ }
+ return mAutomaticBrightnessController.convertToNits(brightness);
+ }
+
+ /**
+ * Convert a brightness nit value to a float scale value.
+ * @param nits The nit value
+ * @return The float scale value or {@link PowerManager.BRIGHTNESS_INVALID_FLOAT} if no
+ * conversion is possible.
+ */
+ public float convertToFloatScale(float nits) {
+ if (mAutomaticBrightnessController == null) {
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+ return mAutomaticBrightnessController.convertToFloatScale(nits);
+ }
+
/**
* Stops the associated listeners when the display is stopped. Invoked when the {@link
* #mDisplayId} is being removed.
@@ -300,6 +356,8 @@ public final class DisplayBrightnessController {
writer.println("DisplayBrightnessController:");
writer.println(" mDisplayId=: " + mDisplayId);
writer.println(" mScreenBrightnessDefault=" + mScreenBrightnessDefault);
+ writer.println(" mPersistBrightnessNitsForDefaultDisplay="
+ + mPersistBrightnessNitsForDefaultDisplay);
synchronized (mLock) {
writer.println(" mPendingScreenBrightness=" + mPendingScreenBrightness);
writer.println(" mCurrentScreenBrightness=" + mCurrentScreenBrightness);
@@ -353,4 +411,29 @@ public final class DisplayBrightnessController {
private void notifyCurrentScreenBrightness() {
mBrightnessChangeExecutor.execute(mOnBrightnessChangeRunnable);
}
+
+ /**
+ * Loads the brightness value. If this is the default display and the config says that we should
+ * persist the nit value, the nit value for the default display will be loaded.
+ */
+ private void loadNitBasedBrightnessSetting() {
+ if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
+ float brightnessNitsForDefaultDisplay =
+ mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
+ if (brightnessNitsForDefaultDisplay >= 0) {
+ float brightnessForDefaultDisplay = convertToFloatScale(
+ brightnessNitsForDefaultDisplay);
+ if (BrightnessUtils.isValidBrightnessValue(brightnessForDefaultDisplay)) {
+ mBrightnessSetting.setBrightness(brightnessForDefaultDisplay);
+ synchronized (mLock) {
+ mCurrentScreenBrightness = brightnessForDefaultDisplay;
+ }
+ return;
+ }
+ }
+ }
+ synchronized (mLock) {
+ mCurrentScreenBrightness = getScreenBrightnessSetting();
+ }
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index 7942e246c2a73..19aae194e73a7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -643,6 +643,34 @@ public final class DisplayPowerController2Test {
verify(mHolder.screenOffBrightnessSensorController).stop();
}
+ @Test
+ public void testBrightnessNitsPersistWhenDisplayDeviceChanges() {
+ float brightness = 0.3f;
+ float nits = 500;
+ when(mResourcesMock.getBoolean(
+ com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay))
+ .thenReturn(true);
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+ when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+
+ mHolder.dpc.setBrightness(brightness);
+ verify(mHolder.brightnessSetting).setBrightnessNitsForDefaultDisplay(nits);
+
+ float newBrightness = 0.4f;
+ when(mHolder.brightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
+ when(mHolder.automaticBrightnessController.convertToFloatScale(nits))
+ .thenReturn(newBrightness);
+ // New display device
+ setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+ mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+ // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged
+ verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 16bf2a227c8a1..02b6ea0d1116d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -488,17 +488,17 @@ public final class DisplayPowerControllerTest {
// We should still set screen state for the default display
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1);
+ advanceTime(1); // Run updatePowerState
verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt());
mHolder = createDisplayPowerController(42, UNIQUE_ID);
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
- advanceTime(1);
+ advanceTime(1); // Run updatePowerState
verify(mHolder.displayPowerState, never()).setScreenState(anyInt());
mHolder.dpc.onBootCompleted();
- advanceTime(1);
+ advanceTime(1); // Run updatePowerState
verify(mHolder.displayPowerState).setScreenState(anyInt());
}
@@ -647,6 +647,34 @@ public final class DisplayPowerControllerTest {
verify(mHolder.screenOffBrightnessSensorController).stop();
}
+ @Test
+ public void testBrightnessNitsPersistWhenDisplayDeviceChanges() {
+ float brightness = 0.3f;
+ float nits = 500;
+ when(mResourcesMock.getBoolean(
+ com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay))
+ .thenReturn(true);
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+ when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+
+ mHolder.dpc.setBrightness(brightness);
+ verify(mHolder.brightnessSetting).setBrightnessNitsForDefaultDisplay(nits);
+
+ float newBrightness = 0.4f;
+ when(mHolder.brightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
+ when(mHolder.automaticBrightnessController.convertToFloatScale(nits))
+ .thenReturn(newBrightness);
+ // New display device
+ setUpDisplay(DISPLAY_ID, "new_unique_id", mHolder.display, mock(DisplayDevice.class),
+ mock(DisplayDeviceConfig.class), /* isEnabled= */ true);
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, Layout.NO_LEAD_DISPLAY);
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+ // One triggered by handleBrightnessModeChange, another triggered by onDisplayChanged
+ verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
diff --git a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
index 35a677e0f816d..817b245a78bf1 100644
--- a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
@@ -377,6 +377,33 @@ public class PersistentDataStoreTest {
assertTrue(Float.isNaN(mDataStore.getBrightness(testDisplayDevice)));
}
+ @Test
+ public void testStoreAndRestoreBrightnessNitsForDefaultDisplay() {
+ float brightnessNitsForDefaultDisplay = 190;
+ mDataStore.loadIfNeeded();
+ mDataStore.setBrightnessNitsForDefaultDisplay(brightnessNitsForDefaultDisplay);
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ mInjector.setWriteStream(baos);
+ mDataStore.saveIfNeeded();
+ mTestLooper.dispatchAll();
+ assertTrue(mInjector.wasWriteSuccessful());
+ TestInjector newInjector = new TestInjector();
+ PersistentDataStore newDataStore = new PersistentDataStore(newInjector);
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ newInjector.setReadStream(bais);
+ newDataStore.loadIfNeeded();
+ assertEquals(brightnessNitsForDefaultDisplay,
+ mDataStore.getBrightnessNitsForDefaultDisplay(), 0);
+ assertEquals(brightnessNitsForDefaultDisplay,
+ newDataStore.getBrightnessNitsForDefaultDisplay(), 0);
+ }
+
+ @Test
+ public void testInitialBrightnessNitsForDefaultDisplay() {
+ mDataStore.loadIfNeeded();
+ assertEquals(-1, mDataStore.getBrightnessNitsForDefaultDisplay(), 0);
+ }
public class TestInjector extends PersistentDataStore.Injector {
private InputStream mReadStream;
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
index ae05e32ae9167..cfb432ab37849 100644
--- a/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.res.Resources;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.HandlerExecutor;
import android.os.PowerManager;
@@ -34,6 +35,7 @@ import android.view.Display;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.display.AutomaticBrightnessController;
import com.android.server.display.BrightnessSetting;
import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy;
import com.android.server.display.brightness.strategy.TemporaryBrightnessStrategy;
@@ -47,7 +49,7 @@ import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidJUnit4.class)
public final class DisplayBrightnessControllerTest {
- private static final int DISPLAY_ID = 1;
+ private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY;
private static final float DEFAULT_BRIGHTNESS = 0.15f;
@Mock
@@ -55,6 +57,8 @@ public final class DisplayBrightnessControllerTest {
@Mock
private Context mContext;
@Mock
+ private Resources mResources;
+ @Mock
private BrightnessSetting mBrightnessSetting;
@Mock
private Runnable mOnBrightnessChangeRunnable;
@@ -67,6 +71,7 @@ public final class DisplayBrightnessControllerTest {
@Before
public void before() {
MockitoAnnotations.initMocks(this);
+ when(mContext.getResources()).thenReturn(mResources);
DisplayBrightnessController.Injector injector = new DisplayBrightnessController.Injector() {
@Override
DisplayBrightnessStrategySelector getDisplayBrightnessStrategySelector(
@@ -75,6 +80,10 @@ public final class DisplayBrightnessControllerTest {
}
};
when(mBrightnessSetting.getBrightness()).thenReturn(Float.NaN);
+ when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(-1f);
+ when(mResources.getBoolean(
+ com.android.internal.R.bool.config_persistBrightnessNitsForDefaultDisplay))
+ .thenReturn(true);
mDisplayBrightnessController = new DisplayBrightnessController(mContext, injector,
DISPLAY_ID, DEFAULT_BRIGHTNESS, mBrightnessSetting, mOnBrightnessChangeRunnable,
mBrightnessChangeExecutor);
@@ -82,8 +91,8 @@ public final class DisplayBrightnessControllerTest {
@Test
public void testIfFirstScreenBrightnessIsDefault() {
- assertEquals(mDisplayBrightnessController.getCurrentBrightness(), DEFAULT_BRIGHTNESS,
- 0.0f);
+ assertEquals(DEFAULT_BRIGHTNESS, mDisplayBrightnessController.getCurrentBrightness(),
+ /* delta= */ 0.0f);
}
@Test
@@ -123,7 +132,7 @@ public final class DisplayBrightnessControllerTest {
float currentScreenBrightness = 0.4f;
mDisplayBrightnessController.setAndNotifyCurrentScreenBrightness(currentScreenBrightness);
assertEquals(mDisplayBrightnessController.getCurrentBrightness(),
- currentScreenBrightness, 0.0f);
+ currentScreenBrightness, /* delta= */ 0.0f);
verify(mBrightnessChangeExecutor).execute(mOnBrightnessChangeRunnable);
// No change to the current screen brightness is same as the existing one
@@ -136,7 +145,7 @@ public final class DisplayBrightnessControllerTest {
float pendingScreenBrightness = 0.4f;
mDisplayBrightnessController.setPendingScreenBrightness(pendingScreenBrightness);
assertEquals(mDisplayBrightnessController.getPendingScreenBrightness(),
- pendingScreenBrightness, 0.0f);
+ pendingScreenBrightness, /* delta= */ 0.0f);
}
@Test
@@ -158,7 +167,7 @@ public final class DisplayBrightnessControllerTest {
verify(temporaryBrightnessStrategy).setTemporaryScreenBrightness(
PowerManager.BRIGHTNESS_INVALID_FLOAT);
assertEquals(mDisplayBrightnessController.getPendingScreenBrightness(),
- PowerManager.BRIGHTNESS_INVALID_FLOAT, 0.0f);
+ PowerManager.BRIGHTNESS_INVALID_FLOAT, /* delta= */ 0.0f);
// user set brightness is set as expected
currentBrightness = 0.4f;
@@ -169,15 +178,15 @@ public final class DisplayBrightnessControllerTest {
mDisplayBrightnessController.setTemporaryBrightness(temporaryScreenBrightness);
assertTrue(mDisplayBrightnessController.updateUserSetScreenBrightness());
assertEquals(mDisplayBrightnessController.getCurrentBrightness(),
- pendingScreenBrightness, 0.0f);
+ pendingScreenBrightness, /* delta= */ 0.0f);
assertEquals(mDisplayBrightnessController.getLastUserSetScreenBrightness(),
- pendingScreenBrightness, 0.0f);
+ pendingScreenBrightness, /* delta= */ 0.0f);
verify(mBrightnessChangeExecutor, times(2))
.execute(mOnBrightnessChangeRunnable);
verify(temporaryBrightnessStrategy, times(2))
.setTemporaryScreenBrightness(PowerManager.BRIGHTNESS_INVALID_FLOAT);
assertEquals(mDisplayBrightnessController.getPendingScreenBrightness(),
- PowerManager.BRIGHTNESS_INVALID_FLOAT, 0.0f);
+ PowerManager.BRIGHTNESS_INVALID_FLOAT, /* delta= */ 0.0f);
}
@Test
@@ -198,20 +207,20 @@ public final class DisplayBrightnessControllerTest {
float brightnessSetting = 0.2f;
when(mBrightnessSetting.getBrightness()).thenReturn(brightnessSetting);
assertEquals(mDisplayBrightnessController.getScreenBrightnessSetting(), brightnessSetting,
- 0.0f);
+ /* delta= */ 0.0f);
// getScreenBrightnessSetting value is clamped if BrightnessSetting returns value beyond max
brightnessSetting = 1.1f;
when(mBrightnessSetting.getBrightness()).thenReturn(brightnessSetting);
assertEquals(mDisplayBrightnessController.getScreenBrightnessSetting(), 1.0f,
- 0.0f);
+ /* delta= */ 0.0f);
// getScreenBrightnessSetting returns default value is BrightnessSetting returns invalid
// value.
brightnessSetting = Float.NaN;
when(mBrightnessSetting.getBrightness()).thenReturn(brightnessSetting);
assertEquals(mDisplayBrightnessController.getScreenBrightnessSetting(), DEFAULT_BRIGHTNESS,
- 0.0f);
+ /* delta= */ 0.0f);
}
@Test
@@ -247,6 +256,64 @@ public final class DisplayBrightnessControllerTest {
verifyNoMoreInteractions(mBrightnessChangeExecutor, mBrightnessSetting);
}
+ @Test
+ public void testBrightnessNitsForDefaultDisplay() {
+ float brightness = 0.3f;
+ float nits = 500;
+ AutomaticBrightnessController automaticBrightnessController =
+ mock(AutomaticBrightnessController.class);
+ when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness);
+ when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
+
+ mDisplayBrightnessController.setAutomaticBrightnessController(
+ automaticBrightnessController);
+ assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(),
+ /* delta= */ 0);
+
+ float newBrightness = 0.5f;
+ float newNits = 700;
+ when(automaticBrightnessController.convertToNits(newBrightness)).thenReturn(newNits);
+ mDisplayBrightnessController.setBrightness(newBrightness);
+ verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(newNits);
+ }
+
+ @Test
+ public void testConvertToNits() {
+ float brightness = 0.5f;
+ float nits = 300;
+
+ // ABC is null
+ assertEquals(-1f, mDisplayBrightnessController.convertToNits(brightness),
+ /* delta= */ 0);
+
+ AutomaticBrightnessController automaticBrightnessController =
+ mock(AutomaticBrightnessController.class);
+ when(automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+ mDisplayBrightnessController.setAutomaticBrightnessController(
+ automaticBrightnessController);
+
+ assertEquals(nits, mDisplayBrightnessController.convertToNits(brightness), /* delta= */ 0);
+ }
+
+ @Test
+ public void testConvertToFloatScale() {
+ float brightness = 0.5f;
+ float nits = 300;
+
+ // ABC is null
+ assertEquals(PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ mDisplayBrightnessController.convertToFloatScale(nits), /* delta= */ 0);
+
+ AutomaticBrightnessController automaticBrightnessController =
+ mock(AutomaticBrightnessController.class);
+ when(automaticBrightnessController.convertToFloatScale(nits)).thenReturn(brightness);
+ mDisplayBrightnessController.setAutomaticBrightnessController(
+ automaticBrightnessController);
+
+ assertEquals(brightness, mDisplayBrightnessController.convertToFloatScale(nits),
+ /* delta= */ 0);
+ }
+
@Test
public void stop() {
BrightnessSetting.BrightnessSettingListener brightnessSettingListener = mock(