diff options
4 files changed, 119 insertions, 21 deletions
diff --git a/services/core/java/com/android/server/display/BrightnessThrottler.java b/services/core/java/com/android/server/display/BrightnessThrottler.java index bba5ba35dbc7..631e7518b746 100644 --- a/services/core/java/com/android/server/display/BrightnessThrottler.java +++ b/services/core/java/com/android/server/display/BrightnessThrottler.java @@ -37,9 +37,11 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel; +import com.android.server.display.config.SensorData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.utils.DebugUtils; import com.android.server.display.utils.DeviceConfigParsingUtils; +import com.android.server.display.utils.SensorUtils; import java.io.PrintWriter; import java.util.HashMap; @@ -79,7 +81,7 @@ class BrightnessThrottler { // Maps the throttling ID to the data. Sourced from DisplayDeviceConfig. @NonNull - private HashMap<String, ThermalBrightnessThrottlingData> mDdcThermalThrottlingDataMap; + private Map<String, ThermalBrightnessThrottlingData> mDdcThermalThrottlingDataMap; // Current throttling data being used. // Null if we do not support throttling. @@ -97,6 +99,10 @@ class BrightnessThrottler { // The brightness throttling configuration that should be used. private String mThermalBrightnessThrottlingDataId; + // Temperature Sensor to be monitored for throttling. + @NonNull + private SensorData mTempSensor; + // This is a collection of brightness throttling data that has been written as overrides from // the DeviceConfig. This will always take priority over the display device config data. // We need to store the data for every display device, so we do not need to update this each @@ -121,17 +127,19 @@ class BrightnessThrottler { BrightnessThrottler(Handler handler, Runnable throttlingChangeCallback, String uniqueDisplayId, String throttlingDataId, - @NonNull HashMap<String, ThermalBrightnessThrottlingData> - thermalBrightnessThrottlingDataMap) { - this(new Injector(), handler, handler, throttlingChangeCallback, - uniqueDisplayId, throttlingDataId, thermalBrightnessThrottlingDataMap); + @NonNull DisplayDeviceConfig displayDeviceConfig) { + this(new Injector(), handler, handler, throttlingChangeCallback, uniqueDisplayId, + throttlingDataId, + displayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(), + displayDeviceConfig.getTempSensor()); } @VisibleForTesting BrightnessThrottler(Injector injector, Handler handler, Handler deviceConfigHandler, Runnable throttlingChangeCallback, String uniqueDisplayId, String throttlingDataId, - @NonNull HashMap<String, ThermalBrightnessThrottlingData> - thermalBrightnessThrottlingDataMap) { + @NonNull Map<String, ThermalBrightnessThrottlingData> + thermalBrightnessThrottlingDataMap, + @NonNull SensorData tempSensor) { mInjector = injector; mHandler = handler; @@ -147,7 +155,7 @@ class BrightnessThrottler { mDdcThermalThrottlingDataMap = thermalBrightnessThrottlingDataMap; loadThermalBrightnessThrottlingDataFromDeviceConfig(); loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig(mDdcThermalThrottlingDataMap, - mThermalBrightnessThrottlingDataId, mUniqueDisplayId); + tempSensor, mThermalBrightnessThrottlingDataId, mUniqueDisplayId); } boolean deviceSupportsThrottling() { @@ -180,12 +188,14 @@ class BrightnessThrottler { } void loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( - HashMap<String, ThermalBrightnessThrottlingData> ddcThrottlingDataMap, + Map<String, ThermalBrightnessThrottlingData> ddcThrottlingDataMap, + SensorData tempSensor, String brightnessThrottlingDataId, String uniqueDisplayId) { mDdcThermalThrottlingDataMap = ddcThrottlingDataMap; mThermalBrightnessThrottlingDataId = brightnessThrottlingDataId; mUniqueDisplayId = uniqueDisplayId; + mTempSensor = tempSensor; resetThermalThrottlingData(); } @@ -310,7 +320,7 @@ class BrightnessThrottler { } if (deviceSupportsThrottling()) { - mSkinThermalStatusObserver.startObserving(); + mSkinThermalStatusObserver.startObserving(mTempSensor); } } @@ -357,6 +367,7 @@ class BrightnessThrottler { private final class SkinThermalStatusObserver extends IThermalEventListener.Stub { private final Injector mInjector; private final Handler mHandler; + private SensorData mObserverTempSensor; private IThermalService mThermalService; private boolean mStarted; @@ -371,28 +382,51 @@ class BrightnessThrottler { if (DEBUG) { Slog.d(TAG, "New thermal throttling status = " + temp.getStatus()); } + + if (mObserverTempSensor.name != null + && !mObserverTempSensor.name.equals(temp.getName())) { + Slog.i(TAG, "Skipping thermal throttling notification as monitored sensor: " + + mObserverTempSensor.name + + " != notified sensor: " + + temp.getName()); + return; + } mHandler.post(() -> { final @Temperature.ThrottlingStatus int status = temp.getStatus(); thermalStatusChanged(status); }); } - void startObserving() { - if (mStarted) { + void startObserving(SensorData tempSensor) { + if (!mStarted || mObserverTempSensor == null) { + mObserverTempSensor = tempSensor; + registerThermalListener(); + return; + } + + String curType = mObserverTempSensor.type; + mObserverTempSensor = tempSensor; + if (curType.equals(tempSensor.type)) { if (DEBUG) { Slog.d(TAG, "Thermal status observer already started"); } return; } + stopObserving(); + registerThermalListener(); + } + + void registerThermalListener() { mThermalService = mInjector.getThermalService(); if (mThermalService == null) { Slog.e(TAG, "Could not observe thermal status. Service not available"); return; } + int temperatureType = SensorUtils.getSensorTemperatureType(mObserverTempSensor); 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); + mThermalService.registerThermalEventListenerWithType(this, temperatureType); mStarted = true; } catch (RemoteException e) { Slog.e(TAG, "Failed to register thermal status listener", e); @@ -418,6 +452,7 @@ class BrightnessThrottler { void dump(PrintWriter writer) { writer.println(" SkinThermalStatusObserver:"); writer.println(" mStarted: " + mStarted); + writer.println(" mObserverTempSensor: " + mObserverTempSensor); if (mThermalService != null) { writer.println(" ThermalService available"); } else { diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index bf30b2ec803e..9b2dcc53f456 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -831,10 +831,10 @@ public class DisplayDeviceConfig { private String mLowBlockingZoneThermalMapId = null; private String mHighBlockingZoneThermalMapId = null; - private final HashMap<String, ThermalBrightnessThrottlingData> + private final Map<String, ThermalBrightnessThrottlingData> mThermalBrightnessThrottlingDataMapByThrottlingId = new HashMap<>(); - private final HashMap<String, PowerThrottlingData> + private final Map<String, PowerThrottlingData> mPowerThrottlingDataMapByThrottlingId = new HashMap<>(); private final Map<String, SparseArray<SurfaceControl.RefreshRateRange>> @@ -1556,7 +1556,7 @@ public class DisplayDeviceConfig { /** * @return brightness throttling configuration data for this display, for each throttling id. */ - public HashMap<String, ThermalBrightnessThrottlingData> + public Map<String, ThermalBrightnessThrottlingData> getThermalBrightnessThrottlingDataMapByThrottlingId() { return mThermalBrightnessThrottlingDataMapByThrottlingId; } @@ -1575,7 +1575,7 @@ public class DisplayDeviceConfig { /** * @return power throttling configuration data for this display, for each throttling id. **/ - public HashMap<String, PowerThrottlingData> + public Map<String, PowerThrottlingData> getPowerThrottlingDataMapByThrottlingId() { return mPowerThrottlingDataMapByThrottlingId; } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index d5863a73a0c3..3965d55b0c28 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -861,6 +861,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mThermalBrightnessThrottlingDataId = thermalBrightnessThrottlingDataId; mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( config.getThermalBrightnessThrottlingDataMapByThrottlingId(), + config.getTempSensor(), mThermalBrightnessThrottlingDataId, mUniqueDisplayId); } @@ -923,6 +924,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessRangeController.loadFromConfig(hbmMetadata, token, info, mDisplayDeviceConfig); mBrightnessThrottler.loadThermalBrightnessThrottlingDataFromDisplayDeviceConfig( mDisplayDeviceConfig.getThermalBrightnessThrottlingDataMapByThrottlingId(), + mDisplayDeviceConfig.getTempSensor(), mThermalBrightnessThrottlingDataId, mUniqueDisplayId); } @@ -1996,7 +1998,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call postBrightnessChangeRunnable(); }, mUniqueDisplayId, mLogicalDisplay.getDisplayInfoLocked().thermalBrightnessThrottlingDataId, - ddConfig.getThermalBrightnessThrottlingDataMapByThrottlingId()); + ddConfig); } private void blockScreenOn() { diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessThrottlerTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessThrottlerTest.java index 8faaf5998d13..05c243fda2b8 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessThrottlerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessThrottlerTest.java @@ -43,6 +43,7 @@ import com.android.internal.os.BackgroundThread; import com.android.server.display.BrightnessThrottler.Injector; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData.ThrottlingLevel; +import com.android.server.display.config.SensorData; import com.android.server.display.mode.DisplayModeDirectorTest; import org.junit.Before; @@ -56,6 +57,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; @SmallTest @RunWith(AndroidJUnit4.class) @@ -292,6 +294,53 @@ public class BrightnessThrottlerTest { assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason()); } + + @Test + public void testThermalThrottlingWithDisplaySensor() throws Exception { + final ThrottlingLevel level = + new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL, 0.25f); + List<ThrottlingLevel> levels = new ArrayList<>(List.of(level)); + final ThermalBrightnessThrottlingData data = ThermalBrightnessThrottlingData.create(levels); + final SensorData tempSensor = new SensorData("DISPLAY", "VIRTUAL-SKIN-DISPLAY"); + final BrightnessThrottler throttler = + createThrottlerSupportedWithTempSensor(data, tempSensor); + assertTrue(throttler.deviceSupportsThrottling()); + + verify(mThermalServiceMock) + .registerThermalEventListenerWithType( + mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_DISPLAY)); + final IThermalEventListener listener = mThermalEventListenerCaptor.getValue(); + + // Set VIRTUAL-SKIN-DISPLAY tatus too low to verify no throttling. + listener.notifyThrottling(getDisplayTempWithName(tempSensor.name, level.thermalStatus - 1)); + mTestLooper.dispatchAll(); + assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f); + assertFalse(throttler.isThrottled()); + assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason()); + + // Verify when skin sensor throttled, no brightness throttling triggered. + listener.notifyThrottling(getSkinTemp(level.thermalStatus + 1)); + mTestLooper.dispatchAll(); + assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f); + assertFalse(throttler.isThrottled()); + assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason()); + + // Verify when display sensor of another name throttled, no brightness throttling triggered. + listener.notifyThrottling(getDisplayTempWithName("ANOTHER-NAME", level.thermalStatus + 1)); + mTestLooper.dispatchAll(); + assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f); + assertFalse(throttler.isThrottled()); + assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE, throttler.getBrightnessMaxReason()); + + // Verify when display sensor of current name throttled, brightness throttling triggered. + listener.notifyThrottling(getDisplayTempWithName(tempSensor.name, level.thermalStatus + 1)); + mTestLooper.dispatchAll(); + assertEquals(level.brightness, throttler.getBrightnessCap(), 0f); + assertTrue(throttler.isThrottled()); + assertEquals(BrightnessInfo.BRIGHTNESS_MAX_REASON_THERMAL, + throttler.getBrightnessMaxReason()); + } + @Test public void testUpdateThermalThrottlingData() throws Exception { // Initialise brightness throttling levels // Ensure that they are overridden by setting the data through device config. @@ -476,18 +525,30 @@ public class BrightnessThrottlerTest { return new BrightnessThrottler(mInjectorMock, mHandler, mHandler, /* throttlingChangeCallback= */ () -> {}, /* uniqueDisplayId= */ null, /* thermalThrottlingDataId= */ null, - /* thermalThrottlingDataMap= */ new HashMap<>(1)); + /* thermalThrottlingDataMap= */ new HashMap<>(1), + /* tempSensor= */ null); } private BrightnessThrottler createThrottlerSupported(ThermalBrightnessThrottlingData data) { + SensorData tempSensor = SensorData.loadTempSensorUnspecifiedConfig(); + return createThrottlerSupportedWithTempSensor(data, tempSensor); + } + private BrightnessThrottler createThrottlerSupportedWithTempSensor( + ThermalBrightnessThrottlingData data, SensorData tempSensor) { assertNotNull(data); - HashMap<String, ThermalBrightnessThrottlingData> throttlingDataMap = new HashMap<>(1); + Map<String, ThermalBrightnessThrottlingData> throttlingDataMap = new HashMap<>(1); throttlingDataMap.put("default", data); return new BrightnessThrottler(mInjectorMock, mHandler, BackgroundThread.getHandler(), - () -> {}, "123", "default", throttlingDataMap); + () -> {}, "123", "default", throttlingDataMap, tempSensor); } private Temperature getSkinTemp(@ThrottlingStatus int status) { return new Temperature(30.0f, Temperature.TYPE_SKIN, "test_skin_temp", status); } + + private Temperature getDisplayTempWithName( + String sensorName, @ThrottlingStatus int status) { + assertNotNull(sensorName); + return new Temperature(30.0f, Temperature.TYPE_DISPLAY, sensorName, status); + } } |