Loading services/core/java/com/android/server/display/HighBrightnessModeController.java +16 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); } Loading Loading @@ -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); }); } } Loading services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java +39 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -698,6 +729,7 @@ public class HighBrightnessModeControllerTest { private class TestHbmBuilder { OffsettableClock mClock; HighBrightnessModeController.HdrBrightnessDeviceConfig mHdrBrightnessCfg; Runnable mHdrChangedCallback = () -> {}; TestHbmBuilder setClock(OffsettableClock clock) { mClock = clock; Loading @@ -711,6 +743,11 @@ public class HighBrightnessModeControllerTest { return this; } TestHbmBuilder setHbmChangedCallback(Runnable runnable) { mHdrChangedCallback = runnable; return this; } HighBrightnessModeController build() { initHandler(mClock); if (mHighBrightnessModeMetadata == null) { Loading @@ -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); } } Loading Loading
services/core/java/com/android/server/display/HighBrightnessModeController.java +16 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); } Loading Loading @@ -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); }); } } Loading
services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java +39 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -698,6 +729,7 @@ public class HighBrightnessModeControllerTest { private class TestHbmBuilder { OffsettableClock mClock; HighBrightnessModeController.HdrBrightnessDeviceConfig mHdrBrightnessCfg; Runnable mHdrChangedCallback = () -> {}; TestHbmBuilder setClock(OffsettableClock clock) { mClock = clock; Loading @@ -711,6 +743,11 @@ public class HighBrightnessModeControllerTest { return this; } TestHbmBuilder setHbmChangedCallback(Runnable runnable) { mHdrChangedCallback = runnable; return this; } HighBrightnessModeController build() { initHandler(mClock); if (mHighBrightnessModeMetadata == null) { Loading @@ -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); } } Loading