diff options
| author | 2024-07-26 15:01:06 +0000 | |
|---|---|---|
| committer | 2024-07-29 14:51:31 +0000 | |
| commit | bfa91592f15623e60ff96f26a7bd41ba3c3aa89c (patch) | |
| tree | b9e8bb594dcda883041c8dd123088719fa0caa1c | |
| parent | 038604323950c233eca3627353a32200ef3f74d9 (diff) | |
Fix UserHandle
LowLuxModifier, DMD and DPC register observer while the system is starting (current user = system), but on some devices, later the current user switches. When Smooth Display for example is enabled with the UI, it's enabled by the new user and not the system user. We should therefore use USER_ALL when registering observers.
When reading the settings, we should use USER_CURRENT instead of getting the user id from the context associated with the system.
We should also re-read the settings if the user switches.
Additionally, update the stale evenDimmer comment in DDC.
Bug: 353645971
Test: AutomaticBrightnessControllerTest, BrightnessClamperControllerTest, BrightnessLowLuxModifierTest, BrightnessMappingStrategyTest, DisplayManagerServiceTest, DisplayModeDirectorTest, DisplayPowerControllerTest
Flag: EXEMPT bugfix
Change-Id: I204478b6f356aea72f50bf9130f92e53b2758202
11 files changed, 315 insertions, 37 deletions
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 7b5cff739ba1..226bdf54ce3b 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -579,6 +579,14 @@ public class AutomaticBrightnessController { return mCurrentBrightnessMapper.getMode(); } + /** + * @return The preset for this mapping strategy. Presets are used on devices that allow users + * to choose from a set of predefined options in display auto-brightness settings. + */ + public int getPreset() { + return mCurrentBrightnessMapper.getPreset(); + } + public boolean isInIdleMode() { return mCurrentBrightnessMapper.getMode() == AUTO_BRIGHTNESS_MODE_IDLE; } diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index 8405e0a52084..b0507fb78a41 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -140,10 +140,10 @@ public abstract class BrightnessMappingStrategy { builder.setShortTermModelLowerLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO); builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO); return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange, - autoBrightnessAdjustmentMaxGamma, mode, displayWhiteBalanceController); + autoBrightnessAdjustmentMaxGamma, mode, preset, displayWhiteBalanceController); } else if (isValidMapping(luxLevels, brightnessLevels)) { return new SimpleMappingStrategy(luxLevels, brightnessLevels, - autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout, mode); + autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout, mode, preset); } else { return null; } @@ -394,6 +394,12 @@ public abstract class BrightnessMappingStrategy { abstract int getMode(); /** + * @return The preset for this mapping strategy. Presets are used on devices that allow users + * to choose from a set of predefined options in display auto-brightness settings. + */ + abstract int getPreset(); + + /** * Check if the short term model should be reset given the anchor lux the last * brightness change was made at and the current ambient lux. */ @@ -598,6 +604,8 @@ public abstract class BrightnessMappingStrategy { @AutomaticBrightnessController.AutomaticBrightnessMode private final int mMode; + private final int mPreset; + private Spline mSpline; private float mMaxGamma; private float mAutoBrightnessAdjustment; @@ -606,7 +614,8 @@ public abstract class BrightnessMappingStrategy { private long mShortTermModelTimeout; private SimpleMappingStrategy(float[] lux, float[] brightness, float maxGamma, - long timeout, @AutomaticBrightnessController.AutomaticBrightnessMode int mode) { + long timeout, @AutomaticBrightnessController.AutomaticBrightnessMode int mode, + int preset) { Preconditions.checkArgument(lux.length != 0 && brightness.length != 0, "Lux and brightness arrays must not be empty!"); Preconditions.checkArgument(lux.length == brightness.length, @@ -633,6 +642,7 @@ public abstract class BrightnessMappingStrategy { computeSpline(); mShortTermModelTimeout = timeout; mMode = mode; + mPreset = preset; } @Override @@ -766,6 +776,11 @@ public abstract class BrightnessMappingStrategy { } @Override + int getPreset() { + return mPreset; + } + + @Override float getUserLux() { return mUserLux; } @@ -837,6 +852,8 @@ public abstract class BrightnessMappingStrategy { @AutomaticBrightnessController.AutomaticBrightnessMode private final int mMode; + private final int mPreset; + // Previous short-term models and the times that they were computed stored for debugging // purposes private List<Spline> mPreviousBrightnessSplines = new ArrayList<>(); @@ -846,7 +863,7 @@ public abstract class BrightnessMappingStrategy { public PhysicalMappingStrategy(BrightnessConfiguration config, float[] nits, float[] brightness, float maxGamma, - @AutomaticBrightnessController.AutomaticBrightnessMode int mode, + @AutomaticBrightnessController.AutomaticBrightnessMode int mode, int preset, @Nullable DisplayWhiteBalanceController displayWhiteBalanceController) { Preconditions.checkArgument(nits.length != 0 && brightness.length != 0, @@ -860,6 +877,7 @@ public abstract class BrightnessMappingStrategy { PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, "brightness"); mMode = mode; + mPreset = preset; mMaxGamma = maxGamma; mAutoBrightnessAdjustment = 0; mUserLux = INVALID_LUX; @@ -1073,6 +1091,11 @@ public abstract class BrightnessMappingStrategy { } @Override + int getPreset() { + return mPreset; + } + + @Override float getUserLux() { return mUserLux; } diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index ed6ed60a6806..cc115f13f5e3 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -588,22 +588,43 @@ import javax.xml.datatype.DatatypeConfigurationException; * <minorVersion>0</minorVersion> * </usiVersion> * <evenDimmer enabled="true"> - * <transitionPoint>0.1</transitionPoint> - * - * <nits>0.2</nits> - * <nits>2.0</nits> - * <nits>500.0</nits> - * <nits>1000.0</nits> - * - * <backlight>0</backlight> - * <backlight>0.0001</backlight> - * <backlight>0.5</backlight> - * <backlight>1.0</backlight> - * - * <brightness>0</brightness> - * <brightness>0.1</brightness> - * <brightness>0.5</brightness> - * <brightness>1.0</brightness> + * <transitionPoint>0.1</transitionPoint> + * <brightnessMapping> + * <brightnessPoint> + * <nits>0.2</nits> + * <backlight>0</backlight> + * <brightness>0</brightness> + * </brightnessPoint> + * <brightnessPoint> + * <nits>2.0</nits> + * <backlight>0.01</backlight> + * <brightness>0.002</brightness> + * </brightnessPoint> + * <brightnessPoint> + * <nits>500.0</nits> + * <backlight>0.5</backlight> + * <brightness>0.5</brightness> + * </brightnessPoint> + * <brightnessPoint> + * <nits>1000</nits> + * <backlight>1.0</backlight> + * <brightness>1.0</brightness> + * </brightnessPoint> + * </brightnessMapping> + * <luxToMinimumNitsMap> + * <point> + * <value>10</value> + * <nits>0.3</nits> + * </point> + * <point> + * <value>50</value> + * <nits>0.7</nits> + * </point> + * <point> + * <value>100</value> + * <nits>1.0</nits> + * </point> + * </luxToMinimumNitsMap> * </evenDimmer> * <screenBrightnessCapForWearBedtimeMode>0.1</screenBrightnessCapForWearBedtimeMode> * <idleScreenRefreshRateTimeout> diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 2cec869c290e..9e905abd78ed 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -722,6 +722,7 @@ public final class DisplayManagerService extends SystemService { if (userSwitching) { mCurrentUserId = newUserId; } + mDisplayModeDirector.onSwitchUser(); mLogicalDisplayMapper.forEachLocked(logicalDisplay -> { if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { return; diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 1177be212222..4152fa005e94 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -702,6 +702,17 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void handleOnSwitchUser(@UserIdInt int newUserId, int userSerial, float newBrightness) { Slog.i(mTag, "Switching user newUserId=" + newUserId + " userSerial=" + userSerial + " newBrightness=" + newBrightness); + + if (mAutomaticBrightnessController != null) { + int autoBrightnessPreset = Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FOR_ALS, + Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL, + UserHandle.USER_CURRENT); + if (autoBrightnessPreset != mAutomaticBrightnessController.getPreset()) { + setUpAutoBrightness(mContext, mHandler); + } + } + handleBrightnessModeChange(); if (mBrightnessTracker != null) { mBrightnessTracker.onSwitchUser(newUserId); @@ -714,6 +725,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mAutomaticBrightnessController != null) { mAutomaticBrightnessController.resetShortTermModel(); } + mBrightnessClamperController.onUserSwitch(); sendUpdatePowerState(); } @@ -1009,7 +1021,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (mFlags.areAutoBrightnessModesEnabled()) { mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_ALS), - /* notifyForDescendants= */ false, mSettingsObserver, UserHandle.USER_CURRENT); + /* notifyForDescendants= */ false, mSettingsObserver, UserHandle.USER_ALL); } handleBrightnessModeChange(); } diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java index 9324fc1c4e06..12c3197aba2a 100644 --- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java +++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java @@ -71,6 +71,7 @@ public class BrightnessClamperController { private final List<DisplayDeviceDataListener> mDisplayDeviceDataListeners = new ArrayList<>(); private final List<StatefulModifier> mStatefulModifiers = new ArrayList<>(); + private final List<UserSwitchListener> mUserSwitchListeners = new ArrayList<>(); private ModifiersAggregatedState mModifiersAggregatedState = new ModifiersAggregatedState(); private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener; @@ -127,6 +128,9 @@ public class BrightnessClamperController { if (m instanceof StatefulModifier s) { mStatefulModifiers.add(s); } + if (m instanceof UserSwitchListener l) { + mUserSwitchListeners.add(l); + } }); mOnPropertiesChangedListener = properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged); @@ -209,6 +213,13 @@ public class BrightnessClamperController { } /** + * Called when the user switches. + */ + public void onUserSwitch() { + mUserSwitchListeners.forEach(listener -> listener.onSwitchUser()); + } + + /** * Used to dump ClampersController state. */ public void dump(PrintWriter writer) { @@ -466,6 +477,13 @@ public class BrightnessClamperController { } /** + * A clamper/modifier should implement this interface if it reads user-specific settings + */ + interface UserSwitchListener { + void onSwitchUser(); + } + + /** * StatefulModifiers contribute to AggregatedState, that is used to decide if brightness * adjustement is needed */ diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java index 951980adac8c..c3596c3e77fe 100644 --- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java +++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java @@ -41,7 +41,8 @@ import java.io.PrintWriter; * Class used to prevent the screen brightness dipping below a certain value, based on current * lux conditions and user preferred minimum. */ -public class BrightnessLowLuxModifier extends BrightnessModifier { +public class BrightnessLowLuxModifier extends BrightnessModifier implements + BrightnessClamperController.UserSwitchListener { // To enable these logs, run: // 'adb shell setprop persist.log.tag.BrightnessLowLuxModifier DEBUG && adb reboot' @@ -81,10 +82,9 @@ public class BrightnessLowLuxModifier extends BrightnessModifier { */ @VisibleForTesting public void recalculateLowerBound() { - int userId = UserHandle.USER_CURRENT; float settingNitsLowerBound = Settings.Secure.getFloatForUser( mContentResolver, Settings.Secure.EVEN_DIMMER_MIN_NITS, - /* def= */ MIN_NITS_DEFAULT, userId); + /* def= */ MIN_NITS_DEFAULT, UserHandle.USER_CURRENT); boolean isActive = isSettingEnabled() && mAmbientLux != BrightnessMappingStrategy.INVALID_LUX; @@ -190,6 +190,11 @@ public class BrightnessLowLuxModifier extends BrightnessModifier { } @Override + public void onSwitchUser() { + recalculateLowerBound(); + } + + @Override public void dump(PrintWriter pw) { pw.println("BrightnessLowLuxModifier:"); pw.println(" mIsActive=" + mIsActive); @@ -221,10 +226,10 @@ public class BrightnessLowLuxModifier extends BrightnessModifier { super(handler); mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_MIN_NITS), - false, this); + false, this, UserHandle.USER_ALL); mContentResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_ACTIVATED), - false, this); + false, this, UserHandle.USER_ALL); } @Override diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java index d610f086b3b5..5e471c82e108 100644 --- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java @@ -121,6 +121,7 @@ public class DisplayModeDirector { private static final int MSG_HIGH_BRIGHTNESS_THRESHOLDS_CHANGED = 6; private static final int MSG_REFRESH_RATE_IN_HBM_SUNLIGHT_CHANGED = 7; private static final int MSG_REFRESH_RATE_IN_HBM_HDR_CHANGED = 8; + private static final int MSG_SWITCH_USER = 9; private final Object mLock = new Object(); private final Context mContext; @@ -564,6 +565,13 @@ public class DisplayModeDirector { } /** + * Called when the user switches. + */ + public void onSwitchUser() { + mHandler.obtainMessage(MSG_SWITCH_USER).sendToTarget(); + } + + /** * Print the object's state and debug information into the given stream. * * @param pw The stream to dump information to. @@ -789,6 +797,13 @@ public class DisplayModeDirector { mHbmObserver.onDeviceConfigRefreshRateInHbmHdrChanged(refreshRateInHbmHdr); break; } + + case MSG_SWITCH_USER: { + synchronized (mLock) { + mSettingsObserver.updateRefreshRateSettingLocked(); + mSettingsObserver.updateModeSwitchingTypeSettingLocked(); + } + } } } } @@ -1012,10 +1027,10 @@ public class DisplayModeDirector { final ContentResolver cr = mContext.getContentResolver(); mInjector.registerPeakRefreshRateObserver(cr, this); mInjector.registerMinRefreshRateObserver(cr, this); - cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this, - UserHandle.USER_SYSTEM); - cr.registerContentObserver(mMatchContentFrameRateSetting, false /*notifyDescendants*/, - this); + cr.registerContentObserver(mLowPowerModeSetting, /* notifyDescendants= */ false, this, + UserHandle.USER_ALL); + cr.registerContentObserver(mMatchContentFrameRateSetting, + /* notifyDescendants= */ false, this, UserHandle.USER_ALL); mInjector.registerDisplayListener(mDisplayListener, mHandler); float deviceConfigDefaultPeakRefresh = @@ -1156,14 +1171,15 @@ public class DisplayModeDirector { float highestRefreshRate = getMaxRefreshRateLocked(displayId); float minRefreshRate = Settings.System.getFloatForUser(cr, - Settings.System.MIN_REFRESH_RATE, 0f, cr.getUserId()); + Settings.System.MIN_REFRESH_RATE, 0f, UserHandle.USER_CURRENT); if (Float.isInfinite(minRefreshRate)) { // Infinity means that we want the highest possible refresh rate minRefreshRate = highestRefreshRate; } float peakRefreshRate = Settings.System.getFloatForUser(cr, - Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate, cr.getUserId()); + Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate, + UserHandle.USER_CURRENT); if (Float.isInfinite(peakRefreshRate)) { // Infinity means that we want the highest possible refresh rate peakRefreshRate = highestRefreshRate; @@ -1234,9 +1250,9 @@ public class DisplayModeDirector { private void updateModeSwitchingTypeSettingLocked() { final ContentResolver cr = mContext.getContentResolver(); - int switchingType = Settings.Secure.getIntForUser( - cr, Settings.Secure.MATCH_CONTENT_FRAME_RATE, mModeSwitchingType /*default*/, - cr.getUserId()); + int switchingType = Settings.Secure.getIntForUser(cr, + Settings.Secure.MATCH_CONTENT_FRAME_RATE, /* default= */ mModeSwitchingType, + UserHandle.USER_CURRENT); if (switchingType != mModeSwitchingType) { mModeSwitchingType = switchingType; notifyDesiredDisplayModeSpecsChangedLocked(); @@ -3033,14 +3049,14 @@ public class DisplayModeDirector { public void registerPeakRefreshRateObserver(@NonNull ContentResolver cr, @NonNull ContentObserver observer) { cr.registerContentObserver(PEAK_REFRESH_RATE_URI, false /*notifyDescendants*/, - observer, UserHandle.USER_SYSTEM); + observer, UserHandle.USER_ALL); } @Override public void registerMinRefreshRateObserver(@NonNull ContentResolver cr, @NonNull ContentObserver observer) { cr.registerContentObserver(MIN_REFRESH_RATE_URI, false /*notifyDescendants*/, - observer, UserHandle.USER_SYSTEM); + observer, UserHandle.USER_ALL); } @Override diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java index fb73aff44c64..f3cd0c960fca 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java @@ -693,6 +693,21 @@ public class BrightnessMappingStrategyTest { } @Test + public void testGetPreset() { + int preset = Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_DIM; + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_FOR_ALS, preset); + setUpResources(); + DisplayDeviceConfig ddc = new DdcBuilder() + .setAutoBrightnessLevels(AUTO_BRIGHTNESS_MODE_DEFAULT, preset, DISPLAY_LEVELS) + .setAutoBrightnessLevelsLux(AUTO_BRIGHTNESS_MODE_DEFAULT, preset, LUX_LEVELS) + .build(); + BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(mContext, ddc, + AUTO_BRIGHTNESS_MODE_DEFAULT, /* displayWhiteBalanceController= */ null); + assertEquals(preset, strategy.getPreset()); + } + + @Test public void testAutoBrightnessModeAndPreset() { int mode = AUTO_BRIGHTNESS_MODE_DOZE; int preset = Settings.System.SCREEN_BRIGHTNESS_AUTOMATIC_DIM; diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt index d672435096b9..6929690baaf8 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt @@ -225,5 +225,37 @@ class BrightnessLowLuxModifierTest { assertThat(modifier.brightnessReason).isEqualTo(BrightnessReason.MODIFIER_MIN_LUX) assertThat(modifier.brightnessLowerBound).isEqualTo(LOW_LUX_BRIGHTNESS) } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER) + fun testUserSwitch() { + // nits: 0.5 -> backlight 0.01 -> brightness -> 0.05 + whenever(mockDisplayDeviceConfig.getBacklightFromNits(/* nits= */ 0.5f)) + .thenReturn(0.01f) + whenever(mockDisplayDeviceConfig.getBrightnessFromBacklight(/* backlight = */ 0.01f)) + .thenReturn(0.05f) + + Settings.Secure.putIntForUser(context.contentResolver, + Settings.Secure.EVEN_DIMMER_ACTIVATED, 0, USER_ID) // off + Settings.Secure.putFloatForUser(context.contentResolver, + Settings.Secure.EVEN_DIMMER_MIN_NITS, 1.0f, USER_ID) + + modifier.recalculateLowerBound() + + assertThat(modifier.isActive).isFalse() + assertThat(modifier.brightnessLowerBound).isEqualTo(TRANSITION_POINT) + assertThat(modifier.brightnessReason).isEqualTo(0) // no reason - i.e. off + + Settings.Secure.putIntForUser(context.contentResolver, + Settings.Secure.EVEN_DIMMER_ACTIVATED, 1, USER_ID) // on + Settings.Secure.putFloatForUser(context.contentResolver, + Settings.Secure.EVEN_DIMMER_MIN_NITS, 0.5f, USER_ID) + modifier.onSwitchUser() + + assertThat(modifier.isActive).isTrue() + assertThat(modifier.brightnessReason).isEqualTo( + BrightnessReason.MODIFIER_MIN_USER_SET_LOWER_BOUND) + assertThat(modifier.brightnessLowerBound).isEqualTo(0.05f) + } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java index 242d5593c3c8..62400ebed149 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java @@ -1088,6 +1088,21 @@ public class DisplayModeDirectorTest { } @Test + public void testModeSwitching_UserSwitch() { + DisplayModeDirector director = createDirectorFromFpsRange(0, 90); + assertThat(director.getModeSwitchingType()).isEqualTo( + DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS); + + int newModeSwitchingType = DisplayManager.SWITCHING_TYPE_NONE; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.MATCH_CONTENT_FRAME_RATE, newModeSwitchingType); + director.onSwitchUser(); + waitForIdleSync(); + + assertThat(director.getModeSwitchingType()).isEqualTo(newModeSwitchingType); + } + + @Test public void testDefaultDisplayModeIsSelectedIfAvailable() { final float[] refreshRates = new float[]{24f, 25f, 30f, 60f, 90f}; final int defaultModeId = 3; @@ -1883,6 +1898,62 @@ public class DisplayModeDirectorTest { } @Test + public void testPeakRefreshRate_UserSwitch() { + when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled()) + .thenReturn(true); + DisplayModeDirector director = + new DisplayModeDirector(mContext, mHandler, mInjector, + mDisplayManagerFlags, mDisplayDeviceConfigProvider); + director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON); + + Display.Mode[] modes1 = new Display.Mode[] { + new Display.Mode(/* modeId= */ 1, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 60), + new Display.Mode(/* modeId= */ 2, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 130), + }; + Display.Mode[] modes2 = new Display.Mode[] { + new Display.Mode(/* modeId= */ 1, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 60), + new Display.Mode(/* modeId= */ 2, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 140), + }; + SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>(); + supportedModesByDisplay.put(DISPLAY_ID, modes1); + supportedModesByDisplay.put(DISPLAY_ID_2, modes2); + + Sensor lightSensor = createLightSensor(); + SensorManager sensorManager = createMockSensorManager(lightSensor); + director.start(sensorManager); + director.injectSupportedModesByDisplay(supportedModesByDisplay); + + // Disable Smooth Display + setPeakRefreshRate(RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE); + + Vote vote1 = director.getVote(DISPLAY_ID, + Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE); + Vote vote2 = director.getVote(DISPLAY_ID_2, + Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE); + assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ 0, + /* frameRateHigh= */ RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE); + assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ 0, + /* frameRateHigh= */ RefreshRateSettingsUtils.DEFAULT_REFRESH_RATE); + + // Switch user to one that has Smooth Display Enabled + Settings.System.putFloat(mContext.getContentResolver(), Settings.System.PEAK_REFRESH_RATE, + Float.POSITIVE_INFINITY); + director.onSwitchUser(); + waitForIdleSync(); + + vote1 = director.getVote(DISPLAY_ID, + Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE); + vote2 = director.getVote(DISPLAY_ID_2, + Vote.PRIORITY_USER_SETTING_PEAK_RENDER_FRAME_RATE); + assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ 0, /* frameRateHigh= */ 130); + assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ 0, /* frameRateHigh= */ 140); + } + + @Test @Parameters({ "true, true, 60", "false, true, 50", @@ -2036,6 +2107,62 @@ public class DisplayModeDirectorTest { } @Test + public void testMinRefreshRate_UserSwitch() { + when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled()) + .thenReturn(true); + DisplayModeDirector director = + new DisplayModeDirector(mContext, mHandler, mInjector, + mDisplayManagerFlags, mDisplayDeviceConfigProvider); + director.getBrightnessObserver().setDefaultDisplayState(Display.STATE_ON); + + Display.Mode[] modes1 = new Display.Mode[] { + new Display.Mode(/* modeId= */ 1, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 60), + new Display.Mode(/* modeId= */ 2, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 130), + }; + Display.Mode[] modes2 = new Display.Mode[] { + new Display.Mode(/* modeId= */ 1, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 60), + new Display.Mode(/* modeId= */ 2, /* width= */ 1280, /* height= */ 720, + /* refreshRate= */ 140), + }; + SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>(); + supportedModesByDisplay.put(DISPLAY_ID, modes1); + supportedModesByDisplay.put(DISPLAY_ID_2, modes2); + + Sensor lightSensor = createLightSensor(); + SensorManager sensorManager = createMockSensorManager(lightSensor); + director.start(sensorManager); + director.injectSupportedModesByDisplay(supportedModesByDisplay); + + // Disable Force Peak Refresh Rate + setMinRefreshRate(0); + + Vote vote1 = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE); + Vote vote2 = director.getVote(DISPLAY_ID_2, + Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE); + assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ 0, + /* frameRateHigh= */ Float.POSITIVE_INFINITY); + assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ 0, + /* frameRateHigh= */ Float.POSITIVE_INFINITY); + + // Switch user to one that has Force Peak Refresh Rate enabled + Settings.System.putFloat(mContext.getContentResolver(), Settings.System.MIN_REFRESH_RATE, + Float.POSITIVE_INFINITY); + director.onSwitchUser(); + waitForIdleSync(); + + vote1 = director.getVote(DISPLAY_ID, Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE); + vote2 = director.getVote(DISPLAY_ID_2, + Vote.PRIORITY_USER_SETTING_MIN_RENDER_FRAME_RATE); + assertVoteForRenderFrameRateRange(vote1, /* frameRateLow= */ 130, + /* frameRateHigh= */ Float.POSITIVE_INFINITY); + assertVoteForRenderFrameRateRange(vote2, /* frameRateLow= */ 140, + /* frameRateHigh= */ Float.POSITIVE_INFINITY); + } + + @Test public void testPeakAndMinRefreshRate_FlagEnabled_DisplayWithOneMode() { when(mDisplayManagerFlags.isBackUpSmoothDisplayAndForcePeakRefreshRateEnabled()) .thenReturn(true); |