diff options
3 files changed, 176 insertions, 57 deletions
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java index bc5fcb449c95..18e8fab54e3e 100644 --- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java +++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java @@ -38,6 +38,7 @@ import com.android.server.display.DisplayDeviceConfig.PowerThrottlingConfigData; import com.android.server.display.DisplayDeviceConfig.PowerThrottlingData; import com.android.server.display.DisplayDeviceConfig.ThermalBrightnessThrottlingData; import com.android.server.display.brightness.BrightnessReason; +import com.android.server.display.config.SensorData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.feature.DisplayManagerFlags; @@ -336,5 +337,10 @@ public class BrightnessClamperController { public float getBrightnessWearBedtimeModeCap() { return mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode(); } + + @NonNull + public SensorData getTempSensor() { + return mDisplayDeviceConfig.getTempSensor(); + } } } diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java index 944a8a65693b..449825831182 100644 --- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java +++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessThermalClamper.java @@ -35,8 +35,10 @@ 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.DeviceConfigParsingUtils; +import com.android.server.display.utils.SensorUtils; import java.io.PrintWriter; import java.util.List; @@ -49,9 +51,8 @@ class BrightnessThermalClamper extends BrightnessClamper<BrightnessThermalClamper.ThermalData> { private static final String TAG = "BrightnessThermalClamper"; - - @Nullable - private final IThermalService mThermalService; + @NonNull + private final ThermalStatusObserver mThermalStatusObserver; @NonNull private final DeviceConfigParameterProvider mConfigParameterProvider; // data from DeviceConfig, for all displays, for all dataSets @@ -66,7 +67,6 @@ class BrightnessThermalClamper extends // otherwise mDataFromDeviceConfig @Nullable private ThermalBrightnessThrottlingData mThermalThrottlingDataActive = null; - private boolean mStarted = false; @Nullable private String mUniqueDisplayId = null; @Nullable @@ -74,14 +74,6 @@ class BrightnessThermalClamper extends @Temperature.ThrottlingStatus private int mThrottlingStatus = Temperature.THROTTLING_NONE; - private final IThermalEventListener mThermalEventListener = new IThermalEventListener.Stub() { - @Override - public void notifyThrottling(Temperature temperature) { - @Temperature.ThrottlingStatus int status = temperature.getStatus(); - mHandler.post(() -> thermalStatusChanged(status)); - } - }; - private final BiFunction<String, String, ThrottlingLevel> mDataPointMapper = (key, value) -> { try { int status = DeviceConfigParsingUtils.parseThermalStatus(key); @@ -105,12 +97,11 @@ class BrightnessThermalClamper extends BrightnessThermalClamper(Injector injector, Handler handler, ClamperChangeListener listener, ThermalData thermalData) { super(handler, listener); - mThermalService = injector.getThermalService(); mConfigParameterProvider = injector.getDeviceConfigParameterProvider(); + mThermalStatusObserver = new ThermalStatusObserver(injector, handler); mHandler.post(() -> { setDisplayData(thermalData); loadOverrideData(); - start(); }); } @@ -139,32 +130,19 @@ class BrightnessThermalClamper extends @Override void stop() { - if (!mStarted) { - return; - } - try { - mThermalService.unregisterThermalEventListener(mThermalEventListener); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to unregister thermal status listener", e); - } - mStarted = false; + mThermalStatusObserver.stopObserving(); } @Override void dump(PrintWriter writer) { writer.println("BrightnessThermalClamper:"); - writer.println(" mStarted: " + mStarted); - if (mThermalService != null) { - writer.println(" ThermalService available"); - } else { - writer.println(" ThermalService not available"); - } writer.println(" mThrottlingStatus: " + mThrottlingStatus); writer.println(" mUniqueDisplayId: " + mUniqueDisplayId); writer.println(" mDataId: " + mDataId); writer.println(" mDataOverride: " + mThermalThrottlingDataOverride); writer.println(" mDataFromDeviceConfig: " + mThermalThrottlingDataFromDeviceConfig); writer.println(" mDataActive: " + mThermalThrottlingDataActive); + mThermalStatusObserver.dump(writer); super.dump(writer); } @@ -193,6 +171,7 @@ class BrightnessThermalClamper extends Slog.wtf(TAG, "Thermal throttling data is missing for thermalThrottlingDataId=" + mDataId); } + mThermalStatusObserver.registerSensor(data.getTempSensor()); } private void recalculateBrightnessCap() { @@ -226,19 +205,91 @@ class BrightnessThermalClamper extends } } - private void start() { - if (mThermalService == null) { - Slog.e(TAG, "Could not observe thermal status. Service not available"); - return; + + private final class ThermalStatusObserver extends IThermalEventListener.Stub { + private final Injector mInjector; + private final Handler mHandler; + private IThermalService mThermalService; + private boolean mStarted; + private SensorData mObserverTempSensor; + + ThermalStatusObserver(Injector injector, Handler handler) { + mInjector = injector; + mHandler = handler; + mStarted = false; } - try { - // We get a callback immediately upon registering so there's no need to query - // for the current value. - mThermalService.registerThermalEventListenerWithType(mThermalEventListener, - Temperature.TYPE_SKIN); - mStarted = true; - } catch (RemoteException e) { - Slog.e(TAG, "Failed to register thermal status listener", e); + + void registerSensor(SensorData tempSensor) { + if (!mStarted || mObserverTempSensor == null) { + mObserverTempSensor = tempSensor; + registerThermalListener(); + return; + } + + String curType = mObserverTempSensor.type; + mObserverTempSensor = tempSensor; + if (curType.equals(tempSensor.type)) { + 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, temperatureType); + mStarted = true; + } catch (RemoteException e) { + Slog.e(TAG, "Failed to register thermal status listener", e); + } + } + + @Override + public void notifyThrottling(Temperature temp) { + 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; + } + @Temperature.ThrottlingStatus int status = temp.getStatus(); + mHandler.post(() -> thermalStatusChanged(status)); + } + + void stopObserving() { + if (!mStarted) { + 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(" ThermalStatusObserver:"); + writer.println(" mStarted: " + mStarted); + writer.println(" mObserverTempSensor: " + mObserverTempSensor); + if (mThermalService != null) { + writer.println(" ThermalService available"); + } else { + writer.println(" ThermalService not available"); + } } } @@ -251,6 +302,9 @@ class BrightnessThermalClamper extends @Nullable ThermalBrightnessThrottlingData getThermalBrightnessThrottlingData(); + + @NonNull + SensorData getTempSensor(); } @VisibleForTesting diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessThermalClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessThermalClamperTest.java index 37d0f6250aaf..34f352e7bf54 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessThermalClamperTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessThermalClamperTest.java @@ -37,10 +37,14 @@ import com.android.internal.annotations.Keep; import com.android.server.display.DisplayDeviceConfig; 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.testutils.FakeDeviceConfigInterface; import com.android.server.testutils.TestHandler; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,9 +54,6 @@ import org.mockito.MockitoAnnotations; import java.util.List; -import junitparams.JUnitParamsRunner; -import junitparams.Parameters; - @RunWith(JUnitParamsRunner.class) public class BrightnessThermalClamperTest { @@ -125,13 +126,13 @@ public class BrightnessThermalClamperTest { public void testNotifyThrottlingAfterOnDisplayChange(List<ThrottlingLevel> throttlingLevels, @Temperature.ThrottlingStatus int throttlingStatus, boolean expectedActive, float expectedBrightness) throws RemoteException { - IThermalEventListener thermalEventListener = captureThermalEventListener(); + IThermalEventListener thermalEventListener = captureSkinThermalEventListener(); mClamper.onDisplayChanged(new TestThermalData(throttlingLevels)); mTestHandler.flush(); assertFalse(mClamper.isActive()); assertEquals(PowerManager.BRIGHTNESS_MAX, mClamper.getBrightnessCap(), FLOAT_TOLERANCE); - thermalEventListener.notifyThrottling(createTemperature(throttlingStatus)); + thermalEventListener.notifyThrottling(createSkinTemperature(throttlingStatus)); mTestHandler.flush(); assertEquals(expectedActive, mClamper.isActive()); assertEquals(expectedBrightness, mClamper.getBrightnessCap(), FLOAT_TOLERANCE); @@ -139,11 +140,11 @@ public class BrightnessThermalClamperTest { @Test @Parameters(method = "testThrottlingData") - public void testOnDisplayChangeAfterNotifyThrottlng(List<ThrottlingLevel> throttlingLevels, + public void testOnDisplayChangeAfterNotifyThrottling(List<ThrottlingLevel> throttlingLevels, @Temperature.ThrottlingStatus int throttlingStatus, boolean expectedActive, float expectedBrightness) throws RemoteException { - IThermalEventListener thermalEventListener = captureThermalEventListener(); - thermalEventListener.notifyThrottling(createTemperature(throttlingStatus)); + IThermalEventListener thermalEventListener = captureSkinThermalEventListener(); + thermalEventListener.notifyThrottling(createSkinTemperature(throttlingStatus)); mTestHandler.flush(); assertFalse(mClamper.isActive()); assertEquals(PowerManager.BRIGHTNESS_MAX, mClamper.getBrightnessCap(), FLOAT_TOLERANCE); @@ -156,8 +157,8 @@ public class BrightnessThermalClamperTest { @Test public void testOverrideData() throws RemoteException { - IThermalEventListener thermalEventListener = captureThermalEventListener(); - thermalEventListener.notifyThrottling(createTemperature(Temperature.THROTTLING_SEVERE)); + IThermalEventListener thermalEventListener = captureSkinThermalEventListener(); + thermalEventListener.notifyThrottling(createSkinTemperature(Temperature.THROTTLING_SEVERE)); mTestHandler.flush(); assertFalse(mClamper.isActive()); assertEquals(PowerManager.BRIGHTNESS_MAX, mClamper.getBrightnessCap(), FLOAT_TOLERANCE); @@ -183,15 +184,60 @@ public class BrightnessThermalClamperTest { assertEquals(0.4f, mClamper.getBrightnessCap(), FLOAT_TOLERANCE); } - private IThermalEventListener captureThermalEventListener() throws RemoteException { + @Test + public void testDisplaySensorBasedThrottling() throws RemoteException { + final int severity = PowerManager.THERMAL_STATUS_SEVERE; + IThermalEventListener thermalEventListener = captureSkinThermalEventListener(); + // Update config to listen to display type sensor. + final SensorData tempSensor = new SensorData("DISPLAY", "VIRTUAL-SKIN-DISPLAY"); + final TestThermalData thermalData = + new TestThermalData( + DISPLAY_ID, + DisplayDeviceConfig.DEFAULT_ID, + List.of(new ThrottlingLevel(severity, 0.5f)), + tempSensor); + mClamper.onDisplayChanged(thermalData); + mTestHandler.flush(); + verify(mMockThermalService).unregisterThermalEventListener(thermalEventListener); + thermalEventListener = captureThermalEventListener(Temperature.TYPE_DISPLAY); + assertFalse(mClamper.isActive()); + + // Verify no throttling triggered when any other sensor notification received. + thermalEventListener.notifyThrottling(createSkinTemperature(severity)); + mTestHandler.flush(); + assertFalse(mClamper.isActive()); + + thermalEventListener.notifyThrottling(createDisplayTemperature("OTHER-SENSOR", severity)); + mTestHandler.flush(); + assertFalse(mClamper.isActive()); + + assertEquals(PowerManager.BRIGHTNESS_MAX, mClamper.getBrightnessCap(), FLOAT_TOLERANCE); + + // Verify throttling triggered when display sensor of given name throttled. + thermalEventListener.notifyThrottling(createDisplayTemperature(tempSensor.name, severity)); + mTestHandler.flush(); + assertTrue(mClamper.isActive()); + assertEquals(0.5f, mClamper.getBrightnessCap(), FLOAT_TOLERANCE); + } + + private IThermalEventListener captureSkinThermalEventListener() throws RemoteException { + return captureThermalEventListener(Temperature.TYPE_SKIN); + } + + private IThermalEventListener captureThermalEventListener(int type) throws RemoteException { ArgumentCaptor<IThermalEventListener> captor = ArgumentCaptor.forClass( IThermalEventListener.class); verify(mMockThermalService).registerThermalEventListenerWithType(captor.capture(), eq( - Temperature.TYPE_SKIN)); + type)); return captor.getValue(); } - private Temperature createTemperature(@Temperature.ThrottlingStatus int status) { + private Temperature createDisplayTemperature( + @NonNull String sensorName, @Temperature.ThrottlingStatus int status) { + return new Temperature(100, Temperature.TYPE_DISPLAY, sensorName, status); + } + + private Temperature createSkinTemperature(@Temperature.ThrottlingStatus int status) { return new Temperature(100, Temperature.TYPE_SKIN, "test_temperature", status); } @@ -217,19 +263,26 @@ public class BrightnessThermalClamperTest { private final String mUniqueDisplayId; private final String mDataId; private final ThermalBrightnessThrottlingData mData; + private final SensorData mTempSensor; private TestThermalData() { - this(DISPLAY_ID, DisplayDeviceConfig.DEFAULT_ID, null); + this(DISPLAY_ID, DisplayDeviceConfig.DEFAULT_ID, null, + SensorData.loadTempSensorUnspecifiedConfig()); } private TestThermalData(List<ThrottlingLevel> data) { - this(DISPLAY_ID, DisplayDeviceConfig.DEFAULT_ID, data); + this(DISPLAY_ID, DisplayDeviceConfig.DEFAULT_ID, data, + SensorData.loadTempSensorUnspecifiedConfig()); } - private TestThermalData(String uniqueDisplayId, String dataId, List<ThrottlingLevel> data) { + + private TestThermalData(String uniqueDisplayId, String dataId, List<ThrottlingLevel> data, + SensorData tempSensor) { mUniqueDisplayId = uniqueDisplayId; mDataId = dataId; mData = ThermalBrightnessThrottlingData.create(data); + mTempSensor = tempSensor; } + @NonNull @Override public String getUniqueDisplayId() { @@ -247,5 +300,11 @@ public class BrightnessThermalClamperTest { public ThermalBrightnessThrottlingData getThermalBrightnessThrottlingData() { return mData; } + + @NonNull + @Override + public SensorData getTempSensor() { + return mTempSensor; + } } } |