From c9ba55902123be5abcf2dcda5af9995be0b8d3d8 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Wed, 18 Jan 2017 16:34:42 -0800 Subject: [PATCH] Add wide color gamut and HDR resource qualifiers Bug: 32984164 Test: Config_test, AaptConfig_test and aapt2_tests Change-Id: Ie9c82bfe2d36b1d6180ee223250ab5bb2ce90dd4 --- api/current.txt | 14 ++ api/system-current.txt | 14 ++ api/test-current.txt | 14 ++ .../java/android/content/pm/ActivityInfo.java | 11 +- .../android/content/res/Configuration.java | 175 ++++++++++++++++++ core/res/res/values/attrs_manifest.xml | 3 + .../topics/resources/providing-resources.jd | 32 ++++ libs/androidfw/ResourceTypes.cpp | 69 +++++++ .../include/androidfw/ResourceTypes.h | 18 +- libs/androidfw/tests/Config_test.cpp | 20 ++ tools/aapt/AaptConfig.cpp | 60 +++++- tools/aapt/AaptConfig.h | 2 + tools/aapt/tests/AaptConfig_test.cpp | 30 +++ tools/aapt2/ConfigDescription.cpp | 73 +++++++- tools/aapt2/ConfigDescription_test.cpp | 30 +++ 15 files changed, 561 insertions(+), 4 deletions(-) diff --git a/api/current.txt b/api/current.txt index b3090cd5215a5..be151aa7069f4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9543,6 +9543,7 @@ package android.content.pm { method public int describeContents(); method public void dump(android.util.Printer, java.lang.String); method public final int getThemeResource(); + field public static final int CONFIG_COLORIMETRY = 16384; // 0x4000 field public static final int CONFIG_DENSITY = 4096; // 0x1000 field public static final int CONFIG_FONT_SCALE = 1073741824; // 0x40000000 field public static final int CONFIG_KEYBOARD = 16; // 0x10 @@ -10537,7 +10538,9 @@ package android.content.res { method public int getLayoutDirection(); method public android.os.LocaleList getLocales(); method public boolean isLayoutSizeAtLeast(int); + method public boolean isScreenHdr(); method public boolean isScreenRound(); + method public boolean isScreenWideColorGamut(); method public static boolean needNewResources(int, int); method public void readFromParcel(android.os.Parcel); method public void setLayoutDirection(java.util.Locale); @@ -10547,6 +10550,16 @@ package android.content.res { method public void setToDefaults(); method public int updateFrom(android.content.res.Configuration); method public void writeToParcel(android.os.Parcel, int); + field public static final int COLORIMETRY_HDR_MASK = 12; // 0xc + field public static final int COLORIMETRY_HDR_NO = 4; // 0x4 + field public static final int COLORIMETRY_HDR_SHIFT = 2; // 0x2 + field public static final int COLORIMETRY_HDR_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_HDR_YES = 8; // 0x8 + field public static final int COLORIMETRY_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_MASK = 3; // 0x3 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_NO = 1; // 0x1 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_YES = 2; // 0x2 field public static final android.os.Parcelable.Creator CREATOR; field public static final int DENSITY_DPI_UNDEFINED = 0; // 0x0 field public static final int HARDKEYBOARDHIDDEN_NO = 1; // 0x1 @@ -10612,6 +10625,7 @@ package android.content.res { field public static final int UI_MODE_TYPE_UNDEFINED = 0; // 0x0 field public static final int UI_MODE_TYPE_VR_HEADSET = 7; // 0x7 field public static final int UI_MODE_TYPE_WATCH = 6; // 0x6 + field public int colorimetry; field public int densityDpi; field public float fontScale; field public int hardKeyboardHidden; diff --git a/api/system-current.txt b/api/system-current.txt index 3bc7be541497a..bb1e9c8a1a5e6 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -9940,6 +9940,7 @@ package android.content.pm { method public int describeContents(); method public void dump(android.util.Printer, java.lang.String); method public final int getThemeResource(); + field public static final int CONFIG_COLORIMETRY = 16384; // 0x4000 field public static final int CONFIG_DENSITY = 4096; // 0x1000 field public static final int CONFIG_FONT_SCALE = 1073741824; // 0x40000000 field public static final int CONFIG_KEYBOARD = 16; // 0x10 @@ -11055,7 +11056,9 @@ package android.content.res { method public int getLayoutDirection(); method public android.os.LocaleList getLocales(); method public boolean isLayoutSizeAtLeast(int); + method public boolean isScreenHdr(); method public boolean isScreenRound(); + method public boolean isScreenWideColorGamut(); method public static boolean needNewResources(int, int); method public void readFromParcel(android.os.Parcel); method public void setLayoutDirection(java.util.Locale); @@ -11065,6 +11068,16 @@ package android.content.res { method public void setToDefaults(); method public int updateFrom(android.content.res.Configuration); method public void writeToParcel(android.os.Parcel, int); + field public static final int COLORIMETRY_HDR_MASK = 12; // 0xc + field public static final int COLORIMETRY_HDR_NO = 4; // 0x4 + field public static final int COLORIMETRY_HDR_SHIFT = 2; // 0x2 + field public static final int COLORIMETRY_HDR_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_HDR_YES = 8; // 0x8 + field public static final int COLORIMETRY_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_MASK = 3; // 0x3 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_NO = 1; // 0x1 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_YES = 2; // 0x2 field public static final android.os.Parcelable.Creator CREATOR; field public static final int DENSITY_DPI_UNDEFINED = 0; // 0x0 field public static final int HARDKEYBOARDHIDDEN_NO = 1; // 0x1 @@ -11130,6 +11143,7 @@ package android.content.res { field public static final int UI_MODE_TYPE_UNDEFINED = 0; // 0x0 field public static final int UI_MODE_TYPE_VR_HEADSET = 7; // 0x7 field public static final int UI_MODE_TYPE_WATCH = 6; // 0x6 + field public int colorimetry; field public int densityDpi; field public float fontScale; field public int hardKeyboardHidden; diff --git a/api/test-current.txt b/api/test-current.txt index 22c5581732f61..d485f20f42162 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -9568,6 +9568,7 @@ package android.content.pm { method public int describeContents(); method public void dump(android.util.Printer, java.lang.String); method public final int getThemeResource(); + field public static final int CONFIG_COLORIMETRY = 16384; // 0x4000 field public static final int CONFIG_DENSITY = 4096; // 0x1000 field public static final int CONFIG_FONT_SCALE = 1073741824; // 0x40000000 field public static final int CONFIG_KEYBOARD = 16; // 0x10 @@ -10569,7 +10570,9 @@ package android.content.res { method public int getLayoutDirection(); method public android.os.LocaleList getLocales(); method public boolean isLayoutSizeAtLeast(int); + method public boolean isScreenHdr(); method public boolean isScreenRound(); + method public boolean isScreenWideColorGamut(); method public static boolean needNewResources(int, int); method public void readFromParcel(android.os.Parcel); method public void setLayoutDirection(java.util.Locale); @@ -10579,6 +10582,16 @@ package android.content.res { method public void setToDefaults(); method public int updateFrom(android.content.res.Configuration); method public void writeToParcel(android.os.Parcel, int); + field public static final int COLORIMETRY_HDR_MASK = 12; // 0xc + field public static final int COLORIMETRY_HDR_NO = 4; // 0x4 + field public static final int COLORIMETRY_HDR_SHIFT = 2; // 0x2 + field public static final int COLORIMETRY_HDR_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_HDR_YES = 8; // 0x8 + field public static final int COLORIMETRY_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_MASK = 3; // 0x3 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_NO = 1; // 0x1 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_UNDEFINED = 0; // 0x0 + field public static final int COLORIMETRY_WIDE_COLOR_GAMUT_YES = 2; // 0x2 field public static final android.os.Parcelable.Creator CREATOR; field public static final int DENSITY_DPI_UNDEFINED = 0; // 0x0 field public static final int HARDKEYBOARDHIDDEN_NO = 1; // 0x1 @@ -10644,6 +10657,7 @@ package android.content.res { field public static final int UI_MODE_TYPE_UNDEFINED = 0; // 0x0 field public static final int UI_MODE_TYPE_VR_HEADSET = 7; // 0x7 field public static final int UI_MODE_TYPE_WATCH = 6; // 0x6 + field public int colorimetry; field public int densityDpi; field public float fontScale; field public int hardKeyboardHidden; diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 298dc4eafa153..4bd091dae77e1 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -566,6 +566,7 @@ public class ActivityInfo extends ComponentInfo CONFIG_SMALLEST_SCREEN_SIZE, CONFIG_DENSITY, CONFIG_LAYOUT_DIRECTION, + CONFIG_COLORIMETRY, CONFIG_FONT_SCALE, }) @Retention(RetentionPolicy.SOURCE) @@ -669,6 +670,12 @@ public class ActivityInfo extends ComponentInfo * {@link android.R.attr#configChanges} attribute. */ public static final int CONFIG_LAYOUT_DIRECTION = 0x2000; + /** + * Bit in {@link #configChanges} that indicates that the activity + * can itself handle the change to the display color gamut or dynamic + * range. Set from the {@link android.R.attr#configChanges} attribute. + */ + public static final int CONFIG_COLORIMETRY = 0x4000; /** * Bit in {@link #configChanges} that indicates that the activity * can itself handle asset path changes. Set from the {@link android.R.attr#configChanges} @@ -706,6 +713,7 @@ public class ActivityInfo extends ComponentInfo Configuration.NATIVE_CONFIG_SMALLEST_SCREEN_SIZE, // SMALLEST SCREEN SIZE Configuration.NATIVE_CONFIG_DENSITY, // DENSITY Configuration.NATIVE_CONFIG_LAYOUTDIR, // LAYOUT DIRECTION + Configuration.NATIVE_CONFIG_COLORIMETRY, // COLORIMETRY }; /** @@ -761,7 +769,8 @@ public class ActivityInfo extends ComponentInfo * {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN}, * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION}, * {@link #CONFIG_ORIENTATION}, {@link #CONFIG_SCREEN_LAYOUT}, - * {@link #CONFIG_DENSITY}, and {@link #CONFIG_LAYOUT_DIRECTION}. + * {@link #CONFIG_DENSITY}, {@link #CONFIG_LAYOUT_DIRECTION} and + * {@link #CONFIG_COLORIMETRY}. * Set from the {@link android.R.attr#configChanges} attribute. */ public int configChanges; diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 65f49578071f2..a81329d9ee67d 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -101,6 +101,68 @@ public final class Configuration implements Parcelable, ComparableCorresponds to the -nowidecg resource qualifier.

+ */ + public static final int COLORIMETRY_WIDE_COLOR_GAMUT_NO = 0x1; + /** + * Constant for {@link #colorimetry}: a {@link #COLORIMETRY_WIDE_COLOR_GAMUT_MASK} value + * indicating that the screen is wide gamut. + *

Corresponds to the -widecg resource qualifier.

+ */ + public static final int COLORIMETRY_WIDE_COLOR_GAMUT_YES = 0x2; + + /** Constant for {@link #colorimetry}: bits that encode whether the dynamic range of the screen. */ + public static final int COLORIMETRY_HDR_MASK = 0xc; + /** Constant for {@link #colorimetry}: bits shift to get the screen dynamic range. */ + public static final int COLORIMETRY_HDR_SHIFT = 2; + /** + * Constant for {@link #colorimetry}: a {@link #COLORIMETRY_HDR_MASK} value + * indicating that it is unknown whether or not the screen is HDR. + */ + public static final int COLORIMETRY_HDR_UNDEFINED = 0x0; + /** + * Constant for {@link #colorimetry}: a {@link #COLORIMETRY_HDR_MASK} value + * indicating that the screen is not HDR (low/standard dynamic range). + *

Corresponds to the -lowdr resource qualifier.

+ */ + public static final int COLORIMETRY_HDR_NO = 0x1 << COLORIMETRY_HDR_SHIFT; + /** + * Constant for {@link #colorimetry}: a {@link #COLORIMETRY_HDR_MASK} value + * indicating that the screen is HDR (dynamic range). + *

Corresponds to the -highdr resource qualifier.

+ */ + public static final int COLORIMETRY_HDR_YES = 0x2 << COLORIMETRY_HDR_SHIFT; + + /** Constant for {@link #colorimetry}: a value indicating that colorimetry is undefined */ + @SuppressWarnings("PointlessBitwiseExpression") + public static final int COLORIMETRY_UNDEFINED = COLORIMETRY_WIDE_COLOR_GAMUT_UNDEFINED | + COLORIMETRY_HDR_UNDEFINED; + + /** + * Bit mask of for color capabilities of the screen. Currently there are two fields: + *

The {@link #COLORIMETRY_WIDE_COLOR_GAMUT_MASK} bits define the color gamut of + * the screen. They may be one of + * {@link #COLORIMETRY_WIDE_COLOR_GAMUT_NO} or {@link #COLORIMETRY_WIDE_COLOR_GAMUT_YES}.

+ * + *

The {@link #COLORIMETRY_HDR_MASK} defines the dynamic range of the screen. They may be + * one of {@link #COLORIMETRY_HDR_NO} or {@link #COLORIMETRY_HDR_YES}.

+ * + *

See Supporting + * Multiple Screens for more information.

+ */ + public int colorimetry; + /** Constant for {@link #screenLayout}: bits that encode the size. */ public static final int SCREENLAYOUT_SIZE_MASK = 0x0f; /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_SIZE_MASK} @@ -331,6 +393,9 @@ public final class Configuration implements Parcelable, ComparableConstruct an invalid Configuration. This state is only suitable for constructing a @@ -805,6 +873,7 @@ public final class Configuration implements Parcelable, Comparable + + diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd index 77e8d7720c61c..021a07ecaa5b4 100644 --- a/docs/html/guide/topics/resources/providing-resources.jd +++ b/docs/html/guide/topics/resources/providing-resources.jd @@ -565,6 +565,38 @@ which indicates whether the screen is long.

method, which indicates whether the screen is round.

+ + Wide Color Gamut + + widecg
+ nowidecg + + +
    +
  • {@code widecg}: Displays with a wide color gamut such as Display P3 or AdobeRGB
  • +
  • {@code nowidecg}: Displays with a narrow color gamut such as sRGB
  • +
+

Added in API level 26.

+

Also see the {@link android.content.res.Configuration#isScreenWideColorGamut()} configuration + method, which indicates whether the screen has a wide color gamut.

+ + + + High Dynamic Range (HDR) + + highdr
+ lowdr + + +
    +
  • {@code highdr}: Displays with a high-dynamic range
  • +
  • {@code lowdr}: Displays with a low/standard dynamic range
  • +
+

Added in API level 26.

+

Also see the {@link android.content.res.Configuration#isScreenHdr()} configuration + method, which indicates whether the screen has a HDR capabilities.

+ + Screen orientation diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index a30c8497b0f84..a4bcc624ef311 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -1907,6 +1907,8 @@ int ResTable_config::compare(const ResTable_config& o) const { if (diff != 0) return diff; diff = (int32_t)(screenLayout2 - o.screenLayout2); if (diff != 0) return diff; + diff = (int32_t)(colorimetry - o.colorimetry); + if (diff != 0) return diff; diff = (int32_t)(uiMode - o.uiMode); if (diff != 0) return diff; diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp); @@ -1967,6 +1969,9 @@ int ResTable_config::compareLogical(const ResTable_config& o) const { if (screenLayout2 != o.screenLayout2) { return screenLayout2 < o.screenLayout2 ? -1 : 1; } + if (colorimetry != o.colorimetry) { + return colorimetry < o.colorimetry ? -1 : 1; + } if (uiMode != o.uiMode) { return uiMode < o.uiMode ? -1 : 1; } @@ -1992,6 +1997,8 @@ int ResTable_config::diff(const ResTable_config& o) const { if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) diffs |= CONFIG_LAYOUTDIR; if ((screenLayout & ~MASK_LAYOUTDIR) != (o.screenLayout & ~MASK_LAYOUTDIR)) diffs |= CONFIG_SCREEN_LAYOUT; if ((screenLayout2 & MASK_SCREENROUND) != (o.screenLayout2 & MASK_SCREENROUND)) diffs |= CONFIG_SCREEN_ROUND; + if ((colorimetry & MASK_WIDE_COLOR_GAMUT) != (o.colorimetry & MASK_WIDE_COLOR_GAMUT)) diffs |= CONFIG_COLORIMETRY; + if ((colorimetry & MASK_HDR) != (o.colorimetry & MASK_HDR)) diffs |= CONFIG_COLORIMETRY; if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE; if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE; if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE; @@ -2103,6 +2110,17 @@ bool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const { } } + if (colorimetry || o.colorimetry) { + if (((colorimetry^o.colorimetry) & MASK_HDR) != 0) { + if (!(colorimetry & MASK_HDR)) return false; + if (!(o.colorimetry & MASK_HDR)) return true; + } + if (((colorimetry^o.colorimetry) & MASK_WIDE_COLOR_GAMUT) != 0) { + if (!(colorimetry & MASK_WIDE_COLOR_GAMUT)) return false; + if (!(o.colorimetry & MASK_WIDE_COLOR_GAMUT)) return true; + } + } + if (orientation != o.orientation) { if (!orientation) return false; if (!o.orientation) return true; @@ -2390,6 +2408,17 @@ bool ResTable_config::isBetterThan(const ResTable_config& o, } } + if (colorimetry || o.colorimetry) { + if (((colorimetry^o.colorimetry) & MASK_WIDE_COLOR_GAMUT) != 0 && + (requested->colorimetry & MASK_WIDE_COLOR_GAMUT)) { + return colorimetry & MASK_WIDE_COLOR_GAMUT; + } + if (((colorimetry^o.colorimetry) & MASK_HDR) != 0 && + (requested->colorimetry & MASK_HDR)) { + return colorimetry & MASK_HDR; + } + } + if ((orientation != o.orientation) && requested->orientation) { return (orientation); } @@ -2639,6 +2668,18 @@ bool ResTable_config::match(const ResTable_config& settings) const { if (screenRound != 0 && screenRound != setScreenRound) { return false; } + + const int hdr = colorimetry & MASK_HDR; + const int setHdr = settings.colorimetry & MASK_HDR; + if (hdr != 0 && hdr != setHdr) { + return false; + } + + const int wideColorGamut = colorimetry & MASK_WIDE_COLOR_GAMUT; + const int setWideColorGamut = settings.colorimetry & MASK_WIDE_COLOR_GAMUT; + if (wideColorGamut != 0 && wideColorGamut != setWideColorGamut) { + return false; + } } if (screenSizeDp != 0) { @@ -2959,6 +3000,34 @@ String8 ResTable_config::toString() const { break; } } + if ((colorimetry&MASK_HDR) != 0) { + if (res.size() > 0) res.append("-"); + switch (colorimetry&MASK_HDR) { + case ResTable_config::HDR_NO: + res.append("lowdr"); + break; + case ResTable_config::HDR_YES: + res.append("highdr"); + break; + default: + res.appendFormat("hdr=%d", dtohs(colorimetry&MASK_HDR)); + break; + } + } + if ((colorimetry&MASK_WIDE_COLOR_GAMUT) != 0) { + if (res.size() > 0) res.append("-"); + switch (colorimetry&MASK_WIDE_COLOR_GAMUT) { + case ResTable_config::WIDE_COLOR_GAMUT_NO: + res.append("nowidecg"); + break; + case ResTable_config::WIDE_COLOR_GAMUT_YES: + res.append("widecg"); + break; + default: + res.appendFormat("wideColorGamut=%d", dtohs(colorimetry&MASK_WIDE_COLOR_GAMUT)); + break; + } + } if (orientation != ORIENTATION_ANY) { if (res.size() > 0) res.append("-"); switch (orientation) { diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index c118b57510f99..1e4aee9d18e7f 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -1146,11 +1146,26 @@ struct ResTable_config SCREENROUND_YES = ACONFIGURATION_SCREENROUND_YES, }; + enum { + // colorimetry bits for wide-color gamut/narrow-color gamut. + MASK_WIDE_COLOR_GAMUT = 0x03, + WIDE_COLOR_GAMUT_ANY = ACONFIGURATION_WIDE_COLOR_GAMUT_ANY, + WIDE_COLOR_GAMUT_NO = ACONFIGURATION_WIDE_COLOR_GAMUT_NO, + WIDE_COLOR_GAMUT_YES = ACONFIGURATION_WIDE_COLOR_GAMUT_YES, + + // colorimetry bits for HDR/LDR. + MASK_HDR = 0x0c, + SHIFT_COLORIMETRY_HDR = 2, + HDR_ANY = ACONFIGURATION_HDR_ANY << SHIFT_COLORIMETRY_HDR, + HDR_NO = ACONFIGURATION_HDR_NO << SHIFT_COLORIMETRY_HDR, + HDR_YES = ACONFIGURATION_HDR_YES << SHIFT_COLORIMETRY_HDR, + }; + // An extension of screenConfig. union { struct { uint8_t screenLayout2; // Contains round/notround qualifier. - uint8_t screenConfigPad1; // Reserved padding. + uint8_t colorimetry; // Wide-gamut, HDR, etc. uint16_t screenConfigPad2; // Reserved padding. }; uint32_t screenConfig2; @@ -1193,6 +1208,7 @@ struct ResTable_config CONFIG_UI_MODE = ACONFIGURATION_UI_MODE, CONFIG_LAYOUTDIR = ACONFIGURATION_LAYOUTDIR, CONFIG_SCREEN_ROUND = ACONFIGURATION_SCREEN_ROUND, + CONFIG_COLORIMETRY = ACONFIGURATION_COLORIMETRY, }; // Compare two configuration, returning CONFIG_* flags set for each value diff --git a/libs/androidfw/tests/Config_test.cpp b/libs/androidfw/tests/Config_test.cpp index 778c7bfb2053f..3e5aca7ab6552 100644 --- a/libs/androidfw/tests/Config_test.cpp +++ b/libs/androidfw/tests/Config_test.cpp @@ -182,4 +182,24 @@ TEST(ConfigTest, RoundIsMoreSpecific) { EXPECT_TRUE(targetConfigC.isBetterThan(targetConfigB, &deviceConfig)); } +TEST(ConfigTest, ScreenIsWideGamut) { + ResTable_config defaultConfig; + memset(&defaultConfig, 0, sizeof(defaultConfig)); + + ResTable_config wideGamutConfig = defaultConfig; + wideGamutConfig.colorimetry = ResTable_config::WIDE_COLOR_GAMUT_YES; + + EXPECT_EQ(defaultConfig.diff(wideGamutConfig), ResTable_config::CONFIG_COLORIMETRY); +} + +TEST(ConfigTest, ScreenIsHdr) { + ResTable_config defaultConfig; + memset(&defaultConfig, 0, sizeof(defaultConfig)); + + ResTable_config hdrConfig = defaultConfig; + hdrConfig.colorimetry = ResTable_config::HDR_YES; + + EXPECT_EQ(defaultConfig.diff(hdrConfig), ResTable_config::CONFIG_COLORIMETRY); +} + } // namespace android. diff --git a/tools/aapt/AaptConfig.cpp b/tools/aapt/AaptConfig.cpp index 565d2f0a0549e..d0026a28ba168 100644 --- a/tools/aapt/AaptConfig.cpp +++ b/tools/aapt/AaptConfig.cpp @@ -131,6 +131,22 @@ bool parse(const String8& str, ConfigDescription* out) { part = parts[index].string(); } + if (parseWideColorGamut(part, &config)) { + index++; + if (index == N) { + goto success; + } + part = parts[index].string(); + } + + if (parseHdr(part, &config)) { + index++; + if (index == N) { + goto success; + } + part = parts[index].string(); + } + if (parseOrientation(part, &config)) { index++; if (index == N) { @@ -250,7 +266,9 @@ void applyVersionForCompatibility(ConfigDescription* config) { uint16_t minSdk = 0; if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) - == ResTable_config::UI_MODE_TYPE_VR_HEADSET) { + == ResTable_config::UI_MODE_TYPE_VR_HEADSET + || config->colorimetry & ResTable_config::MASK_WIDE_COLOR_GAMUT + || config->colorimetry & ResTable_config::MASK_HDR) { minSdk = SDK_O; } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) { minSdk = SDK_MNC; @@ -431,6 +449,46 @@ bool parseScreenRound(const char* name, ResTable_config* out) { return false; } +bool parseWideColorGamut(const char* name, ResTable_config* out) { + if (strcmp(name, kWildcardName) == 0) { + if (out) out->colorimetry = + (out->colorimetry&~ResTable_config::MASK_WIDE_COLOR_GAMUT) + | ResTable_config::WIDE_COLOR_GAMUT_ANY; + return true; + } else if (strcmp(name, "widecg") == 0) { + if (out) out->colorimetry = + (out->colorimetry&~ResTable_config::MASK_WIDE_COLOR_GAMUT) + | ResTable_config::WIDE_COLOR_GAMUT_YES; + return true; + } else if (strcmp(name, "nowidecg") == 0) { + if (out) out->colorimetry = + (out->colorimetry&~ResTable_config::MASK_WIDE_COLOR_GAMUT) + | ResTable_config::WIDE_COLOR_GAMUT_NO; + return true; + } + return false; +} + +bool parseHdr(const char* name, ResTable_config* out) { + if (strcmp(name, kWildcardName) == 0) { + if (out) out->colorimetry = + (out->colorimetry&~ResTable_config::MASK_HDR) + | ResTable_config::HDR_ANY; + return true; + } else if (strcmp(name, "highdr") == 0) { + if (out) out->colorimetry = + (out->colorimetry&~ResTable_config::MASK_HDR) + | ResTable_config::HDR_YES; + return true; + } else if (strcmp(name, "lowdr") == 0) { + if (out) out->colorimetry = + (out->colorimetry&~ResTable_config::MASK_HDR) + | ResTable_config::HDR_NO; + return true; + } + return false; +} + bool parseOrientation(const char* name, ResTable_config* out) { if (strcmp(name, kWildcardName) == 0) { if (out) out->orientation = out->ORIENTATION_ANY; diff --git a/tools/aapt/AaptConfig.h b/tools/aapt/AaptConfig.h index 04c763f20d310..a6dd252281f56 100644 --- a/tools/aapt/AaptConfig.h +++ b/tools/aapt/AaptConfig.h @@ -61,6 +61,8 @@ bool parseScreenHeightDp(const char* str, android::ResTable_config* out = NULL); bool parseScreenLayoutSize(const char* str, android::ResTable_config* out = NULL); bool parseScreenLayoutLong(const char* str, android::ResTable_config* out = NULL); bool parseScreenRound(const char* name, android::ResTable_config* out = NULL); +bool parseWideColorGamut(const char* name, android::ResTable_config* out = NULL); +bool parseHdr(const char* name, android::ResTable_config* out = NULL); bool parseOrientation(const char* str, android::ResTable_config* out = NULL); bool parseUiModeType(const char* str, android::ResTable_config* out = NULL); bool parseUiModeNight(const char* str, android::ResTable_config* out = NULL); diff --git a/tools/aapt/tests/AaptConfig_test.cpp b/tools/aapt/tests/AaptConfig_test.cpp index 8bb38bac6d425..23f61e9e4b704 100644 --- a/tools/aapt/tests/AaptConfig_test.cpp +++ b/tools/aapt/tests/AaptConfig_test.cpp @@ -98,3 +98,33 @@ TEST(AaptConfigTest, TestParsingRoundQualifier) { EXPECT_EQ(SDK_MNC, config.sdkVersion); EXPECT_EQ(String8("notround-v23"), config.toString()); } + +TEST(AaptConfigTest, WideColorGamutQualifier) { + ConfigDescription config; + EXPECT_TRUE(TestParse("widecg", &config)); + EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_YES, + config.colorimetry & android::ResTable_config::MASK_WIDE_COLOR_GAMUT); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(String8("widecg-v26"), config.toString()); + + EXPECT_TRUE(TestParse("nowidecg", &config)); + EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_NO, + config.colorimetry & android::ResTable_config::MASK_WIDE_COLOR_GAMUT); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(String8("nowidecg-v26"), config.toString()); +} + +TEST(AaptConfigTest, HdrQualifier) { + ConfigDescription config; + EXPECT_TRUE(TestParse("highdr", &config)); + EXPECT_EQ(android::ResTable_config::HDR_YES, + config.colorimetry & android::ResTable_config::MASK_HDR); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(String8("highdr-v26"), config.toString()); + + EXPECT_TRUE(TestParse("lowdr", &config)); + EXPECT_EQ(android::ResTable_config::HDR_NO, + config.colorimetry & android::ResTable_config::MASK_HDR); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(String8("lowdr-v26"), config.toString()); +} \ No newline at end of file diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp index c97d6d4876fdf..5bea3ad1bbade 100644 --- a/tools/aapt2/ConfigDescription.cpp +++ b/tools/aapt2/ConfigDescription.cpp @@ -206,6 +206,52 @@ static bool parseScreenRound(const char* name, ResTable_config* out) { return false; } +static bool parseWideColorGamut(const char* name, ResTable_config* out) { + if (strcmp(name, kWildcardName) == 0) { + if (out) + out->colorimetry = + (out->colorimetry & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) | + ResTable_config::WIDE_COLOR_GAMUT_ANY; + return true; + } else if (strcmp(name, "widecg") == 0) { + if (out) + out->colorimetry = + (out->colorimetry & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) | + ResTable_config::WIDE_COLOR_GAMUT_YES; + return true; + } else if (strcmp(name, "nowidecg") == 0) { + if (out) + out->colorimetry = + (out->colorimetry & ~ResTable_config::MASK_WIDE_COLOR_GAMUT) | + ResTable_config::WIDE_COLOR_GAMUT_NO; + return true; + } + return false; +} + +static bool parseHdr(const char* name, ResTable_config* out) { + if (strcmp(name, kWildcardName) == 0) { + if (out) + out->colorimetry = + (out->colorimetry & ~ResTable_config::MASK_HDR) | + ResTable_config::HDR_ANY; + return true; + } else if (strcmp(name, "highdr") == 0) { + if (out) + out->colorimetry = + (out->colorimetry & ~ResTable_config::MASK_HDR) | + ResTable_config::HDR_YES; + return true; + } else if (strcmp(name, "lowdr") == 0) { + if (out) + out->colorimetry = + (out->colorimetry & ~ResTable_config::MASK_HDR) | + ResTable_config::HDR_NO; + return true; + } + return false; +} + static bool parseOrientation(const char* name, ResTable_config* out) { if (strcmp(name, kWildcardName) == 0) { if (out) out->orientation = out->ORIENTATION_ANY; @@ -687,6 +733,20 @@ bool ConfigDescription::Parse(const StringPiece& str, ConfigDescription* out) { } } + if (parseWideColorGamut(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { + goto success; + } + } + + if (parseHdr(part_iter->c_str(), &config)) { + ++part_iter; + if (part_iter == parts_end) { + goto success; + } + } + if (parseOrientation(part_iter->c_str(), &config)) { ++part_iter; if (part_iter == parts_end) { @@ -779,7 +839,9 @@ void ConfigDescription::ApplyVersionForCompatibility( ConfigDescription* config) { uint16_t min_sdk = 0; if ((config->uiMode & ResTable_config::MASK_UI_MODE_TYPE) - == ResTable_config::UI_MODE_TYPE_VR_HEADSET) { + == ResTable_config::UI_MODE_TYPE_VR_HEADSET || + config->colorimetry & ResTable_config::MASK_WIDE_COLOR_GAMUT || + config->colorimetry & ResTable_config::MASK_HDR) { min_sdk = SDK_O; } else if (config->screenLayout2 & ResTable_config::MASK_SCREENROUND) { min_sdk = SDK_MARSHMALLOW; @@ -850,6 +912,12 @@ bool ConfigDescription::HasHigherPrecedenceThan( if ((screenLayout2 | o.screenLayout2) & MASK_SCREENROUND) { return !(o.screenLayout2 & MASK_SCREENROUND); } + if ((colorimetry | o.colorimetry) & MASK_HDR) { + return !(o.colorimetry & MASK_HDR); + } + if ((colorimetry | o.colorimetry) & MASK_WIDE_COLOR_GAMUT) { + return !(o.colorimetry & MASK_WIDE_COLOR_GAMUT); + } if (orientation || o.orientation) return (!o.orientation); if ((uiMode | o.uiMode) & MASK_UI_MODE_TYPE) { return !(o.uiMode & MASK_UI_MODE_TYPE); @@ -896,6 +964,9 @@ bool ConfigDescription::ConflictsWith(const ConfigDescription& o) const { !pred(uiMode & MASK_UI_MODE_NIGHT, o.uiMode & MASK_UI_MODE_NIGHT) || !pred(screenLayout2 & MASK_SCREENROUND, o.screenLayout2 & MASK_SCREENROUND) || + !pred(colorimetry & MASK_HDR, o.colorimetry & MASK_HDR) || + !pred(colorimetry & MASK_WIDE_COLOR_GAMUT, + o.colorimetry & MASK_WIDE_COLOR_GAMUT) || !pred(orientation, o.orientation) || !pred(touchscreen, o.touchscreen) || !pred(inputFlags & MASK_KEYSHIDDEN, o.inputFlags & MASK_KEYSHIDDEN) || diff --git a/tools/aapt2/ConfigDescription_test.cpp b/tools/aapt2/ConfigDescription_test.cpp index 793356861c1a0..b88838ae26f52 100644 --- a/tools/aapt2/ConfigDescription_test.cpp +++ b/tools/aapt2/ConfigDescription_test.cpp @@ -102,6 +102,36 @@ TEST(ConfigDescriptionTest, TestParsingRoundQualifier) { EXPECT_EQ(std::string("notround-v23"), config.toString().string()); } +TEST(ConfigDescriptionTest, TestWideColorGamutQualifier) { + ConfigDescription config; + EXPECT_TRUE(TestParse("widecg", &config)); + EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_YES, + config.colorimetry & android::ResTable_config::MASK_WIDE_COLOR_GAMUT); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(std::string("widecg-v26"), config.toString().string()); + + EXPECT_TRUE(TestParse("nowidecg", &config)); + EXPECT_EQ(android::ResTable_config::WIDE_COLOR_GAMUT_NO, + config.colorimetry & android::ResTable_config::MASK_WIDE_COLOR_GAMUT); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(std::string("nowidecg-v26"), config.toString().string()); +} + +TEST(ConfigDescriptionTest, TestHdrQualifier) { + ConfigDescription config; + EXPECT_TRUE(TestParse("highdr", &config)); + EXPECT_EQ(android::ResTable_config::HDR_YES, + config.colorimetry & android::ResTable_config::MASK_HDR); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(std::string("highdr-v26"), config.toString().string()); + + EXPECT_TRUE(TestParse("lowdr", &config)); + EXPECT_EQ(android::ResTable_config::HDR_NO, + config.colorimetry & android::ResTable_config::MASK_HDR); + EXPECT_EQ(SDK_O, config.sdkVersion); + EXPECT_EQ(std::string("lowdr-v26"), config.toString().string()); +} + TEST(ConfigDescriptionTest, ParseVrAttribute) { ConfigDescription config; EXPECT_TRUE(TestParse("vrheadset", &config));