From 2c26ea64bc74c7c75e3f65bd9e8cebd6494571d5 Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Mon, 4 Oct 2021 15:23:59 -0400 Subject: [PATCH] [DO NOT MERGE] Improve brightness handling during screen off timeout. - Align doze brightness logic with DisplayPowerController, so that the 'minimum dim amount' is taken into account by DozeScreenBrightness. - Clamp brightness to the now-correct dim value during the entire screen off animation, rather than sometimes transitioning to the sensor value. Apply the sensor brightness value on changing to the DOZE Display state, which happens after the screen off animation. Bug: 194972547 Test: at 0%, 45%, and 100% brightness, allow the screen to time out in bright and dark rooms, observe minimal brightness changes Change-Id: I528a944e04f8906cd8c7740eea97dd8fba7c3d3e --- .../systemui/doze/DozeScreenBrightness.java | 36 +++++++++++++++---- .../systemui/doze/DozeScreenState.java | 11 +++++- .../doze/DozeScreenBrightnessTest.java | 12 +++++-- .../systemui/doze/DozeScreenStateTest.java | 5 ++- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java index da7b389fbd36e..058f37a2ef389 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java @@ -36,6 +36,7 @@ import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.doze.dagger.WrappedService; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.util.sensors.AsyncSensorManager; import java.io.PrintWriter; @@ -55,6 +56,16 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi "com.android.systemui.doze.AOD_BRIGHTNESS"; protected static final String BRIGHTNESS_BUCKET = "brightness_bucket"; + /** + * Just before the screen times out from user inactivity, DisplayPowerController dims the screen + * brightness to the lower of {@link #mScreenBrightnessDim}, or the current brightness minus + * DisplayPowerController#SCREEN_DIM_MINIMUM_REDUCTION_FLOAT. + * + * This value is 0.04f * 255, which converts SCREEN_DIM_MINIMUM_REDUCTION_FLOAT to the integer + * brightness values used by doze. + */ + private static final int SCREEN_DIM_MINIMUM_REDUCTION_INT = 10; + private final Context mContext; private final DozeMachine.Service mDozeService; private final DozeHost mDozeHost; @@ -82,6 +93,8 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi */ private int mDebugBrightnessBucket = -1; + private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; + @Inject public DozeScreenBrightness(Context context, @WrappedService DozeMachine.Service service, AsyncSensorManager sensorManager, @@ -89,7 +102,8 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi AlwaysOnDisplayPolicy alwaysOnDisplayPolicy, WakefulnessLifecycle wakefulnessLifecycle, DozeParameters dozeParameters, - DockManager dockManager) { + DockManager dockManager, + UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) { mContext = context; mDozeService = service; mSensorManager = sensorManager; @@ -99,6 +113,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi mDozeHost = host; mHandler = handler; mDockManager = dockManager; + mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; mDefaultDozeBrightness = alwaysOnDisplayPolicy.defaultDozeBrightness; mScreenBrightnessDim = alwaysOnDisplayPolicy.dimBrightness; @@ -148,14 +163,15 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi } } - private void updateBrightnessAndReady(boolean force) { + public void updateBrightnessAndReady(boolean force) { if (force || mRegistered || mDebugBrightnessBucket != -1) { int sensorValue = mDebugBrightnessBucket == -1 ? mLastSensorValue : mDebugBrightnessBucket; int brightness = computeBrightness(sensorValue); boolean brightnessReady = brightness > 0; if (brightnessReady) { - mDozeService.setDozeScreenBrightness(clampToUserSetting(brightness)); + mDozeService.setDozeScreenBrightness( + clampToDimBrightnessForScreenOff(clampToUserSetting(brightness))); } int scrimOpacity = -1; @@ -207,13 +223,21 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi /** * Clamp the brightness to the dim brightness value used by PowerManagerService just before the * device times out and goes to sleep, if we are sleeping from a timeout. This ensures that we - * don't raise the brightness back to the user setting before playing the screen off animation. + * don't raise the brightness back to the user setting before or during the screen off + * animation. */ private int clampToDimBrightnessForScreenOff(int brightness) { - if (mDozeParameters.shouldControlUnlockedScreenOff() + if (mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying() && mWakefulnessLifecycle.getLastSleepReason() == PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) { - return Math.min(mScreenBrightnessDim, brightness); + return Math.max( + PowerManager.BRIGHTNESS_OFF, + // Use the lower of either the dim brightness, or the current brightness reduced + // by the minimum dim amount. This is the same logic used in + // DisplayPowerController#updatePowerState to apply a minimum dim amount. + Math.min( + brightness - SCREEN_DIM_MINIMUM_REDUCTION_INT, + mScreenBrightnessDim)); } else { return brightness; } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java index 8f1486b0c7cbb..038be48b53eeb 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java @@ -77,6 +77,7 @@ public class DozeScreenState implements DozeMachine.Part { private final Provider mUdfpsControllerProvider; @Nullable private UdfpsController mUdfpsController; private final DozeLog mDozeLog; + private final DozeScreenBrightness mDozeScreenBrightness; private int mPendingScreenState = Display.STATE_UNKNOWN; private SettableWakeLock mWakeLock; @@ -90,7 +91,8 @@ public class DozeScreenState implements DozeMachine.Part { WakeLock wakeLock, AuthController authController, Provider udfpsControllerProvider, - DozeLog dozeLog) { + DozeLog dozeLog, + DozeScreenBrightness dozeScreenBrightness) { mDozeService = service; mHandler = handler; mParameters = parameters; @@ -99,6 +101,7 @@ public class DozeScreenState implements DozeMachine.Part { mAuthController = authController; mUdfpsControllerProvider = udfpsControllerProvider; mDozeLog = dozeLog; + mDozeScreenBrightness = dozeScreenBrightness; updateUdfpsController(); if (mUdfpsController == null) { @@ -204,6 +207,12 @@ public class DozeScreenState implements DozeMachine.Part { if (screenState != Display.STATE_UNKNOWN) { if (DEBUG) Log.d(TAG, "setDozeScreenState(" + screenState + ")"); mDozeService.setDozeScreenState(screenState); + if (screenState == Display.STATE_DOZE) { + // If we're entering doze, update the doze screen brightness. We might have been + // clamping it to the dim brightness during the screen off animation, and we should + // now change it to the brightness we actually want according to the sensor. + mDozeScreenBrightness.updateBrightnessAndReady(false /* force */); + } mPendingScreenState = Display.STATE_UNKNOWN; mWakeLock.setAcquired(false); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java index e0520b406a0ae..1d00531af42cb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java @@ -51,6 +51,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.dock.DockManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.statusbar.phone.DozeParameters; +import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.FakeThreadFactory; import com.android.systemui.util.sensors.AsyncSensorManager; @@ -86,6 +87,8 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { DozeParameters mDozeParameters; @Mock DockManager mDockManager; + @Mock + private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); private FakeThreadFactory mFakeThreadFactory = new FakeThreadFactory(mFakeExecutor); @@ -113,7 +116,8 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { mSensor = fakeSensorManager.getFakeLightSensor(); mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager, Optional.of(mSensor.getSensor()), mDozeHost, null /* handler */, - mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager); + mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager, + mUnlockedScreenOffAnimationController); } @Test @@ -211,7 +215,8 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { public void testPulsing_withoutLightSensor_setsAoDDimmingScrimTransparent() throws Exception { mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager, Optional.empty() /* sensor */, mDozeHost, null /* handler */, - mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager); + mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager, + mUnlockedScreenOffAnimationController); mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE); reset(mDozeHost); @@ -240,7 +245,8 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { public void testNullSensor() throws Exception { mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager, Optional.empty() /* sensor */, mDozeHost, null /* handler */, - mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager); + mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager, + mUnlockedScreenOffAnimationController); mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(INITIALIZED, DOZE_AOD); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java index 150ab7700e4be..3e19cc436dca6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java @@ -82,6 +82,8 @@ public class DozeScreenStateTest extends SysuiTestCase { private UdfpsController mUdfpsController; @Mock private DozeLog mDozeLog; + @Mock + private DozeScreenBrightness mDozeScreenBrightness; @Before public void setUp() throws Exception { @@ -96,7 +98,8 @@ public class DozeScreenStateTest extends SysuiTestCase { mHandlerFake = new FakeHandler(Looper.getMainLooper()); mWakeLock = new WakeLockFake(); mScreen = new DozeScreenState(mServiceFake, mHandlerFake, mDozeHost, mDozeParameters, - mWakeLock, mAuthController, mUdfpsControllerProvider, mDozeLog); + mWakeLock, mAuthController, mUdfpsControllerProvider, mDozeLog, + mDozeScreenBrightness); } @Test