diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 2d73aa67ed1a2..2846b36959581 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3262,11 +3262,13 @@ package android.hardware.display { public final class DisplayManager { method @RequiresPermission(android.Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS) public java.util.List getAmbientBrightnessStats(); method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration(); + method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfigurationForDisplay(@NonNull String); method @RequiresPermission(android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE) public java.util.List getBrightnessEvents(); method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration(); method public android.util.Pair getMinimumBrightnessCurve(); method public android.graphics.Point getStableDisplaySize(); method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration); + method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfigurationForDisplay(@NonNull android.hardware.display.BrightnessConfiguration, @NonNull String); method @Deprecated @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_SATURATION) public void setSaturationLevel(float); } diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index e13a7b6eac659..5034ef1dfec5a 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -939,6 +939,34 @@ public final class DisplayManager { setBrightnessConfigurationForUser(c, mContext.getUserId(), mContext.getPackageName()); } + /** + * Sets the brightness configuration for the specified display. + * If the specified display doesn't exist, then this will return and do nothing. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) + public void setBrightnessConfigurationForDisplay(@NonNull BrightnessConfiguration c, + @NonNull String uniqueId) { + mGlobal.setBrightnessConfigurationForDisplay(c, uniqueId, mContext.getUserId(), + mContext.getPackageName()); + } + + /** + * Gets the brightness configuration for the specified display and default user. + * Returns the default configuration if unset or display is invalid. + * + * @hide + */ + @Nullable + @SystemApi + @RequiresPermission(Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) + public BrightnessConfiguration getBrightnessConfigurationForDisplay( + @NonNull String uniqueId) { + return mGlobal.getBrightnessConfigurationForDisplay(uniqueId, mContext.getUserId()); + } + /** * Sets the global display brightness configuration for a specific user. * diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index a9b95fce87778..3e15c0ee6ebdf 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -704,6 +704,34 @@ public final class DisplayManagerGlobal { } } + /** + * Sets the brightness configuration for a given display. + * + * @hide + */ + public void setBrightnessConfigurationForDisplay(BrightnessConfiguration c, + String uniqueDisplayId, int userId, String packageName) { + try { + mDm.setBrightnessConfigurationForDisplay(c, uniqueDisplayId, userId, packageName); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + + /** + * Gets the brightness configuration for a given display or null if one hasn't been set. + * + * @hide + */ + public BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueDisplayId, + int userId) { + try { + return mDm.getBrightnessConfigurationForDisplay(uniqueDisplayId, userId); + } catch (RemoteException ex) { + throw ex.rethrowFromSystemServer(); + } + } + /** * Gets the global brightness configuration for a given user or null if one hasn't been set. * diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index 2303353ad101e..116214625e268 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -118,6 +118,16 @@ interface IDisplayManager { void setBrightnessConfigurationForUser(in BrightnessConfiguration c, int userId, String packageName); + // Sets the global brightness configuration for a given display. Requires + // CONFIGURE_DISPLAY_BRIGHTNESS. + void setBrightnessConfigurationForDisplay(in BrightnessConfiguration c, String uniqueDisplayId, + int userId, String packageName); + + // Gets the brightness configuration for a given display. Requires + // CONFIGURE_DISPLAY_BRIGHTNESS. + BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueDisplayId, + int userId); + // Gets the global brightness configuration for a given user. Requires // CONFIGURE_DISPLAY_BRIGHTNESS, and INTERACT_ACROSS_USER if the user is not // the same as the calling user. diff --git a/services/core/java/com/android/server/display/DisplayDeviceRepository.java b/services/core/java/com/android/server/display/DisplayDeviceRepository.java index 57f44864d2c09..2b52350f06344 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceRepository.java +++ b/services/core/java/com/android/server/display/DisplayDeviceRepository.java @@ -123,6 +123,17 @@ class DisplayDeviceRepository implements DisplayAdapter.Listener { return null; } + // String uniqueId -> DisplayDevice object with that given uniqueId + public DisplayDevice getByUniqueIdLocked(@NonNull String uniqueId) { + for (int i = mDisplayDevices.size() - 1; i >= 0; i--) { + final DisplayDevice displayDevice = mDisplayDevices.get(i); + if (displayDevice.getUniqueId().equals(uniqueId)) { + return displayDevice; + } + } + return null; + } + private void handleDisplayDeviceAdded(DisplayDevice device) { synchronized (mSyncRoot) { DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 1adcf4074db93..d3dc72e63126d 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -197,7 +197,7 @@ public final class DisplayManagerService extends SystemService { private static final int MSG_DELIVER_DISPLAY_EVENT = 3; private static final int MSG_REQUEST_TRAVERSAL = 4; private static final int MSG_UPDATE_VIEWPORT = 5; - private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; + private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATIONS = 6; private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7; private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8; @@ -523,16 +523,29 @@ public final class DisplayManagerService extends SystemService { final int newUserId = to.getUserIdentifier(); final int userSerial = getUserManager().getUserSerialNumber(newUserId); synchronized (mSyncRoot) { - final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( - Display.DEFAULT_DISPLAY); - if (mCurrentUserId != newUserId) { + boolean userSwitching = mCurrentUserId != newUserId; + if (userSwitching) { mCurrentUserId = newUserId; - BrightnessConfiguration config = - mPersistentDataStore.getBrightnessConfiguration(userSerial); - displayPowerController.setBrightnessConfiguration(config); - handleSettingsChange(); } - displayPowerController.onSwitchUser(newUserId); + mLogicalDisplayMapper.forEachLocked(logicalDisplay -> { + if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { + return; + } + final DisplayPowerController dpc = mDisplayPowerControllers.get( + logicalDisplay.getDisplayIdLocked()); + if (dpc == null) { + return; + } + if (userSwitching) { + BrightnessConfiguration config = + getBrightnessConfigForDisplayWithPdsFallbackLocked( + logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(), + userSerial); + dpc.setBrightnessConfiguration(config); + } + dpc.onSwitchUser(newUserId); + }); + handleSettingsChange(); } } @@ -1316,6 +1329,13 @@ public final class DisplayManagerService extends SystemService { if (work != null) { mHandler.post(work); } + final int displayId = display.getDisplayIdLocked(); + DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); + if (dpc != null) { + dpc.onDisplayChanged(); + } + mPersistentDataStore.saveIfNeeded(); + mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATIONS); handleLogicalDisplayChangedLocked(display); } @@ -1424,24 +1444,42 @@ public final class DisplayManagerService extends SystemService { return mDisplayModeDirector.getModeSwitchingType(); } - private void setBrightnessConfigurationForUserInternal( - @Nullable BrightnessConfiguration c, @UserIdInt int userId, - @Nullable String packageName) { + private void setBrightnessConfigurationForDisplayInternal( + @Nullable BrightnessConfiguration c, String uniqueId, @UserIdInt int userId, + String packageName) { validateBrightnessConfiguration(c); final int userSerial = getUserManager().getUserSerialNumber(userId); synchronized (mSyncRoot) { try { - mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial, - packageName); + DisplayDevice displayDevice = mDisplayDeviceRepo.getByUniqueIdLocked(uniqueId); + if (displayDevice == null) { + return; + } + mPersistentDataStore.setBrightnessConfigurationForDisplayLocked(c, displayDevice, + userSerial, packageName); } finally { mPersistentDataStore.saveIfNeeded(); } - if (userId == mCurrentUserId) { - mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration(c); + if (userId != mCurrentUserId) { + return; + } + DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId); + if (dpc != null) { + dpc.setBrightnessConfiguration(c); } } } + private DisplayPowerController getDpcFromUniqueIdLocked(String uniqueId) { + final DisplayDevice displayDevice = mDisplayDeviceRepo.getByUniqueIdLocked(uniqueId); + final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayDevice); + if (logicalDisplay != null) { + final int displayId = logicalDisplay.getDisplayIdLocked(); + return mDisplayPowerControllers.get(displayId); + } + return null; + } + @VisibleForTesting void validateBrightnessConfiguration(BrightnessConfiguration config) { if (config == null) { @@ -1464,13 +1502,22 @@ public final class DisplayManagerService extends SystemService { return false; } - private void loadBrightnessConfiguration() { + private void loadBrightnessConfigurations() { + int userSerial = getUserManager().getUserSerialNumber(mContext.getUserId()); synchronized (mSyncRoot) { - final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId); - BrightnessConfiguration config = - mPersistentDataStore.getBrightnessConfiguration(userSerial); - mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration( - config); + mLogicalDisplayMapper.forEachLocked((logicalDisplay) -> { + final String uniqueId = + logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); + final BrightnessConfiguration config = + getBrightnessConfigForDisplayWithPdsFallbackLocked(uniqueId, userSerial); + if (config != null) { + final DisplayPowerController dpc = mDisplayPowerControllers.get( + logicalDisplay.getDisplayIdLocked()); + if (dpc != null) { + dpc.setBrightnessConfiguration(config); + } + } + }); } } @@ -1681,9 +1728,17 @@ public final class DisplayManagerService extends SystemService { return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp); } - void resetBrightnessConfiguration() { - setBrightnessConfigurationForUserInternal(null, mContext.getUserId(), + void resetBrightnessConfigurations() { + mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(), mContext.getPackageName()); + mLogicalDisplayMapper.forEachLocked((logicalDisplay -> { + if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { + return; + } + final String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); + setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(), + mContext.getPackageName()); + })); } void setAutoBrightnessLoggingEnabled(boolean enabled) { @@ -2132,6 +2187,18 @@ public final class DisplayManagerService extends SystemService { return display == null ? null : display.getPrimaryDisplayDeviceLocked(); } + private BrightnessConfiguration getBrightnessConfigForDisplayWithPdsFallbackLocked( + String uniqueId, int userSerial) { + BrightnessConfiguration config = + mPersistentDataStore.getBrightnessConfigurationForDisplayLocked( + uniqueId, userSerial); + if (config == null) { + // Get from global configurations + config = mPersistentDataStore.getBrightnessConfiguration(userSerial); + } + return config; + } + private final class DisplayManagerHandler extends Handler { public DisplayManagerHandler(Looper looper) { super(looper, null, true /*async*/); @@ -2173,8 +2240,8 @@ public final class DisplayManagerService extends SystemService { break; } - case MSG_LOAD_BRIGHTNESS_CONFIGURATION: - loadBrightnessConfiguration(); + case MSG_LOAD_BRIGHTNESS_CONFIGURATIONS: + loadBrightnessConfigurations(); break; case MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE: @@ -2789,6 +2856,19 @@ public final class DisplayManagerService extends SystemService { @Override // Binder call public void setBrightnessConfigurationForUser( BrightnessConfiguration c, @UserIdInt int userId, String packageName) { + mLogicalDisplayMapper.forEachLocked(logicalDisplay -> { + if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { + return; + } + final DisplayDevice displayDevice = logicalDisplay.getPrimaryDisplayDeviceLocked(); + setBrightnessConfigurationForDisplay(c, displayDevice.getUniqueId(), userId, + packageName); + }); + } + + @Override // Binder call + public void setBrightnessConfigurationForDisplay(BrightnessConfiguration c, + String uniqueId, int userId, String packageName) { mContext.enforceCallingOrSelfPermission( Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, "Permission required to change the display's brightness configuration"); @@ -2796,21 +2876,19 @@ public final class DisplayManagerService extends SystemService { mContext.enforceCallingOrSelfPermission( Manifest.permission.INTERACT_ACROSS_USERS, "Permission required to change the display brightness" - + " configuration of another user"); - } - if (packageName != null && !validatePackageName(getCallingUid(), packageName)) { - packageName = null; + + " configuration of another user"); } final long token = Binder.clearCallingIdentity(); try { - setBrightnessConfigurationForUserInternal(c, userId, packageName); + setBrightnessConfigurationForDisplayInternal(c, uniqueId, userId, packageName); } finally { Binder.restoreCallingIdentity(token); } } @Override // Binder call - public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) { + public BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueId, + int userId) { mContext.enforceCallingOrSelfPermission( Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, "Permission required to read the display's brightness configuration"); @@ -2821,14 +2899,19 @@ public final class DisplayManagerService extends SystemService { + " configuration of another user"); } final long token = Binder.clearCallingIdentity(); + final int userSerial = getUserManager().getUserSerialNumber(userId); try { - final int userSerial = getUserManager().getUserSerialNumber(userId); synchronized (mSyncRoot) { + // Get from per-display configurations BrightnessConfiguration config = - mPersistentDataStore.getBrightnessConfiguration(userSerial); + getBrightnessConfigForDisplayWithPdsFallbackLocked( + uniqueId, userSerial); if (config == null) { - config = mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) - .getDefaultBrightnessConfiguration(); + // Get default configuration + DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId); + if (dpc != null) { + config = dpc.getDefaultBrightnessConfiguration(); + } } return config; } @@ -2837,6 +2920,21 @@ public final class DisplayManagerService extends SystemService { } } + + + @Override // Binder call + public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) { + final String uniqueId; + synchronized (mSyncRoot) { + DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked( + Display.DEFAULT_DISPLAY).getPrimaryDisplayDeviceLocked(); + uniqueId = displayDevice.getUniqueId(); + } + return getBrightnessConfigurationForDisplay(uniqueId, userId); + + + } + @Override // Binder call public BrightnessConfiguration getDefaultBrightnessConfiguration() { mContext.enforceCallingOrSelfPermission( @@ -3105,7 +3203,7 @@ public final class DisplayManagerService extends SystemService { initializeDisplayPowerControllersLocked(); } - mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION); + mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATIONS); } @Override diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java index 94e64f070ef89..9412c938f934d 100644 --- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java +++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java @@ -120,7 +120,7 @@ class DisplayManagerShellCommand extends ShellCommand { } private int resetBrightnessConfiguration() { - mService.resetBrightnessConfiguration(); + mService.resetBrightnessConfigurations(); return 0; } diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java index 4c9a2d702114e..a931718353651 100644 --- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java +++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java @@ -195,6 +195,9 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener { } public LogicalDisplay getDisplayLocked(DisplayDevice device) { + if (device == null) { + return null; + } final int count = mLogicalDisplays.size(); for (int i = 0; i < count; i++) { final LogicalDisplay display = mLogicalDisplays.valueAt(i); diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java index c90ddf48a0918..4b0d43b3d1d4f 100644 --- a/services/core/java/com/android/server/display/PersistentDataStore.java +++ b/services/core/java/com/android/server/display/PersistentDataStore.java @@ -63,6 +63,15 @@ import java.util.Objects; * <display unique-id="XXXXXXX"> * <color-mode>0</color-mode> * <brightness-value>0</brightness-value> + * <brightness-configurations> + * <brightness-configuration user-serial="0" package-name="com.example" + * timestamp="1234"> + * <brightness-curve description="some text"> + * <brightness-point lux="0" nits="13.25"/> + * <brightness-point lux="20" nits="35.94"/> + * </brightness-curve> + * </brightness-configuration> + * </brightness-configurations> * </display> * </display-states> * <stable-device-values> @@ -120,7 +129,8 @@ final class PersistentDataStore { private final StableDeviceValues mStableDeviceValues = new StableDeviceValues(); // Brightness configuration by user - private BrightnessConfigurations mBrightnessConfigurations = new BrightnessConfigurations(); + private BrightnessConfigurations mGlobalBrightnessConfigurations = + new BrightnessConfigurations(); // True if the data has been loaded. private boolean mLoaded; @@ -293,18 +303,44 @@ final class PersistentDataStore { } } + // Used for testing & reset public void setBrightnessConfigurationForUser(BrightnessConfiguration c, int userSerial, @Nullable String packageName) { loadIfNeeded(); - if (mBrightnessConfigurations.setBrightnessConfigurationForUser(c, userSerial, + if (mGlobalBrightnessConfigurations.setBrightnessConfigurationForUser(c, userSerial, packageName)) { + setDirty(); } } + public boolean setBrightnessConfigurationForDisplayLocked(BrightnessConfiguration configuration, + DisplayDevice device, int userSerial, String packageName) { + if (device == null || !device.hasStableUniqueId()) { + return false; + } + DisplayState state = getDisplayState(device.getUniqueId(), /*createIfAbsent*/ true); + if (state.setBrightnessConfiguration(configuration, userSerial, packageName)) { + setDirty(); + return true; + } + return false; + } + + + public BrightnessConfiguration getBrightnessConfigurationForDisplayLocked( + String uniqueDisplayId, int userSerial) { + loadIfNeeded(); + DisplayState state = mDisplayStates.get(uniqueDisplayId); + if (state != null) { + return state.getBrightnessConfiguration(userSerial); + } + return null; + } + public BrightnessConfiguration getBrightnessConfiguration(int userSerial) { loadIfNeeded(); - return mBrightnessConfigurations.getBrightnessConfiguration(userSerial); + return mGlobalBrightnessConfigurations.getBrightnessConfiguration(userSerial); } private DisplayState getDisplayState(String uniqueId, boolean createIfAbsent) { @@ -391,7 +427,7 @@ final class PersistentDataStore { mStableDeviceValues.loadFromXml(parser); } if (parser.getName().equals(TAG_BRIGHTNESS_CONFIGURATIONS)) { - mBrightnessConfigurations.loadFromXml(parser); + mGlobalBrightnessConfigurations.loadFromXml(parser); } } } @@ -470,7 +506,7 @@ final class PersistentDataStore { mStableDeviceValues.saveToXml(serializer); serializer.endTag(null, TAG_STABLE_DEVICE_VALUES); serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS); - mBrightnessConfigurations.saveToXml(serializer); + mGlobalBrightnessConfigurations.saveToXml(serializer); serializer.endTag(null, TAG_BRIGHTNESS_CONFIGURATIONS); serializer.endTag(null, TAG_DISPLAY_MANAGER_STATE); serializer.endDocument(); @@ -493,14 +529,18 @@ final class PersistentDataStore { } pw.println(" StableDeviceValues:"); mStableDeviceValues.dump(pw, " "); - pw.println(" BrightnessConfigurations:"); - mBrightnessConfigurations.dump(pw, " "); + pw.println(" GlobalBrightnessConfigurations:"); + mGlobalBrightnessConfigurations.dump(pw, " "); } private static final class DisplayState { private int mColorMode; private float mBrightness; + // Brightness configuration by user + private BrightnessConfigurations mDisplayBrightnessConfigurations = + new BrightnessConfigurations(); + public boolean setColorMode(int colorMode) { if (colorMode == mColorMode) { return false; @@ -525,6 +565,16 @@ final class PersistentDataStore { return mBrightness; } + public boolean setBrightnessConfiguration(BrightnessConfiguration configuration, + int userSerial, String packageName) { + mDisplayBrightnessConfigurations.setBrightnessConfigurationForUser( + configuration, userSerial, packageName); + return true; + } + + public BrightnessConfiguration getBrightnessConfiguration(int userSerial) { + return mDisplayBrightnessConfigurations.mConfigurations.get(userSerial); + } public void loadFromXml(TypedXmlPullParser parser) throws IOException, XmlPullParserException { @@ -540,6 +590,9 @@ final class PersistentDataStore { String brightness = parser.nextText(); mBrightness = Float.parseFloat(brightness); break; + case TAG_BRIGHTNESS_CONFIGURATIONS: + mDisplayBrightnessConfigurations.loadFromXml(parser); + break; } } } @@ -548,15 +601,21 @@ final class PersistentDataStore { serializer.startTag(null, TAG_COLOR_MODE); serializer.text(Integer.toString(mColorMode)); serializer.endTag(null, TAG_COLOR_MODE); + serializer.startTag(null, TAG_BRIGHTNESS_VALUE); serializer.text(Float.toString(mBrightness)); serializer.endTag(null, TAG_BRIGHTNESS_VALUE); + serializer.startTag(null, TAG_BRIGHTNESS_CONFIGURATIONS); + mDisplayBrightnessConfigurations.saveToXml(serializer); + serializer.endTag(null, TAG_BRIGHTNESS_CONFIGURATIONS); } public void dump(final PrintWriter pw, final String prefix) { pw.println(prefix + "ColorMode=" + mColorMode); pw.println(prefix + "BrightnessValue=" + mBrightness); + pw.println(prefix + "DisplayBrightnessConfigurations: "); + mDisplayBrightnessConfigurations.dump(pw, prefix); } } @@ -621,11 +680,11 @@ final class PersistentDataStore { private static final class BrightnessConfigurations { // Maps from a user ID to the users' given brightness configuration - private SparseArray mConfigurations; + private final SparseArray mConfigurations; // Timestamp of time the configuration was set. - private SparseLongArray mTimeStamps; + private final SparseLongArray mTimeStamps; // Package that set the configuration. - private SparseArray mPackageNames; + private final SparseArray mPackageNames; public BrightnessConfigurations() { mConfigurations = new SparseArray<>(); diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index bcb2cf8fa0c35..68b84693f0ef8 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -71,6 +71,7 @@ + diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index 5ba375b922e23..7c55716c5e99a 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -885,6 +885,61 @@ public class DisplayManagerServiceTest { assertFalse(callback.mDisplayAddedCalled); } + + + @Test + public void testSettingTwoBrightnessConfigurationsOnMultiDisplay() { + Context mContext = InstrumentationRegistry.getInstrumentation().getContext(); + DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); + + // get the first two internal displays + Display[] displays = displayManager.getDisplays(); + Display internalDisplayOne = null; + Display internalDisplayTwo = null; + for (Display display : displays) { + if (display.getType() == Display.TYPE_INTERNAL) { + if (internalDisplayOne == null) { + internalDisplayOne = display; + } else { + internalDisplayTwo = display; + break; + } + } + } + + // return if there are fewer than 2 displays on this device + if (internalDisplayOne == null || internalDisplayTwo == null) { + return; + } + + final String uniqueDisplayIdOne = internalDisplayOne.getUniqueId(); + final String uniqueDisplayIdTwo = internalDisplayTwo.getUniqueId(); + + BrightnessConfiguration configOne = + new BrightnessConfiguration.Builder( + new float[]{0.0f, 12345.0f}, new float[]{15.0f, 400.0f}) + .setDescription("model:1").build(); + BrightnessConfiguration configTwo = + new BrightnessConfiguration.Builder( + new float[]{0.0f, 6789.0f}, new float[]{12.0f, 300.0f}) + .setDescription("model:2").build(); + + displayManager.setBrightnessConfigurationForDisplay(configOne, + uniqueDisplayIdOne); + displayManager.setBrightnessConfigurationForDisplay(configTwo, + uniqueDisplayIdTwo); + + BrightnessConfiguration configFromOne = + displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdOne); + BrightnessConfiguration configFromTwo = + displayManager.getBrightnessConfigurationForDisplay(uniqueDisplayIdTwo); + + assertNotNull(configFromOne); + assertEquals(configOne, configFromOne); + assertEquals(configTwo, configFromTwo); + + } + private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled) throws Exception { DisplayManagerService displayManager = 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 196454bd32cec..57a9cb278c808 100644 --- a/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/display/PersistentDataStoreTest.java @@ -17,13 +17,16 @@ package com.android.server.display; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import android.content.Context; import android.hardware.display.BrightnessConfiguration; import android.util.Pair; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -144,15 +147,93 @@ public class PersistentDataStoreTest { } @Test - public void testStoreAndReloadOfBrightnessConfigurations() { + public void testStoreAndReloadOfDisplayBrightnessConfigurations() { + final String uniqueDisplayId = "test:123"; + int userSerial = 0; + String packageName = "pdsTestPackage"; final float[] lux = { 0f, 10f }; final float[] nits = {1f, 100f }; final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits) .setDescription("a description") .build(); + mDataStore.loadIfNeeded(); + assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId, + userSerial)); + + DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) { + @Override + public boolean hasStableUniqueId() { + return true; + } + + @Override + public DisplayDeviceInfo getDisplayDeviceInfoLocked() { + return null; + } + }; + + mDataStore.setBrightnessConfigurationForDisplayLocked(config, testDisplayDevice, userSerial, + packageName); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + mInjector.setWriteStream(baos); + mDataStore.saveIfNeeded(); + assertTrue(mInjector.wasWriteSuccessful()); + TestInjector newInjector = new TestInjector(); + PersistentDataStore newDataStore = new PersistentDataStore(newInjector); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + newInjector.setReadStream(bais); + newDataStore.loadIfNeeded(); + assertNotNull(newDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId, + userSerial)); + assertEquals(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId, + userSerial), newDataStore.getBrightnessConfigurationForDisplayLocked( + uniqueDisplayId, userSerial)); + } + + @Test + public void testSetBrightnessConfigurationFailsWithUnstableId() { + final String uniqueDisplayId = "test:123"; + int userSerial = 0; + String packageName = "pdsTestPackage"; + final float[] lux = { 0f, 10f }; + final float[] nits = {1f, 100f }; + final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits) + .setDescription("a description") + .build(); + mDataStore.loadIfNeeded(); + assertNull(mDataStore.getBrightnessConfigurationForDisplayLocked(uniqueDisplayId, + userSerial)); + + DisplayDevice testDisplayDevice = new DisplayDevice(null, null, uniqueDisplayId, null) { + @Override + public boolean hasStableUniqueId() { + return false; + } + + @Override + public DisplayDeviceInfo getDisplayDeviceInfoLocked() { + return null; + } + }; + + assertFalse(mDataStore.setBrightnessConfigurationForDisplayLocked( + config, testDisplayDevice, userSerial, packageName)); + } + + @Test + public void testStoreAndReloadOfBrightnessConfigurations() { + final float[] lux = { 0f, 10f }; + final float[] nits = {1f, 100f }; + final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits) + .setDescription("a description") + .build(); + Context context = InstrumentationRegistry.getInstrumentation().getContext(); + String packageName = context.getPackageName(); + mDataStore.loadIfNeeded(); assertNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); - mDataStore.setBrightnessConfigurationForUser(config, 0, "packagename"); + mDataStore.setBrightnessConfigurationForUser(config, 0, packageName); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); mInjector.setWriteStream(baos); @@ -173,17 +254,18 @@ public class PersistentDataStoreTest { public void testNullBrightnessConfiguration() { final float[] lux = { 0f, 10f }; final float[] nits = {1f, 100f }; + int userSerial = 0; final BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits) .setDescription("a description") .build(); mDataStore.loadIfNeeded(); - assertNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); + assertNull(mDataStore.getBrightnessConfiguration(userSerial)); - mDataStore.setBrightnessConfigurationForUser(config, 0, "packagename"); - assertNotNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); + mDataStore.setBrightnessConfigurationForUser(config, userSerial, "packagename"); + assertNotNull(mDataStore.getBrightnessConfiguration(userSerial)); - mDataStore.setBrightnessConfigurationForUser(null, 0, "packagename"); - assertNull(mDataStore.getBrightnessConfiguration(0 /*userSerial*/)); + mDataStore.setBrightnessConfigurationForUser(null, userSerial, "packagename"); + assertNull(mDataStore.getBrightnessConfiguration(userSerial)); } public class TestInjector extends PersistentDataStore.Injector {