diff options
4 files changed, 188 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 25f3237e9b8b..320684fe3a0f 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -1922,8 +1922,25 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call if (isValidBrightnessValue(animateValue) && (animateValue != currentBrightness || sdrAnimateValue != currentSdrBrightness)) { - if (initialRampSkip || hasBrightnessBuckets - || !isDisplayContentVisible || brightnessIsTemporary) { + boolean skipAnimation = initialRampSkip || hasBrightnessBuckets + || !isDisplayContentVisible || brightnessIsTemporary; + if (!skipAnimation && BrightnessSynchronizer.floatEquals( + sdrAnimateValue, currentSdrBrightness)) { + // Going from HDR to no HDR; visually this should be a "no-op" anyway + // as the remaining SDR content's brightness should be holding steady + // due to the sdr brightness not shifting + if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, animateValue)) { + skipAnimation = true; + } + + // Going from no HDR to HDR; visually this is a significant scene change + // and the animation just prevents advanced clients from doing their own + // handling of enter/exit animations if they would like to do such a thing + if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, currentBrightness)) { + skipAnimation = true; + } + } + if (skipAnimation) { animateScreenBrightness(animateValue, sdrAnimateValue, SCREEN_ANIMATION_RATE_MINIMUM); } else { diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 595abfd81c23..597738e8b293 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -1524,8 +1524,25 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal if (BrightnessUtils.isValidBrightnessValue(animateValue) && (animateValue != currentBrightness || sdrAnimateValue != currentSdrBrightness)) { - if (initialRampSkip || hasBrightnessBuckets - || !isDisplayContentVisible || brightnessIsTemporary) { + boolean skipAnimation = initialRampSkip || hasBrightnessBuckets + || !isDisplayContentVisible || brightnessIsTemporary; + if (!skipAnimation && BrightnessSynchronizer.floatEquals( + sdrAnimateValue, currentSdrBrightness)) { + // Going from HDR to no HDR; visually this should be a "no-op" anyway + // as the remaining SDR content's brightness should be holding steady + // due to the sdr brightness not shifting + if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, animateValue)) { + skipAnimation = true; + } + + // Going from no HDR to HDR; visually this is a significant scene change + // and the animation just prevents advanced clients from doing their own + // handling of enter/exit animations if they would like to do such a thing + if (BrightnessSynchronizer.floatEquals(sdrAnimateValue, currentBrightness)) { + skipAnimation = true; + } + } + if (skipAnimation) { animateScreenBrightness(animateValue, sdrAnimateValue, SCREEN_ANIMATION_RATE_MINIMUM); } else if (customTransitionRate > 0) { diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java index 9722426667db..89e28cb8ab83 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java @@ -100,6 +100,7 @@ public final class DisplayPowerController2Test { private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1; private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789"; private static final float PROX_SENSOR_MAX_RANGE = 5; + private static final float BRIGHTNESS_RAMP_RATE_MINIMUM = 0.0f; private static final float BRIGHTNESS_RAMP_RATE_FAST_DECREASE = 0.3f; private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f; @@ -698,6 +699,80 @@ public final class DisplayPowerController2Test { } @Test + public void testDisplayBrightnessHdr_SkipAnimationOnHdrAppearance() { + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + final float sdrBrightness = 0.1f; + final float hdrBrightness = 0.3f; + when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); + when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(sdrBrightness); + when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(1.0f); + + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(sdrBrightness); + when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); + + when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( + BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); + when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness); + clearInvocations(mHolder.animator); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + } + + @Test + public void testDisplayBrightnessHdr_SkipAnimationOnHdrRemoval() { + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + final float sdrBrightness = 0.1f; + final float hdrBrightness = 0.3f; + when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); + when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.automaticBrightnessController.isInIdleMode()).thenReturn(true); + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(sdrBrightness); + when(mHolder.hdrClamper.getMaxBrightness()).thenReturn(1.0f); + + when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( + BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); + when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness); + + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(hdrBrightness); + when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); + when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( + BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF); + + clearInvocations(mHolder.animator); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + } + + @Test public void testDoesNotSetScreenStateForNonDefaultDisplayUntilBootCompleted() { // We should still set screen state for the default display DisplayPowerRequest dpr = new DisplayPowerRequest(); @@ -1185,6 +1260,8 @@ public final class DisplayPowerController2Test { DisplayPowerRequest dpr = new DisplayPowerRequest(); when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(.2f); + when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(.1f); when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(PowerManager.BRIGHTNESS_MAX); diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java index 4a6665acf92b..971ece365f30 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -43,6 +43,7 @@ import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorEventListener; import android.hardware.SensorManager; +import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks; import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; import android.os.Handler; @@ -98,6 +99,7 @@ public final class DisplayPowerControllerTest { private static final int SECOND_FOLLOWER_DISPLAY_ID = FOLLOWER_DISPLAY_ID + 1; private static final String SECOND_FOLLOWER_UNIQUE_DISPLAY_ID = "unique_id_789"; private static final float PROX_SENSOR_MAX_RANGE = 5; + private static final float BRIGHTNESS_RAMP_RATE_MINIMUM = 0.0f; private static final float BRIGHTNESS_RAMP_RATE_FAST_DECREASE = 0.3f; private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f; @@ -1185,6 +1187,77 @@ public final class DisplayPowerControllerTest { verify(mHolder.displayPowerState, times(1)).stop(); } + @Test + public void testDisplayBrightnessHdr_SkipAnimationOnHdrAppearance() { + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + final float sdrBrightness = 0.1f; + final float hdrBrightness = 0.3f; + when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); + when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(sdrBrightness); + + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(sdrBrightness); + when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); + + when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( + BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); + when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness); + clearInvocations(mHolder.animator); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + } + + @Test + public void testDisplayBrightnessHdr_SkipAnimationOnHdrRemoval() { + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + final float sdrBrightness = 0.1f; + final float hdrBrightness = 0.3f; + when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); + when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(sdrBrightness); + + when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( + BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR); + when(mHolder.hbmController.getHdrBrightnessValue()).thenReturn(hdrBrightness); + + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(hdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(hdrBrightness); + when(mHolder.displayPowerState.getSdrScreenBrightness()).thenReturn(sdrBrightness); + when(mHolder.hbmController.getHighBrightnessMode()).thenReturn( + BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF); + + clearInvocations(mHolder.animator); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(sdrBrightness), eq(sdrBrightness), + eq(BRIGHTNESS_RAMP_RATE_MINIMUM)); + } + private void advanceTime(long timeMs) { mClock.fastForward(timeMs); mTestLooper.dispatchAll(); |