Loading services/core/java/com/android/server/display/DisplayModeDirector.java +71 −4 Original line number Original line Diff line number Diff line Loading @@ -36,9 +36,14 @@ import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.fingerprint.IUdfpsHbmListener; import android.hardware.fingerprint.IUdfpsHbmListener; import android.net.Uri; import android.net.Uri; import android.os.Handler; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.Looper; import android.os.Looper; import android.os.Message; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemClock; import android.os.Temperature; import android.os.UserHandle; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings; Loading Loading @@ -108,6 +113,7 @@ public class DisplayModeDirector { private final UdfpsObserver mUdfpsObserver; private final UdfpsObserver mUdfpsObserver; private final SensorObserver mSensorObserver; private final SensorObserver mSensorObserver; private final HbmObserver mHbmObserver; private final HbmObserver mHbmObserver; private final SkinThermalStatusObserver mSkinThermalStatusObserver; private final DeviceConfigInterface mDeviceConfig; private final DeviceConfigInterface mDeviceConfig; private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; Loading Loading @@ -156,6 +162,7 @@ public class DisplayModeDirector { }; }; mSensorObserver = new SensorObserver(context, ballotBox, injector); mSensorObserver = new SensorObserver(context, ballotBox, injector); mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler()); mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler()); mSkinThermalStatusObserver = new SkinThermalStatusObserver(injector, ballotBox); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); mDeviceConfig = injector.getDeviceConfig(); mDeviceConfig = injector.getDeviceConfig(); mAlwaysRespectAppRequest = false; mAlwaysRespectAppRequest = false; Loading @@ -174,6 +181,7 @@ public class DisplayModeDirector { mBrightnessObserver.observe(sensorManager); mBrightnessObserver.observe(sensorManager); mSensorObserver.observe(); mSensorObserver.observe(); mHbmObserver.observe(); mHbmObserver.observe(); mSkinThermalStatusObserver.observe(); synchronized (mLock) { synchronized (mLock) { // We may have a listener already registered before the call to start, so go ahead and // We may have a listener already registered before the call to start, so go ahead and // notify them to pick up our newly initialized state. // notify them to pick up our newly initialized state. Loading Loading @@ -606,6 +614,7 @@ public class DisplayModeDirector { mUdfpsObserver.dumpLocked(pw); mUdfpsObserver.dumpLocked(pw); mSensorObserver.dumpLocked(pw); mSensorObserver.dumpLocked(pw); mHbmObserver.dumpLocked(pw); mHbmObserver.dumpLocked(pw); mSkinThermalStatusObserver.dumpLocked(pw); } } } } Loading Loading @@ -714,7 +723,6 @@ public class DisplayModeDirector { return mUdfpsObserver; return mUdfpsObserver; } } @VisibleForTesting @VisibleForTesting DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings( DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings( float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) { float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) { Loading Loading @@ -950,16 +958,19 @@ public class DisplayModeDirector { // user seeing the display flickering when the switches occur. // user seeing the display flickering when the switches occur. public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 8; public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 8; // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL. public static final int PRIORITY_SKIN_TEMPERATURE = 9; // High-brightness-mode may need a specific range of refresh-rates to function properly. // High-brightness-mode may need a specific range of refresh-rates to function properly. public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 9; public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 10; // The proximity sensor needs the refresh rate to be locked in order to function, so this is // The proximity sensor needs the refresh rate to be locked in order to function, so this is // set to a high priority. // set to a high priority. public static final int PRIORITY_PROXIMITY = 10; public static final int PRIORITY_PROXIMITY = 11; // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order // to function, so this needs to be the highest priority of all votes. // to function, so this needs to be the highest priority of all votes. public static final int PRIORITY_UDFPS = 11; public static final int PRIORITY_UDFPS = 12; // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString. // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString. Loading Loading @@ -1054,6 +1065,8 @@ public class DisplayModeDirector { return "PRIORITY_PROXIMITY"; return "PRIORITY_PROXIMITY"; case PRIORITY_LOW_POWER_MODE: case PRIORITY_LOW_POWER_MODE: return "PRIORITY_LOW_POWER_MODE"; return "PRIORITY_LOW_POWER_MODE"; case PRIORITY_SKIN_TEMPERATURE: return "PRIORITY_SKIN_TEMPERATURE"; case PRIORITY_UDFPS: case PRIORITY_UDFPS: return "PRIORITY_UDFPS"; return "PRIORITY_UDFPS"; case PRIORITY_USER_SETTING_MIN_REFRESH_RATE: case PRIORITY_USER_SETTING_MIN_REFRESH_RATE: Loading Loading @@ -2309,6 +2322,52 @@ public class DisplayModeDirector { } } } } private final class SkinThermalStatusObserver extends IThermalEventListener.Stub { private final BallotBox mBallotBox; private final Injector mInjector; private @Temperature.ThrottlingStatus int mStatus = -1; SkinThermalStatusObserver(Injector injector, BallotBox ballotBox) { mInjector = injector; mBallotBox = ballotBox; } @Override public void notifyThrottling(Temperature temp) { mStatus = temp.getStatus(); if (mLoggingEnabled) { Slog.d(TAG, "New thermal throttling status " + ", current thermal status = " + mStatus); } final Vote vote; if (mStatus >= Temperature.THROTTLING_CRITICAL) { vote = Vote.forRefreshRates(0f, 60f); } else { vote = null; } mBallotBox.vote(GLOBAL_ID, Vote.PRIORITY_SKIN_TEMPERATURE, vote); } public void observe() { IThermalService thermalService = mInjector.getThermalService(); if (thermalService == null) { Slog.w(TAG, "Could not observe thermal status. Service not available"); return; } try { thermalService.registerThermalEventListenerWithType(this, Temperature.TYPE_SKIN); } catch (RemoteException e) { Slog.e(TAG, "Failed to register thermal status listener", e); } } void dumpLocked(PrintWriter writer) { writer.println(" SkinThermalStatusObserver:"); writer.println(" mStatus: " + mStatus); } } private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { public DeviceConfigDisplaySettings() { public DeviceConfigDisplaySettings() { } } Loading Loading @@ -2470,6 +2529,8 @@ public class DisplayModeDirector { BrightnessInfo getBrightnessInfo(int displayId); BrightnessInfo getBrightnessInfo(int displayId); boolean isDozeState(Display d); boolean isDozeState(Display d); IThermalService getThermalService(); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -2530,6 +2591,12 @@ public class DisplayModeDirector { return Display.isDozeState(d.getState()); return Display.isDozeState(d.getState()); } } @Override public IThermalService getThermalService() { return IThermalService.Stub.asInterface( ServiceManager.getService(Context.THERMAL_SERVICE)); } private DisplayManager getDisplayManager() { private DisplayManager getDisplayManager() { if (mDisplayManager == null) { if (mDisplayManager == null) { mDisplayManager = mContext.getSystemService(DisplayManager.class); mDisplayManager = mContext.getSystemService(DisplayManager.class); Loading services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +52 −0 Original line number Original line Diff line number Diff line Loading @@ -56,7 +56,11 @@ import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation; import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.fingerprint.IUdfpsHbmListener; import android.hardware.fingerprint.IUdfpsHbmListener; import android.os.Handler; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.Looper; import android.os.Looper; import android.os.RemoteException; import android.os.Temperature; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings; import android.test.mock.MockContentResolver; import android.test.mock.MockContentResolver; Loading Loading @@ -116,6 +120,8 @@ public class DisplayModeDirectorTest { public SensorManagerInternal mSensorManagerInternalMock; public SensorManagerInternal mSensorManagerInternalMock; @Mock @Mock public DisplayManagerInternal mDisplayManagerInternalMock; public DisplayManagerInternal mDisplayManagerInternalMock; @Mock public IThermalService mThermalServiceMock; @Before @Before public void setUp() throws Exception { public void setUp() throws Exception { Loading @@ -124,6 +130,7 @@ public class DisplayModeDirectorTest { final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext); final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext); when(mContext.getContentResolver()).thenReturn(resolver); when(mContext.getContentResolver()).thenReturn(resolver); mInjector = spy(new FakesInjector()); mInjector = spy(new FakesInjector()); when(mInjector.getThermalService()).thenReturn(mThermalServiceMock); mHandler = new Handler(Looper.getMainLooper()); mHandler = new Handler(Looper.getMainLooper()); LocalServices.removeServiceForTest(StatusBarManagerInternal.class); LocalServices.removeServiceForTest(StatusBarManagerInternal.class); Loading Loading @@ -1547,12 +1554,52 @@ public class DisplayModeDirectorTest { assertNull(vote); assertNull(vote); } } @Test public void testSkinTemperature() throws RemoteException { DisplayModeDirector director = createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0); director.start(createMockSensorManager()); ArgumentCaptor<IThermalEventListener> thermalEventListener = ArgumentCaptor.forClass(IThermalEventListener.class); verify(mThermalServiceMock).registerThermalEventListenerWithType( thermalEventListener.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener listener = thermalEventListener.getValue(); // Verify that there is no skin temperature vote initially. Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_SKIN_TEMPERATURE); assertNull(vote); // Set the skin temperature to critical and verify that we added a vote. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_SKIN_TEMPERATURE); assertVoteForRefreshRateRange(vote, 0f, 60.f); // Set the skin temperature to severe and verify that the vote is gone. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_SEVERE)); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_SKIN_TEMPERATURE); assertNull(vote); } private Temperature getSkinTemp(@Temperature.ThrottlingStatus int status) { return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status); } private void assertVoteForRefreshRate(Vote vote, float refreshRate) { private void assertVoteForRefreshRate(Vote vote, float refreshRate) { assertThat(vote).isNotNull(); assertThat(vote).isNotNull(); final RefreshRateRange expectedRange = new RefreshRateRange(refreshRate, refreshRate); final RefreshRateRange expectedRange = new RefreshRateRange(refreshRate, refreshRate); assertThat(vote.refreshRateRange).isEqualTo(expectedRange); assertThat(vote.refreshRateRange).isEqualTo(expectedRange); } } private void assertVoteForRefreshRateRange( Vote vote, float refreshRateLow, float refreshRateHigh) { assertThat(vote).isNotNull(); final RefreshRateRange expectedRange = new RefreshRateRange(refreshRateLow, refreshRateHigh); assertThat(vote.refreshRateRange).isEqualTo(expectedRange); } public static class FakeDeviceConfig extends FakeDeviceConfigInterface { public static class FakeDeviceConfig extends FakeDeviceConfigInterface { @Override @Override public String getProperty(String namespace, String name) { public String getProperty(String namespace, String name) { Loading Loading @@ -1748,6 +1795,11 @@ public class DisplayModeDirectorTest { return false; return false; } } @Override public IThermalService getThermalService() { return null; } void notifyPeakRefreshRateChanged() { void notifyPeakRefreshRateChanged() { if (mPeakRefreshRateObserver != null) { if (mPeakRefreshRateObserver != null) { mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/, mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/, Loading Loading
services/core/java/com/android/server/display/DisplayModeDirector.java +71 −4 Original line number Original line Diff line number Diff line Loading @@ -36,9 +36,14 @@ import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.fingerprint.IUdfpsHbmListener; import android.hardware.fingerprint.IUdfpsHbmListener; import android.net.Uri; import android.net.Uri; import android.os.Handler; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.Looper; import android.os.Looper; import android.os.Message; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemClock; import android.os.Temperature; import android.os.UserHandle; import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings; Loading Loading @@ -108,6 +113,7 @@ public class DisplayModeDirector { private final UdfpsObserver mUdfpsObserver; private final UdfpsObserver mUdfpsObserver; private final SensorObserver mSensorObserver; private final SensorObserver mSensorObserver; private final HbmObserver mHbmObserver; private final HbmObserver mHbmObserver; private final SkinThermalStatusObserver mSkinThermalStatusObserver; private final DeviceConfigInterface mDeviceConfig; private final DeviceConfigInterface mDeviceConfig; private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings; Loading Loading @@ -156,6 +162,7 @@ public class DisplayModeDirector { }; }; mSensorObserver = new SensorObserver(context, ballotBox, injector); mSensorObserver = new SensorObserver(context, ballotBox, injector); mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler()); mHbmObserver = new HbmObserver(injector, ballotBox, BackgroundThread.getHandler()); mSkinThermalStatusObserver = new SkinThermalStatusObserver(injector, ballotBox); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings(); mDeviceConfig = injector.getDeviceConfig(); mDeviceConfig = injector.getDeviceConfig(); mAlwaysRespectAppRequest = false; mAlwaysRespectAppRequest = false; Loading @@ -174,6 +181,7 @@ public class DisplayModeDirector { mBrightnessObserver.observe(sensorManager); mBrightnessObserver.observe(sensorManager); mSensorObserver.observe(); mSensorObserver.observe(); mHbmObserver.observe(); mHbmObserver.observe(); mSkinThermalStatusObserver.observe(); synchronized (mLock) { synchronized (mLock) { // We may have a listener already registered before the call to start, so go ahead and // We may have a listener already registered before the call to start, so go ahead and // notify them to pick up our newly initialized state. // notify them to pick up our newly initialized state. Loading Loading @@ -606,6 +614,7 @@ public class DisplayModeDirector { mUdfpsObserver.dumpLocked(pw); mUdfpsObserver.dumpLocked(pw); mSensorObserver.dumpLocked(pw); mSensorObserver.dumpLocked(pw); mHbmObserver.dumpLocked(pw); mHbmObserver.dumpLocked(pw); mSkinThermalStatusObserver.dumpLocked(pw); } } } } Loading Loading @@ -714,7 +723,6 @@ public class DisplayModeDirector { return mUdfpsObserver; return mUdfpsObserver; } } @VisibleForTesting @VisibleForTesting DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings( DesiredDisplayModeSpecs getDesiredDisplayModeSpecsWithInjectedFpsSettings( float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) { float minRefreshRate, float peakRefreshRate, float defaultRefreshRate) { Loading Loading @@ -950,16 +958,19 @@ public class DisplayModeDirector { // user seeing the display flickering when the switches occur. // user seeing the display flickering when the switches occur. public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 8; public static final int PRIORITY_FLICKER_REFRESH_RATE_SWITCH = 8; // Force display to [0, 60HZ] if skin temperature is at or above CRITICAL. public static final int PRIORITY_SKIN_TEMPERATURE = 9; // High-brightness-mode may need a specific range of refresh-rates to function properly. // High-brightness-mode may need a specific range of refresh-rates to function properly. public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 9; public static final int PRIORITY_HIGH_BRIGHTNESS_MODE = 10; // The proximity sensor needs the refresh rate to be locked in order to function, so this is // The proximity sensor needs the refresh rate to be locked in order to function, so this is // set to a high priority. // set to a high priority. public static final int PRIORITY_PROXIMITY = 10; public static final int PRIORITY_PROXIMITY = 11; // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order // The Under-Display Fingerprint Sensor (UDFPS) needs the refresh rate to be locked in order // to function, so this needs to be the highest priority of all votes. // to function, so this needs to be the highest priority of all votes. public static final int PRIORITY_UDFPS = 11; public static final int PRIORITY_UDFPS = 12; // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and // Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString. // APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString. Loading Loading @@ -1054,6 +1065,8 @@ public class DisplayModeDirector { return "PRIORITY_PROXIMITY"; return "PRIORITY_PROXIMITY"; case PRIORITY_LOW_POWER_MODE: case PRIORITY_LOW_POWER_MODE: return "PRIORITY_LOW_POWER_MODE"; return "PRIORITY_LOW_POWER_MODE"; case PRIORITY_SKIN_TEMPERATURE: return "PRIORITY_SKIN_TEMPERATURE"; case PRIORITY_UDFPS: case PRIORITY_UDFPS: return "PRIORITY_UDFPS"; return "PRIORITY_UDFPS"; case PRIORITY_USER_SETTING_MIN_REFRESH_RATE: case PRIORITY_USER_SETTING_MIN_REFRESH_RATE: Loading Loading @@ -2309,6 +2322,52 @@ public class DisplayModeDirector { } } } } private final class SkinThermalStatusObserver extends IThermalEventListener.Stub { private final BallotBox mBallotBox; private final Injector mInjector; private @Temperature.ThrottlingStatus int mStatus = -1; SkinThermalStatusObserver(Injector injector, BallotBox ballotBox) { mInjector = injector; mBallotBox = ballotBox; } @Override public void notifyThrottling(Temperature temp) { mStatus = temp.getStatus(); if (mLoggingEnabled) { Slog.d(TAG, "New thermal throttling status " + ", current thermal status = " + mStatus); } final Vote vote; if (mStatus >= Temperature.THROTTLING_CRITICAL) { vote = Vote.forRefreshRates(0f, 60f); } else { vote = null; } mBallotBox.vote(GLOBAL_ID, Vote.PRIORITY_SKIN_TEMPERATURE, vote); } public void observe() { IThermalService thermalService = mInjector.getThermalService(); if (thermalService == null) { Slog.w(TAG, "Could not observe thermal status. Service not available"); return; } try { thermalService.registerThermalEventListenerWithType(this, Temperature.TYPE_SKIN); } catch (RemoteException e) { Slog.e(TAG, "Failed to register thermal status listener", e); } } void dumpLocked(PrintWriter writer) { writer.println(" SkinThermalStatusObserver:"); writer.println(" mStatus: " + mStatus); } } private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener { public DeviceConfigDisplaySettings() { public DeviceConfigDisplaySettings() { } } Loading Loading @@ -2470,6 +2529,8 @@ public class DisplayModeDirector { BrightnessInfo getBrightnessInfo(int displayId); BrightnessInfo getBrightnessInfo(int displayId); boolean isDozeState(Display d); boolean isDozeState(Display d); IThermalService getThermalService(); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -2530,6 +2591,12 @@ public class DisplayModeDirector { return Display.isDozeState(d.getState()); return Display.isDozeState(d.getState()); } } @Override public IThermalService getThermalService() { return IThermalService.Stub.asInterface( ServiceManager.getService(Context.THERMAL_SERVICE)); } private DisplayManager getDisplayManager() { private DisplayManager getDisplayManager() { if (mDisplayManager == null) { if (mDisplayManager == null) { mDisplayManager = mContext.getSystemService(DisplayManager.class); mDisplayManager = mContext.getSystemService(DisplayManager.class); Loading
services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java +52 −0 Original line number Original line Diff line number Diff line Loading @@ -56,7 +56,11 @@ import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation; import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.fingerprint.IUdfpsHbmListener; import android.hardware.fingerprint.IUdfpsHbmListener; import android.os.Handler; import android.os.Handler; import android.os.IThermalEventListener; import android.os.IThermalService; import android.os.Looper; import android.os.Looper; import android.os.RemoteException; import android.os.Temperature; import android.provider.DeviceConfig; import android.provider.DeviceConfig; import android.provider.Settings; import android.provider.Settings; import android.test.mock.MockContentResolver; import android.test.mock.MockContentResolver; Loading Loading @@ -116,6 +120,8 @@ public class DisplayModeDirectorTest { public SensorManagerInternal mSensorManagerInternalMock; public SensorManagerInternal mSensorManagerInternalMock; @Mock @Mock public DisplayManagerInternal mDisplayManagerInternalMock; public DisplayManagerInternal mDisplayManagerInternalMock; @Mock public IThermalService mThermalServiceMock; @Before @Before public void setUp() throws Exception { public void setUp() throws Exception { Loading @@ -124,6 +130,7 @@ public class DisplayModeDirectorTest { final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext); final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext); when(mContext.getContentResolver()).thenReturn(resolver); when(mContext.getContentResolver()).thenReturn(resolver); mInjector = spy(new FakesInjector()); mInjector = spy(new FakesInjector()); when(mInjector.getThermalService()).thenReturn(mThermalServiceMock); mHandler = new Handler(Looper.getMainLooper()); mHandler = new Handler(Looper.getMainLooper()); LocalServices.removeServiceForTest(StatusBarManagerInternal.class); LocalServices.removeServiceForTest(StatusBarManagerInternal.class); Loading Loading @@ -1547,12 +1554,52 @@ public class DisplayModeDirectorTest { assertNull(vote); assertNull(vote); } } @Test public void testSkinTemperature() throws RemoteException { DisplayModeDirector director = createDirectorFromRefreshRateArray(new float[] {60.0f, 90.0f}, 0); director.start(createMockSensorManager()); ArgumentCaptor<IThermalEventListener> thermalEventListener = ArgumentCaptor.forClass(IThermalEventListener.class); verify(mThermalServiceMock).registerThermalEventListenerWithType( thermalEventListener.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener listener = thermalEventListener.getValue(); // Verify that there is no skin temperature vote initially. Vote vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_SKIN_TEMPERATURE); assertNull(vote); // Set the skin temperature to critical and verify that we added a vote. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_CRITICAL)); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_SKIN_TEMPERATURE); assertVoteForRefreshRateRange(vote, 0f, 60.f); // Set the skin temperature to severe and verify that the vote is gone. listener.notifyThrottling(getSkinTemp(Temperature.THROTTLING_SEVERE)); vote = director.getVote(DISPLAY_ID, Vote.PRIORITY_SKIN_TEMPERATURE); assertNull(vote); } private Temperature getSkinTemp(@Temperature.ThrottlingStatus int status) { return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status); } private void assertVoteForRefreshRate(Vote vote, float refreshRate) { private void assertVoteForRefreshRate(Vote vote, float refreshRate) { assertThat(vote).isNotNull(); assertThat(vote).isNotNull(); final RefreshRateRange expectedRange = new RefreshRateRange(refreshRate, refreshRate); final RefreshRateRange expectedRange = new RefreshRateRange(refreshRate, refreshRate); assertThat(vote.refreshRateRange).isEqualTo(expectedRange); assertThat(vote.refreshRateRange).isEqualTo(expectedRange); } } private void assertVoteForRefreshRateRange( Vote vote, float refreshRateLow, float refreshRateHigh) { assertThat(vote).isNotNull(); final RefreshRateRange expectedRange = new RefreshRateRange(refreshRateLow, refreshRateHigh); assertThat(vote.refreshRateRange).isEqualTo(expectedRange); } public static class FakeDeviceConfig extends FakeDeviceConfigInterface { public static class FakeDeviceConfig extends FakeDeviceConfigInterface { @Override @Override public String getProperty(String namespace, String name) { public String getProperty(String namespace, String name) { Loading Loading @@ -1748,6 +1795,11 @@ public class DisplayModeDirectorTest { return false; return false; } } @Override public IThermalService getThermalService() { return null; } void notifyPeakRefreshRateChanged() { void notifyPeakRefreshRateChanged() { if (mPeakRefreshRateObserver != null) { if (mPeakRefreshRateObserver != null) { mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/, mPeakRefreshRateObserver.dispatchChange(false /*selfChange*/, Loading