Add wide color gamut and HDR resource qualifiers

Bug: 32984164
Test: Config_test, AaptConfig_test and aapt2_tests
Change-Id: Ie9c82bfe2d36b1d6180ee223250ab5bb2ce90dd4
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index a30c849..a4bcc62 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1907,6 +1907,8 @@
     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 @@
     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 @@
     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 @@
         }
     }
 
+    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 @@
             }
         }
 
+        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 @@
         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 @@
                 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) {