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

Commit eeccbd76 authored by Azhara Assanova's avatar Azhara Assanova
Browse files

Add new API Context#checkContentUriPermission

Currently, apps can't check if an app has access to a content URI. That
is because the existing checkUriPermission() API is limited to checking
permissions via URI grant flags. Hence, this change adds a new API that
focuses on content URIs and on top of grant flags, it checks for general
access to the URI's content provider.

In addition to this API, we'll be introducing Activity APIs and a
Manifest attribute to help apps with checking content URI permissions on
activity callers.

Finally, to minimise code duplication, we merged checkUriPermission()'s
implementation in ActivityManagerService and UriGrantsManagerInternal.

Bug: 293467489
Test: atest WmTests:ActivityStarterTests
Test: atest FrameworksServicesTests:com.android.server.uri
Test: atest CtsWindowManagerDeviceActivity:ActivityStarterTests
Test: atest CtsWindowManagerDeviceWindow:CrossAppDragAndDropTests
Test: atest AppEnumerationTests
Test: atest CtsContentTestCases:android.content.cts.ContextTest
Change-Id: I61a0574e3979702ed32f4d926c664f134046f555
parent e4584f38
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10379,6 +10379,7 @@ package android.content {
    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 @FlaggedApi("android.security.content_uri_permission_apis") public int checkContentUriPermissionFull(@NonNull android.net.Uri, int, int, 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);
+11 −0
Original line number Diff line number Diff line
@@ -2409,6 +2409,17 @@ class ContextImpl extends Context {
        }
    }

    @Override
    public int checkContentUriPermissionFull(Uri uri, int pid, int uid, int modeFlags) {
        try {
            return ActivityManager.getService().checkContentUriPermissionFull(
                    ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags,
                    resolveUserId(uri));
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @NonNull
    @Override
    public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
+1 −0
Original line number Diff line number Diff line
@@ -274,6 +274,7 @@ interface IActivityManager {
    int getProcessLimit();
    int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
            in IBinder callerToken);
    int checkContentUriPermissionFull(in Uri uri, int pid, int uid, int mode, int userId);
    int[] checkUriPermissions(in List<Uri> uris, int pid, int uid, int mode, int userId,
                in IBinder callerToken);
    void grantUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
+37 −6
Original line number Diff line number Diff line
@@ -6734,7 +6734,7 @@ public abstract class Context {
            @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether a particular process and user ID has been granted
     * Determine whether a particular process and uid has been granted
     * permission to access a specific URI.  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
@@ -6758,7 +6758,38 @@ public abstract class Context {
            @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether a particular process and user ID has been granted
     * Determine whether a particular process and uid has been granted
     * permission to access a specific content URI.
     *
     * <p>Unlike {@link #checkUriPermission(Uri, int, int, int)}, this method
     * checks for general access to the URI's content provider, as well as
     * explicitly granted permissions.</p>
     *
     * <p>Note, this check will throw an {@link IllegalArgumentException}
     * for non-content URIs.</p>
     *
     * @param uri The content uri that is being checked.
     * @param pid (Optional) The process ID being checked against. If the
     * pid is unknown, pass -1.
     * @param uid The UID being checked against.  A uid of 0 is the root
     * user, which will pass every permission check.
     * @param modeFlags The access modes to check.
     *
     * @return {@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)
     */
    @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
    @PackageManager.PermissionResult
    public int checkContentUriPermissionFull(@NonNull Uri uri, int pid, int uid,
            @Intent.AccessUriMode int modeFlags) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Determine whether a particular process and uid 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
@@ -6794,7 +6825,7 @@ public abstract class Context {
            @Intent.AccessUriMode int modeFlags, IBinder callerToken);

    /**
     * Determine whether the calling process and user ID has been
     * Determine whether the calling process and uid has been
     * granted permission to access a specific URI.  This is basically
     * the same as calling {@link #checkUriPermission(Uri, int, int,
     * int)} with the pid and uid returned by {@link
@@ -6817,7 +6848,7 @@ public abstract class Context {
    public abstract int checkCallingUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether the calling process and user ID has been
     * Determine whether the calling process and uid 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
@@ -6911,7 +6942,7 @@ public abstract class Context {
            @Intent.AccessUriMode int modeFlags);

    /**
     * If a particular process and user ID has not been granted
     * If a particular process and uid has not been granted
     * permission to access a specific URI, throw {@link
     * SecurityException}.  This only checks for permissions that have
     * been explicitly granted -- if the given process/uid has more
@@ -6931,7 +6962,7 @@ public abstract class Context {
            Uri uri, int pid, int uid, @Intent.AccessUriMode int modeFlags, String message);

    /**
     * If the calling process and user ID has not been granted
     * If the calling process and uid has not been granted
     * permission to access a specific URI, throw {@link
     * SecurityException}.  This is basically the same as calling
     * {@link #enforceUriPermission(Uri, int, int, int, String)} with
+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.content;

import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -1003,6 +1004,12 @@ public class ContextWrapper extends Context {
        return mBase.checkUriPermission(uri, pid, uid, modeFlags);
    }

    @FlaggedApi(android.security.Flags.FLAG_CONTENT_URI_PERMISSION_APIS)
    @Override
    public int checkContentUriPermissionFull(@NonNull Uri uri, int pid, int uid, int modeFlags) {
        return mBase.checkContentUriPermissionFull(uri, pid, uid, modeFlags);
    }

    @NonNull
    @Override
    public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
Loading