summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Piotr Wilczyński <wilczynskip@google.com> 2024-07-26 15:01:06 +0000
committer Piotr Wilczyński <wilczynskip@google.com> 2024-07-29 14:51:31 +0000
commitbfa91592f15623e60ff96f26a7bd41ba3c3aa89c (patch)
treeb9e8bb594dcda883041c8dd123088719fa0caa1c
parent038604323950c233eca3627353a32200ef3f74d9 (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
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java8
-rw-r--r--services/core/java/com/android/server/display/BrightnessMappingStrategy.java31
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java53
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java1
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java14
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java18
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java15
-rw-r--r--services/core/java/com/android/server/display/mode/DisplayModeDirector.java38
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java15
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt32
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java127
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);