Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9787a945 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Iterate on storage permissions model.

This change updates the permissions design to use app-ops for
controlling write access, which is only extended to the default app
for a particular collection type.

Bug: 119713234
Test: atest android.appsecurity.cts.PermissionsHostTest
Test: atest android.appsecurity.cts.ExternalStorageHostTest
Test: atest cts/tests/tests/provider/src/android/provider/cts/MediaStore*
Change-Id: I40811ff175b3b8410b58ed901948a23a56f8a8c2
parent 0430c3ce
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -159,9 +159,6 @@ package android {
    field public static final java.lang.String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS";
    field public static final deprecated java.lang.String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
    field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
    field public static final java.lang.String WRITE_MEDIA_AUDIO = "android.permission.WRITE_MEDIA_AUDIO";
    field public static final java.lang.String WRITE_MEDIA_IMAGES = "android.permission.WRITE_MEDIA_IMAGES";
    field public static final java.lang.String WRITE_MEDIA_VIDEO = "android.permission.WRITE_MEDIA_VIDEO";
    field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
    field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
    field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
+6 −6
Original line number Diff line number Diff line
@@ -1180,11 +1180,11 @@ public class AppOpsManager {
            Manifest.permission.ACTIVITY_RECOGNITION,
            Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
            Manifest.permission.READ_MEDIA_AUDIO,
            Manifest.permission.WRITE_MEDIA_AUDIO,
            null, // no permission for OP_WRITE_MEDIA_AUDIO
            Manifest.permission.READ_MEDIA_VIDEO,
            Manifest.permission.WRITE_MEDIA_VIDEO,
            null, // no permission for OP_WRITE_MEDIA_VIDEO
            Manifest.permission.READ_MEDIA_IMAGES,
            Manifest.permission.WRITE_MEDIA_IMAGES,
            null, // no permission for OP_WRITE_MEDIA_IMAGES
    };

    /**
@@ -1462,11 +1462,11 @@ public class AppOpsManager {
            AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
            AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
            AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
            AppOpsManager.MODE_ALLOWED, // WRITE_MEDIA_AUDIO
            AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
            AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
            AppOpsManager.MODE_ALLOWED, // WRITE_MEDIA_VIDEO
            AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
            AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
            AppOpsManager.MODE_ALLOWED, // WRITE_MEDIA_IMAGES
            AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
    };

    /**
+5 −27
Original line number Diff line number Diff line
@@ -2532,55 +2532,33 @@ public class PackageParser {

                final ArraySet<String> newPermissions = new ArraySet<>();
                newPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO);
                newPermissions.add(android.Manifest.permission.WRITE_MEDIA_AUDIO);
                newPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO);
                newPermissions.add(android.Manifest.permission.WRITE_MEDIA_VIDEO);
                newPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES);
                newPermissions.add(android.Manifest.permission.WRITE_MEDIA_IMAGES);
                newPermissions.add(android.Manifest.permission.ACCESS_MEDIA_LOCATION);
                newPermissions.add(android.Manifest.permission.WRITE_OBB);

                final ArraySet<String> dangerousPermissions = new ArraySet<>();
                dangerousPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
                dangerousPermissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
                final ArraySet<String> removedPermissions = new ArraySet<>();
                removedPermissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE);
                removedPermissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);

                for (int i = pkg.permissions.size() - 1; i >= 0; i--) {
                    final Permission p = pkg.permissions.get(i);
                    if (newPermissions.contains(p.info.name)) {
                        pkg.permissions.remove(i);
                    } else if (dangerousPermissions.contains(p.info.name)) {
                        p.info.protectionLevel &= ~PermissionInfo.PROTECTION_MASK_BASE;
                        p.info.protectionLevel |= PermissionInfo.PROTECTION_DANGEROUS;
                    } else if (removedPermissions.contains(p.info.name)) {
                        p.info.flags &= ~PermissionInfo.FLAG_REMOVED;
                    }
                }
            }
        } else {
            if (FORCE_AUDIO_PACKAGES.contains(pkg.packageName)) {
                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO);
                pkg.requestedPermissions.add(android.Manifest.permission.WRITE_MEDIA_AUDIO);
            }
            if (FORCE_VIDEO_PACKAGES.contains(pkg.packageName)) {
                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO);
                pkg.requestedPermissions.add(android.Manifest.permission.WRITE_MEDIA_VIDEO);
            }
            if (FORCE_IMAGES_PACKAGES.contains(pkg.packageName)) {
                pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES);
                pkg.requestedPermissions.add(android.Manifest.permission.WRITE_MEDIA_IMAGES);
            }

            if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_LEGACY, false)) {
                if (pkg.requestedPermissions
                        .contains(android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_AUDIO);
                    pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_VIDEO);
                    pkg.requestedPermissions.add(android.Manifest.permission.READ_MEDIA_IMAGES);
                }
                if (pkg.requestedPermissions
                        .contains(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    pkg.requestedPermissions.add(android.Manifest.permission.WRITE_MEDIA_AUDIO);
                    pkg.requestedPermissions.add(android.Manifest.permission.WRITE_MEDIA_VIDEO);
                    pkg.requestedPermissions.add(android.Manifest.permission.WRITE_MEDIA_IMAGES);
                }
            }
        }

+0 −2
Original line number Diff line number Diff line
@@ -137,8 +137,6 @@ public class StorageManager {
    public static final String PROP_FORCE_VIDEO = "persist.fw.force_video";
    /** {@hide} */
    public static final String PROP_FORCE_IMAGES = "persist.fw.force_images";
    /** {@hide} */
    public static final String PROP_FORCE_LEGACY = "persist.fw.force_legacy";

    /** {@hide} */
    public static final String UUID_PRIVATE_INTERNAL = null;
+11 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.Process;
import android.os.SystemProperties;
import android.os.storage.StorageManager;
import android.permission.PermissionManager.SplitPermissionInfo;
import android.text.TextUtils;
@@ -930,6 +931,16 @@ public class SystemConfig {
                XmlUtils.skipCurrentTag(parser);
            }
        }
        // If the storage model feature flag is disabled, we need to fiddle
        // around with permission definitions to return us to pre-Q behavior.
        // STOPSHIP(b/112545973): remove once feature enabled by default
        if (!SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, false)) {
            if (newPermissions.contains(android.Manifest.permission.READ_MEDIA_AUDIO) ||
                    newPermissions.contains(android.Manifest.permission.READ_MEDIA_VIDEO) ||
                    newPermissions.contains(android.Manifest.permission.READ_MEDIA_IMAGES)) {
                return;
            }
        }
        if (!newPermissions.isEmpty()) {
            mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk));
        }
Loading