Merge "mediav2 CTS: Update color format(s) support as per CDD"
diff --git a/tests/media/AndroidManifest.xml b/tests/media/AndroidManifest.xml
index 3a97bbe..0a1f5e0 100644
--- a/tests/media/AndroidManifest.xml
+++ b/tests/media/AndroidManifest.xml
@@ -23,6 +23,7 @@
 
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.CAMERA" />
 
     <application
         android:requestLegacyExternalStorage="true"
diff --git a/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java b/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java
index b1ccc46..2736823 100644
--- a/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java
+++ b/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java
@@ -26,6 +26,11 @@
 import static org.junit.Assert.fail;
 
 import android.content.Context;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.params.DynamicRangeProfiles;
 import android.hardware.display.DisplayManager;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
@@ -115,6 +120,7 @@
             SystemProperties.getInt("ro.vndk.version", Build.VERSION_CODES.CUR_DEVELOPMENT)
                     >= Build.VERSION_CODES.TIRAMISU;
     public static final boolean IS_HDR_EDITING_SUPPORTED;
+    public static final boolean IS_HDR_CAPTURE_SUPPORTED;
     private static final String LOG_TAG = CodecTestBase.class.getSimpleName();
 
     public static final ArrayList<String> HDR_INFO_IN_BITSTREAM_CODECS = new ArrayList<>();
@@ -280,6 +286,7 @@
     static {
         MEDIA_CODEC_LIST_ALL = new MediaCodecList(MediaCodecList.ALL_CODECS);
         MEDIA_CODEC_LIST_REGULAR = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        IS_HDR_CAPTURE_SUPPORTED = isHDRCaptureSupported();
         IS_HDR_EDITING_SUPPORTED = isHDREditingSupported();
         CODEC_SEL_KEY_MEDIA_TYPE_MAP.put("vp8", MediaFormat.MIMETYPE_VIDEO_VP8);
         CODEC_SEL_KEY_MEDIA_TYPE_MAP.put("vp9", MediaFormat.MIMETYPE_VIDEO_VP9);
@@ -455,6 +462,31 @@
         return isSupported;
     }
 
+    public static boolean isHDRCaptureSupported() {
+        // If the device supports HDR, hlg support should always return true
+        if (!MediaUtils.hasCamera()) return false;
+        CameraManager cm = CONTEXT.getSystemService(CameraManager.class);
+        try {
+            String[] cameraIds = cm.getCameraIdList();
+            for (String id : cameraIds) {
+                CameraCharacteristics ch = cm.getCameraCharacteristics(id);
+                int[] caps = ch.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+                if (IntStream.of(caps).anyMatch(x -> x
+                        == CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT)) {
+                    Set<Long> profiles =
+                            ch.get(CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES)
+                                    .getSupportedProfiles();
+                    if (profiles.contains(DynamicRangeProfiles.HLG10)) return true;
+                }
+            }
+        } catch (CameraAccessException e) {
+            Log.e(LOG_TAG, "encountered " + e.getMessage()
+                    + " marking hdr capture to be available to catch your attention");
+            return true;
+        }
+        return false;
+    }
+
     public static boolean isHDREditingSupported() {
         for (MediaCodecInfo codecInfo : MEDIA_CODEC_LIST_REGULAR.getCodecInfos()) {
             if (!codecInfo.isEncoder()) {
@@ -508,7 +540,7 @@
     public static boolean canDisplaySupportHDRContent() {
         DisplayManager displayManager = CONTEXT.getSystemService(DisplayManager.class);
         return displayManager.getDisplay(Display.DEFAULT_DISPLAY).getHdrCapabilities()
-                .getSupportedHdrTypes().length != 0;
+                .getSupportedHdrTypes().length > 0;
     }
 
     public static boolean areFormatsSupported(String name, String mediaType,
diff --git a/tests/media/src/android/mediav2/cts/CodecInfoTest.java b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
index 5896b23..d295a59 100644
--- a/tests/media/src/android/mediav2/cts/CodecInfoTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecInfoTest.java
@@ -19,28 +19,30 @@
 import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_Format32bitABGR2101010;
 import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
 import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
 import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
 import static android.media.MediaCodecInfo.CodecCapabilities.FEATURE_HdrEditing;
-import static android.mediav2.common.cts.CodecTestBase.CONTEXT;
 import static android.mediav2.common.cts.CodecTestBase.FIRST_SDK_IS_AT_LEAST_T;
 import static android.mediav2.common.cts.CodecTestBase.IS_AT_LEAST_T;
+import static android.mediav2.common.cts.CodecTestBase.IS_HDR_CAPTURE_SUPPORTED;
 import static android.mediav2.common.cts.CodecTestBase.PROFILE_HDR10_MAP;
 import static android.mediav2.common.cts.CodecTestBase.PROFILE_HDR10_PLUS_MAP;
-import static android.mediav2.common.cts.CodecTestBase.PROFILE_HDR_MAP;
 import static android.mediav2.common.cts.CodecTestBase.VNDK_IS_AT_LEAST_T;
+import static android.mediav2.common.cts.CodecTestBase.canDisplaySupportHDRContent;
 import static android.mediav2.common.cts.CodecTestBase.isVendorCodec;
 import static android.mediav2.common.cts.CodecTestBase.selectCodecs;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.hardware.display.DisplayManager;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecProfileLevel;
 import android.media.MediaCodecList;
 import android.mediav2.common.cts.CodecTestBase;
 import android.os.Build;
-import android.view.Display;
 
 import androidx.test.filters.SmallTest;
 
@@ -68,19 +70,11 @@
 @RunWith(Parameterized.class)
 public class CodecInfoTest {
     private static final String LOG_TAG = CodecInfoTest.class.getSimpleName();
-    private static final int[] DISPLAY_HDR_TYPES;
 
     public String mMediaType;
     public String mCodecName;
     public MediaCodecInfo mCodecInfo;
 
-    static {
-        DisplayManager displayManager = CONTEXT.getSystemService(DisplayManager.class);
-        DISPLAY_HDR_TYPES =
-                displayManager.getDisplay(Display.DEFAULT_DISPLAY).getHdrCapabilities()
-                        .getSupportedHdrTypes();
-    }
-
     public CodecInfoTest(String mediaType, String codecName, MediaCodecInfo codecInfo) {
         mMediaType = mediaType;
         mCodecName = codecName;
@@ -145,7 +139,7 @@
             // native level, separate the following to independent checks for HDR10 and HDR10+
             if (isHdr10Profile || isHdr10PlusProfile) {
                 assertTrue(mCodecInfo.getName() + " Advertises support for HDR10/HDR10+ profile " +
-                        pl.profile + " without any HDR display", DISPLAY_HDR_TYPES.length > 0);
+                        pl.profile + " without any HDR display", canDisplaySupportHDRContent());
             }
         }
     }
@@ -155,7 +149,8 @@
      * formats. The test only checks if the decoder/encoder is advertising the required color
      * format. It doesn't verify if it actually supports by decoding/encoding.
      */
-    @CddTest(requirements = {"5.1.7/C-1-2", "5.1.7/C-4-1", "5.12/C-6-5", "5.12/C-7-3"})
+    @CddTest(requirements = {"5.1.7/C-1-2", "5.1.7/C-1-3", "5.1.7/C-4-1", "5.12/C-6-5",
+            "5.12/C-7-1", "5.12/C-7-3"})
     @Test
     public void testColorFormatSupport() {
         Assume.assumeTrue("Test is applicable for video codecs", mMediaType.startsWith("video/"));
@@ -164,20 +159,54 @@
                 IntStream.of(caps.colorFormats)
                         .noneMatch(x -> x == COLOR_FormatYUV420Flexible));
 
-        // Encoders that support FEATURE_HdrEditing, must support P010 and ABGR2101010
-        // color format and at least one HDR profile
-        boolean hdrEditingSupported = caps.isFeatureSupported(FEATURE_HdrEditing);
-        if (mCodecInfo.isEncoder() && hdrEditingSupported) {
-            boolean abgr2101010Supported =
-                    IntStream.of(caps.colorFormats)
-                            .anyMatch(x -> x == COLOR_Format32bitABGR2101010);
-            boolean p010Supported =
-                    IntStream.of(caps.colorFormats).anyMatch(x -> x == COLOR_FormatYUVP010);
-            assertTrue(mCodecName + " supports FEATURE_HdrEditing, but does not support " +
-                    "COLOR_FormatABGR2101010 and COLOR_FormatYUVP010 color formats.",
-                    abgr2101010Supported && p010Supported);
-            assertTrue(mCodecName + " supports FEATURE_HdrEditing, but does not support any HDR " +
-                    "profiles.", CodecTestBase.doesCodecSupportHDRProfile(mCodecName, mMediaType));
+        assertFalse(mCodecInfo.getName()
+                        + " does not support at least one of planar or semi planar yuv 420 888",
+                IntStream.of(caps.colorFormats)
+                        .noneMatch(x -> x == COLOR_FormatYUV420PackedPlanar)
+                        && IntStream.of(caps.colorFormats)
+                        .noneMatch(x -> x == COLOR_FormatYUV420Planar)
+                        && IntStream.of(caps.colorFormats)
+                        .noneMatch(x -> x == COLOR_FormatYUV420PackedSemiPlanar)
+                        && IntStream.of(caps.colorFormats)
+                        .noneMatch(x -> x == COLOR_FormatYUV420SemiPlanar));
+
+        boolean canHandleHdr = CodecTestBase.doesCodecSupportHDRProfile(mCodecName, mMediaType);
+        if (mCodecInfo.isEncoder()) {
+            if (IS_HDR_CAPTURE_SUPPORTED && canHandleHdr) {
+                assertFalse(mCodecInfo.getName()
+                                + " supports HDR profile but does not support COLOR_FormatYUVP010",
+                        IntStream.of(caps.colorFormats).noneMatch(x -> x == COLOR_FormatYUVP010));
+            }
+
+            // Encoders that support FEATURE_HdrEditing, must support ABGR2101010 color format
+            // and at least one HDR profile
+            boolean hdrEditingSupported = caps.isFeatureSupported(FEATURE_HdrEditing);
+            if (hdrEditingSupported) {
+                boolean abgr2101010Supported = IntStream.of(caps.colorFormats)
+                        .anyMatch(x -> x == COLOR_Format32bitABGR2101010);
+                assertTrue(mCodecName + " supports FEATURE_HdrEditing, but does not support"
+                        + " COLOR_FormatABGR2101010 color formats.", abgr2101010Supported);
+                assertTrue(mCodecName + " supports FEATURE_HdrEditing, but does not support"
+                        + " any HDR profiles.", canHandleHdr);
+            }
+        } else {
+            if (FIRST_SDK_IS_AT_LEAST_T && VNDK_IS_AT_LEAST_T && canDisplaySupportHDRContent()) {
+                if (MediaUtils.isTv()) {
+                    // Some TV devices support HDR10 display with VO instead of GPU. In this
+                    // case, skip checking P010 on TV devices.
+                    Assume.assumeFalse(mCodecInfo.getName()
+                                    + " supports HDR profile but does not support "
+                                    + "COLOR_FormatYUVP010. Skip checking on TV device",
+                            IntStream.of(caps.colorFormats)
+                                    .noneMatch(x -> x == COLOR_FormatYUVP010));
+                } else {
+                    assertFalse(mCodecInfo.getName()
+                                    + " supports HDR profile but does not support "
+                                    + "COLOR_FormatYUVP010",
+                            IntStream.of(caps.colorFormats)
+                                    .noneMatch(x -> x == COLOR_FormatYUVP010));
+                }
+            }
         }
 
         // COLOR_FormatSurface support is an existing requirement, but we did not
@@ -190,41 +219,6 @@
         }
     }
 
-    /** For devices launching with Android T or higher, if a codec supports an HDR profile and
-     * device supports HDR display, it must support COLOR_FormatYUVP010 as a video decoder output
-     * format. For TVs, this requirement is optional.
-     */
-    @CddTest(requirements = "5.12/C-6-5")
-    @Test
-    public void testP010SupportForHDRDisplay() {
-        Assume.assumeTrue("Test is applicable for video codecs", mMediaType.startsWith("video/"));
-        MediaCodecInfo.CodecCapabilities caps = mCodecInfo.getCapabilitiesForType(mMediaType);
-        int[] HdrProfileArray = PROFILE_HDR_MAP.get(mMediaType);
-        if (FIRST_SDK_IS_AT_LEAST_T && VNDK_IS_AT_LEAST_T
-                && HdrProfileArray != null && DISPLAY_HDR_TYPES.length > 0) {
-            for (CodecProfileLevel pl : caps.profileLevels) {
-                if (IntStream.of(HdrProfileArray).anyMatch(x -> x == pl.profile)) {
-                    if (MediaUtils.isTv()) {
-                        // Some TV devices support HDR10 display with VO instead of GPU. In this
-                        // case, skip checking P010 on TV devices.
-                        Assume.assumeFalse(mCodecInfo.getName() + " supports HDR profile "
-                                        + pl.profile + ","
-                                        + " but does not support COLOR_FormatYUVP010."
-                                        + " Skip checking on TV device",
-                                IntStream.of(caps.colorFormats)
-                                        .noneMatch(x -> x == COLOR_FormatYUVP010));
-                    } else {
-                        assertFalse(mCodecInfo.getName() + " supports HDR profile "
-                                        + pl.profile + "," +
-                                        " but does not support COLOR_FormatYUVP010",
-                                IntStream.of(caps.colorFormats)
-                                        .noneMatch(x -> x == COLOR_FormatYUVP010));
-                    }
-                }
-            }
-        }
-    }
-
     /**
      * For all the available encoders on the device, the test checks if their encoding
      * capabilities are in sync with the device's decoding capabilities.