From c9bad2432f6e9296f29c17f129bb2abce82e1dd5 Mon Sep 17 00:00:00 2001 From: Fiona Campbell Date: Thu, 9 Feb 2023 12:41:28 +0000 Subject: [PATCH] Add throttlingDataId to deviceConfig Currently, we don't have the ability to specify the brightnessThrottlingDataModeId when overriding values in BrightnessThrottler through the DeviceConfig. If we do use the DeviceConfig to override values, any mode-specific throttling policies will be overwritten and lost, since we do not pick and choose between the DeviceConfig values and the DisplayDeviceConfig values. This change allows us to specify the brightness throttling id in the DeviceConfig strings, in order to change the throttling policy based on the id chosen based on the current display layout. Strings passed used by the display config must specify the uniqueDisplayId, and may specify the throttling id, if unspecified, "default" will be used. Valid strings can include: 123,1,critical,0.8;456,2,moderate,0.9,critical,0.7 123,1,critical,0.8,default;123,1,moderate,0.6,mode_2;456,2,moderate,0.9,critical,0.7 Given that one BrightnessThrottler is currently created for each DisplayPowerController, the values stored for the current mode are just per display, but the String & derived data passed in via DeviceConfig will continue to be global, since this is more effective for debugging purposes. DeviceConfig values take top priority, however, throttling Id specific values take priority over default values, so an Id-specific value set from the DisplayDeviceConfig, will take priority over a default throttling id value from DeviceConfig. Bug: 267623520 Test: atest com.server.android.display Test: atest BrightnessThrottlerTest DisplayModeDirectorTest LogicalDisplayMapperTest Test: adb shell cmd device_state state 4 && adb shell device_config put display_manager brightness_throttling_data "local:4619827677550801152,3,moderate,0.5,severe,0.379518072,emergency,0.248995984\;local:4619827677550801153,1,moderate,0.75\;local:4619827677550801153,1,moderate,0.11,concurrent" Change-Id: I90bd673c794bdcf4b6522997bacd924d7e122c09 --- .../hardware/display/DisplayManager.java | 6 +- .../server/display/BrightnessThrottler.java | 169 +++++++++++++----- .../server/display/DisplayDeviceConfig.java | 56 +++--- .../display/DisplayPowerController.java | 20 ++- .../display/DisplayPowerController2.java | 18 +- .../android/server/display/layout/Layout.java | 4 +- .../display/BrightnessThrottlerTest.java | 60 +++---- .../display/DisplayDeviceConfigTest.java | 64 ++++--- 8 files changed, 243 insertions(+), 154 deletions(-) diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index b5281a5025b84..2aead3c22deb6 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -1758,10 +1758,12 @@ public final class DisplayManager { /** * Key for the brightness throttling data as a String formatted: * ,,[,] - * Where the latter part is repeated for each throttling level, and the entirety is repeated - * for each display, separated by a semicolon. + * [,]? + * Where [,] is repeated for each throttling level. + * The entirety is repeated for each display and throttling id, separated by a semicolon. * For example: * 123,1,critical,0.8;456,2,moderate,0.9,critical,0.7 + * 123,1,critical,0.8,default;123,1,moderate,0.6,id_2;456,2,moderate,0.9,critical,0.7 */ String KEY_BRIGHTNESS_THROTTLING_DATA = "brightness_throttling_data"; } diff --git a/services/core/java/com/android/server/display/BrightnessThrottler.java b/services/core/java/com/android/server/display/BrightnessThrottler.java index eccee52f37aab..067a2d6d8b0dc 100644 --- a/services/core/java/com/android/server/display/BrightnessThrottler.java +++ b/services/core/java/com/android/server/display/BrightnessThrottler.java @@ -16,7 +16,10 @@ package com.android.server.display; +import static com.android.server.display.DisplayDeviceConfig.DEFAULT_ID; + import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManager; @@ -63,8 +66,16 @@ class BrightnessThrottler { private final DeviceConfigInterface mDeviceConfig; private int mThrottlingStatus; + + // Maps the throttling ID to the data. Sourced from DisplayDeviceConfig. + @NonNull + private HashMap mDdcThrottlingDataMap; + + // Current throttling data being used. + // Null if we do not support throttling. + @Nullable private BrightnessThrottlingData mThrottlingData; - private BrightnessThrottlingData mDdcThrottlingData; + private float mBrightnessCap = PowerManager.BRIGHTNESS_MAX; private @BrightnessInfo.BrightnessMaxReason int mBrightnessMaxReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; @@ -73,35 +84,45 @@ class BrightnessThrottler { // The most recent string that has been set from DeviceConfig private String mBrightnessThrottlingDataString; + // The brightness throttling configuration that should be used. + private String mBrightnessThrottlingDataId; + // 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. - private HashMap mBrightnessThrottlingDataOverride = - new HashMap<>(1); + // We need to store the data for every display device, so we do not need to update this each + // time the underlying display device changes. + // This map is indexed by uniqueDisplayId, to provide maps for throttlingId -> throttlingData. + // HashMap< uniqueDisplayId, HashMap< throttlingDataId, BrightnessThrottlingData >> + private final HashMap> + mBrightnessThrottlingDataOverride = new HashMap<>(1); - BrightnessThrottler(Handler handler, BrightnessThrottlingData throttlingData, - Runnable throttlingChangeCallback, String uniqueDisplayId) { - this(new Injector(), handler, handler, throttlingData, throttlingChangeCallback, - uniqueDisplayId); + BrightnessThrottler(Handler handler, Runnable throttlingChangeCallback, String uniqueDisplayId, + String throttlingDataId, + @NonNull HashMap brightnessThrottlingDataMap) { + this(new Injector(), handler, handler, throttlingChangeCallback, + uniqueDisplayId, throttlingDataId, brightnessThrottlingDataMap); } @VisibleForTesting BrightnessThrottler(Injector injector, Handler handler, Handler deviceConfigHandler, - BrightnessThrottlingData throttlingData, Runnable throttlingChangeCallback, - String uniqueDisplayId) { + Runnable throttlingChangeCallback, String uniqueDisplayId, String throttlingDataId, + @NonNull HashMap brightnessThrottlingDataMap) { mInjector = injector; mHandler = handler; mDeviceConfigHandler = deviceConfigHandler; - mThrottlingData = throttlingData; - mDdcThrottlingData = throttlingData; + mDdcThrottlingDataMap = brightnessThrottlingDataMap; mThrottlingChangeCallback = throttlingChangeCallback; mSkinThermalStatusObserver = new SkinThermalStatusObserver(mInjector, mHandler); mUniqueDisplayId = uniqueDisplayId; mDeviceConfig = injector.getDeviceConfig(); mDeviceConfigListener = new DeviceConfigListener(); - - resetThrottlingData(mThrottlingData, mUniqueDisplayId); + mBrightnessThrottlingDataId = throttlingDataId; + mDdcThrottlingDataMap = brightnessThrottlingDataMap; + loadBrightnessThrottlingDataFromDeviceConfig(); + loadBrightnessThrottlingDataFromDisplayDeviceConfig(mDdcThrottlingDataMap, + mBrightnessThrottlingDataId, mUniqueDisplayId); } boolean deviceSupportsThrottling() { @@ -133,23 +154,14 @@ class BrightnessThrottler { mThrottlingStatus = THROTTLING_INVALID; } - private void resetThrottlingData() { - resetThrottlingData(mDdcThrottlingData, mUniqueDisplayId); - } - - void resetThrottlingData(BrightnessThrottlingData throttlingData, String displayId) { - stop(); - - mUniqueDisplayId = displayId; - mDdcThrottlingData = throttlingData; - mDeviceConfigListener.startListening(); - reloadBrightnessThrottlingDataOverride(); - mThrottlingData = mBrightnessThrottlingDataOverride.getOrDefault(mUniqueDisplayId, - throttlingData); - - if (deviceSupportsThrottling()) { - mSkinThermalStatusObserver.startObserving(); - } + void loadBrightnessThrottlingDataFromDisplayDeviceConfig( + HashMap ddcThrottlingDataMap, + String brightnessThrottlingDataId, + String uniqueDisplayId) { + mDdcThrottlingDataMap = ddcThrottlingDataMap; + mBrightnessThrottlingDataId = brightnessThrottlingDataId; + mUniqueDisplayId = uniqueDisplayId; + resetThrottlingData(); } private float verifyAndConstrainBrightnessCap(float brightness) { @@ -183,7 +195,7 @@ class BrightnessThrottler { float brightnessCap = PowerManager.BRIGHTNESS_MAX; int brightnessMaxReason = BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE; - if (mThrottlingStatus != THROTTLING_INVALID) { + if (mThrottlingStatus != THROTTLING_INVALID && mThrottlingData != null) { // Throttling levels are sorted by increasing severity for (ThrottlingLevel level : mThrottlingData.throttlingLevels) { if (level.thermalStatus <= mThrottlingStatus) { @@ -218,13 +230,14 @@ class BrightnessThrottler { private void dumpLocal(PrintWriter pw) { pw.println("BrightnessThrottler:"); + pw.println(" mBrightnessThrottlingDataId=" + mBrightnessThrottlingDataId); pw.println(" mThrottlingData=" + mThrottlingData); - pw.println(" mDdcThrottlingData=" + mDdcThrottlingData); pw.println(" mUniqueDisplayId=" + mUniqueDisplayId); pw.println(" mThrottlingStatus=" + mThrottlingStatus); pw.println(" mBrightnessCap=" + mBrightnessCap); pw.println(" mBrightnessMaxReason=" + BrightnessInfo.briMaxReasonToString(mBrightnessMaxReason)); + pw.println(" mDdcThrottlingDataMap=" + mDdcThrottlingDataMap); pw.println(" mBrightnessThrottlingDataOverride=" + mBrightnessThrottlingDataOverride); pw.println(" mBrightnessThrottlingDataString=" + mBrightnessThrottlingDataString); @@ -237,8 +250,18 @@ class BrightnessThrottler { /* defaultValue= */ null); } - private boolean parseAndSaveData(@NonNull String strArray, - @NonNull HashMap tempBrightnessThrottlingData) { + // The brightness throttling data id may or may not be specified in the string that is passed + // in, if there is none specified, we assume it is for the default case. Each string passed in + // here must be for one display and one throttling id. + // 123,1,critical,0.8 + // 456,2,moderate,0.9,critical,0.7 + // 456,2,moderate,0.9,critical,0.7,default + // 456,2,moderate,0.9,critical,0.7,id_2 + // displayId, number, * number + // displayId, * number>, throttlingId + private boolean parseAndAddData(@NonNull String strArray, + @NonNull HashMap> + displayIdToThrottlingIdToBtd) { boolean validConfig = true; String[] items = strArray.split(","); int i = 0; @@ -254,29 +277,42 @@ class BrightnessThrottler { for (int j = 0; j < noOfThrottlingPoints; j++) { String severity = items[i++]; int status = parseThermalStatus(severity); - float brightnessPoint = parseBrightness(items[i++]); - throttlingLevels.add(new ThrottlingLevel(status, brightnessPoint)); } - BrightnessThrottlingData toSave = + + String throttlingDataId = (i < items.length) ? items[i++] : DEFAULT_ID; + BrightnessThrottlingData throttlingLevelsData = DisplayDeviceConfig.BrightnessThrottlingData.create(throttlingLevels); - tempBrightnessThrottlingData.put(uniqueDisplayId, toSave); + + // Add throttlingLevelsData to inner map where necessary. + HashMap throttlingMapForDisplay = + displayIdToThrottlingIdToBtd.get(uniqueDisplayId); + if (throttlingMapForDisplay == null) { + throttlingMapForDisplay = new HashMap<>(); + throttlingMapForDisplay.put(throttlingDataId, throttlingLevelsData); + displayIdToThrottlingIdToBtd.put(uniqueDisplayId, throttlingMapForDisplay); + } else if (throttlingMapForDisplay.containsKey(throttlingDataId)) { + Slog.e(TAG, "Throttling data for display " + uniqueDisplayId + + "contains duplicate throttling ids: '" + throttlingDataId + "'"); + return false; + } else { + throttlingMapForDisplay.put(throttlingDataId, throttlingLevelsData); + } } catch (NumberFormatException | IndexOutOfBoundsException | UnknownThermalStatusException e) { - validConfig = false; Slog.e(TAG, "Throttling data is invalid array: '" + strArray + "'", e); + validConfig = false; } if (i != items.length) { validConfig = false; } - return validConfig; } - public void reloadBrightnessThrottlingDataOverride() { - HashMap tempBrightnessThrottlingData = + private void loadBrightnessThrottlingDataFromDeviceConfig() { + HashMap> tempThrottlingData = new HashMap<>(1); mBrightnessThrottlingDataString = getBrightnessThrottlingDataString(); boolean validConfig = true; @@ -284,15 +320,15 @@ class BrightnessThrottler { if (mBrightnessThrottlingDataString != null) { String[] throttlingDataSplits = mBrightnessThrottlingDataString.split(";"); for (String s : throttlingDataSplits) { - if (!parseAndSaveData(s, tempBrightnessThrottlingData)) { + if (!parseAndAddData(s, tempThrottlingData)) { validConfig = false; break; } } if (validConfig) { - mBrightnessThrottlingDataOverride.putAll(tempBrightnessThrottlingData); - tempBrightnessThrottlingData.clear(); + mBrightnessThrottlingDataOverride.putAll(tempThrottlingData); + tempThrottlingData.clear(); } } else { @@ -300,15 +336,50 @@ class BrightnessThrottler { } } + private void resetThrottlingData() { + stop(); + + mDeviceConfigListener.startListening(); + + // Get throttling data for this id, if it exists + mThrottlingData = getConfigFromId(mBrightnessThrottlingDataId); + + // Fallback to default id otherwise. + if (!DEFAULT_ID.equals(mBrightnessThrottlingDataId) && mThrottlingData == null) { + mThrottlingData = getConfigFromId(DEFAULT_ID); + Slog.d(TAG, "Falling back to default throttling Id"); + } + + if (deviceSupportsThrottling()) { + mSkinThermalStatusObserver.startObserving(); + } + } + + private BrightnessThrottlingData getConfigFromId(String id) { + BrightnessThrottlingData returnValue; + + // Fallback pattern for fetching correct throttling data for this display and id. + // 1) throttling data from device config for this throttling data id + returnValue = mBrightnessThrottlingDataOverride.get(mUniqueDisplayId) == null + ? null + : mBrightnessThrottlingDataOverride.get(mUniqueDisplayId).get(id); + // 2) throttling data from ddc for this throttling data id + returnValue = returnValue == null + ? mDdcThrottlingDataMap.get(id) + : returnValue; + + return returnValue; + } + /** * Listens to config data change and updates the brightness throttling data using * DisplayManager#KEY_BRIGHTNESS_THROTTLING_DATA. * The format should be a string similar to: "local:4619827677550801152,2,moderate,0.5,severe, * 0.379518072;local:4619827677550801151,1,moderate,0.75" * In this order: - * ,,[,] - * Where the latter part is repeated for each throttling level, and the entirety is repeated - * for each display, separated by a semicolon. + * ,,[,][,throttlingId]? + * Where [,] is repeated for each throttling level, and the + * entirety is repeated for each display & throttling data id, separated by a semicolon. */ public class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener { public Executor mExecutor = new HandlerExecutor(mDeviceConfigHandler); @@ -320,7 +391,7 @@ class BrightnessThrottler { @Override public void onPropertiesChanged(DeviceConfig.Properties properties) { - reloadBrightnessThrottlingDataOverride(); + loadBrightnessThrottlingDataFromDeviceConfig(); resetThrottlingData(); } } diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index f4b3f1ab7b11d..da021158eb652 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -143,17 +143,17 @@ import javax.xml.datatype.DatatypeConfigurationException; * 0.01 * * - * - * - * severe - * 0.07 - * - * - * critical - * 0.005 - * - * - * + * // optional attribute, leave blank for default + * + * moderate + * 0.2 + * + * + * severe + * 0.1 + * + * + * * critical * @@ -687,8 +687,8 @@ public class DisplayDeviceConfig { private int[] mHighDisplayBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS; private int[] mHighAmbientBrightnessThresholds = DEFAULT_BRIGHTNESS_THRESHOLDS; - private final Map mBrightnessThrottlingDataMap = - new HashMap<>(); + private final HashMap + mBrightnessThrottlingDataMapByThrottlingId = new HashMap<>(); private final Map> mRefreshRateThrottlingMap = new HashMap<>(); @@ -1346,11 +1346,11 @@ public class DisplayDeviceConfig { } /** - * @param id The ID of the throttling data - * @return brightness throttling configuration data for the display. + * @return brightness throttling configuration data for this display, for each throttling id. */ - public BrightnessThrottlingData getBrightnessThrottlingData(String id) { - return BrightnessThrottlingData.create(mBrightnessThrottlingDataMap.get(id)); + public HashMap + getBrightnessThrottlingDataMapByThrottlingId() { + return mBrightnessThrottlingDataMapByThrottlingId; } /** @@ -1525,7 +1525,8 @@ public class DisplayDeviceConfig { + ", isHbmEnabled=" + mIsHighBrightnessModeEnabled + ", mHbmData=" + mHbmData + ", mSdrToHdrRatioSpline=" + mSdrToHdrRatioSpline - + ", mBrightnessThrottlingData=" + mBrightnessThrottlingDataMap + + ", mBrightnessThrottlingDataMapByThrottlingId=" + + mBrightnessThrottlingDataMapByThrottlingId + "\n" + ", mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease @@ -1918,11 +1919,11 @@ public class DisplayDeviceConfig { if (!badConfig) { String id = map.getId() == null ? DEFAULT_ID : map.getId(); - if (mBrightnessThrottlingDataMap.containsKey(id)) { + if (mBrightnessThrottlingDataMapByThrottlingId.containsKey(id)) { throw new RuntimeException("Brightness throttling data with ID " + id + " already exists"); } - mBrightnessThrottlingDataMap.put(id, + mBrightnessThrottlingDataMapByThrottlingId.put(id, BrightnessThrottlingData.create(throttlingLevels)); } } @@ -1971,8 +1972,8 @@ public class DisplayDeviceConfig { )); } if (refreshRates.size() == 0) { - Slog.w(TAG, "RefreshRateThrottling: no valid throttling points fond for map, mapId=" - + id); + Slog.w(TAG, "RefreshRateThrottling: no valid throttling points found for map, " + + "mapId=" + id); continue; } mRefreshRateThrottlingMap.put(id, refreshRates); @@ -3077,7 +3078,7 @@ public class DisplayDeviceConfig { /** - * Creates multiple teperature based throttling levels of brightness + * Creates multiple temperature based throttling levels of brightness */ public static BrightnessThrottlingData create(List throttlingLevels) { if (throttlingLevels == null || throttlingLevels.size() == 0) { @@ -3120,15 +3121,6 @@ public class DisplayDeviceConfig { return new BrightnessThrottlingData(throttlingLevels); } - static public BrightnessThrottlingData create(BrightnessThrottlingData other) { - if (other == null) { - return null; - } - - return BrightnessThrottlingData.create(other.throttlingLevels); - } - - @Override public String toString() { return "BrightnessThrottlingData{" diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index f5859eed34f1d..2322e03d6d378 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -505,7 +505,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private DisplayDeviceConfig mDisplayDeviceConfig; - // Identifiers for suspend blocker acuisition requests + // Identifiers for suspend blocker acquisition requests private final String mSuspendBlockerIdUnfinishedBusiness; private final String mSuspendBlockerIdOnStateChanged; private final String mSuspendBlockerIdProxPositive; @@ -515,6 +515,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private boolean mIsEnabled; private boolean mIsInTransition; + // The id of the brightness throttling policy that should be used. private String mBrightnessThrottlingDataId; // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there @@ -905,14 +906,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call loadNitBasedBrightnessSetting(); /// Since the underlying display-device changed, we really don't know the - // last command that was sent to change it's state. Lets assume it is unknown so + // last command that was sent to change it's state. Let's assume it is unknown so // that we trigger a change immediately. mPowerState.resetScreenState(); } else if (!mBrightnessThrottlingDataId.equals(brightnessThrottlingDataId)) { changed = true; mBrightnessThrottlingDataId = brightnessThrottlingDataId; - mBrightnessThrottler.resetThrottlingData( - config.getBrightnessThrottlingData(mBrightnessThrottlingDataId), + mBrightnessThrottler.loadBrightnessThrottlingDataFromDisplayDeviceConfig( + config.getBrightnessThrottlingDataMapByThrottlingId(), + mBrightnessThrottlingDataId, mUniqueDisplayId); } if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) { @@ -981,9 +983,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call sdrBrightness, maxDesiredHdrSdrRatio); } }); - mBrightnessThrottler.resetThrottlingData( - mDisplayDeviceConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId), - mUniqueDisplayId); + mBrightnessThrottler.loadBrightnessThrottlingDataFromDisplayDeviceConfig( + mDisplayDeviceConfig.getBrightnessThrottlingDataMapByThrottlingId(), + mBrightnessThrottlingDataId, mUniqueDisplayId); } private void sendUpdatePowerState() { @@ -2116,11 +2118,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); return new BrightnessThrottler(mHandler, - ddConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId), () -> { sendUpdatePowerState(); postBrightnessChangeRunnable(); - }, mUniqueDisplayId); + }, mUniqueDisplayId, mLogicalDisplay.getBrightnessThrottlingDataIdLocked(), + ddConfig.getBrightnessThrottlingDataMapByThrottlingId()); } private void blockScreenOn() { diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 5306ac0e57b9f..11a7a8c061259 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -400,6 +400,7 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private boolean mIsEnabled; private boolean mIsInTransition; + // The id of the brightness throttling policy that should be used. private String mBrightnessThrottlingDataId; // DPCs following the brightness of this DPC. This is used in concurrent displays mode - there @@ -722,14 +723,15 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mDisplayPowerProximityStateController.notifyDisplayDeviceChanged(config); // Since the underlying display-device changed, we really don't know the - // last command that was sent to change it's state. Lets assume it is unknown so + // last command that was sent to change it's state. Let's assume it is unknown so // that we trigger a change immediately. mPowerState.resetScreenState(); } else if (!mBrightnessThrottlingDataId.equals(brightnessThrottlingDataId)) { changed = true; mBrightnessThrottlingDataId = brightnessThrottlingDataId; - mBrightnessThrottler.resetThrottlingData( - config.getBrightnessThrottlingData(mBrightnessThrottlingDataId), + mBrightnessThrottler.loadBrightnessThrottlingDataFromDisplayDeviceConfig( + config.getBrightnessThrottlingDataMapByThrottlingId(), + mBrightnessThrottlingDataId, mUniqueDisplayId); } if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) { @@ -795,9 +797,9 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal sdrBrightness, maxDesiredHdrSdrRatio); } }); - mBrightnessThrottler.resetThrottlingData( - mDisplayDeviceConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId), - mUniqueDisplayId); + mBrightnessThrottler.loadBrightnessThrottlingDataFromDisplayDeviceConfig( + mDisplayDeviceConfig.getBrightnessThrottlingDataMapByThrottlingId(), + mBrightnessThrottlingDataId, mUniqueDisplayId); } private void sendUpdatePowerState() { @@ -1756,11 +1758,11 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked(); final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig(); return new BrightnessThrottler(mHandler, - ddConfig.getBrightnessThrottlingData(mBrightnessThrottlingDataId), () -> { sendUpdatePowerState(); postBrightnessChangeRunnable(); - }, mUniqueDisplayId); + }, mUniqueDisplayId, mLogicalDisplay.getBrightnessThrottlingDataIdLocked(), + ddConfig.getBrightnessThrottlingDataMapByThrottlingId()); } private void blockScreenOn() { diff --git a/services/core/java/com/android/server/display/layout/Layout.java b/services/core/java/com/android/server/display/layout/Layout.java index f86ee249408c2..634f31d6268cd 100644 --- a/services/core/java/com/android/server/display/layout/Layout.java +++ b/services/core/java/com/android/server/display/layout/Layout.java @@ -338,7 +338,9 @@ public class Layout { } /** - * @return The ID of the brightness throttling map that this display should use. + * Gets the id of the brightness throttling map that should be used. + * @return The ID of the brightness throttling map that this display should use, null if + * unspecified, will fall back to default. */ public String getBrightnessThrottlingMapId() { return mBrightnessThrottlingMapId; diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java index ffe2fec380a83..ce4b438470dfb 100644 --- a/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/BrightnessThrottlerTest.java @@ -54,6 +54,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; @SmallTest @@ -122,8 +123,6 @@ public class BrightnessThrottlerTest { BrightnessThrottlingData data; data = BrightnessThrottlingData.create((List)null); assertEquals(data, null); - data = BrightnessThrottlingData.create((BrightnessThrottlingData)null); - assertEquals(data, null); data = BrightnessThrottlingData.create(new ArrayList()); assertEquals(data, null); data = BrightnessThrottlingData.create(unsortedThermalLevels); @@ -146,7 +145,7 @@ public class BrightnessThrottlerTest { } @Test - public void testThrottlingUnsupported() throws Exception { + public void testThrottlingUnsupported() { final BrightnessThrottler throttler = createThrottlerUnsupported(); assertFalse(throttler.deviceSupportsThrottling()); @@ -307,37 +306,18 @@ public class BrightnessThrottlerTest { verify(mThermalServiceMock).registerThermalEventListenerWithType( mThermalEventListenerCaptor.capture(), eq(Temperature.TYPE_SKIN)); final IThermalEventListener listener = mThermalEventListenerCaptor.getValue(); + testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.4f); - // Set status too low to trigger throttling - listener.notifyThrottling(getSkinTemp(level.thermalStatus - 1)); - mTestLooper.dispatchAll(); - assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f); - assertFalse(throttler.isThrottled()); - - // Set status high enough to trigger throttling - listener.notifyThrottling(getSkinTemp(level.thermalStatus)); - mTestLooper.dispatchAll(); - assertEquals(0.4f, throttler.getBrightnessCap(), 0f); - assertTrue(throttler.isThrottled()); - - // Update thresholds - // This data is equivalent to the string "123,1,critical,0.8", passed below - final ThrottlingLevel newLevel = new ThrottlingLevel(PowerManager.THERMAL_STATUS_CRITICAL, - 0.8f); // Set new (valid) data from device config mDeviceConfigFake.setBrightnessThrottlingData("123,1,critical,0.8"); + testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.8f); - // Set status too low to trigger throttling - listener.notifyThrottling(getSkinTemp(newLevel.thermalStatus - 1)); - mTestLooper.dispatchAll(); - assertEquals(PowerManager.BRIGHTNESS_MAX, throttler.getBrightnessCap(), 0f); - assertFalse(throttler.isThrottled()); - - // Set status high enough to trigger throttling - listener.notifyThrottling(getSkinTemp(newLevel.thermalStatus)); - mTestLooper.dispatchAll(); - assertEquals(newLevel.brightness, throttler.getBrightnessCap(), 0f); - assertTrue(throttler.isThrottled()); + mDeviceConfigFake.setBrightnessThrottlingData( + "123,1,critical,0.75;123,1,critical,0.99,id_2"); + testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.75f); + mDeviceConfigFake.setBrightnessThrottlingData( + "123,1,critical,0.8,default;123,1,critical,0.99,id_2"); + testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.8f); } @Test public void testInvalidThrottlingStrings() throws Exception { @@ -370,6 +350,18 @@ public class BrightnessThrottlerTest { testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f); mDeviceConfigFake.setBrightnessThrottlingData(""); // Invalid format testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f); + // Invalid string format + mDeviceConfigFake.setBrightnessThrottlingData( + "123,default,1,critical,0.75,1,critical,0.99"); + testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f); + // Invalid level string and number string + mDeviceConfigFake.setBrightnessThrottlingData( + "123,1,1,critical,0.75,id_2,1,critical,0.99"); + testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f); + // Invalid format - (two default ids for same display) + mDeviceConfigFake.setBrightnessThrottlingData( + "123,1,critical,0.75,default;123,1,critical,0.99"); + testThrottling(throttler, listener, PowerManager.BRIGHTNESS_MAX, 0.25f); } private void testThrottling(BrightnessThrottler throttler, IThermalEventListener listener, @@ -472,13 +464,17 @@ public class BrightnessThrottlerTest { } private BrightnessThrottler createThrottlerUnsupported() { - return new BrightnessThrottler(mInjectorMock, mHandler, mHandler, null, () -> {}, null); + return new BrightnessThrottler(mInjectorMock, mHandler, mHandler, + /* throttlingChangeCallback= */ () -> {}, /* uniqueDisplayId= */ null, + /* throttlingDataId= */ null, /* throttlingDataMap= */ new HashMap<>(1)); } private BrightnessThrottler createThrottlerSupported(BrightnessThrottlingData data) { assertNotNull(data); + HashMap throttlingDataMap = new HashMap<>(1); + throttlingDataMap.put("default", data); return new BrightnessThrottler(mInjectorMock, mHandler, BackgroundThread.getHandler(), - data, () -> {}, "123"); + () -> {}, "123", "default", throttlingDataMap); } private Temperature getSkinTemp(@ThrottlingStatus int status) { diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java index 9fd647bb0b905..ed07559498698 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -50,6 +50,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; @SmallTest @@ -186,50 +187,72 @@ public final class DisplayDeviceConfigTest { assertArrayEquals(new int[]{-1, 10, 20, 30, 40}, mDisplayDeviceConfig.getScreenOffBrightnessSensorValueToLux()); - List throttlingLevels = - new ArrayList(); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + List + defaultThrottlingLevels = new ArrayList<>(); + defaultThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 0.4f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + defaultThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 0.3f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + defaultThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 0.2f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + defaultThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 0.1f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + defaultThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 0.05f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + defaultThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 0.025f )); - assertEquals(new DisplayDeviceConfig.BrightnessThrottlingData(throttlingLevels), - mDisplayDeviceConfig.getBrightnessThrottlingData("default")); - throttlingLevels.clear(); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.BrightnessThrottlingData defaultThrottlingData = + new DisplayDeviceConfig.BrightnessThrottlingData(defaultThrottlingLevels); + + List + concurrentThrottlingLevels = new ArrayList<>(); + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 0.2f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 0.15f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 0.1f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 0.05f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 0.025f )); - throttlingLevels.add(new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.BrightnessThrottlingData.ThrottlingLevel( DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 0.0125f )); - assertEquals(new DisplayDeviceConfig.BrightnessThrottlingData(throttlingLevels), - mDisplayDeviceConfig.getBrightnessThrottlingData("concurrent")); + DisplayDeviceConfig.BrightnessThrottlingData concurrentThrottlingData = + new DisplayDeviceConfig.BrightnessThrottlingData(concurrentThrottlingLevels); + + HashMap throttlingDataMap = + new HashMap<>(2); + throttlingDataMap.put("default", defaultThrottlingData); + throttlingDataMap.put("concurrent", concurrentThrottlingData); + + assertEquals(throttlingDataMap, + mDisplayDeviceConfig.getBrightnessThrottlingDataMapByThrottlingId()); assertNotNull(mDisplayDeviceConfig.getHostUsiVersion()); assertEquals(mDisplayDeviceConfig.getHostUsiVersion().getMajorVersion(), 2); @@ -246,8 +269,7 @@ public final class DisplayDeviceConfigTest { mDisplayDeviceConfig.getHdrBrightnessFromSdr(0.62f, 1.25f), SMALL_DELTA); - - // Todo: Add asserts for BrightnessThrottlingData, DensityMapping, + // Todo: Add asserts for DensityMapping, // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor. }