summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author John Reck <jreck@google.com> 2023-08-22 21:46:38 -0400
committer John Reck <jreck@google.com> 2023-08-22 21:51:44 -0400
commit7bbb49fb62fa62f8e15fb6476904952f2024e51b (patch)
treef9e1c5a9588d7911e144fc6015361c1c7c67a041
parentaf3eb24f8e68617e7a4686edd6201fea1b0fe59d (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
-rw-r--r--services/core/java/com/android/server/display/HighBrightnessModeController.java22
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/HighBrightnessModeControllerTest.java41
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);
}
}