Add support for media permissions split

Bug: 194956016
Test: atest MediaProviderTests
Change-Id: I04ad3c2151f74dd188ab231a2847273bf8d7f389
(cherry picked from commit 91bc28573c8b6d988e9cbb13f5cb6174b16a0106)
diff --git a/src/com/android/providers/media/LocalCallingIdentity.java b/src/com/android/providers/media/LocalCallingIdentity.java
index 6191457..cb8d2b2 100644
--- a/src/com/android/providers/media/LocalCallingIdentity.java
+++ b/src/com/android/providers/media/LocalCallingIdentity.java
@@ -17,7 +17,6 @@
 package com.android.providers.media;
 
 import static android.Manifest.permission.ACCESS_MEDIA_LOCATION;
-import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.permissionToOp;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
@@ -306,6 +305,7 @@
     }
 
     private boolean hasPermissionInternal(int permission) {
+        boolean targetSdkIsAtLeastT = getTargetSdkVersion() > Build.VERSION_CODES.S;
         // While we're here, enforce any broad user-level restrictions
         if ((uid == Process.SHELL_UID) && context.getSystemService(UserManager.class)
                 .hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
@@ -338,13 +338,13 @@
 
             case PERMISSION_READ_AUDIO:
                 return checkPermissionReadAudio(
-                        context, pid, uid, getPackageName(), attributionTag);
+                        context, pid, uid, getPackageName(), attributionTag, targetSdkIsAtLeastT);
             case PERMISSION_READ_VIDEO:
                 return checkPermissionReadVideo(
-                        context, pid, uid, getPackageName(), attributionTag);
+                        context, pid, uid, getPackageName(), attributionTag, targetSdkIsAtLeastT);
             case PERMISSION_READ_IMAGES:
                 return checkPermissionReadImages(
-                        context, pid, uid, getPackageName(), attributionTag);
+                        context, pid, uid, getPackageName(), attributionTag, targetSdkIsAtLeastT);
             case PERMISSION_WRITE_AUDIO:
                 return checkPermissionWriteAudio(
                         context, pid, uid, getPackageName(), attributionTag);
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 7c4fd9a..eac8bca 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -1092,6 +1092,12 @@
 
         mAppOpsManager.startWatchingMode(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE,
                 null /* all packages */, mModeListener);
+        mAppOpsManager.startWatchingMode(AppOpsManager.OPSTR_READ_MEDIA_AUDIO,
+                null /* all packages */, mModeListener);
+        mAppOpsManager.startWatchingMode(AppOpsManager.OPSTR_READ_MEDIA_IMAGES,
+                null /* all packages */, mModeListener);
+        mAppOpsManager.startWatchingMode(AppOpsManager.OPSTR_READ_MEDIA_VIDEO,
+                null /* all packages */, mModeListener);
         mAppOpsManager.startWatchingMode(AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE,
                 null /* all packages */, mModeListener);
         mAppOpsManager.startWatchingMode(permissionToOp(ACCESS_MEDIA_LOCATION),
diff --git a/src/com/android/providers/media/util/PermissionUtils.java b/src/com/android/providers/media/util/PermissionUtils.java
index 28dc14b..8ef172a 100644
--- a/src/com/android/providers/media/util/PermissionUtils.java
+++ b/src/com/android/providers/media/util/PermissionUtils.java
@@ -23,15 +23,18 @@
 import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
 import static android.Manifest.permission.MANAGE_MEDIA;
 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.READ_MEDIA_AUDIO;
+import static android.Manifest.permission.READ_MEDIA_IMAGE;
+import static android.Manifest.permission.READ_MEDIA_VIDEO;
 import static android.Manifest.permission.UPDATE_DEVICE_STATS;
 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES;
 import static android.app.AppOpsManager.OPSTR_LEGACY_STORAGE;
 import static android.app.AppOpsManager.OPSTR_NO_ISOLATED_STORAGE;
 import static android.app.AppOpsManager.OPSTR_READ_MEDIA_AUDIO;
 import static android.app.AppOpsManager.OPSTR_READ_MEDIA_IMAGES;
 import static android.app.AppOpsManager.OPSTR_READ_MEDIA_VIDEO;
+import static android.app.AppOpsManager.OPSTR_REQUEST_INSTALL_PACKAGES;
 import static android.app.AppOpsManager.OPSTR_WRITE_MEDIA_AUDIO;
 import static android.app.AppOpsManager.OPSTR_WRITE_MEDIA_IMAGES;
 import static android.app.AppOpsManager.OPSTR_WRITE_MEDIA_VIDEO;
@@ -147,9 +150,17 @@
         return checkNoIsolatedStorageGranted(context, uid, packageName, attributionTag);
     }
 
-    public static boolean checkPermissionReadAudio(@NonNull Context context, int pid, int uid,
-            @NonNull String packageName, @Nullable String attributionTag) {
-        if (!checkPermissionForPreflight(context, READ_EXTERNAL_STORAGE, pid, uid, packageName)) {
+    public static boolean checkPermissionReadAudio(
+            @NonNull Context context,
+            int pid,
+            int uid,
+            @NonNull String packageName,
+            @Nullable String attributionTag,
+            boolean targetSdkIsAtLeastT) {
+
+        String permission = targetSdkIsAtLeastT ? READ_MEDIA_AUDIO : READ_EXTERNAL_STORAGE;
+
+        if (!checkPermissionForPreflight(context, permission, pid, uid, packageName)) {
             return false;
         }
         return checkAppOpAllowingLegacy(context, OPSTR_READ_MEDIA_AUDIO, pid,
@@ -168,11 +179,19 @@
                 generateAppOpMessage(packageName, sOpDescription.get()));
     }
 
-    public static boolean checkPermissionReadVideo(@NonNull Context context, int pid, int uid,
-            @NonNull String packageName, @Nullable String attributionTag) {
-        if (!checkPermissionForPreflight(context, READ_EXTERNAL_STORAGE, pid, uid, packageName)) {
+    public static boolean checkPermissionReadVideo(
+            @NonNull Context context,
+            int pid,
+            int uid,
+            @NonNull String packageName,
+            @Nullable String attributionTag,
+            boolean targetSdkIsAtLeastT) {
+        String permission = targetSdkIsAtLeastT ? READ_MEDIA_VIDEO : READ_EXTERNAL_STORAGE;
+
+        if (!checkPermissionForPreflight(context, permission, pid, uid, packageName)) {
             return false;
         }
+
         return checkAppOpAllowingLegacy(context, OPSTR_READ_MEDIA_VIDEO, pid,
                 uid, packageName, attributionTag,
                 generateAppOpMessage(packageName, sOpDescription.get()));
@@ -189,11 +208,19 @@
                 generateAppOpMessage(packageName, sOpDescription.get()));
     }
 
-    public static boolean checkPermissionReadImages(@NonNull Context context, int pid, int uid,
-            @NonNull String packageName, @Nullable String attributionTag) {
-        if (!checkPermissionForPreflight(context, READ_EXTERNAL_STORAGE, pid, uid, packageName)) {
+    public static boolean checkPermissionReadImages(
+            @NonNull Context context,
+            int pid,
+            int uid,
+            @NonNull String packageName,
+            @Nullable String attributionTag,
+            boolean targetSdkIsAtLeastT) {
+        String permission = targetSdkIsAtLeastT ? READ_MEDIA_IMAGE : READ_EXTERNAL_STORAGE;
+
+        if (!checkPermissionForPreflight(context, permission, pid, uid, packageName)) {
             return false;
         }
+
         return checkAppOpAllowingLegacy(context, OPSTR_READ_MEDIA_IMAGES, pid,
                 uid, packageName, attributionTag,
                 generateAppOpMessage(packageName, sOpDescription.get()));
@@ -424,6 +451,7 @@
             return checkRuntimePermission(context, permission, pid, uid, packageName,
                     attributionTag, message, forDataDelivery);
         }
+
         return context.checkPermission(permission, pid, uid) == PERMISSION_GRANTED;
     }
 
@@ -441,6 +469,9 @@
             case ACCESS_MEDIA_LOCATION:
             case READ_EXTERNAL_STORAGE:
             case WRITE_EXTERNAL_STORAGE:
+            case READ_MEDIA_AUDIO:
+            case READ_MEDIA_VIDEO:
+            case READ_MEDIA_IMAGE:
                 return true;
         }
         return false;
diff --git a/tests/Android.bp b/tests/Android.bp
index 07590b7..c8d57ea 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -42,6 +42,25 @@
 }
 
 android_test_helper_app {
+    name: "MediaProviderTestAppWithMediaPerms",
+    manifest: "test_app/TestAppWithMediaPerms.xml",
+    srcs: [
+        "test_app/src/**/*.java",
+        "src/com/android/providers/media/util/TestUtils.java",
+    ],
+    static_libs: [
+        "cts-install-lib",
+    ],
+    sdk_version: "test_current",
+    target_sdk_version: "30",
+    min_sdk_version: "30",
+    test_suites: [
+        "general-tests",
+        "mts-mediaprovider",
+    ],
+}
+
+android_test_helper_app {
     name: "MediaProviderTestAppWithoutPerms",
     manifest: "test_app/TestAppWithoutPerms.xml",
     srcs: [
@@ -152,6 +171,7 @@
 
     java_resources: [
         ":MediaProviderTestAppWithStoragePerms",
+        ":MediaProviderTestAppWithMediaPerms",
         ":MediaProviderTestAppWithoutPerms",
         ":MediaProviderTestAppForPermissionActivity",
         ":LegacyMediaProviderTestApp",
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index fc561af..9513873 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -18,6 +18,7 @@
         <option name="test-file-name" value="MediaProviderTests.apk" />
         <option name="test-file-name" value="MediaProviderTestAppForPermissionActivity.apk" />
         <option name="test-file-name" value="MediaProviderTestAppWithStoragePerms.apk" />
+        <option name="test-file-name" value="MediaProviderTestAppWithMediaPerms.apk" />
         <option name="test-file-name" value="MediaProviderTestAppWithoutPerms.apk" />
         <option name="test-file-name" value="LegacyMediaProviderTestApp.apk" />
         <option name="install-arg" value="-g" />
diff --git a/tests/src/com/android/providers/media/util/PermissionUtilsTest.java b/tests/src/com/android/providers/media/util/PermissionUtilsTest.java
index c434bd2..7e8c33c 100644
--- a/tests/src/com/android/providers/media/util/PermissionUtilsTest.java
+++ b/tests/src/com/android/providers/media/util/PermissionUtilsTest.java
@@ -51,11 +51,8 @@
 import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteStorage;
 import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteVideo;
 import static com.android.providers.media.util.PermissionUtils.checkWriteImagesOrVideoAppOps;
-import static com.android.providers.media.util.TestUtils.QUERY_TYPE;
-import static com.android.providers.media.util.TestUtils.RUN_INFINITE_ACTIVITY;
 import static com.android.providers.media.util.TestUtils.adoptShellPermission;
 import static com.android.providers.media.util.TestUtils.dropShellPermission;
-import static com.android.providers.media.util.TestUtils.getPid;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -63,26 +60,28 @@
 
 import android.app.AppOpsManager;
 import android.content.Context;
-import android.content.Intent;
 
 import androidx.test.filters.SdkSuppress;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.cts.install.lib.TestApp;
 
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.HashMap;
-import java.util.Map;
-
 @RunWith(AndroidJUnit4.class)
 public class PermissionUtilsTest {
     private static final TestApp TEST_APP_WITH_STORAGE_PERMS = new TestApp(
             "TestAppWithStoragePerms",
             "com.android.providers.media.testapp.withstorageperms", 1, false,
             "MediaProviderTestAppWithStoragePerms.apk");
+    private static final TestApp TEST_APP_WITH_MEDIA_PERMS =
+            new TestApp(
+                    "TestAppWithMediaPerms",
+                    "com.android.providers.media.testapp.withmediaperms",
+                    1,
+                    false,
+                    "MediaProviderTestAppWithMediaPerms.apk");
     private static final TestApp TEST_APP_WITHOUT_PERMS = new TestApp("TestAppWithoutPerms",
             "com.android.providers.media.testapp.withoutperms", 1, false,
             "MediaProviderTestAppWithoutPerms.apk");
@@ -120,11 +119,11 @@
         assertThat(checkPermissionReadStorage(context, pid, uid, packageName, null)).isTrue();
         assertThat(checkPermissionWriteStorage(context, pid, uid, packageName, null)).isTrue();
 
-        assertThat(checkPermissionReadAudio(context, pid, uid, packageName, null)).isTrue();
+        assertThat(checkPermissionReadAudio(context, pid, uid, packageName, null, false)).isTrue();
         assertThat(checkPermissionWriteAudio(context, pid, uid, packageName, null)).isFalse();
-        assertThat(checkPermissionReadVideo(context, pid, uid, packageName, null)).isTrue();
+        assertThat(checkPermissionReadVideo(context, pid, uid, packageName, null, false)).isTrue();
         assertThat(checkPermissionWriteVideo(context, pid, uid, packageName, null)).isFalse();
-        assertThat(checkPermissionReadImages(context, pid, uid, packageName, null)).isTrue();
+        assertThat(checkPermissionReadImages(context, pid, uid, packageName, null, false)).isTrue();
         assertThat(checkPermissionWriteImages(context, pid, uid, packageName, null)).isFalse();
         assertThat(checkPermissionInstallPackages(context, pid, uid, packageName, null)).isFalse();
     }
@@ -159,9 +158,46 @@
                     checkPermissionAccessMtp(getContext(), TEST_APP_PID, testAppUid, packageName,
                             null)).isFalse();
             assertThat(
-                    checkPermissionWriteStorage(getContext(), TEST_APP_PID, testAppUid, packageName,
+                    checkPermissionWriteStorage(getContext(), TEST_APP_PID, testAppUid,
+                        packageName, null)).isTrue();
+            assertThat(
+                    checkPermissionReadStorage(getContext(), TEST_APP_PID, testAppUid, packageName,
                             null)).isTrue();
-            checkReadPermissions(TEST_APP_PID, testAppUid, packageName, true);
+            assertMediaReadPermissions(TEST_APP_PID, testAppUid, packageName,
+                false /* targetSdkIsAtLeastT */, true /* expected */);
+            // APPs with W_E_S can also read media.
+            assertMediaReadPermissions(TEST_APP_PID, testAppUid, packageName,
+                true /* targetSdkIsAtLeastT */, true /* expected */);
+
+        } finally {
+            dropShellPermission();
+        }
+    }
+
+    @Test
+    public void testDefaultPermissionsOnTestAppWithMediaPerms() throws Exception {
+        String packageName = TEST_APP_WITH_MEDIA_PERMS.getPackageName();
+        int testAppUid = getContext().getPackageManager().getPackageUid(packageName, 0);
+        adoptShellPermission(UPDATE_APP_OPS_STATS);
+
+        try {
+            assertThat(checkPermissionSelf(getContext(), TEST_APP_PID, testAppUid)).isFalse();
+            assertThat(checkPermissionShell(getContext(), TEST_APP_PID, testAppUid)).isFalse();
+            assertThat(checkIsLegacyStorageGranted(getContext(), testAppUid, packageName, null))
+                    .isFalse();
+            assertThat(checkPermissionInstallPackages(
+                        getContext(), TEST_APP_PID, testAppUid, packageName, null)).isFalse();
+            assertThat(checkPermissionAccessMtp(
+                        getContext(), TEST_APP_PID, testAppUid, packageName, null)).isFalse();
+            assertThat(checkPermissionWriteStorage(
+                        getContext(), TEST_APP_PID, testAppUid, packageName, null)).isFalse();
+            assertThat(checkPermissionReadStorage(
+                        getContext(), TEST_APP_PID, testAppUid, packageName, null)).isFalse();
+            assertMediaReadPermissions(TEST_APP_PID, testAppUid, packageName,
+                true /* targetSdkIsAtLeastT */, true /* expected */);
+            assertMediaReadPermissions(TEST_APP_PID, testAppUid, packageName,
+                false /* targetSdkIsAtLeastT */, false /* expected */);
+
         } finally {
             dropShellPermission();
         }
@@ -193,15 +229,20 @@
                             null)).isFalse();
             assertThat(
                     checkPermissionInstallPackages(getContext(), TEST_APP_PID, testAppUid,
-                            packageName,
-                            null)).isFalse();
+                        packageName, null)).isFalse();
             assertThat(
                     checkPermissionAccessMtp(getContext(), TEST_APP_PID, testAppUid, packageName,
                             null)).isFalse();
             assertThat(
                     checkPermissionWriteStorage(getContext(), TEST_APP_PID, testAppUid, packageName,
                             null)).isFalse();
-            checkReadPermissions(TEST_APP_PID, testAppUid, packageName, false);
+            assertThat(
+                    checkPermissionReadStorage( getContext(), TEST_APP_PID, testAppUid, packageName,
+                            null)).isFalse();
+            assertMediaReadPermissions(TEST_APP_PID, testAppUid, packageName,
+                false /* targetSdkIsAtLeastT */, false /* expected */);
+            assertMediaReadPermissions(TEST_APP_PID, testAppUid, packageName,
+                true /* targetSdkIsAtLeastT */, false /* expected */);
         } finally {
             dropShellPermission();
         }
@@ -238,9 +279,12 @@
                     checkPermissionAccessMtp(getContext(), TEST_APP_PID, testAppUid, packageName,
                             null)).isFalse();
             assertThat(
-                    checkPermissionWriteStorage(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isFalse();
-            checkReadPermissions(TEST_APP_PID, testAppUid, packageName, true);
+                    checkPermissionWriteStorage(getContext(), TEST_APP_PID, testAppUid,
+                        packageName, null)).isFalse();
+            assertThat(checkPermissionReadStorage(getContext(), TEST_APP_PID, testAppUid,
+                        packageName, null)).isTrue();
+            assertMediaReadPermissions(TEST_APP_PID, testAppUid, packageName,
+                false /* targetSdkIsAtLeastT */, true /* expected */);
         } finally {
             dropShellPermission();
         }
@@ -346,26 +390,29 @@
     }
 
     @Test
-    public void testReadVideoOnTestApp() throws Exception {
-        final String packageName = TEST_APP_WITH_STORAGE_PERMS.getPackageName();
-        int testAppUid = getContext().getPackageManager().getPackageUid(
-                packageName, 0);
+    public void testReadVideoOnTestAppWithStoragePerms() throws Exception {
+        assertReadVideoOnTestApp(TEST_APP_WITH_STORAGE_PERMS);
+    }
+
+    @Test
+    public void testReadVideoOnTestAppWithMediaPerms() throws Exception {
+        assertReadVideoOnTestApp(TEST_APP_WITH_MEDIA_PERMS);
+    }
+
+    private static void assertReadVideoOnTestApp(TestApp app) throws Exception {
+        boolean isAtLeastT = (app == TEST_APP_WITH_MEDIA_PERMS) ? true : false;
+        final String packageName = app.getPackageName();
+        int testAppUid = getContext().getPackageManager().getPackageUid(packageName, 0);
         adoptShellPermission(UPDATE_APP_OPS_STATS, MANAGE_APP_OPS_MODES);
-
         try {
-            assertThat(
-                    checkPermissionReadVideo(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isTrue();
-
+            assertThat(checkPermissionReadVideo(getContext(), TEST_APP_PID, testAppUid,
+                    packageName, null, isAtLeastT)).isTrue();
             modifyAppOp(testAppUid, OPSTR_READ_MEDIA_VIDEO, AppOpsManager.MODE_ERRORED);
-            assertThat(
-                    checkPermissionReadVideo(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isFalse();
-
+            assertThat(checkPermissionReadVideo(getContext(), TEST_APP_PID, testAppUid,
+                    packageName, null, isAtLeastT)).isFalse();
             modifyAppOp(testAppUid, OPSTR_READ_MEDIA_VIDEO, AppOpsManager.MODE_ALLOWED);
-            assertThat(
-                    checkPermissionReadVideo(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isTrue();
+            assertThat(checkPermissionReadVideo(getContext(), TEST_APP_PID, testAppUid,
+                packageName, null, isAtLeastT)).isTrue();
         } finally {
             dropShellPermission();
         }
@@ -398,51 +445,62 @@
     }
 
     @Test
-    public void testReadAudioOnTestApp() throws Exception {
-        final String packageName = TEST_APP_WITH_STORAGE_PERMS.getPackageName();
-        int testAppUid = getContext().getPackageManager().getPackageUid(
-                packageName, 0);
-        adoptShellPermission(UPDATE_APP_OPS_STATS, MANAGE_APP_OPS_MODES);
+    public void testReadAudioOnTestAppWithStoragePerms() throws Exception {
+        assertReadAudioOnTestApp(TEST_APP_WITH_STORAGE_PERMS);
+    }
 
+    @Test
+    public void testReadAudioOnTestAppWithMediaPerms() throws Exception {
+        assertReadAudioOnTestApp(TEST_APP_WITH_MEDIA_PERMS);
+    }
+
+    private static void assertReadAudioOnTestApp(TestApp app) throws Exception {
+        boolean isAtLeastT = (app == TEST_APP_WITH_MEDIA_PERMS) ? true : false;
+        final String packageName = app.getPackageName();
+        int testAppUid = getContext().getPackageManager().getPackageUid(packageName, 0);
+        adoptShellPermission(UPDATE_APP_OPS_STATS, MANAGE_APP_OPS_MODES);
         try {
-            assertThat(
-                    checkPermissionReadAudio(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isTrue();
+            assertThat(checkPermissionReadAudio(getContext(), TEST_APP_PID, testAppUid,
+                        packageName, null, isAtLeastT)).isTrue();
 
             modifyAppOp(testAppUid, OPSTR_READ_MEDIA_AUDIO, AppOpsManager.MODE_ERRORED);
-            assertThat(
-                    checkPermissionReadAudio(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isFalse();
+            assertThat(checkPermissionReadAudio(getContext(), TEST_APP_PID, testAppUid,
+                        packageName, null, isAtLeastT)).isFalse();
 
             modifyAppOp(testAppUid, OPSTR_READ_MEDIA_AUDIO, AppOpsManager.MODE_ALLOWED);
-            assertThat(
-                    checkPermissionReadAudio(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isTrue();
+            assertThat(checkPermissionReadAudio(getContext(), TEST_APP_PID, testAppUid,
+                        packageName, null, isAtLeastT)).isTrue();
         } finally {
             dropShellPermission();
         }
     }
 
     @Test
-    public void testReadImagesOnTestApp() throws Exception {
-        final String packageName = TEST_APP_WITH_STORAGE_PERMS.getPackageName();
+    public void testReadImagesOnTestAppWithStoragePerms() throws Exception {
+        assertReadImagesOnTestApp(TEST_APP_WITH_STORAGE_PERMS);
+    }
+
+    @Test
+    public void testReadImagesOnTestAppWithMediaPerms() throws Exception {
+        assertReadImagesOnTestApp(TEST_APP_WITH_MEDIA_PERMS);
+    }
+
+    private static void assertReadImagesOnTestApp(TestApp app) throws Exception {
+        boolean isAtLeastT = (app == TEST_APP_WITH_MEDIA_PERMS) ? true : false;
+        final String packageName = app.getPackageName();
         int testAppUid = getContext().getPackageManager().getPackageUid(packageName, 0);
         adoptShellPermission(UPDATE_APP_OPS_STATS, MANAGE_APP_OPS_MODES);
-
         try {
-            assertThat(
-                    checkPermissionReadImages(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isTrue();
+            assertThat(checkPermissionReadImages(getContext(), TEST_APP_PID, testAppUid,
+                            packageName, null, isAtLeastT)).isTrue();
 
             modifyAppOp(testAppUid, OPSTR_READ_MEDIA_IMAGES, AppOpsManager.MODE_ERRORED);
-            assertThat(
-                    checkPermissionReadImages(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isFalse();
+            assertThat(checkPermissionReadImages(getContext(), TEST_APP_PID, testAppUid,
+                            packageName, null, isAtLeastT)).isFalse();
 
             modifyAppOp(testAppUid, OPSTR_READ_MEDIA_IMAGES, AppOpsManager.MODE_ALLOWED);
-            assertThat(
-                    checkPermissionReadImages(getContext(), TEST_APP_PID, testAppUid, packageName,
-                            null)).isTrue();
+            assertThat(checkPermissionReadImages(getContext(), TEST_APP_PID, testAppUid,
+                            packageName, null, isAtLeastT)).isTrue();
         } finally {
             dropShellPermission();
         }
@@ -491,15 +549,19 @@
                 .isFalse();
     }
 
-    static private void checkReadPermissions(int pid, int uid, String packageName,
-            boolean expected) {
-        assertEquals(expected,
-                checkPermissionReadStorage(getContext(), pid, uid, packageName, null));
-        assertEquals(expected,
-                checkPermissionReadAudio(getContext(), pid, uid, packageName, null));
-        assertEquals(expected,
-                checkPermissionReadImages(getContext(), pid, uid, packageName, null));
-        assertEquals(expected,
-                checkPermissionReadVideo(getContext(), pid, uid, packageName, null));
+    private static void assertMediaReadPermissions(
+            int pid, int uid, String packageName, boolean targetSdkIsAtLeastT, boolean expected) {
+        assertEquals(
+                expected,
+                checkPermissionReadAudio(
+                        getContext(), pid, uid, packageName, null, targetSdkIsAtLeastT));
+        assertEquals(
+                expected,
+                checkPermissionReadImages(
+                        getContext(), pid, uid, packageName, null, targetSdkIsAtLeastT));
+        assertEquals(
+                expected,
+                checkPermissionReadVideo(
+                        getContext(), pid, uid, packageName, null, targetSdkIsAtLeastT));
     }
 }
diff --git a/tests/test_app/TestAppWithMediaPerms.xml b/tests/test_app/TestAppWithMediaPerms.xml
new file mode 100644
index 0000000..29b1ac8
--- /dev/null
+++ b/tests/test_app/TestAppWithMediaPerms.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.providers.media.testapp.withmediaperms"
+          android:versionCode="1"
+          android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="30" android:targetSdkVersion="32" />
+    <uses-permission android:name="android.permission.READ_MEDIA_IMAGE"/>
+    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
+    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
+
+    <application android:label="TestAppWithMediaPerms">
+        <activity android:name="com.android.providers.media.util.TestAppActivity"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
\ No newline at end of file