Merge "Make brightness per-user in PersistentDataStore" into udc-qpr-dev
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java
index de42370..651828b 100644
--- a/services/core/java/com/android/server/display/BrightnessSetting.java
+++ b/services/core/java/com/android/server/display/BrightnessSetting.java
@@ -40,6 +40,7 @@
private final LogicalDisplay mLogicalDisplay;
+ private int mUserSerial;
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
@@ -56,13 +57,15 @@
@GuardedBy("mSyncRoot")
private float mBrightness;
- BrightnessSetting(@NonNull PersistentDataStore persistentDataStore,
+ BrightnessSetting(int userSerial,
+ @NonNull PersistentDataStore persistentDataStore,
@NonNull LogicalDisplay logicalDisplay,
DisplayManagerService.SyncRoot syncRoot) {
mPersistentDataStore = persistentDataStore;
mLogicalDisplay = logicalDisplay;
+ mUserSerial = userSerial;
mBrightness = mPersistentDataStore.getBrightness(
- mLogicalDisplay.getPrimaryDisplayDeviceLocked());
+ mLogicalDisplay.getPrimaryDisplayDeviceLocked(), userSerial);
mSyncRoot = syncRoot;
}
@@ -96,8 +99,13 @@
mListeners.remove(l);
}
+ /** Sets the user serial for the brightness setting */
+ public void setUserSerial(int userSerial) {
+ mUserSerial = userSerial;
+ }
+
/**
- * Sets the brigtness and broadcasts the change to the listeners.
+ * Sets the brightness and broadcasts the change to the listeners.
* @param brightness The value to which the brightness is to be set.
*/
public void setBrightness(float brightness) {
@@ -112,7 +120,8 @@
// changed.
if (brightness != mBrightness) {
mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(),
- brightness);
+ brightness, mUserSerial
+ );
}
mBrightness = brightness;
int toSend = Float.floatToIntBits(mBrightness);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 3844529..be65c53 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -652,6 +652,12 @@
logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(),
userSerial);
dpc.setBrightnessConfiguration(config, /* shouldResetShortTermModel= */ true);
+ // change the brightness value according to the selected user.
+ final DisplayDevice device = logicalDisplay.getPrimaryDisplayDeviceLocked();
+ if (device != null) {
+ dpc.setBrightness(
+ mPersistentDataStore.getBrightness(device, userSerial), userSerial);
+ }
}
dpc.onSwitchUser(newUserId);
});
@@ -3134,8 +3140,9 @@
mBrightnessTracker = new BrightnessTracker(mContext, null);
}
- final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore,
- display, mSyncRoot);
+ final int userSerial = getUserManager().getUserSerialNumber(mContext.getUserId());
+ final BrightnessSetting brightnessSetting = new BrightnessSetting(userSerial,
+ mPersistentDataStore, display, mSyncRoot);
final DisplayPowerControllerInterface displayPowerController;
// If display is internal and has a HighBrightnessModeMetadata mapping, use that.
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 2b5523a..7d8bde9 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -2664,9 +2664,10 @@
}
@Override
- public void setBrightness(float brightnessValue) {
+ public void setBrightness(float brightnessValue, int userSerial) {
// Update the setting, which will eventually call back into DPC to have us actually update
// the display with the new value.
+ mBrightnessSetting.setUserSerial(userSerial);
mBrightnessSetting.setBrightness(brightnessValue);
if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
float nits = convertToNits(brightnessValue);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index cc9f539..040cecc 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -2172,8 +2172,8 @@
}
@Override
- public void setBrightness(float brightnessValue) {
- mDisplayBrightnessController.setBrightness(brightnessValue);
+ public void setBrightness(float brightnessValue, int userSerial) {
+ mDisplayBrightnessController.setBrightness(brightnessValue, userSerial);
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
index 73edb97..5fbbcbd 100644
--- a/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
+++ b/services/core/java/com/android/server/display/DisplayPowerControllerInterface.java
@@ -29,7 +29,7 @@
* An interface to manage the display's power state and brightness
*/
public interface DisplayPowerControllerInterface {
-
+ int DEFAULT_USER_SERIAL = -1;
/**
* Notified when the display is changed.
*
@@ -98,7 +98,17 @@
* Set the screen brightness of the associated display
* @param brightness The value to which the brightness is to be set
*/
- void setBrightness(float brightness);
+ default void setBrightness(float brightness) {
+ setBrightness(brightness, DEFAULT_USER_SERIAL);
+ }
+
+ /**
+ * Set the screen brightness of the associated display
+ * @param brightness The value to which the brightness is to be set
+ * @param userSerial The user for which the brightness value is to be set. Use userSerial = -1,
+ * if brightness needs to be updated for the current user.
+ */
+ void setBrightness(float brightness, int userSerial);
/**
* Checks if the proximity sensor is available
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index 6d6ed72..2d7792d 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -133,6 +133,7 @@
private static final String TAG_BRIGHTNESS_NITS_FOR_DEFAULT_DISPLAY =
"brightness-nits-for-default-display";
+ public static final int DEFAULT_USER_ID = -1;
// Remembered Wifi display devices.
private ArrayList<WifiDisplay> mRememberedWifiDisplays = new ArrayList<WifiDisplay>();
@@ -294,7 +295,7 @@
return false;
}
- public float getBrightness(DisplayDevice device) {
+ public float getBrightness(DisplayDevice device, int userSerial) {
if (device == null || !device.hasStableUniqueId()) {
return Float.NaN;
}
@@ -302,10 +303,10 @@
if (state == null) {
return Float.NaN;
}
- return state.getBrightness();
+ return state.getBrightness(userSerial);
}
- public boolean setBrightness(DisplayDevice displayDevice, float brightness) {
+ public boolean setBrightness(DisplayDevice displayDevice, float brightness, int userSerial) {
if (displayDevice == null || !displayDevice.hasStableUniqueId()) {
return false;
}
@@ -314,7 +315,7 @@
return false;
}
final DisplayState state = getDisplayState(displayDeviceUniqueId, true);
- if (state.setBrightness(brightness)) {
+ if (state.setBrightness(brightness, userSerial)) {
setDirty();
return true;
}
@@ -611,6 +612,7 @@
state.saveToXml(serializer);
serializer.endTag(null, TAG_DISPLAY);
}
+
serializer.endTag(null, TAG_DISPLAY_STATES);
serializer.startTag(null, TAG_STABLE_DEVICE_VALUES);
mStableDeviceValues.saveToXml(serializer);
@@ -649,7 +651,8 @@
private static final class DisplayState {
private int mColorMode;
- private float mBrightness = Float.NaN;
+
+ private SparseArray<Float> mPerUserBrightness = new SparseArray<>();
private int mWidth;
private int mHeight;
private float mRefreshRate;
@@ -670,16 +673,25 @@
return mColorMode;
}
- public boolean setBrightness(float brightness) {
- if (brightness == mBrightness) {
+ public boolean setBrightness(float brightness, int userSerial) {
+ // Remove the default user brightness, before setting a new user-specific value.
+ // This is a one-time operation, required to restructure the config after user-specific
+ // brightness was introduced.
+ mPerUserBrightness.remove(DEFAULT_USER_ID);
+
+ if (getBrightness(userSerial) == brightness) {
return false;
}
- mBrightness = brightness;
+ mPerUserBrightness.set(userSerial, brightness);
return true;
}
- public float getBrightness() {
- return mBrightness;
+ public float getBrightness(int userSerial) {
+ float brightness = mPerUserBrightness.get(userSerial, Float.NaN);
+ if (Float.isNaN(brightness)) {
+ brightness = mPerUserBrightness.get(DEFAULT_USER_ID, Float.NaN);
+ }
+ return brightness;
}
public boolean setBrightnessConfiguration(BrightnessConfiguration configuration,
@@ -729,12 +741,7 @@
mColorMode = Integer.parseInt(value);
break;
case TAG_BRIGHTNESS_VALUE:
- String brightness = parser.nextText();
- try {
- mBrightness = Float.parseFloat(brightness);
- } catch (NumberFormatException e) {
- mBrightness = Float.NaN;
- }
+ loadBrightnessFromXml(parser);
break;
case TAG_BRIGHTNESS_CONFIGURATIONS:
mDisplayBrightnessConfigurations.loadFromXml(parser);
@@ -760,11 +767,12 @@
serializer.text(Integer.toString(mColorMode));
serializer.endTag(null, TAG_COLOR_MODE);
- serializer.startTag(null, TAG_BRIGHTNESS_VALUE);
- if (!Float.isNaN(mBrightness)) {
- serializer.text(Float.toString(mBrightness));
+ for (int i = 0; i < mPerUserBrightness.size(); i++) {
+ serializer.startTag(null, TAG_BRIGHTNESS_VALUE);
+ serializer.attributeInt(null, ATTR_USER_SERIAL, mPerUserBrightness.keyAt(i));
+ serializer.text(Float.toString(mPerUserBrightness.valueAt(i)));
+ serializer.endTag(null, TAG_BRIGHTNESS_VALUE);
}
- serializer.endTag(null, TAG_BRIGHTNESS_VALUE);
serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS);
mDisplayBrightnessConfigurations.saveToXml(serializer);
@@ -785,12 +793,33 @@
public void dump(final PrintWriter pw, final String prefix) {
pw.println(prefix + "ColorMode=" + mColorMode);
- pw.println(prefix + "BrightnessValue=" + mBrightness);
+ pw.println(prefix + "BrightnessValues: ");
+ for (int i = 0; i < mPerUserBrightness.size(); i++) {
+ pw.println("User: " + mPerUserBrightness.keyAt(i)
+ + " Value: " + mPerUserBrightness.valueAt(i));
+ }
pw.println(prefix + "DisplayBrightnessConfigurations: ");
mDisplayBrightnessConfigurations.dump(pw, prefix);
pw.println(prefix + "Resolution=" + mWidth + " " + mHeight);
pw.println(prefix + "RefreshRate=" + mRefreshRate);
}
+
+ private void loadBrightnessFromXml(TypedXmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ int userSerial;
+ try {
+ userSerial = parser.getAttributeInt(null, ATTR_USER_SERIAL);
+ } catch (NumberFormatException | XmlPullParserException e) {
+ userSerial = DEFAULT_USER_ID;
+ Slog.e(TAG, "Failed to read user serial", e);
+ }
+ String brightness = parser.nextText();
+ try {
+ mPerUserBrightness.set(userSerial, Float.parseFloat(brightness));
+ } catch (NumberFormatException nfe) {
+ Slog.e(TAG, "Failed to read brightness", nfe);
+ }
+ }
}
private static final class StableDeviceValues {
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 7574de8..2f52b70 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -38,6 +38,8 @@
* display. Applies the chosen brightness.
*/
public final class DisplayBrightnessController {
+ private static final int DEFAULT_USER_SERIAL = -1;
+
// The ID of the display tied to this DisplayBrightnessController
private final int mDisplayId;
@@ -274,8 +276,16 @@
* Notifies the brightnessSetting to persist the supplied brightness value.
*/
public void setBrightness(float brightnessValue) {
+ setBrightness(brightnessValue, DEFAULT_USER_SERIAL);
+ }
+
+ /**
+ * Notifies the brightnessSetting to persist the supplied brightness value for a user.
+ */
+ public void setBrightness(float brightnessValue, int userSerial) {
// Update the setting, which will eventually call back into DPC to have us actually
// update the display with the new value.
+ mBrightnessSetting.setUserSerial(userSerial);
mBrightnessSetting.setBrightness(brightnessValue);
if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
float nits = convertToNits(brightnessValue);
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 817b245..642f54c 100644
--- a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java
@@ -60,6 +60,114 @@
}
@Test
+ public void testLoadBrightness() {
+ final String uniqueDisplayId = "test:123";
+ final DisplayDevice testDisplayDevice = new DisplayDevice(
+ null, null, uniqueDisplayId, null) {
+ @Override
+ public boolean hasStableUniqueId() {
+ return true;
+ }
+
+ @Override
+ public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+ return null;
+ }
+ };
+
+ String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<display-manager-state>\n"
+ + " <display-states>\n"
+ + " <display unique-id=\"test:123\">\n"
+ + " <brightness-value user-serial=\"1\">0.1</brightness-value>\n"
+ + " <brightness-value user-serial=\"2\">0.2</brightness-value>\n"
+ + " </display>\n"
+ + " </display-states>\n"
+ + "</display-manager-state>\n";
+
+ InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
+ mInjector.setReadStream(is);
+ mDataStore.loadIfNeeded();
+
+ float brightness = mDataStore.getBrightness(testDisplayDevice, 1);
+ assertEquals(0.1, brightness, 0.01);
+
+ brightness = mDataStore.getBrightness(testDisplayDevice, 2);
+ assertEquals(0.2, brightness, 0.01);
+ }
+
+ @Test
+ public void testSetBrightness_brightnessTagWithNoUserId_updatesToBrightnessTagWithUserId() {
+ final String uniqueDisplayId = "test:123";
+ final DisplayDevice testDisplayDevice =
+ new DisplayDevice(null, null, uniqueDisplayId, null) {
+ @Override
+ public boolean hasStableUniqueId() {
+ return true;
+ }
+
+ @Override
+ public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
+ return null;
+ }
+ };
+
+ String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<display-manager-state>\n"
+ + " <display-states>\n"
+ + " <color-mode>0</color-mode>\n"
+ + " <display unique-id=\"test:123\">\n"
+ + " <brightness-value>0.5</brightness-value>\n"
+ + " </display>\n"
+ + " </display-states>\n"
+ + "</display-manager-state>\n";
+
+ InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
+ mInjector.setReadStream(is);
+ mDataStore.loadIfNeeded();
+
+ float user1Brightness = mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ float user2Brightness = mDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ assertEquals(0.5, user1Brightness, 0.01);
+ assertEquals(0.5, user2Brightness, 0.01);
+
+ // Override the value for user 2. Default user must have been removed.
+ mDataStore.setBrightness(testDisplayDevice, 0.2f, 2 /* userSerial */ /* brightness*/);
+
+ user1Brightness = mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ user2Brightness = mDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ assertTrue(Float.isNaN(user1Brightness));
+ assertEquals(0.2f, user2Brightness, 0.01);
+
+ // Override the value for user 1. User-specific brightness values should co-exist.
+ mDataStore.setBrightness(testDisplayDevice, 0.1f, 1 /* userSerial */ /* brightness*/);
+ user1Brightness = mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ user2Brightness = mDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ assertEquals(0.1f, user1Brightness, 0.01);
+ assertEquals(0.2f, user2Brightness, 0.01);
+
+ // Validate saveIfNeeded writes user-specific brightnes.
+ 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();
+
+ user1Brightness = newDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */);
+ user2Brightness = newDataStore.getBrightness(testDisplayDevice, 2 /* userSerial */);
+ float unknownUserBrightness =
+ newDataStore.getBrightness(testDisplayDevice, 999 /* userSerial */);
+ assertEquals(0.1f, user1Brightness, 0.01);
+ assertEquals(0.2f, user2Brightness, 0.01);
+ assertTrue(Float.isNaN(unknownUserBrightness));
+ }
+
+ @Test
public void testLoadingBrightnessConfigurations() {
String contents = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<display-manager-state>\n"
@@ -374,7 +482,7 @@
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
newInjector.setReadStream(bais);
newDataStore.loadIfNeeded();
- assertTrue(Float.isNaN(mDataStore.getBrightness(testDisplayDevice)));
+ assertTrue(Float.isNaN(mDataStore.getBrightness(testDisplayDevice, 1 /* userSerial */)));
}
@Test
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 e6d3bbc..c4f4838 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
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -247,6 +248,7 @@
0.0f);
verify(mBrightnessChangeExecutor).execute(mOnBrightnessChangeRunnable);
verify(mBrightnessSetting).setBrightness(brightnessValue);
+ verify(mBrightnessSetting).setUserSerial(anyInt());
// Does nothing if the value is invalid
mDisplayBrightnessController.updateScreenBrightnessSetting(Float.NaN);
@@ -358,4 +360,28 @@
verify(mBrightnessSetting, never()).getBrightnessNitsForDefaultDisplay();
verify(mBrightnessSetting, never()).setBrightness(brightness);
}
+
+ @Test
+ public void testChangeBrightnessNitsWhenUserChanges() {
+ float brightnessValue1 = 0.3f;
+ float nits1 = 200f;
+ float brightnessValue2 = 0.5f;
+ float nits2 = 300f;
+ AutomaticBrightnessController automaticBrightnessController =
+ mock(AutomaticBrightnessController.class);
+ when(automaticBrightnessController.convertToNits(brightnessValue1)).thenReturn(nits1);
+ when(automaticBrightnessController.convertToNits(brightnessValue2)).thenReturn(nits2);
+ mDisplayBrightnessController.setAutomaticBrightnessController(
+ automaticBrightnessController);
+
+ mDisplayBrightnessController.setBrightness(brightnessValue1, 1 /* user-serial */);
+ verify(mBrightnessSetting).setUserSerial(1);
+ verify(mBrightnessSetting).setBrightness(brightnessValue1);
+ verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits1);
+
+ mDisplayBrightnessController.setBrightness(brightnessValue2, 2 /* user-serial */);
+ verify(mBrightnessSetting).setUserSerial(2);
+ verify(mBrightnessSetting).setBrightness(brightnessValue2);
+ verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits2);
+ }
}