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

Commit a0d5569c authored by Abhijeet Kaur's avatar Abhijeet Kaur
Browse files

Add new API to check a collection of URIs at once

Optimizes the workflow to check multiple URI permissions, which
currently need to be checked one URI at a time.

New APIs are logically similar to existing APIs: checkUriPermission,
checkCallingUriPermission and checkCallingOrSelfUriPermission. The
new APIs would take input of a collection of URIs instead of just one
URI.

Bug: 179362563
Test: atest ContextTest.java
Test: atest ExternalStorageHostTest#testMediaEscalation_RequestWriteFilePathSupport

Change-Id: I9cd6278f9b865c0532afc337b089771df6aea8c5
parent bd6db335
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -10226,12 +10226,15 @@ package android.content {
    method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.INTERACT_ACROSS_PROFILES}) public boolean bindServiceAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull android.os.UserHandle);
    method @CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)") public abstract int checkCallingOrSelfPermission(@NonNull String);
    method @CheckResult(suggest="#enforceCallingOrSelfUriPermission(Uri,int,String)") public abstract int checkCallingOrSelfUriPermission(android.net.Uri, int);
    method @NonNull public int[] checkCallingOrSelfUriPermissions(@NonNull java.util.List<android.net.Uri>, int);
    method @CheckResult(suggest="#enforceCallingPermission(String,String)") public abstract int checkCallingPermission(@NonNull String);
    method @CheckResult(suggest="#enforceCallingUriPermission(Uri,int,String)") public abstract int checkCallingUriPermission(android.net.Uri, int);
    method @NonNull public int[] checkCallingUriPermissions(@NonNull java.util.List<android.net.Uri>, int);
    method @CheckResult(suggest="#enforcePermission(String,int,int,String)") public abstract int checkPermission(@NonNull String, int, int);
    method public abstract int checkSelfPermission(@NonNull String);
    method @CheckResult(suggest="#enforceUriPermission(Uri,int,int,String)") public abstract int checkUriPermission(android.net.Uri, int, int, int);
    method @CheckResult(suggest="#enforceUriPermission(Uri,String,String,int,int,int,String)") public abstract int checkUriPermission(@Nullable android.net.Uri, @Nullable String, @Nullable String, int, int, int);
    method @NonNull public int[] checkUriPermissions(@NonNull java.util.List<android.net.Uri>, int, int, int);
    method @Deprecated public abstract void clearWallpaper() throws java.io.IOException;
    method @NonNull public android.content.Context createAttributionContext(@Nullable String);
    method public abstract android.content.Context createConfigurationContext(@NonNull android.content.res.Configuration);
+32 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.StrictMode.vmIncorrectContextUseEnabled;

@@ -105,6 +106,7 @@ import java.lang.annotation.RetentionPolicy;
import java.nio.ByteOrder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -2181,6 +2183,18 @@ class ContextImpl extends Context {
        }
    }

    @NonNull
    @Override
    public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
            int modeFlags) {
        try {
            return ActivityManager.getService().checkUriPermissions(uris, pid, uid, modeFlags,
                    null);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** @hide */
    @Override
    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
@@ -2207,12 +2221,30 @@ class ContextImpl extends Context {
        return PackageManager.PERMISSION_DENIED;
    }

    @NonNull
    @Override
    public int[] checkCallingUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
        int pid = Binder.getCallingPid();
        if (pid != Process.myPid()) {
            return checkUriPermissions(uris, pid, Binder.getCallingUid(), modeFlags);
        }
        int[] res = new int[uris.size()];
        Arrays.fill(res, PERMISSION_DENIED);
        return res;
    }

    @Override
    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
        return checkUriPermission(uri, Binder.getCallingPid(),
                Binder.getCallingUid(), modeFlags);
    }

    @NonNull
    @Override
    public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
        return checkUriPermissions(uris, Binder.getCallingPid(), Binder.getCallingUid(), modeFlags);
    }

    @Override
    public int checkUriPermission(Uri uri, String readPermission,
            String writePermission, int pid, int uid, int modeFlags) {
+2 −0
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ interface IActivityManager {
    int getProcessLimit();
    int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
            in IBinder callerToken);
    int[] checkUriPermissions(in List<Uri> uris, int pid, int uid, int mode,
                in IBinder callerToken);
    void grantUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
            int mode, int userId);
    void revokeUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
+75 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.concurrent.Executor;

/**
@@ -5725,6 +5726,32 @@ public abstract class Context {
    public abstract int checkUriPermission(Uri uri, int pid, int uid,
            @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether a particular process and user ID has been granted
     * permission to access a list of URIs.  This only checks for permissions
     * that have been explicitly granted -- if the given process/uid has
     * more general access to the URI's content provider then this check will
     * always fail.
     *
     * @param uris The list of URIs that is being checked.
     * @param pid The process ID being checked against.  Must be &gt; 0.
     * @param uid The user ID being checked against.  A uid of 0 is the root
     * user, which will pass every permission check.
     * @param modeFlags The access modes to check for the list of uris
     *
     * @return Array of permission grants corresponding to each entry in the list of uris.
     * {@link PackageManager#PERMISSION_GRANTED} if the given pid/uid is allowed to access that uri,
     * or {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see #checkCallingUriPermission
     */
    @NonNull
    @PackageManager.PermissionResult
    public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
            @Intent.AccessUriMode int modeFlags) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /** @hide */
    @SuppressWarnings("HiddenAbstractMethod")
    @PackageManager.PermissionResult
@@ -5754,6 +5781,32 @@ public abstract class Context {
    @PackageManager.PermissionResult
    public abstract int checkCallingUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether the calling process and user ID has been
     * granted permission to access a list of URIs.  This is basically
     * the same as calling {@link #checkUriPermissions(List, int, int, int)}
     * with the pid and uid returned by {@link
     * android.os.Binder#getCallingPid} and {@link
     * android.os.Binder#getCallingUid}.  One important difference is
     * that if you are not currently processing an IPC, this function
     * will always fail.
     *
     * @param uris The list of URIs that is being checked.
     * @param modeFlags The access modes to check.
     *
     * @return Array of permission grants corresponding to each entry in the list of uris.
     * {@link PackageManager#PERMISSION_GRANTED} if the given pid/uid is allowed to access that uri,
     * or {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see #checkUriPermission(Uri, int, int, int)
     */
    @NonNull
    @PackageManager.PermissionResult
    public int[] checkCallingUriPermissions(@NonNull List<Uri> uris,
            @Intent.AccessUriMode int modeFlags) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Determine whether the calling process of an IPC <em>or you</em> has been granted
     * permission to access a specific URI.  This is the same as
@@ -5774,6 +5827,28 @@ public abstract class Context {
    public abstract int checkCallingOrSelfUriPermission(Uri uri,
            @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether the calling process of an IPC <em>or you</em> has been granted
     * permission to access a list of URIs.  This is the same as
     * {@link #checkCallingUriPermission}, except it grants your own permissions
     * if you are not currently processing an IPC.  Use with care!
     *
     * @param uris The list of URIs that is being checked.
     * @param modeFlags The access modes to check.
     *
     * @return Array of permission grants corresponding to each entry in the list of uris.
     * {@link PackageManager#PERMISSION_GRANTED} if the given pid/uid is allowed to access that uri,
     * or {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see #checkCallingUriPermission
     */
    @NonNull
    @PackageManager.PermissionResult
    public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris,
            @Intent.AccessUriMode int modeFlags) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Check both a Uri and normal permission.  This allows you to perform
     * both {@link #checkPermission} and {@link #checkUriPermission} in one
+20 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.Executor;

/**
@@ -905,6 +906,13 @@ public class ContextWrapper extends Context {
        return mBase.checkUriPermission(uri, pid, uid, modeFlags);
    }

    @NonNull
    @Override
    public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
            int modeFlags) {
        return mBase.checkUriPermissions(uris, pid, uid, modeFlags);
    }

    /** @hide */
    @Override
    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
@@ -916,11 +924,23 @@ public class ContextWrapper extends Context {
        return mBase.checkCallingUriPermission(uri, modeFlags);
    }

    @NonNull
    @Override
    public int[] checkCallingUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
        return mBase.checkCallingUriPermissions(uris, modeFlags);
    }

    @Override
    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
        return mBase.checkCallingOrSelfUriPermission(uri, modeFlags);
    }

    @NonNull
    @Override
    public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
        return mBase.checkCallingOrSelfUriPermissions(uris, modeFlags);
    }

    @Override
    public int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission,
            @Nullable String writePermission, int pid, int uid, int modeFlags) {
Loading