diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index dafa0ad7989f7..993fcf8770553 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6092,4 +6092,8 @@
false
+
+
+ false
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 591ba5feeee91..c04c322e2d87d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2282,6 +2282,7 @@
+
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 8b579ac6539da..2292d9b60713c 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -1127,6 +1127,14 @@ class AutomaticBrightnessController {
}
}
+ public float convertToFloatScale(float nits) {
+ if (mCurrentBrightnessMapper != null) {
+ return mCurrentBrightnessMapper.convertToFloatScale(nits);
+ } else {
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+ }
+
public void recalculateSplines(boolean applyAdjustment, float[] adjustment) {
mCurrentBrightnessMapper.recalculateSplines(applyAdjustment, adjustment);
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 3fc50c4edf6d6..d0471837d79b3 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -321,6 +321,14 @@ public abstract class BrightnessMappingStrategy {
*/
public abstract float convertToNits(float brightness);
+ /**
+ * Converts the provided nit value to a float scale value if possible.
+ *
+ * Returns {@link PowerManager.BRIGHTNESS_INVALID_FLOAT} if there's no available mapping for
+ * the nits to float scale.
+ */
+ public abstract float convertToFloatScale(float nits);
+
/**
* Adds a user interaction data point to the brightness mapping.
*
@@ -670,6 +678,11 @@ public abstract class BrightnessMappingStrategy {
return -1.0f;
}
+ @Override
+ public float convertToFloatScale(float nits) {
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+
@Override
public void addUserDataPoint(float lux, float brightness) {
float unadjustedBrightness = getUnadjustedBrightness(lux);
@@ -912,6 +925,11 @@ public abstract class BrightnessMappingStrategy {
return mBrightnessToNitsSpline.interpolate(brightness);
}
+ @Override
+ public float convertToFloatScale(float nits) {
+ return mNitsToBrightnessSpline.interpolate(nits);
+ }
+
@Override
public void addUserDataPoint(float lux, float brightness) {
float unadjustedBrightness = getUnadjustedBrightness(lux);
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java
index 74486113dcf9b..9982d2eb31d1c 100644
--- a/services/core/java/com/android/server/display/BrightnessSetting.java
+++ b/services/core/java/com/android/server/display/BrightnessSetting.java
@@ -117,6 +117,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.
+ */
+ 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
+ */
+ 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 5ecc7f2b7bb8d..0b4bc875fee18 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;
@@ -583,6 +587,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();
@@ -651,7 +658,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
loadProximitySensor();
- mCurrentScreenBrightnessSetting = getScreenBrightnessSetting();
+ loadNitBasedBrightnessSetting();
mScreenBrightnessForVr = getScreenBrightnessForVrSetting();
mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
mTemporaryScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
@@ -829,6 +836,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mDisplayStatsId = mUniqueDisplayId.hashCode();
mDisplayDeviceConfig = config;
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
@@ -2497,10 +2505,33 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return clampScreenBrightnessForVr(brightnessFloat);
}
+ 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();
+ }
+
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);
+ }
+ }
}
void onBootCompleted() {
@@ -2513,7 +2544,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
return;
}
setCurrentScreenBrightness(brightnessValue);
- mBrightnessSetting.setBrightness(brightnessValue);
+ setBrightness(brightnessValue);
}
private void setCurrentScreenBrightness(float brightnessValue) {
@@ -2592,6 +2623,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;
@@ -2689,25 +2727,27 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
pw.println(" mScreenBrightnessForVrRangeMaximum=" + mScreenBrightnessForVrRangeMaximum);
pw.println(" mScreenBrightnessForVrDefault=" + mScreenBrightnessForVrDefault);
pw.println(" mUseSoftwareAutoBrightnessConfig=" + mUseSoftwareAutoBrightnessConfig);
- pw.println(" mAllowAutoBrightnessWhileDozingConfig=" +
- mAllowAutoBrightnessWhileDozingConfig);
+ pw.println(" mAllowAutoBrightnessWhileDozingConfig="
+ + mAllowAutoBrightnessWhileDozingConfig);
+ pw.println(" mPersistBrightnessNitsForDefaultDisplay="
+ + mPersistBrightnessNitsForDefaultDisplay);
pw.println(" mSkipScreenOnBrightnessRamp=" + mSkipScreenOnBrightnessRamp);
pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
pw.println(" mColorFadeEnabled=" + mColorFadeEnabled);
synchronized (mCachedBrightnessInfo) {
- pw.println(" mCachedBrightnessInfo.brightness=" +
- mCachedBrightnessInfo.brightness.value);
- pw.println(" mCachedBrightnessInfo.adjustedBrightness=" +
- mCachedBrightnessInfo.adjustedBrightness.value);
- pw.println(" mCachedBrightnessInfo.brightnessMin=" +
- mCachedBrightnessInfo.brightnessMin.value);
- pw.println(" mCachedBrightnessInfo.brightnessMax=" +
- mCachedBrightnessInfo.brightnessMax.value);
+ pw.println(" mCachedBrightnessInfo.brightness="
+ + mCachedBrightnessInfo.brightness.value);
+ pw.println(" mCachedBrightnessInfo.adjustedBrightness="
+ + mCachedBrightnessInfo.adjustedBrightness.value);
+ pw.println(" mCachedBrightnessInfo.brightnessMin="
+ + mCachedBrightnessInfo.brightnessMin.value);
+ pw.println(" mCachedBrightnessInfo.brightnessMax="
+ + mCachedBrightnessInfo.brightnessMax.value);
pw.println(" mCachedBrightnessInfo.hbmMode=" + mCachedBrightnessInfo.hbmMode.value);
- pw.println(" mCachedBrightnessInfo.hbmTransitionPoint=" +
- mCachedBrightnessInfo.hbmTransitionPoint.value);
- pw.println(" mCachedBrightnessInfo.brightnessMaxReason =" +
- mCachedBrightnessInfo.brightnessMaxReason.value);
+ pw.println(" mCachedBrightnessInfo.hbmTransitionPoint="
+ + mCachedBrightnessInfo.hbmTransitionPoint.value);
+ pw.println(" mCachedBrightnessInfo.brightnessMaxReason ="
+ + mCachedBrightnessInfo.brightnessMaxReason.value);
}
pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index 73131a1dc220e..a8e0d58cc4ff4 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/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;