summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java44
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController2.java44
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java206
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java202
4 files changed, 436 insertions, 60 deletions
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 40c879a3c5e7..d4877eb4973d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1193,17 +1193,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
loadScreenOffBrightnessSensor();
int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
- // TODO (b/265793751): Don't instantiate ScreenOffBrightnessSensorController if this is
- // a complementary display
if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
- mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
- mSensorManager,
- mScreenOffBrightnessSensor,
- mHandler,
- SystemClock::uptimeMillis,
- sensorValueToLux,
- mInteractiveModeBrightnessMapper
- );
+ mScreenOffBrightnessSensorController =
+ mInjector.getScreenOffBrightnessSensorController(
+ mSensorManager,
+ mScreenOffBrightnessSensor,
+ mHandler,
+ SystemClock::uptimeMillis,
+ sensorValueToLux,
+ mInteractiveModeBrightnessMapper);
}
} else {
mUseSoftwareAutoBrightnessConfig = false;
@@ -1395,8 +1393,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
- && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
- && !mAllowAutoBrightnessWhileDozingConfig)));
+ && mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
+ && !mAllowAutoBrightnessWhileDozingConfig))
+ && mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
}
boolean skipRampBecauseOfProximityChangeToNegative = false;
@@ -2544,11 +2543,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
- mHandler.post(() -> {
+ mHandler.postAtTime(() -> {
mUseAutoBrightness = screenBrightnessModeSetting
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
updatePowerState();
- });
+ }, mClock.uptimeMillis());
}
private float getAutoBrightnessAdjustmentSetting() {
@@ -3446,6 +3445,23 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
potentialOldBrightnessRange);
}
+
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager,
+ Sensor lightSensor,
+ Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock,
+ int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return new ScreenOffBrightnessSensorController(
+ sensorManager,
+ lightSensor,
+ handler,
+ clock,
+ sensorValueToLux,
+ brightnessMapper
+ );
+ }
}
static class CachedBrightnessInfo {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 5ea8aaa5e814..a92877796a8a 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -1030,17 +1030,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
loadScreenOffBrightnessSensor();
int[] sensorValueToLux = mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux();
- // TODO (b/265793751): Don't instantiate ScreenOffBrightnessSensorController if this is
- // a complementary display
if (mScreenOffBrightnessSensor != null && sensorValueToLux != null) {
- mScreenOffBrightnessSensorController = new ScreenOffBrightnessSensorController(
- mSensorManager,
- mScreenOffBrightnessSensor,
- mHandler,
- SystemClock::uptimeMillis,
- sensorValueToLux,
- mInteractiveModeBrightnessMapper
- );
+ mScreenOffBrightnessSensorController =
+ mInjector.getScreenOffBrightnessSensorController(
+ mSensorManager,
+ mScreenOffBrightnessSensor,
+ mHandler,
+ SystemClock::uptimeMillis,
+ sensorValueToLux,
+ mInteractiveModeBrightnessMapper);
}
} else {
mUseSoftwareAutoBrightnessConfig = false;
@@ -1189,8 +1187,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
if (mScreenOffBrightnessSensorController != null) {
mScreenOffBrightnessSensorController.setLightSensorEnabled(mUseAutoBrightness
- && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
- && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig())));
+ && mIsEnabled && (state == Display.STATE_OFF || (state == Display.STATE_DOZE
+ && !mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig()))
+ && mLeadDisplayId == Layout.NO_LEAD_DISPLAY);
}
// Initialize things the first time the power state is changed.
@@ -2150,11 +2149,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
- mHandler.post(() -> {
+ mHandler.postAtTime(() -> {
mUseAutoBrightness = screenBrightnessModeSetting
== Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
updatePowerState();
- });
+ }, mClock.uptimeMillis());
}
private float getAutoBrightnessAdjustmentSetting() {
@@ -2924,6 +2923,23 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal
darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
potentialOldBrightnessRange);
}
+
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager,
+ Sensor lightSensor,
+ Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock,
+ int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return new ScreenOffBrightnessSensorController(
+ sensorManager,
+ lightSensor,
+ handler,
+ clock,
+ sensorValueToLux,
+ brightnessMapper
+ );
+ }
}
static class CachedBrightnessInfo {
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index b9f2059c0799..96b63455598d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -26,12 +26,15 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
@@ -44,7 +47,9 @@ import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.provider.Settings;
import android.util.FloatProperty;
import android.view.Display;
import android.view.DisplayInfo;
@@ -57,6 +62,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
+import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.color.ColorDisplayService;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import com.android.server.policy.WindowManagerPolicy;
@@ -122,6 +128,7 @@ public final class DisplayPowerController2Test {
.spyStatic(SystemProperties.class)
.spyStatic(LocalServices.class)
.spyStatic(BatteryStatsService.class)
+ .spyStatic(Settings.System.class)
.startMocking();
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mClock = new OffsettableClock.Stopped();
@@ -139,8 +146,7 @@ public final class DisplayPowerController2Test {
ColorDisplayService.ColorDisplayServiceInternal.class));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
- mProxSensor = setUpProxSensor();
-
+ setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
}
@@ -169,7 +175,7 @@ public final class DisplayPowerController2Test {
advanceTime(1);
// two times, one for unfinished business and one for proximity
- verify(mHolder.wakelockController).acquireWakelock(
+ verify(mHolder.wakelockController, times(2)).acquireWakelock(
WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS);
verify(mHolder.wakelockController).acquireWakelock(
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
@@ -177,7 +183,7 @@ public final class DisplayPowerController2Test {
mHolder.dpc.stop();
advanceTime(1);
// two times, one for unfinished business and one for proximity
- verify(mHolder.wakelockController).acquireWakelock(
+ verify(mHolder.wakelockController, times(2)).acquireWakelock(
WakelockController.WAKE_LOCK_UNFINISHED_BUSINESS);
verify(mHolder.wakelockController).acquireWakelock(
WakelockController.WAKE_LOCK_PROXIMITY_DEBOUNCE);
@@ -214,12 +220,13 @@ public final class DisplayPowerController2Test {
mTestLooper.dispatchAll();
}
- private Sensor setUpProxSensor() throws Exception {
- Sensor proxSensor = TestUtils.createSensor(
+ private void setUpSensors() throws Exception {
+ mProxSensor = TestUtils.createSensor(
Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY);
+ Sensor screenOffBrightnessSensor = TestUtils.createSensor(
+ Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
- .thenReturn(List.of(proxSensor));
- return proxSensor;
+ .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
}
private SensorEventListener getSensorEventListener(Sensor sensor) {
@@ -229,14 +236,15 @@ public final class DisplayPowerController2Test {
}
private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
- DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock) {
+ DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
+ boolean isEnabled) {
DisplayInfo info = new DisplayInfo();
DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
- when(logicalDisplayMock.isEnabledLocked()).thenReturn(true);
+ when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
@@ -253,7 +261,14 @@ public final class DisplayPowerController2Test {
when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
new DisplayDeviceConfig.SensorData());
when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData());
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_LIGHT;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
+ .thenReturn(new int[0]);
}
@Test
@@ -466,7 +481,7 @@ public final class DisplayPowerController2Test {
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1);
- verify(mHolder.displayPowerState).setScreenState(anyInt());
+ verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt());
mHolder = createDisplayPowerController(42, UNIQUE_ID);
@@ -479,8 +494,145 @@ public final class DisplayPowerController2Test {
verify(mHolder.displayPowerState).setScreenState(anyInt());
}
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsOff() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ when(mResourcesMock.getBoolean(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing))
+ .thenReturn(true);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_AutoBrightnessIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ false);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsOn() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsAFollower() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, /* leadDisplayId= */ 42);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
+ return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
+ }
+
+ private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
+ String uniqueId, boolean isEnabled) {
final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
final AutomaticBrightnessController automaticBrightnessController =
@@ -489,10 +641,12 @@ public final class DisplayPowerController2Test {
final BrightnessMappingStrategy brightnessMappingStrategy =
mock(BrightnessMappingStrategy.class);
final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
+ final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
+ mock(ScreenOffBrightnessSensorController.class);
TestInjector injector = new TestInjector(displayPowerState, animator,
automaticBrightnessController, wakelockController, brightnessMappingStrategy,
- hysteresisLevels);
+ hysteresisLevels, screenOffBrightnessSensorController);
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -500,7 +654,7 @@ public final class DisplayPowerController2Test {
final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
- setUpDisplay(displayId, uniqueId, display, device, config);
+ setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
final DisplayPowerController2 dpc = new DisplayPowerController2(
mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler,
@@ -509,7 +663,8 @@ public final class DisplayPowerController2Test {
hbmMetadata, /* bootCompleted= */ false);
return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator,
- automaticBrightnessController, wakelockController);
+ automaticBrightnessController, wakelockController,
+ screenOffBrightnessSensorController, hbmMetadata);
}
/**
@@ -523,18 +678,24 @@ public final class DisplayPowerController2Test {
public final DualRampAnimator<DisplayPowerState> animator;
public final AutomaticBrightnessController automaticBrightnessController;
public final WakelockController wakelockController;
+ public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
+ public final HighBrightnessModeMetadata hbmMetadata;
DisplayPowerControllerHolder(DisplayPowerController2 dpc,
DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
- WakelockController wakelockController) {
+ WakelockController wakelockController,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
+ HighBrightnessModeMetadata hbmMetadata) {
this.dpc = dpc;
this.displayPowerState = displayPowerState;
this.brightnessSetting = brightnessSetting;
this.animator = animator;
this.automaticBrightnessController = automaticBrightnessController;
this.wakelockController = wakelockController;
+ this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
+ this.hbmMetadata = hbmMetadata;
}
}
@@ -545,18 +706,21 @@ public final class DisplayPowerController2Test {
private final WakelockController mWakelockController;
private final BrightnessMappingStrategy mBrightnessMappingStrategy;
private final HysteresisLevels mHysteresisLevels;
+ private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
WakelockController wakelockController,
BrightnessMappingStrategy brightnessMappingStrategy,
- HysteresisLevels hysteresisLevels) {
+ HysteresisLevels hysteresisLevels,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController) {
mDisplayPowerState = dps;
mAnimator = animator;
mAutomaticBrightnessController = automaticBrightnessController;
mWakelockController = wakelockController;
mBrightnessMappingStrategy = brightnessMappingStrategy;
mHysteresisLevels = hysteresisLevels;
+ mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
}
@Override
@@ -636,5 +800,13 @@ public final class DisplayPowerController2Test {
float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
return mHysteresisLevels;
}
+
+ @Override
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager, Sensor lightSensor, Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return mScreenOffBrightnessSensorController;
+ }
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 1e9041c48e44..28319acc5f1b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -26,12 +26,15 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
@@ -44,7 +47,9 @@ import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.os.test.TestLooper;
+import android.provider.Settings;
import android.util.FloatProperty;
import android.view.Display;
import android.view.DisplayInfo;
@@ -57,6 +62,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
+import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.color.ColorDisplayService;
import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import com.android.server.policy.WindowManagerPolicy;
@@ -122,6 +128,7 @@ public final class DisplayPowerControllerTest {
.spyStatic(SystemProperties.class)
.spyStatic(LocalServices.class)
.spyStatic(BatteryStatsService.class)
+ .spyStatic(Settings.System.class)
.startMocking();
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mClock = new OffsettableClock.Stopped();
@@ -140,8 +147,7 @@ public final class DisplayPowerControllerTest {
ColorDisplayService.ColorDisplayServiceInternal.class));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
- mProxSensor = setUpProxSensor();
-
+ setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
}
@@ -217,12 +223,13 @@ public final class DisplayPowerControllerTest {
mTestLooper.dispatchAll();
}
- private Sensor setUpProxSensor() throws Exception {
- Sensor proxSensor = TestUtils.createSensor(
+ private void setUpSensors() throws Exception {
+ mProxSensor = TestUtils.createSensor(
Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY);
+ Sensor screenOffBrightnessSensor = TestUtils.createSensor(
+ Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
- .thenReturn(List.of(proxSensor));
- return proxSensor;
+ .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
}
private SensorEventListener getSensorEventListener(Sensor sensor) {
@@ -232,14 +239,15 @@ public final class DisplayPowerControllerTest {
}
private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
- DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock) {
+ DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
+ boolean isEnabled) {
DisplayInfo info = new DisplayInfo();
DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
- when(logicalDisplayMock.isEnabledLocked()).thenReturn(true);
+ when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
@@ -256,7 +264,14 @@ public final class DisplayPowerControllerTest {
when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
new DisplayDeviceConfig.SensorData());
when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData());
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_LIGHT;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
+ .thenReturn(new int[0]);
}
@Test
@@ -470,7 +485,7 @@ public final class DisplayPowerControllerTest {
DisplayPowerRequest dpr = new DisplayPowerRequest();
mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
advanceTime(1);
- verify(mHolder.displayPowerState).setScreenState(anyInt());
+ verify(mHolder.displayPowerState, times(2)).setScreenState(anyInt());
mHolder = createDisplayPowerController(42, UNIQUE_ID);
@@ -483,8 +498,145 @@ public final class DisplayPowerControllerTest {
verify(mHolder.displayPowerState).setScreenState(anyInt());
}
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsOff() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorEnabled_DisplayIsInDoze() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ when(mResourcesMock.getBoolean(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing))
+ .thenReturn(true);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(true);
+
+ // The display turns on and we use the brightness value recommended by
+ // ScreenOffBrightnessSensorController
+ clearInvocations(mHolder.screenOffBrightnessSensorController);
+ float brightness = 0.14f;
+ when(mHolder.screenOffBrightnessSensorController.getAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .getAutomaticScreenBrightness();
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_AutoBrightnessIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsDisabled() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+ mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID, /* isEnabled= */ false);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsOn() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
+ @Test
+ public void testSetScreenOffBrightnessSensorDisabled_DisplayIsAFollower() {
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+
+ mHolder.dpc.onDisplayChanged(mHolder.hbmMetadata, /* leadDisplayId= */ 42);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.screenOffBrightnessSensorController, atLeastOnce())
+ .setLightSensorEnabled(false);
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
+ return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
+ }
+
+ private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
+ String uniqueId, boolean isEnabled) {
final DisplayPowerState displayPowerState = mock(DisplayPowerState.class);
final DualRampAnimator<DisplayPowerState> animator = mock(DualRampAnimator.class);
final AutomaticBrightnessController automaticBrightnessController =
@@ -492,9 +644,12 @@ public final class DisplayPowerControllerTest {
final BrightnessMappingStrategy brightnessMappingStrategy =
mock(BrightnessMappingStrategy.class);
final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
+ final ScreenOffBrightnessSensorController screenOffBrightnessSensorController =
+ mock(ScreenOffBrightnessSensorController.class);
DisplayPowerController.Injector injector = new TestInjector(displayPowerState, animator,
- automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels);
+ automaticBrightnessController, brightnessMappingStrategy, hysteresisLevels,
+ screenOffBrightnessSensorController);
final LogicalDisplay display = mock(LogicalDisplay.class);
final DisplayDevice device = mock(DisplayDevice.class);
@@ -502,7 +657,7 @@ public final class DisplayPowerControllerTest {
final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
- setUpDisplay(displayId, uniqueId, display, device, config);
+ setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
final DisplayPowerController dpc = new DisplayPowerController(
mContextSpy, injector, mDisplayPowerCallbacksMock, mHandler,
@@ -511,7 +666,7 @@ public final class DisplayPowerControllerTest {
hbmMetadata, /* bootCompleted= */ false);
return new DisplayPowerControllerHolder(dpc, displayPowerState, brightnessSetting, animator,
- automaticBrightnessController);
+ automaticBrightnessController, screenOffBrightnessSensorController, hbmMetadata);
}
/**
@@ -524,16 +679,22 @@ public final class DisplayPowerControllerTest {
public final BrightnessSetting brightnessSetting;
public final DualRampAnimator<DisplayPowerState> animator;
public final AutomaticBrightnessController automaticBrightnessController;
+ public final ScreenOffBrightnessSensorController screenOffBrightnessSensorController;
+ public final HighBrightnessModeMetadata hbmMetadata;
DisplayPowerControllerHolder(DisplayPowerController dpc,
DisplayPowerState displayPowerState, BrightnessSetting brightnessSetting,
DualRampAnimator<DisplayPowerState> animator,
- AutomaticBrightnessController automaticBrightnessController) {
+ AutomaticBrightnessController automaticBrightnessController,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
+ HighBrightnessModeMetadata hbmMetadata) {
this.dpc = dpc;
this.displayPowerState = displayPowerState;
this.brightnessSetting = brightnessSetting;
this.animator = animator;
this.automaticBrightnessController = automaticBrightnessController;
+ this.screenOffBrightnessSensorController = screenOffBrightnessSensorController;
+ this.hbmMetadata = hbmMetadata;
}
}
@@ -543,16 +704,19 @@ public final class DisplayPowerControllerTest {
private final AutomaticBrightnessController mAutomaticBrightnessController;
private final BrightnessMappingStrategy mBrightnessMappingStrategy;
private final HysteresisLevels mHysteresisLevels;
+ private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
TestInjector(DisplayPowerState dps, DualRampAnimator<DisplayPowerState> animator,
AutomaticBrightnessController automaticBrightnessController,
BrightnessMappingStrategy brightnessMappingStrategy,
- HysteresisLevels hysteresisLevels) {
+ HysteresisLevels hysteresisLevels,
+ ScreenOffBrightnessSensorController screenOffBrightnessSensorController) {
mDisplayPowerState = dps;
mAnimator = animator;
mAutomaticBrightnessController = automaticBrightnessController;
mBrightnessMappingStrategy = brightnessMappingStrategy;
mHysteresisLevels = hysteresisLevels;
+ mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
}
@Override
@@ -616,5 +780,13 @@ public final class DisplayPowerControllerTest {
float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
return mHysteresisLevels;
}
+
+ @Override
+ ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
+ SensorManager sensorManager, Sensor lightSensor, Handler handler,
+ ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux,
+ BrightnessMappingStrategy brightnessMapper) {
+ return mScreenOffBrightnessSensorController;
+ }
}
}