diff options
| author | 2023-04-03 11:49:14 +0200 | |
|---|---|---|
| committer | 2023-05-25 15:54:23 +0000 | |
| commit | 963c80fb07bb441f097a19d72f88e5a24d48d024 (patch) | |
| tree | 5b910fefff7a7ba4747d504831c72422fcf38f7b | |
| parent | 6bcaace5d291c5af8f18561d0c123b51c0ef3e58 (diff) | |
Make brightness per-user in PersistentDataStore
Bug: 275503471
Test: atest PersistentDataStoreTest
Change-Id: I934ae2c453f47cfe9fccbedebb00e86cd6070c38
9 files changed, 233 insertions, 33 deletions
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java index de42370e6d84..651828b6b9e2 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 @@ public class BrightnessSetting { 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 @@ public class BrightnessSetting { @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 @@ public class BrightnessSetting { 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 @@ public class BrightnessSetting { // 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 38445295b0f1..be65c531b913 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 @@ public final class DisplayManagerService extends SystemService { 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 @@ public final class DisplayManagerService extends SystemService { 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 2b5523ae52b0..7d8bde9feabf 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 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } @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 cc9f5394df9b..040ceccbc7c9 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 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } @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 73edb970ff95..5fbbcbd2959f 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 @@ import java.io.PrintWriter; * 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 @@ public interface DisplayPowerControllerInterface { * 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 6d6ed726161b..2d7792d01c53 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 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { return false; } final DisplayState state = getDisplayState(displayDeviceUniqueId, true); - if (state.setBrightness(brightness)) { + if (state.setBrightness(brightness, userSerial)) { setDirty(); return true; } @@ -611,6 +612,7 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { 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 @@ final class PersistentDataStore { 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 7574de841440..2f52b708dfb5 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 @@ import java.io.PrintWriter; * 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 @@ public final class DisplayBrightnessController { * 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 817b245a78bf..642f54c25a46 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 @@ public class PersistentDataStoreTest { } @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 @@ public class PersistentDataStoreTest { 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 e6d3bbc53c83..c4f483810478 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 @@ package com.android.server.display.brightness; 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 @@ public final class DisplayBrightnessControllerTest { 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 @@ public final class DisplayBrightnessControllerTest { 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); + } } |