diff options
| author | 2023-08-22 21:46:38 -0400 | |
|---|---|---|
| committer | 2023-08-22 21:51:44 -0400 | |
| commit | 7bbb49fb62fa62f8e15fb6476904952f2024e51b (patch) | |
| tree | f9e1c5a9588d7911e144fc6015361c1c7c67a041 | |
| parent | af3eb24f8e68617e7a4686edd6201fea1b0fe59d (diff) | |
Fix that changes in desiredHdrSdrRatio doesn't update brightness
When onHdrInfoChanged is received from SF and the resulting
maxDesiredHdrSdrRatio changes ensure that the hbmChanged
callback is invoked even though the high-level mode did not
otherwise change. Otherwise the display brightness does not
react to the change, and so changes in the desired HDR headroom
does not result in changes to the actual display brightness.
Bug: 234181960
Test: HighBrightnessModeControllerTest#testHdrRespectsChangingDesiredHdrSdrRatio
Change-Id: I41f8062781493a73d4f1752c6c88d38dfad74909
2 files changed, 55 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java index c04c2793b3c5..39172b8252ed 100644 --- a/services/core/java/com/android/server/display/HighBrightnessModeController.java +++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java @@ -25,6 +25,7 @@ import android.os.Handler;  import android.os.IBinder;  import android.os.PowerManager;  import android.os.SystemClock; +import android.os.Trace;  import android.os.UserHandle;  import android.provider.Settings;  import android.util.MathUtils; @@ -33,6 +34,7 @@ import android.util.TimeUtils;  import android.view.SurfaceControlHdrLayerInfoListener;  import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.display.BrightnessSynchronizer;  import com.android.internal.util.FrameworkStatsLog;  import com.android.server.display.DisplayDeviceConfig.HighBrightnessModeData;  import com.android.server.display.DisplayManagerService.Clock; @@ -99,6 +101,7 @@ class HighBrightnessModeController {      private boolean mIsHdrLayerPresent = false;      // mMaxDesiredHdrSdrRatio should only be applied when there is a valid backlight->nits mapping      private float mMaxDesiredHdrSdrRatio = DEFAULT_MAX_DESIRED_HDR_SDR_RATIO; +    private boolean mForceHbmChangeCallback = false;      private boolean mIsBlockedByLowPowerMode = false;      private int mWidth;      private int mHeight; @@ -484,7 +487,8 @@ class HighBrightnessModeController {      private void updateHbmMode() {          int newHbmMode = calculateHighBrightnessMode();          updateHbmStats(newHbmMode); -        if (mHbmMode != newHbmMode) { +        if (mHbmMode != newHbmMode || mForceHbmChangeCallback) { +            mForceHbmChangeCallback = false;              mHbmMode = newHbmMode;              mHbmChangeCallback.run();          } @@ -600,26 +604,32 @@ class HighBrightnessModeController {          public void onHdrInfoChanged(IBinder displayToken, int numberOfHdrLayers,                  int maxW, int maxH, int flags, float maxDesiredHdrSdrRatio) {              mHandler.post(() -> { +                Trace.traceBegin(Trace.TRACE_TAG_POWER, "HBMController#onHdrInfoChanged");                  mIsHdrLayerPresent = numberOfHdrLayers > 0                          && (float) (maxW * maxH) >= ((float) (mWidth * mHeight)                                     * mHbmData.minimumHdrPercentOfScreen); -                final float candidateDesiredHdrSdrRatio = +                float candidateDesiredHdrSdrRatio =                          mIsHdrLayerPresent && mHdrBrightnessCfg != null                                  ? maxDesiredHdrSdrRatio                                  : DEFAULT_MAX_DESIRED_HDR_SDR_RATIO; -                if (candidateDesiredHdrSdrRatio >= 1.0f) { -                    mMaxDesiredHdrSdrRatio = candidateDesiredHdrSdrRatio; -                } else { +                if (candidateDesiredHdrSdrRatio < 1.0f) {                      Slog.w(TAG, "Ignoring invalid desired HDR/SDR Ratio: "                              + candidateDesiredHdrSdrRatio); -                    mMaxDesiredHdrSdrRatio = DEFAULT_MAX_DESIRED_HDR_SDR_RATIO; +                    candidateDesiredHdrSdrRatio = DEFAULT_MAX_DESIRED_HDR_SDR_RATIO; +                } + +                if (!BrightnessSynchronizer.floatEquals( +                        mMaxDesiredHdrSdrRatio, candidateDesiredHdrSdrRatio)) { +                    mForceHbmChangeCallback = true; +                    mMaxDesiredHdrSdrRatio = candidateDesiredHdrSdrRatio;                  }                  // Calling the brightness update so that we can recalculate                  // brightness with HDR in mind.                  onBrightnessChanged(mBrightness, mUnthrottledBrightness, mThrottlingReason); +                Trace.traceEnd(Trace.TRACE_TAG_POWER);              });          }      } diff --git a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java index 76e6ec7f6780..8e01a11cb23f 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java @@ -32,8 +32,10 @@ import static org.junit.Assert.assertTrue;  import static org.mockito.Mockito.anyFloat;  import static org.mockito.Mockito.anyInt;  import static org.mockito.Mockito.eq; +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.verify;  import static org.mockito.Mockito.when; @@ -390,6 +392,35 @@ public class HighBrightnessModeControllerTest {          assertEquals(Float.POSITIVE_INFINITY, hbmc.getHdrBrightnessValue(), 0.0);      } +    @Test +    public void testHdrRespectsChangingDesiredHdrSdrRatio() { +        final Runnable hbmChangedCallback = mock(Runnable.class); +        final HighBrightnessModeController hbmc = new TestHbmBuilder() +                .setClock(new OffsettableClock()) +                .setHdrBrightnessConfig(mHdrBrightnessDeviceConfigMock) +                .setHbmChangedCallback(hbmChangedCallback) +                .build(); + +        // Passthrough return the max desired hdr/sdr ratio +        when(mHdrBrightnessDeviceConfigMock.getHdrBrightnessFromSdr(anyFloat(), anyFloat())) +                .thenAnswer(i -> i.getArgument(1)); + +        hbmc.getHdrListener().onHdrInfoChanged(null /*displayToken*/, 1 /*numberOfHdrLayers*/, +                DISPLAY_WIDTH, DISPLAY_HEIGHT, 0 /*flags*/, 2.0f /*maxDesiredHdrSdrRatio*/); +        advanceTime(0); +        assertEquals(2.0f, hbmc.getHdrBrightnessValue(), EPSILON); +        verify(hbmChangedCallback, times(1)).run(); + +        // Verify that a change in only the desired hdrSdrRatio still results in the changed +        // callback being invoked +        hbmc.getHdrListener().onHdrInfoChanged(null /*displayToken*/, 1 /*numberOfHdrLayers*/, +                DISPLAY_WIDTH, DISPLAY_HEIGHT, 0 /*flags*/, +                3.0f /*maxDesiredHdrSdrRatio*/); +        advanceTime(0); +        assertEquals(3.0f, hbmc.getHdrBrightnessValue(), 0.0); +        verify(hbmChangedCallback, times(2)).run(); +    } +      @Test      public void testHdrTrumpsSunlight() { @@ -698,6 +729,7 @@ public class HighBrightnessModeControllerTest {      private class TestHbmBuilder {          OffsettableClock mClock;          HighBrightnessModeController.HdrBrightnessDeviceConfig mHdrBrightnessCfg; +        Runnable mHdrChangedCallback = () -> {};          TestHbmBuilder setClock(OffsettableClock clock) {              mClock = clock; @@ -711,6 +743,11 @@ public class HighBrightnessModeControllerTest {              return this;          } +        TestHbmBuilder setHbmChangedCallback(Runnable runnable) { +            mHdrChangedCallback = runnable; +            return this; +        } +          HighBrightnessModeController build() {              initHandler(mClock);              if (mHighBrightnessModeMetadata == null) { @@ -718,8 +755,8 @@ public class HighBrightnessModeControllerTest {              }              return new HighBrightnessModeController(mInjectorMock, mHandler, DISPLAY_WIDTH,                      DISPLAY_HEIGHT, mDisplayToken, mDisplayUniqueId, DEFAULT_MIN, DEFAULT_MAX, -                    DEFAULT_HBM_DATA, mHdrBrightnessCfg, () -> {}, mHighBrightnessModeMetadata, -                    mContextSpy); +                    DEFAULT_HBM_DATA, mHdrBrightnessCfg, mHdrChangedCallback, +                    mHighBrightnessModeMetadata, mContextSpy);          }      }  |