From 0b54b9bf3174bcb7fe4b2c3eeffd63962d13c0be Mon Sep 17 00:00:00 2001 From: Kriti Dang Date: Fri, 30 Dec 2022 11:53:21 +0100 Subject: [PATCH] Store the HDR Conversion mode setting to Global settings Bug: 251168516 Test: atest android.display.cts.HdrConversionTest Change-Id: I8367aab1bcc2c361a48c4aae7314d3ad5bff70c1 --- core/api/test-current.txt | 2 + core/api/test-lint-baseline.txt | 4 ++ .../hardware/display/HdrConversionMode.java | 39 ++++++++++++++- core/java/android/provider/Settings.java | 30 ++++++++++++ core/java/android/view/Display.java | 19 ++++++++ .../settings/backup/GlobalSettings.java | 2 + .../validators/GlobalSettingsValidators.java | 22 +++++++++ .../server/display/DisplayManagerService.java | 47 +++++++++++++++++-- .../display/DisplayManagerServiceTest.java | 34 ++++++++++++-- 9 files changed, 191 insertions(+), 8 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 5f2f623683762..161ea792f3203 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2395,6 +2395,8 @@ package android.provider { field public static final String DISABLE_WINDOW_BLURS = "disable_window_blurs"; field public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold"; field public static final String DYNAMIC_POWER_SAVINGS_ENABLED = "dynamic_power_savings_enabled"; + field public static final String HDR_CONVERSION_MODE = "hdr_conversion_mode"; + field public static final String HDR_FORCE_CONVERSION_TYPE = "hdr_force_conversion_type"; field public static final String HIDDEN_API_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions"; field public static final String HIDDEN_API_POLICY = "hidden_api_policy"; field public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs"; diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt index e849cdbc88eba..4a972806b3149 100644 --- a/core/api/test-lint-baseline.txt +++ b/core/api/test-lint-baseline.txt @@ -855,6 +855,10 @@ NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_DISAB New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD); use getters/setters in relevant manager class NoSettingsProvider: android.provider.Settings.Global#DYNAMIC_POWER_SAVINGS_ENABLED: New setting keys are not allowed (Field: DYNAMIC_POWER_SAVINGS_ENABLED); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Global#HDR_CONVERSION_MODE: + New setting keys are not allowed (Field: HDR_CONVERSION_MODE); use getters/setters in relevant manager class +NoSettingsProvider: android.provider.Settings.Global#HDR_FORCE_CONVERSION_TYPE: + New setting keys are not allowed (Field: HDR_FORCE_CONVERSION_TYPE); use getters/setters in relevant manager class NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_BLACKLIST_EXEMPTIONS: New setting keys are not allowed (Field: HIDDEN_API_BLACKLIST_EXEMPTIONS); use getters/setters in relevant manager class NoSettingsProvider: android.provider.Settings.Global#HIDDEN_API_POLICY: diff --git a/core/java/android/hardware/display/HdrConversionMode.java b/core/java/android/hardware/display/HdrConversionMode.java index 1accd17482861..da2b0163cc7bb 100644 --- a/core/java/android/hardware/display/HdrConversionMode.java +++ b/core/java/android/hardware/display/HdrConversionMode.java @@ -18,6 +18,7 @@ package android.hardware.display; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -119,4 +120,40 @@ public final class HdrConversionMode implements Parcelable { dest.writeInt(mConversionMode); dest.writeInt(mPreferredHdrOutputType); } -} + + @Override + public boolean equals(@Nullable Object o) { + return o instanceof HdrConversionMode && equals((HdrConversionMode) o); + } + + @Override + public int hashCode() { + return 0; // don't care + } + + @Override + public String toString() { + return "HdrConversionMode{ConversionMode=" + hdrConversionModeString(getConversionMode()) + + ", PreferredHdrOutputType=" + + Display.HdrCapabilities.hdrTypeToString(getPreferredHdrOutputType()) + "}"; + } + + private boolean equals(HdrConversionMode other) { + return other != null + && mConversionMode == other.getConversionMode() + && mPreferredHdrOutputType == other.getPreferredHdrOutputType(); + } + + private static String hdrConversionModeString(int hdrConversionMode) { + switch (hdrConversionMode) { + case HDR_CONVERSION_PASSTHROUGH: + return "HDR_CONVERSION_PASSTHROUGH"; + case HDR_CONVERSION_SYSTEM: + return "HDR_CONVERSION_SYSTEM"; + case HDR_CONVERSION_FORCE: + return "HDR_CONVERSION_FORCE"; + default: + return "HDR_CONVERSION_UNKNOWN"; + } + } +} \ No newline at end of file diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index ff57003f573f1..40b2810413eed 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -15833,6 +15833,36 @@ public final class Settings { public static final String USER_PREFERRED_RESOLUTION_WIDTH = "user_preferred_resolution_width"; + /** + * The HDR output mode chosen by the user. This is one of: + * {@link android.hardware.display.HdrConversionMode#HDR_CONVERSION_PASSTHROUGH}, + * {@link android.hardware.display.HdrConversionMode#HDR_CONVERSION_SYSTEM}, + * {@link android.hardware.display.HdrConversionMode#HDR_CONVERSION_FORCE}. + * + * @hide + */ + @TestApi + @Readable + public static final String HDR_CONVERSION_MODE = "hdr_conversion_mode"; + + /** + * The output HDR type chosen by the user in case when {@link #HDR_CONVERSION_MODE} is + * {@link #HDR_CONVERSION_FORCE}. This is one of: + * {@link android.view.Display.HdrCapabilities#HDR_TYPE_INVALID}, + * {@link android.view.Display.HdrCapabilities#HDR_TYPE_DOLBY_VISION}, + * {@link android.view.Display.HdrCapabilities#HDR_TYPE_HDR10}, + * {@link android.view.Display.HdrCapabilities#HDR_TYPE_HLG}, + * {@link android.view.Display.HdrCapabilities#HDR_TYPE_HDR10_PLUS} + *

+ * The value is {@link android.view.Display.HdrCapabilities#HDR_TYPE_INVALID} when user + * chooses SDR output type.

+ * + * @hide + */ + @TestApi + @Readable + public static final String HDR_FORCE_CONVERSION_TYPE = "hdr_force_conversion_type"; + /** * The name of the device */ diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 25863a6babe13..22e8319793e0e 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -2497,5 +2497,24 @@ public final class Display { + ", mMaxAverageLuminance=" + mMaxAverageLuminance + ", mMinLuminance=" + mMinLuminance + '}'; } + + /** + * @hide + */ + @NonNull + public static String hdrTypeToString(int hdrType) { + switch (hdrType) { + case HDR_TYPE_DOLBY_VISION: + return "HDR_TYPE_DOLBY_VISION"; + case HDR_TYPE_HDR10: + return "HDR_TYPE_HDR10"; + case HDR_TYPE_HLG: + return "HDR_TYPE_HLG"; + case HDR_TYPE_HDR10_PLUS: + return "HDR_TYPE_HDR10_PLUS"; + default: + return "HDR_TYPE_INVALID"; + } + } } } diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java index c0818a80c757a..7cd8d7087b7f6 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java @@ -99,5 +99,7 @@ public class GlobalSettings { Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_MS, Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_SET_BY_USER, Settings.Global.Wearable.DYNAMIC_COLOR_THEME_ENABLED, + Settings.Global.HDR_CONVERSION_MODE, + Settings.Global.HDR_FORCE_CONVERSION_TYPE, }; } diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java index 7b8ca4d36ed88..f64cb766259db 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java @@ -16,6 +16,9 @@ package android.provider.settings.validators; +import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_FORCE; +import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_PASSTHROUGH; +import static android.hardware.display.HdrConversionMode.HDR_CONVERSION_SYSTEM; import static android.media.AudioFormat.SURROUND_SOUND_ENCODING; import static android.provider.settings.validators.SettingsValidators.ANY_INTEGER_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.ANY_STRING_VALIDATOR; @@ -26,6 +29,11 @@ import static android.provider.settings.validators.SettingsValidators.NON_NEGATI import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.PERCENTAGE_INTEGER_VALIDATOR; import static android.view.Display.HdrCapabilities.HDR_TYPES; +import static android.view.Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION; +import static android.view.Display.HdrCapabilities.HDR_TYPE_HDR10; +import static android.view.Display.HdrCapabilities.HDR_TYPE_HDR10_PLUS; +import static android.view.Display.HdrCapabilities.HDR_TYPE_HLG; +import static android.view.Display.HdrCapabilities.HDR_TYPE_INVALID; import android.os.BatteryManager; import android.provider.Settings.Global; @@ -338,6 +346,20 @@ public class GlobalSettingsValidators { VALIDATORS.put(Global.USER_PREFERRED_REFRESH_RATE, NON_NEGATIVE_FLOAT_VALIDATOR); VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_HEIGHT, ANY_INTEGER_VALIDATOR); VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_WIDTH, ANY_INTEGER_VALIDATOR); + VALIDATORS.put(Global.HDR_CONVERSION_MODE, new DiscreteValueValidator( + new String[] { + String.valueOf(HDR_CONVERSION_PASSTHROUGH), + String.valueOf(HDR_CONVERSION_SYSTEM), + String.valueOf(HDR_CONVERSION_FORCE) + })); + VALIDATORS.put(Global.HDR_FORCE_CONVERSION_TYPE, new DiscreteValueValidator( + new String[] { + String.valueOf(HDR_TYPE_INVALID), + String.valueOf(HDR_TYPE_DOLBY_VISION), + String.valueOf(HDR_TYPE_HDR10), + String.valueOf(HDR_TYPE_HLG), + String.valueOf(HDR_TYPE_HDR10_PLUS) + })); VALIDATORS.put(Global.RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO_ENABLED, new DiscreteValueValidator(new String[]{"0", "1"})); VALIDATORS.put(Global.Wearable.WET_MODE_ON, BOOLEAN_VALIDATOR); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 3f49ebe43ecb3..350bccf1dddf3 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -245,7 +245,7 @@ public final class DisplayManagerService extends SystemService { private Display.Mode mUserPreferredMode; // HDR conversion mode chosen by user @GuardedBy("mSyncRoot") - private HdrConversionMode mHdrConversionMode; + private HdrConversionMode mHdrConversionMode = null; // The synchronization root for the display manager. // This lock guards most of the display manager's state. @@ -647,6 +647,7 @@ public final class DisplayManagerService extends SystemService { updateSettingsLocked(); updateUserDisabledHdrTypesFromSettingsLocked(); updateUserPreferredDisplayModeSettingsLocked(); + updateHdrConversionModeSettingsLocked(); } mDisplayModeDirector.setDesiredDisplayModeSpecsListener( @@ -1805,6 +1806,31 @@ public final class DisplayManagerService extends SystemService { device.setUserPreferredDisplayModeLocked(modeBuilder.build()); } + @GuardedBy("mSyncRoot") + private void storeHdrConversionModeLocked(HdrConversionMode hdrConversionMode) { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.HDR_CONVERSION_MODE, hdrConversionMode.getConversionMode()); + final int preferredHdrOutputType = + hdrConversionMode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_FORCE + ? hdrConversionMode.getPreferredHdrOutputType() + : Display.HdrCapabilities.HDR_TYPE_INVALID; + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.HDR_FORCE_CONVERSION_TYPE, preferredHdrOutputType); + } + + @GuardedBy("mSyncRoot") + void updateHdrConversionModeSettingsLocked() { + final int conversionMode = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.HDR_CONVERSION_MODE, HdrConversionMode.HDR_CONVERSION_SYSTEM); + final int preferredHdrOutputType = conversionMode == HdrConversionMode.HDR_CONVERSION_FORCE + ? Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.HDR_FORCE_CONVERSION_TYPE, + Display.HdrCapabilities.HDR_TYPE_DOLBY_VISION) + : Display.HdrCapabilities.HDR_TYPE_INVALID; + mHdrConversionMode = new HdrConversionMode(conversionMode, preferredHdrOutputType); + setHdrConversionModeInternal(mHdrConversionMode); + } + // If we've never recorded stable device stats for this device before and they aren't // explicitly configured, go ahead and record the stable device stats now based on the status // of the default display at first boot. @@ -1961,13 +1987,14 @@ public final class DisplayManagerService extends SystemService { int[] autoHdrOutputTypes = null; synchronized (mSyncRoot) { mHdrConversionMode = hdrConversionMode; + storeHdrConversionModeLocked(mHdrConversionMode); // For auto mode, all supported HDR types are allowed except the ones specifically // disabled by the user. if (hdrConversionMode.getConversionMode() == HdrConversionMode.HDR_CONVERSION_SYSTEM) { autoHdrOutputTypes = getEnabledAutoHdrTypesLocked(); } - DisplayControl.setHdrConversionMode(hdrConversionMode.getConversionMode(), + mInjector.setHdrConversionMode(hdrConversionMode.getConversionMode(), hdrConversionMode.getPreferredHdrOutputType(), autoHdrOutputTypes); } } @@ -1983,7 +2010,7 @@ public final class DisplayManagerService extends SystemService { private @Display.HdrCapabilities.HdrType int[] getSupportedHdrOutputTypesInternal() { if (mSupportedHdrOutputType == null) { - mSupportedHdrOutputType = DisplayControl.getSupportedHdrOutputTypes(); + mSupportedHdrOutputType = mInjector.getSupportedHdrOutputTypes(); } return mSupportedHdrOutputType; } @@ -2601,6 +2628,10 @@ public final class DisplayManagerService extends SystemService { } } + if (mHdrConversionMode != null) { + pw.println(" mHdrConversionMode=" + mHdrConversionMode); + } + pw.println(); final int displayStateCount = mDisplayStates.size(); pw.println("Display States: size=" + displayStateCount); @@ -2709,6 +2740,16 @@ public final class DisplayManagerService extends SystemService { long getDefaultDisplayDelayTimeout() { return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; } + + void setHdrConversionMode(int conversionMode, int preferredHdrOutputType, + int[] autoHdrTypes) { + DisplayControl.setHdrConversionMode(conversionMode, preferredHdrOutputType, + autoHdrTypes); + } + + int[] getSupportedHdrOutputTypes() { + return DisplayControl.getSupportedHdrOutputTypes(); + } } @VisibleForTesting diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index 2d252cbbbd9c6..e801e2293aea9 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -56,6 +56,7 @@ import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayViewport; import android.hardware.display.DisplayedContentSample; import android.hardware.display.DisplayedContentSamplingAttributes; +import android.hardware.display.HdrConversionMode; import android.hardware.display.IDisplayManagerCallback; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.VirtualDisplayConfig; @@ -171,6 +172,17 @@ public class DisplayManagerServiceTest { } }); } + + @Override + void setHdrConversionMode(int conversionMode, int preferredHdrOutputType, + int[] autoHdrTypes) { + return; + } + + @Override + int[] getSupportedHdrOutputTypes() { + return new int[]{}; + } } private final DisplayManagerService.Injector mBasicInjector = new BasicInjector(); @@ -240,8 +252,7 @@ public class DisplayManagerServiceTest { // the usage of SensorManager, which is available only after the PowerManagerService // is ready. resetConfigToIgnoreSensorManager(mContext); - DisplayManagerService displayManager = - new DisplayManagerService(mContext, mBasicInjector); + DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); displayManager.systemReady(false /* safeMode */); displayManager.windowManagerAndInputReady(); @@ -316,8 +327,7 @@ public class DisplayManagerServiceTest { // the usage of SensorManager, which is available only after the PowerManagerService // is ready. resetConfigToIgnoreSensorManager(mContext); - DisplayManagerService displayManager = - new DisplayManagerService(mContext, mBasicInjector); + DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); displayManager.systemReady(false /* safeMode */); displayManager.windowManagerAndInputReady(); @@ -1511,6 +1521,22 @@ public class DisplayManagerServiceTest { } + @Test + public void testHdrConversionModeEquals() { + assertEquals( + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2), + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2)); + assertNotEquals( + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2), + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 3)); + assertEquals( + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM), + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM)); + assertNotEquals( + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_FORCE, 2), + new HdrConversionMode(HdrConversionMode.HDR_CONVERSION_SYSTEM)); + } + private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled) throws Exception { DisplayManagerService displayManager =