MetadataRetriever: Use RGBA_8888 as default color format based on a flag

When the flag mediametadataretriever_default_rgba8888 is set, use
RGBA_8888 as the color format in getFrameAtTime call.

Add the unit test to check the intended behaviour.

Test: adb shell setprop persist.device_config.aconfig_flags.\
media_solutions.com.android.media.playback.flags.\
mediametadataretriever_default_rgba8888 true
Test: adb shell device_config put media_solutions \
com.android.media.playback.flags.mediametadataretriever_default_rgba8888 \
true
Test: atest com.android.mediaframeworktest.unit.MediaMetadataRetrieverTest
Bug: 298965955

Change-Id: I8452e75e07bcfcd2483ad2da971806147f5a9067
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 0265431..45f6570 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -199,6 +199,24 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+// Media
+aconfig_declarations {
+    name: "android.media.playback.flags-aconfig",
+    package: "com.android.media.playback.flags",
+    srcs: ["media/jni/playback_flags.aconfig"],
+}
+
+cc_aconfig_library {
+    name: "android.media.playback.flags-aconfig-cc",
+    aconfig_declarations: "android.media.playback.flags-aconfig",
+}
+
+java_aconfig_library {
+    name: "android.media.playback.flags-aconfig-java",
+    aconfig_declarations: "android.media.playback.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // VCN
 aconfig_declarations {
     name: "android.net.vcn.flags-aconfig",
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index ed1072c..6031ef7 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -81,6 +81,7 @@
         "libhidlallocatorutils",
         "libhidlbase",
         "libsonivox",
+        "server_configurable_flags",
         "android.hardware.cas@1.0",
         "android.hardware.cas.native@1.0",
         "android.hardware.drm@1.3",
@@ -99,6 +100,7 @@
     static_libs: [
         "libgrallocusage",
         "libmedia_midiiowrapper",
+        "android.media.playback.flags-aconfig-cc",
     ],
 
     include_dirs: [
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 1458758..2a10fa7 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -35,7 +35,9 @@
 #include "android_media_MediaDataSource.h"
 #include "android_media_Streams.h"
 #include "android_util_Binder.h"
+#include <com_android_media_playback_flags.h>
 
+namespace playback_flags = com::android::media::playback::flags;
 using namespace android;
 
 struct fields_t {
@@ -374,9 +376,12 @@
         jniThrowException(env, "java/lang/IllegalStateException", "No retriever available");
         return NULL;
     }
-    // For getFrameAtTime family of calls, default to ANDROID_BITMAP_FORMAT_RGB_565
-    // to keep the behavior consistent with older releases
-    AndroidBitmapFormat colorFormat = getColorFormat(env, params, ANDROID_BITMAP_FORMAT_RGB_565);
+
+    AndroidBitmapFormat defaultColorFormat =
+            playback_flags::mediametadataretriever_default_rgba8888()
+            ? ANDROID_BITMAP_FORMAT_RGBA_8888
+            : ANDROID_BITMAP_FORMAT_RGB_565;
+    AndroidBitmapFormat colorFormat = getColorFormat(env, params, defaultColorFormat);
 
     // Call native method to retrieve a video frame
     VideoFrame *videoFrame = NULL;
diff --git a/media/jni/playback_flags.aconfig b/media/jni/playback_flags.aconfig
new file mode 100644
index 0000000..2bb0ec5
--- /dev/null
+++ b/media/jni/playback_flags.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.media.playback.flags"
+
+flag {
+  name: "mediametadataretriever_default_rgba8888"
+  namespace: "media_solutions"
+  description: "Change MediaMetadataRetriever to use RGBA8888 for bitmap handling by default."
+  bug: "298965955"
+}
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
index bdd7afe..7a329bc 100644
--- a/media/tests/MediaFrameworkTest/Android.bp
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -20,6 +20,8 @@
         "androidx.test.ext.junit",
         "androidx.test.rules",
         "android-ex-camera2",
+        "android.media.playback.flags-aconfig-java",
+        "flag-junit",
         "testables",
         "testng",
         "truth",
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
index f70d2d1..e3d3897 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
@@ -16,19 +16,27 @@
 
 package com.android.mediaframeworktest.unit;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Bitmap;
 import android.media.MediaMetadataRetriever;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.util.Log;
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.media.playback.flags.Flags;
 import com.android.mediaframeworktest.MediaNames;
 import com.android.mediaframeworktest.MediaProfileReader;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -40,6 +48,9 @@
 
     private static final String TAG = "MediaMetadataRetrieverTest";
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     // Test album art extraction.
     @MediumTest
     @Test
@@ -284,6 +295,34 @@
         assertTrue(!hasFailed);
     }
 
+    /** Test the thumbnail is generated when the default is set to RGBA8888 */
+    @MediumTest
+    // TODO(b/305160754) Remove the following annotation and use SetFlagsRule.enableFlags
+    @RequiresFlagsEnabled(Flags.FLAG_MEDIAMETADATARETRIEVER_DEFAULT_RGBA8888)
+    @Test
+    public void testGetFrameAtTimeWithRGBA8888Flag_Set() throws IOException {
+        try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
+            retriever.setDataSource(MediaNames.TEST_PATH_1);
+            Bitmap bitmap = retriever.getFrameAtTime(-1);
+            assertNotNull(bitmap);
+            assertEquals(Bitmap.Config.ARGB_8888, bitmap.getConfig());
+        }
+    }
+
+    /** Test the thumbnail is generated when the default is not set to RGBA8888 */
+    @MediumTest
+    // TODO(b/305160754) Remove the following annotation and use SetFlagsRule.disableFlags
+    @RequiresFlagsDisabled(Flags.FLAG_MEDIAMETADATARETRIEVER_DEFAULT_RGBA8888)
+    @Test
+    public void testGetFrameAtTimeWithRGBA8888Flag_Unset() throws IOException {
+        try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
+            retriever.setDataSource(MediaNames.TEST_PATH_1);
+            Bitmap bitmap = retriever.getFrameAtTime(-1);
+            assertNotNull(bitmap);
+            assertEquals(Bitmap.Config.RGB_565, bitmap.getConfig());
+        }
+    }
+
     // TODO:
     // Encode and test for the correct mix of metadata elements on a per-file basis?
     // We should be able to compare the actual returned metadata with the expected metadata