Loading services/core/java/com/android/server/display/DisplayDeviceConfig.java +1 −9 Original line number Diff line number Diff line Loading @@ -2396,7 +2396,6 @@ public class DisplayDeviceConfig { mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000; mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000; mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000; mHbmData.thermalStatusLimit = convertThermalStatus(hbm.getThermalStatusLimit_all()); mHbmData.allowInLowPowerMode = hbm.getAllowInLowPowerMode_all(); final RefreshRateRange rr = hbm.getRefreshRate_all(); if (rr != null) { Loading Loading @@ -2972,9 +2971,6 @@ public class DisplayDeviceConfig { /** Brightness level at which we transition from normal to high-brightness. */ public float transitionPoint; /** Enable HBM only if the thermal status is not higher than this. */ public @PowerManager.ThermalStatus int thermalStatusLimit; /** Whether HBM is allowed when {@code Settings.Global.LOW_POWER_MODE} is active. */ public boolean allowInLowPowerMode; Loading @@ -2993,15 +2989,13 @@ public class DisplayDeviceConfig { HighBrightnessModeData() {} HighBrightnessModeData(float minimumLux, float transitionPoint, long timeWindowMillis, long timeMaxMillis, long timeMinMillis, @PowerManager.ThermalStatus int thermalStatusLimit, boolean allowInLowPowerMode, long timeMaxMillis, long timeMinMillis, boolean allowInLowPowerMode, float minimumHdrPercentOfScreen) { this.minimumLux = minimumLux; this.transitionPoint = transitionPoint; this.timeWindowMillis = timeWindowMillis; this.timeMaxMillis = timeMaxMillis; this.timeMinMillis = timeMinMillis; this.thermalStatusLimit = thermalStatusLimit; this.allowInLowPowerMode = allowInLowPowerMode; this.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen; } Loading @@ -3016,7 +3010,6 @@ public class DisplayDeviceConfig { other.timeMaxMillis = timeMaxMillis; other.timeMinMillis = timeMinMillis; other.transitionPoint = transitionPoint; other.thermalStatusLimit = thermalStatusLimit; other.allowInLowPowerMode = allowInLowPowerMode; other.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen; } Loading @@ -3029,7 +3022,6 @@ public class DisplayDeviceConfig { + ", timeWindow: " + timeWindowMillis + "ms" + ", timeMax: " + timeMaxMillis + "ms" + ", timeMin: " + timeMinMillis + "ms" + ", thermalStatusLimit: " + thermalStatusLimit + ", allowInLowPowerMode: " + allowInLowPowerMode + ", minimumHdrPercentOfScreen: " + minimumHdrPercentOfScreen + "} "; Loading services/core/java/com/android/server/display/HighBrightnessModeController.java +12 −115 Original line number Diff line number Diff line Loading @@ -22,13 +22,8 @@ import android.hardware.display.BrightnessInfo; import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.Temperature; import android.os.UserHandle; import android.provider.Settings; import android.util.MathUtils; Loading Loading @@ -75,7 +70,6 @@ class HighBrightnessModeController { private final Runnable mHbmChangeCallback; private final Runnable mRecalcRunnable; private final Clock mClock; private final SkinThermalStatusObserver mSkinThermalStatusObserver; private final Context mContext; private final SettingsObserver mSettingsObserver; private final Injector mInjector; Loading @@ -100,10 +94,8 @@ class HighBrightnessModeController { private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; 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 mIsThermalStatusWithinLimit = true; private boolean mIsBlockedByLowPowerMode = false; private int mWidth; private int mHeight; Loading Loading @@ -138,7 +130,6 @@ class HighBrightnessModeController { mBrightnessMax = brightnessMax; mHbmChangeCallback = hbmChangeCallback; mHighBrightnessModeMetadata = hbmMetadata; mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler); mSettingsObserver = new SettingsObserver(mHandler); mRecalcRunnable = this::recalculateTimeAllowance; mHdrListener = new HdrListener(); Loading Loading @@ -261,7 +252,6 @@ class HighBrightnessModeController { void stop() { registerHdrListener(null /*displayToken*/); mSkinThermalStatusObserver.stopObserving(); mSettingsObserver.stopObserving(); } Loading @@ -278,15 +268,10 @@ class HighBrightnessModeController { mDisplayStatsId = displayUniqueId.hashCode(); unregisterHdrListener(); mSkinThermalStatusObserver.stopObserving(); mSettingsObserver.stopObserving(); if (deviceSupportsHbm()) { registerHdrListener(displayToken); recalculateTimeAllowance(); if (mHbmData.thermalStatusLimit > PowerManager.THERMAL_STATUS_NONE) { mIsThermalStatusWithinLimit = true; mSkinThermalStatusObserver.startObserving(); } if (!mHbmData.allowInLowPowerMode) { mIsBlockedByLowPowerMode = false; mSettingsObserver.startObserving(); Loading Loading @@ -327,7 +312,6 @@ class HighBrightnessModeController { pw.println(" mIsTimeAvailable= " + mIsTimeAvailable); pw.println(" mRunningStartTimeMillis=" + TimeUtils.formatUptime(mHighBrightnessModeMetadata.getRunningStartTimeMillis())); pw.println(" mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit); pw.println(" mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode); pw.println(" width*height=" + mWidth + "*" + mHeight); pw.println(" mEvents="); Loading @@ -344,8 +328,6 @@ class HighBrightnessModeController { } lastStartTime = dumpHbmEvent(pw, event); } mSkinThermalStatusObserver.dump(pw); } private long dumpHbmEvent(PrintWriter pw, HbmEvent event) { Loading @@ -367,7 +349,7 @@ class HighBrightnessModeController { // See {@link #getHdrBrightnessValue}. return !mIsHdrLayerPresent && (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange && mIsThermalStatusWithinLimit && !mIsBlockedByLowPowerMode); && !mIsBlockedByLowPowerMode); } private boolean deviceSupportsHbm() { Loading Loading @@ -469,7 +451,6 @@ class HighBrightnessModeController { + ", isAutoBrightnessEnabled: " + mIsAutoBrightnessEnabled + ", mIsTimeAvailable: " + mIsTimeAvailable + ", mIsInAllowedAmbientRange: " + mIsInAllowedAmbientRange + ", mIsThermalStatusWithinLimit: " + mIsThermalStatusWithinLimit + ", mIsBlockedByLowPowerMode: " + mIsBlockedByLowPowerMode + ", mBrightness: " + mBrightness + ", mUnthrottledBrightness: " + mUnthrottledBrightness Loading Loading @@ -499,13 +480,12 @@ class HighBrightnessModeController { } private void updateHbmStats(int newMode) { final float transitionPoint = mHbmData.transitionPoint; int state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF; if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR && getHdrBrightnessValue() > transitionPoint) { && getHdrBrightnessValue() > mHbmData.transitionPoint) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_HDR; } else if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT && mBrightness > transitionPoint) { && mBrightness > mHbmData.transitionPoint) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT; } if (state == mHbmStatsState) { Loading @@ -519,16 +499,6 @@ class HighBrightnessModeController { final boolean newHbmSv = (state == FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT); if (oldHbmSv && !newHbmSv) { // HighBrightnessModeController (HBMC) currently supports throttling from two sources: // 1. Internal, received from HBMC.SkinThermalStatusObserver.notifyThrottling() // 2. External, received from HBMC.onBrightnessChanged() // TODO(b/216373254): Deprecate internal throttling source final boolean internalThermalThrottling = !mIsThermalStatusWithinLimit; final boolean externalThermalThrottling = mUnthrottledBrightness > transitionPoint && // We would've liked HBM brightness... mBrightness <= transitionPoint && // ...but we got NBM, because of... mThrottlingReason == BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; // ...thermals. // If more than one conditions are flipped and turn off HBM sunlight // visibility, only one condition will be reported to make it simple. if (!mIsAutoBrightnessEnabled && mIsAutoBrightnessOffByState) { Loading @@ -541,7 +511,7 @@ class HighBrightnessModeController { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_LUX_DROP; } else if (!mIsTimeAvailable) { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_TIME_LIMIT; } else if (internalThermalThrottling || externalThermalThrottling) { } else if (isThermalThrottlingActive()) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT; } else if (mIsHdrLayerPresent) { Loading @@ -561,6 +531,14 @@ class HighBrightnessModeController { mHbmStatsState = state; } @VisibleForTesting boolean isThermalThrottlingActive() { // We would've liked HBM, but we got NBM (normal brightness mode) because of thermals. return mUnthrottledBrightness > mHbmData.transitionPoint && mBrightness <= mHbmData.transitionPoint && mThrottlingReason == BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; } private String hbmStatsStateToString(int hbmStatsState) { switch (hbmStatsState) { case FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF: Loading Loading @@ -635,82 +613,6 @@ class HighBrightnessModeController { } } private final class SkinThermalStatusObserver extends IThermalEventListener.Stub { private final Injector mInjector; private final Handler mHandler; private IThermalService mThermalService; private boolean mStarted; SkinThermalStatusObserver(Injector injector, Handler handler) { mInjector = injector; mHandler = handler; } @Override public void notifyThrottling(Temperature temp) { if (DEBUG) { Slog.d(TAG, "New thermal throttling status " + ", current thermal status = " + temp.getStatus() + ", threshold = " + mHbmData.thermalStatusLimit); } mHandler.post(() -> { mIsThermalStatusWithinLimit = temp.getStatus() <= mHbmData.thermalStatusLimit; // This recalculates HbmMode and runs mHbmChangeCallback if the mode has changed updateHbmMode(); }); } void startObserving() { if (mStarted) { if (DEBUG) { Slog.d(TAG, "Thermal status observer already started"); } return; } mThermalService = mInjector.getThermalService(); if (mThermalService == null) { Slog.w(TAG, "Could not observe thermal status. Service not available"); return; } try { // We get a callback immediately upon registering so there's no need to query // for the current value. mThermalService.registerThermalEventListenerWithType(this, Temperature.TYPE_SKIN); mStarted = true; } catch (RemoteException e) { Slog.e(TAG, "Failed to register thermal status listener", e); } } void stopObserving() { mIsThermalStatusWithinLimit = true; if (!mStarted) { if (DEBUG) { Slog.d(TAG, "Stop skipped because thermal status observer not started"); } return; } try { mThermalService.unregisterThermalEventListener(this); mStarted = false; } catch (RemoteException e) { Slog.e(TAG, "Failed to unregister thermal status listener", e); } mThermalService = null; } void dump(PrintWriter writer) { writer.println(" SkinThermalStatusObserver:"); writer.println(" mStarted: " + mStarted); if (mThermalService != null) { writer.println(" ThermalService available"); } else { writer.println(" ThermalService not available"); } } } private final class SettingsObserver extends ContentObserver { private final Uri mLowPowerModeSetting = Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE); Loading Loading @@ -766,11 +668,6 @@ class HighBrightnessModeController { return SystemClock::uptimeMillis; } public IThermalService getThermalService() { return IThermalService.Stub.asInterface( ServiceManager.getService(Context.THERMAL_SERVICE)); } public void reportHbmStateChange(int display, int state, int reason) { FrameworkStatsLog.write( FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED, display, state, reason); Loading services/core/xsd/display-device-config/display-device-config.xsd +0 −6 Original line number Diff line number Diff line Loading @@ -153,12 +153,6 @@ <xs:annotation name="nullable"/> <xs:annotation name="final"/> </xs:element> <!-- The highest (most severe) thermal status at which high-brightness-mode is allowed to operate. --> <xs:element name="thermalStatusLimit" type="thermalStatus" minOccurs="0" maxOccurs="1"> <xs:annotation name="nonnull"/> <xs:annotation name="final"/> </xs:element> <xs:element name="allowInLowPowerMode" type="xs:boolean" minOccurs="0" maxOccurs="1"> <xs:annotation name="nonnull"/> <xs:annotation name="final"/> Loading services/core/xsd/display-device-config/schema/current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -156,7 +156,6 @@ package com.android.server.display.config { method @NonNull public final java.math.BigDecimal getMinimumLux_all(); method @Nullable public final com.android.server.display.config.RefreshRateRange getRefreshRate_all(); method @Nullable public final com.android.server.display.config.SdrHdrRatioMap getSdrHdrRatioMap_all(); method @NonNull public final com.android.server.display.config.ThermalStatus getThermalStatusLimit_all(); method public com.android.server.display.config.HbmTiming getTiming_all(); method @NonNull public final java.math.BigDecimal getTransitionPoint_all(); method public final void setAllowInLowPowerMode_all(@NonNull boolean); Loading @@ -165,7 +164,6 @@ package com.android.server.display.config { method public final void setMinimumLux_all(@NonNull java.math.BigDecimal); method public final void setRefreshRate_all(@Nullable com.android.server.display.config.RefreshRateRange); method public final void setSdrHdrRatioMap_all(@Nullable com.android.server.display.config.SdrHdrRatioMap); method public final void setThermalStatusLimit_all(@NonNull com.android.server.display.config.ThermalStatus); method public void setTiming_all(com.android.server.display.config.HbmTiming); method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal); } Loading services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java +23 −81 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.server.display; import static android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; import static android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR; import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT; Loading @@ -29,6 +27,8 @@ import static com.android.server.display.DisplayDeviceConfig.HDR_PERCENT_OF_SCRE import static com.android.server.display.HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.anyFloat; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; Loading @@ -39,14 +39,10 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.ContextWrapper; import android.hardware.display.BrightnessInfo; import android.os.Binder; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.Message; import android.os.PowerManager; import android.os.Temperature; import android.os.Temperature.ThrottlingStatus; import android.os.test.TestLooper; import android.test.mock.MockContentResolver; import android.util.MathUtils; Loading @@ -66,8 +62,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading @@ -80,7 +74,6 @@ public class HighBrightnessModeControllerTest { private static final long TIME_WINDOW_MILLIS = 55 * 1000; private static final long TIME_ALLOWED_IN_WINDOW_MILLIS = 12 * 1000; private static final long TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS = 5 * 1000; private static final int THERMAL_STATUS_LIMIT = PowerManager.THERMAL_STATUS_SEVERE; private static final boolean ALLOW_IN_LOW_POWER_MODE = false; private static final float DEFAULT_MIN = 0.01f; Loading @@ -102,17 +95,13 @@ public class HighBrightnessModeControllerTest { @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule(); @Mock IThermalService mThermalServiceMock; @Mock Injector mInjectorMock; @Mock HighBrightnessModeController.HdrBrightnessDeviceConfig mHdrBrightnessDeviceConfigMock; @Captor ArgumentCaptor<IThermalEventListener> mThermalEventListenerCaptor; private static final HighBrightnessModeData DEFAULT_HBM_DATA = new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS, TIME_ALLOWED_IN_WINDOW_MILLIS, TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS, THERMAL_STATUS_LIMIT, ALLOW_IN_LOW_POWER_MODE, HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT); ALLOW_IN_LOW_POWER_MODE, HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT); @Before public void setUp() { Loading @@ -125,8 +114,6 @@ public class HighBrightnessModeControllerTest { mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy); when(mContextSpy.getContentResolver()).thenReturn(resolver); when(mInjectorMock.getThermalService()).thenReturn(mThermalServiceMock); } ///////////////// Loading Loading @@ -321,34 +308,14 @@ public class HighBrightnessModeControllerTest { } @Test public void testNoHbmInHighThermalState() throws Exception { public void testHbmIsNotTurnedOffInHighThermalState() throws Exception { final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock()); verify(mThermalServiceMock).registerThermalEventListenerWithType( mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener listener = mThermalEventListenerCaptor.getValue(); // Set the thermal status too high. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); // Try to go into HBM mode but fail hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); hbmc.onAmbientLuxChange(MINIMUM_LUX + 1); advanceTime(10); // Disabled thermal throttling hbmc.onBrightnessChanged(/*brightness=*/ 1f, /*unthrottledBrightness*/ 1f, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode()); } @Test public void testHbmTurnsOffInHighThermalState() throws Exception { final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock()); verify(mThermalServiceMock).registerThermalEventListenerWithType( mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener listener = mThermalEventListenerCaptor.getValue(); // Set the thermal status tolerable listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_LIGHT)); assertFalse(hbmc.isThermalThrottlingActive()); // Try to go into HBM mode hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); Loading @@ -357,15 +324,19 @@ public class HighBrightnessModeControllerTest { assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode()); // Set the thermal status too high and verify we're off. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); // Enable thermal throttling hbmc.onBrightnessChanged(/*brightness=*/ TRANSITION_POINT - 0.01f, /*unthrottledBrightness*/ 1f, BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL); advanceTime(10); assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode()); assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode()); assertTrue(hbmc.isThermalThrottlingActive()); // Set the thermal status low again and verify we're back on. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_SEVERE)); // Disabled thermal throttling hbmc.onBrightnessChanged(/*brightness=*/ 1f, /*unthrottledBrightness*/ 1f, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); advanceTime(1); assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode()); assertFalse(hbmc.isThermalThrottlingActive()); } @Test Loading Loading @@ -578,33 +549,6 @@ public class HighBrightnessModeControllerTest { anyInt()); } // Test reporting of thermal throttling when triggered by HighBrightnessModeController's // internal thermal throttling. @Test public void testHbmStats_InternalThermalOff() throws Exception { final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock()); final int displayStatsId = mDisplayUniqueId.hashCode(); verify(mThermalServiceMock).registerThermalEventListenerWithType( mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener thermListener = mThermalEventListenerCaptor.getValue(); hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); hbmc.onAmbientLuxChange(MINIMUM_LUX + 1); hbmcOnBrightnessChanged(hbmc, TRANSITION_POINT + 0.01f); advanceTime(1); verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN)); thermListener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); advanceTime(10); assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode()); verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT)); } // Test reporting of thermal throttling when triggered externally through // HighBrightnessModeController.onBrightnessChanged() @Test Loading @@ -617,14 +561,16 @@ public class HighBrightnessModeControllerTest { hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); hbmc.onAmbientLuxChange(MINIMUM_LUX + 1); // Brightness is unthrottled, HBM brightness granted hbmc.onBrightnessChanged(hbmBrightness, hbmBrightness, BRIGHTNESS_MAX_REASON_NONE); hbmc.onBrightnessChanged(hbmBrightness, hbmBrightness, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); advanceTime(1); verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN)); // Brightness is thermally throttled, HBM brightness denied (NBM brightness granted) hbmc.onBrightnessChanged(nbmBrightness, hbmBrightness, BRIGHTNESS_MAX_REASON_THERMAL); hbmc.onBrightnessChanged(nbmBrightness, hbmBrightness, BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL); advanceTime(1); // We expect HBM mode to remain set to sunlight, indicating that HBMC *allows* this mode. // However, we expect the HBM state reported by HBMC to be off, since external thermal Loading Loading @@ -784,11 +730,7 @@ public class HighBrightnessModeControllerTest { mTestLooper.dispatchAll(); } private Temperature getSkinTemp(@ThrottlingStatus int status) { return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status); } private void hbmcOnBrightnessChanged(HighBrightnessModeController hbmc, float brightness) { hbmc.onBrightnessChanged(brightness, brightness, BRIGHTNESS_MAX_REASON_NONE); hbmc.onBrightnessChanged(brightness, brightness, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); } } Loading
services/core/java/com/android/server/display/DisplayDeviceConfig.java +1 −9 Original line number Diff line number Diff line Loading @@ -2396,7 +2396,6 @@ public class DisplayDeviceConfig { mHbmData.timeWindowMillis = hbmTiming.getTimeWindowSecs_all().longValue() * 1000; mHbmData.timeMaxMillis = hbmTiming.getTimeMaxSecs_all().longValue() * 1000; mHbmData.timeMinMillis = hbmTiming.getTimeMinSecs_all().longValue() * 1000; mHbmData.thermalStatusLimit = convertThermalStatus(hbm.getThermalStatusLimit_all()); mHbmData.allowInLowPowerMode = hbm.getAllowInLowPowerMode_all(); final RefreshRateRange rr = hbm.getRefreshRate_all(); if (rr != null) { Loading Loading @@ -2972,9 +2971,6 @@ public class DisplayDeviceConfig { /** Brightness level at which we transition from normal to high-brightness. */ public float transitionPoint; /** Enable HBM only if the thermal status is not higher than this. */ public @PowerManager.ThermalStatus int thermalStatusLimit; /** Whether HBM is allowed when {@code Settings.Global.LOW_POWER_MODE} is active. */ public boolean allowInLowPowerMode; Loading @@ -2993,15 +2989,13 @@ public class DisplayDeviceConfig { HighBrightnessModeData() {} HighBrightnessModeData(float minimumLux, float transitionPoint, long timeWindowMillis, long timeMaxMillis, long timeMinMillis, @PowerManager.ThermalStatus int thermalStatusLimit, boolean allowInLowPowerMode, long timeMaxMillis, long timeMinMillis, boolean allowInLowPowerMode, float minimumHdrPercentOfScreen) { this.minimumLux = minimumLux; this.transitionPoint = transitionPoint; this.timeWindowMillis = timeWindowMillis; this.timeMaxMillis = timeMaxMillis; this.timeMinMillis = timeMinMillis; this.thermalStatusLimit = thermalStatusLimit; this.allowInLowPowerMode = allowInLowPowerMode; this.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen; } Loading @@ -3016,7 +3010,6 @@ public class DisplayDeviceConfig { other.timeMaxMillis = timeMaxMillis; other.timeMinMillis = timeMinMillis; other.transitionPoint = transitionPoint; other.thermalStatusLimit = thermalStatusLimit; other.allowInLowPowerMode = allowInLowPowerMode; other.minimumHdrPercentOfScreen = minimumHdrPercentOfScreen; } Loading @@ -3029,7 +3022,6 @@ public class DisplayDeviceConfig { + ", timeWindow: " + timeWindowMillis + "ms" + ", timeMax: " + timeMaxMillis + "ms" + ", timeMin: " + timeMinMillis + "ms" + ", thermalStatusLimit: " + thermalStatusLimit + ", allowInLowPowerMode: " + allowInLowPowerMode + ", minimumHdrPercentOfScreen: " + minimumHdrPercentOfScreen + "} "; Loading
services/core/java/com/android/server/display/HighBrightnessModeController.java +12 −115 Original line number Diff line number Diff line Loading @@ -22,13 +22,8 @@ import android.hardware.display.BrightnessInfo; import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.Temperature; import android.os.UserHandle; import android.provider.Settings; import android.util.MathUtils; Loading Loading @@ -75,7 +70,6 @@ class HighBrightnessModeController { private final Runnable mHbmChangeCallback; private final Runnable mRecalcRunnable; private final Clock mClock; private final SkinThermalStatusObserver mSkinThermalStatusObserver; private final Context mContext; private final SettingsObserver mSettingsObserver; private final Injector mInjector; Loading @@ -100,10 +94,8 @@ class HighBrightnessModeController { private int mHbmMode = BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; 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 mIsThermalStatusWithinLimit = true; private boolean mIsBlockedByLowPowerMode = false; private int mWidth; private int mHeight; Loading Loading @@ -138,7 +130,6 @@ class HighBrightnessModeController { mBrightnessMax = brightnessMax; mHbmChangeCallback = hbmChangeCallback; mHighBrightnessModeMetadata = hbmMetadata; mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler); mSettingsObserver = new SettingsObserver(mHandler); mRecalcRunnable = this::recalculateTimeAllowance; mHdrListener = new HdrListener(); Loading Loading @@ -261,7 +252,6 @@ class HighBrightnessModeController { void stop() { registerHdrListener(null /*displayToken*/); mSkinThermalStatusObserver.stopObserving(); mSettingsObserver.stopObserving(); } Loading @@ -278,15 +268,10 @@ class HighBrightnessModeController { mDisplayStatsId = displayUniqueId.hashCode(); unregisterHdrListener(); mSkinThermalStatusObserver.stopObserving(); mSettingsObserver.stopObserving(); if (deviceSupportsHbm()) { registerHdrListener(displayToken); recalculateTimeAllowance(); if (mHbmData.thermalStatusLimit > PowerManager.THERMAL_STATUS_NONE) { mIsThermalStatusWithinLimit = true; mSkinThermalStatusObserver.startObserving(); } if (!mHbmData.allowInLowPowerMode) { mIsBlockedByLowPowerMode = false; mSettingsObserver.startObserving(); Loading Loading @@ -327,7 +312,6 @@ class HighBrightnessModeController { pw.println(" mIsTimeAvailable= " + mIsTimeAvailable); pw.println(" mRunningStartTimeMillis=" + TimeUtils.formatUptime(mHighBrightnessModeMetadata.getRunningStartTimeMillis())); pw.println(" mIsThermalStatusWithinLimit=" + mIsThermalStatusWithinLimit); pw.println(" mIsBlockedByLowPowerMode=" + mIsBlockedByLowPowerMode); pw.println(" width*height=" + mWidth + "*" + mHeight); pw.println(" mEvents="); Loading @@ -344,8 +328,6 @@ class HighBrightnessModeController { } lastStartTime = dumpHbmEvent(pw, event); } mSkinThermalStatusObserver.dump(pw); } private long dumpHbmEvent(PrintWriter pw, HbmEvent event) { Loading @@ -367,7 +349,7 @@ class HighBrightnessModeController { // See {@link #getHdrBrightnessValue}. return !mIsHdrLayerPresent && (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange && mIsThermalStatusWithinLimit && !mIsBlockedByLowPowerMode); && !mIsBlockedByLowPowerMode); } private boolean deviceSupportsHbm() { Loading Loading @@ -469,7 +451,6 @@ class HighBrightnessModeController { + ", isAutoBrightnessEnabled: " + mIsAutoBrightnessEnabled + ", mIsTimeAvailable: " + mIsTimeAvailable + ", mIsInAllowedAmbientRange: " + mIsInAllowedAmbientRange + ", mIsThermalStatusWithinLimit: " + mIsThermalStatusWithinLimit + ", mIsBlockedByLowPowerMode: " + mIsBlockedByLowPowerMode + ", mBrightness: " + mBrightness + ", mUnthrottledBrightness: " + mUnthrottledBrightness Loading Loading @@ -499,13 +480,12 @@ class HighBrightnessModeController { } private void updateHbmStats(int newMode) { final float transitionPoint = mHbmData.transitionPoint; int state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF; if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR && getHdrBrightnessValue() > transitionPoint) { && getHdrBrightnessValue() > mHbmData.transitionPoint) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_HDR; } else if (newMode == BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT && mBrightness > transitionPoint) { && mBrightness > mHbmData.transitionPoint) { state = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT; } if (state == mHbmStatsState) { Loading @@ -519,16 +499,6 @@ class HighBrightnessModeController { final boolean newHbmSv = (state == FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT); if (oldHbmSv && !newHbmSv) { // HighBrightnessModeController (HBMC) currently supports throttling from two sources: // 1. Internal, received from HBMC.SkinThermalStatusObserver.notifyThrottling() // 2. External, received from HBMC.onBrightnessChanged() // TODO(b/216373254): Deprecate internal throttling source final boolean internalThermalThrottling = !mIsThermalStatusWithinLimit; final boolean externalThermalThrottling = mUnthrottledBrightness > transitionPoint && // We would've liked HBM brightness... mBrightness <= transitionPoint && // ...but we got NBM, because of... mThrottlingReason == BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; // ...thermals. // If more than one conditions are flipped and turn off HBM sunlight // visibility, only one condition will be reported to make it simple. if (!mIsAutoBrightnessEnabled && mIsAutoBrightnessOffByState) { Loading @@ -541,7 +511,7 @@ class HighBrightnessModeController { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_LUX_DROP; } else if (!mIsTimeAvailable) { reason = FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_TIME_LIMIT; } else if (internalThermalThrottling || externalThermalThrottling) { } else if (isThermalThrottlingActive()) { reason = FrameworkStatsLog .DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT; } else if (mIsHdrLayerPresent) { Loading @@ -561,6 +531,14 @@ class HighBrightnessModeController { mHbmStatsState = state; } @VisibleForTesting boolean isThermalThrottlingActive() { // We would've liked HBM, but we got NBM (normal brightness mode) because of thermals. return mUnthrottledBrightness > mHbmData.transitionPoint && mBrightness <= mHbmData.transitionPoint && mThrottlingReason == BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; } private String hbmStatsStateToString(int hbmStatsState) { switch (hbmStatsState) { case FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF: Loading Loading @@ -635,82 +613,6 @@ class HighBrightnessModeController { } } private final class SkinThermalStatusObserver extends IThermalEventListener.Stub { private final Injector mInjector; private final Handler mHandler; private IThermalService mThermalService; private boolean mStarted; SkinThermalStatusObserver(Injector injector, Handler handler) { mInjector = injector; mHandler = handler; } @Override public void notifyThrottling(Temperature temp) { if (DEBUG) { Slog.d(TAG, "New thermal throttling status " + ", current thermal status = " + temp.getStatus() + ", threshold = " + mHbmData.thermalStatusLimit); } mHandler.post(() -> { mIsThermalStatusWithinLimit = temp.getStatus() <= mHbmData.thermalStatusLimit; // This recalculates HbmMode and runs mHbmChangeCallback if the mode has changed updateHbmMode(); }); } void startObserving() { if (mStarted) { if (DEBUG) { Slog.d(TAG, "Thermal status observer already started"); } return; } mThermalService = mInjector.getThermalService(); if (mThermalService == null) { Slog.w(TAG, "Could not observe thermal status. Service not available"); return; } try { // We get a callback immediately upon registering so there's no need to query // for the current value. mThermalService.registerThermalEventListenerWithType(this, Temperature.TYPE_SKIN); mStarted = true; } catch (RemoteException e) { Slog.e(TAG, "Failed to register thermal status listener", e); } } void stopObserving() { mIsThermalStatusWithinLimit = true; if (!mStarted) { if (DEBUG) { Slog.d(TAG, "Stop skipped because thermal status observer not started"); } return; } try { mThermalService.unregisterThermalEventListener(this); mStarted = false; } catch (RemoteException e) { Slog.e(TAG, "Failed to unregister thermal status listener", e); } mThermalService = null; } void dump(PrintWriter writer) { writer.println(" SkinThermalStatusObserver:"); writer.println(" mStarted: " + mStarted); if (mThermalService != null) { writer.println(" ThermalService available"); } else { writer.println(" ThermalService not available"); } } } private final class SettingsObserver extends ContentObserver { private final Uri mLowPowerModeSetting = Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE); Loading Loading @@ -766,11 +668,6 @@ class HighBrightnessModeController { return SystemClock::uptimeMillis; } public IThermalService getThermalService() { return IThermalService.Stub.asInterface( ServiceManager.getService(Context.THERMAL_SERVICE)); } public void reportHbmStateChange(int display, int state, int reason) { FrameworkStatsLog.write( FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED, display, state, reason); Loading
services/core/xsd/display-device-config/display-device-config.xsd +0 −6 Original line number Diff line number Diff line Loading @@ -153,12 +153,6 @@ <xs:annotation name="nullable"/> <xs:annotation name="final"/> </xs:element> <!-- The highest (most severe) thermal status at which high-brightness-mode is allowed to operate. --> <xs:element name="thermalStatusLimit" type="thermalStatus" minOccurs="0" maxOccurs="1"> <xs:annotation name="nonnull"/> <xs:annotation name="final"/> </xs:element> <xs:element name="allowInLowPowerMode" type="xs:boolean" minOccurs="0" maxOccurs="1"> <xs:annotation name="nonnull"/> <xs:annotation name="final"/> Loading
services/core/xsd/display-device-config/schema/current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -156,7 +156,6 @@ package com.android.server.display.config { method @NonNull public final java.math.BigDecimal getMinimumLux_all(); method @Nullable public final com.android.server.display.config.RefreshRateRange getRefreshRate_all(); method @Nullable public final com.android.server.display.config.SdrHdrRatioMap getSdrHdrRatioMap_all(); method @NonNull public final com.android.server.display.config.ThermalStatus getThermalStatusLimit_all(); method public com.android.server.display.config.HbmTiming getTiming_all(); method @NonNull public final java.math.BigDecimal getTransitionPoint_all(); method public final void setAllowInLowPowerMode_all(@NonNull boolean); Loading @@ -165,7 +164,6 @@ package com.android.server.display.config { method public final void setMinimumLux_all(@NonNull java.math.BigDecimal); method public final void setRefreshRate_all(@Nullable com.android.server.display.config.RefreshRateRange); method public final void setSdrHdrRatioMap_all(@Nullable com.android.server.display.config.SdrHdrRatioMap); method public final void setThermalStatusLimit_all(@NonNull com.android.server.display.config.ThermalStatus); method public void setTiming_all(com.android.server.display.config.HbmTiming); method public final void setTransitionPoint_all(@NonNull java.math.BigDecimal); } Loading
services/tests/servicestests/src/com/android/server/display/HighBrightnessModeControllerTest.java +23 −81 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.server.display; import static android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; import static android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL; import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR; import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF; import static android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_SUNLIGHT; Loading @@ -29,6 +27,8 @@ import static com.android.server.display.DisplayDeviceConfig.HDR_PERCENT_OF_SCRE import static com.android.server.display.HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.anyFloat; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; Loading @@ -39,14 +39,10 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.ContextWrapper; import android.hardware.display.BrightnessInfo; import android.os.Binder; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.Message; import android.os.PowerManager; import android.os.Temperature; import android.os.Temperature.ThrottlingStatus; import android.os.test.TestLooper; import android.test.mock.MockContentResolver; import android.util.MathUtils; Loading @@ -66,8 +62,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading @@ -80,7 +74,6 @@ public class HighBrightnessModeControllerTest { private static final long TIME_WINDOW_MILLIS = 55 * 1000; private static final long TIME_ALLOWED_IN_WINDOW_MILLIS = 12 * 1000; private static final long TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS = 5 * 1000; private static final int THERMAL_STATUS_LIMIT = PowerManager.THERMAL_STATUS_SEVERE; private static final boolean ALLOW_IN_LOW_POWER_MODE = false; private static final float DEFAULT_MIN = 0.01f; Loading @@ -102,17 +95,13 @@ public class HighBrightnessModeControllerTest { @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule(); @Mock IThermalService mThermalServiceMock; @Mock Injector mInjectorMock; @Mock HighBrightnessModeController.HdrBrightnessDeviceConfig mHdrBrightnessDeviceConfigMock; @Captor ArgumentCaptor<IThermalEventListener> mThermalEventListenerCaptor; private static final HighBrightnessModeData DEFAULT_HBM_DATA = new HighBrightnessModeData(MINIMUM_LUX, TRANSITION_POINT, TIME_WINDOW_MILLIS, TIME_ALLOWED_IN_WINDOW_MILLIS, TIME_MINIMUM_AVAILABLE_TO_ENABLE_MILLIS, THERMAL_STATUS_LIMIT, ALLOW_IN_LOW_POWER_MODE, HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT); ALLOW_IN_LOW_POWER_MODE, HDR_PERCENT_OF_SCREEN_REQUIRED_DEFAULT); @Before public void setUp() { Loading @@ -125,8 +114,6 @@ public class HighBrightnessModeControllerTest { mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContextSpy); when(mContextSpy.getContentResolver()).thenReturn(resolver); when(mInjectorMock.getThermalService()).thenReturn(mThermalServiceMock); } ///////////////// Loading Loading @@ -321,34 +308,14 @@ public class HighBrightnessModeControllerTest { } @Test public void testNoHbmInHighThermalState() throws Exception { public void testHbmIsNotTurnedOffInHighThermalState() throws Exception { final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock()); verify(mThermalServiceMock).registerThermalEventListenerWithType( mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener listener = mThermalEventListenerCaptor.getValue(); // Set the thermal status too high. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); // Try to go into HBM mode but fail hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); hbmc.onAmbientLuxChange(MINIMUM_LUX + 1); advanceTime(10); // Disabled thermal throttling hbmc.onBrightnessChanged(/*brightness=*/ 1f, /*unthrottledBrightness*/ 1f, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode()); } @Test public void testHbmTurnsOffInHighThermalState() throws Exception { final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock()); verify(mThermalServiceMock).registerThermalEventListenerWithType( mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener listener = mThermalEventListenerCaptor.getValue(); // Set the thermal status tolerable listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_LIGHT)); assertFalse(hbmc.isThermalThrottlingActive()); // Try to go into HBM mode hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); Loading @@ -357,15 +324,19 @@ public class HighBrightnessModeControllerTest { assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode()); // Set the thermal status too high and verify we're off. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); // Enable thermal throttling hbmc.onBrightnessChanged(/*brightness=*/ TRANSITION_POINT - 0.01f, /*unthrottledBrightness*/ 1f, BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL); advanceTime(10); assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode()); assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode()); assertTrue(hbmc.isThermalThrottlingActive()); // Set the thermal status low again and verify we're back on. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_SEVERE)); // Disabled thermal throttling hbmc.onBrightnessChanged(/*brightness=*/ 1f, /*unthrottledBrightness*/ 1f, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); advanceTime(1); assertEquals(HIGH_BRIGHTNESS_MODE_SUNLIGHT, hbmc.getHighBrightnessMode()); assertFalse(hbmc.isThermalThrottlingActive()); } @Test Loading Loading @@ -578,33 +549,6 @@ public class HighBrightnessModeControllerTest { anyInt()); } // Test reporting of thermal throttling when triggered by HighBrightnessModeController's // internal thermal throttling. @Test public void testHbmStats_InternalThermalOff() throws Exception { final HighBrightnessModeController hbmc = createDefaultHbm(new OffsettableClock()); final int displayStatsId = mDisplayUniqueId.hashCode(); verify(mThermalServiceMock).registerThermalEventListenerWithType( mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener thermListener = mThermalEventListenerCaptor.getValue(); hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); hbmc.onAmbientLuxChange(MINIMUM_LUX + 1); hbmcOnBrightnessChanged(hbmc, TRANSITION_POINT + 0.01f); advanceTime(1); verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN)); thermListener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); advanceTime(10); assertEquals(HIGH_BRIGHTNESS_MODE_OFF, hbmc.getHighBrightnessMode()); verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_OFF), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_SV_OFF_THERMAL_LIMIT)); } // Test reporting of thermal throttling when triggered externally through // HighBrightnessModeController.onBrightnessChanged() @Test Loading @@ -617,14 +561,16 @@ public class HighBrightnessModeControllerTest { hbmc.setAutoBrightnessEnabled(AUTO_BRIGHTNESS_ENABLED); hbmc.onAmbientLuxChange(MINIMUM_LUX + 1); // Brightness is unthrottled, HBM brightness granted hbmc.onBrightnessChanged(hbmBrightness, hbmBrightness, BRIGHTNESS_MAX_REASON_NONE); hbmc.onBrightnessChanged(hbmBrightness, hbmBrightness, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); advanceTime(1); verify(mInjectorMock).reportHbmStateChange(eq(displayStatsId), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__STATE__HBM_ON_SUNLIGHT), eq(FrameworkStatsLog.DISPLAY_HBM_STATE_CHANGED__REASON__HBM_TRANSITION_REASON_UNKNOWN)); // Brightness is thermally throttled, HBM brightness denied (NBM brightness granted) hbmc.onBrightnessChanged(nbmBrightness, hbmBrightness, BRIGHTNESS_MAX_REASON_THERMAL); hbmc.onBrightnessChanged(nbmBrightness, hbmBrightness, BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL); advanceTime(1); // We expect HBM mode to remain set to sunlight, indicating that HBMC *allows* this mode. // However, we expect the HBM state reported by HBMC to be off, since external thermal Loading Loading @@ -784,11 +730,7 @@ public class HighBrightnessModeControllerTest { mTestLooper.dispatchAll(); } private Temperature getSkinTemp(@ThrottlingStatus int status) { return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status); } private void hbmcOnBrightnessChanged(HighBrightnessModeController hbmc, float brightness) { hbmc.onBrightnessChanged(brightness, brightness, BRIGHTNESS_MAX_REASON_NONE); hbmc.onBrightnessChanged(brightness, brightness, BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE); } }