HBMController thermals via BrightnessThrottler

Bug: 266063390

Test: atest HighBrightnessModeControllerTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:476f58d5297955154d50f87a587eee5ec98bd705)
Merged-In: Ib0c06d18457386abd6cd12211cca77804076e4cc
Change-Id: Ib0c06d18457386abd6cd12211cca77804076e4cc
This commit is contained in:
Oleg Blinnikov
2023-03-08 15:56:30 +00:00
committed by Cherrypicker Worker
parent a97a48b528
commit 478afa4a35
5 changed files with 36 additions and 213 deletions

View File

@@ -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) {
@@ -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;
@@ -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;
}
@@ -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;
}
@@ -3029,7 +3022,6 @@ public class DisplayDeviceConfig {
+ ", timeWindow: " + timeWindowMillis + "ms"
+ ", timeMax: " + timeMaxMillis + "ms"
+ ", timeMin: " + timeMinMillis + "ms"
+ ", thermalStatusLimit: " + thermalStatusLimit
+ ", allowInLowPowerMode: " + allowInLowPowerMode
+ ", minimumHdrPercentOfScreen: " + minimumHdrPercentOfScreen
+ "} ";

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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();
@@ -261,7 +252,6 @@ class HighBrightnessModeController {
void stop() {
registerHdrListener(null /*displayToken*/);
mSkinThermalStatusObserver.stopObserving();
mSettingsObserver.stopObserving();
}
@@ -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();
@@ -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=");
@@ -344,8 +328,6 @@ class HighBrightnessModeController {
}
lastStartTime = dumpHbmEvent(pw, event);
}
mSkinThermalStatusObserver.dump(pw);
}
private long dumpHbmEvent(PrintWriter pw, HbmEvent event) {
@@ -367,7 +349,7 @@ class HighBrightnessModeController {
// See {@link #getHdrBrightnessValue}.
return !mIsHdrLayerPresent
&& (mIsAutoBrightnessEnabled && mIsTimeAvailable && mIsInAllowedAmbientRange
&& mIsThermalStatusWithinLimit && !mIsBlockedByLowPowerMode);
&& !mIsBlockedByLowPowerMode);
}
private boolean deviceSupportsHbm() {
@@ -469,7 +451,6 @@ class HighBrightnessModeController {
+ ", isAutoBrightnessEnabled: " + mIsAutoBrightnessEnabled
+ ", mIsTimeAvailable: " + mIsTimeAvailable
+ ", mIsInAllowedAmbientRange: " + mIsInAllowedAmbientRange
+ ", mIsThermalStatusWithinLimit: " + mIsThermalStatusWithinLimit
+ ", mIsBlockedByLowPowerMode: " + mIsBlockedByLowPowerMode
+ ", mBrightness: " + mBrightness
+ ", mUnthrottledBrightness: " + mUnthrottledBrightness
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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:
@@ -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);
@@ -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);

View File

@@ -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"/>

View File

@@ -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);
@@ -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);
}

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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() {
@@ -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);
}
/////////////////
@@ -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();
// Disabled thermal throttling
hbmc.onBrightnessChanged(/*brightness=*/ 1f, /*unthrottledBrightness*/ 1f,
BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE);
// 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);
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);
@@ -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
@@ -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
@@ -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
@@ -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);
}
}