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

Commit af615e7b authored by Thomas Vannet's avatar Thomas Vannet
Browse files

Add self revocation public API

Test: Manual test using a non-privileged app, atest
android.permission.cts.SelfRevokeRuntimePermissionTest

When calling the API, the permission (along with any other permissions
from the same group) for the current package is downgraded to a one-time
permission, and a one-time permission session is started.

Bug: 210387494

Change-Id: I9f061cbc8c3db720127c96200fe94a644246b6d7
parent e5033031
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -10876,6 +10876,8 @@ package android.content {
    method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void removeStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
    method public abstract void revokeUriPermission(android.net.Uri, int);
    method public abstract void revokeUriPermission(String, android.net.Uri, int);
    method public void selfRevokePermission(@NonNull String);
    method public void selfRevokePermissions(@NonNull java.util.Collection<java.lang.String>);
    method public abstract void sendBroadcast(@RequiresPermission android.content.Intent);
    method public abstract void sendBroadcast(@RequiresPermission android.content.Intent, @Nullable String);
    method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
+1 −0
Original line number Diff line number Diff line
@@ -9584,6 +9584,7 @@ package android.permission {
    method @Deprecated @BinderThread public void onRestoreRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);
    method @BinderThread public abstract void onRevokeRuntimePermission(@NonNull String, @NonNull String, @NonNull Runnable);
    method @BinderThread public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull String, @NonNull java.util.function.Consumer<java.util.Map<java.lang.String,java.util.List<java.lang.String>>>);
    method @BinderThread public void onSelfRevokePermissions(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull Runnable);
    method @Deprecated @BinderThread public abstract void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Consumer<java.lang.Boolean>);
    method @BinderThread public void onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String, @NonNull android.permission.AdminPermissionControlParams, @NonNull java.util.function.Consumer<java.lang.Boolean>);
    method @BinderThread public void onStageAndApplyRuntimePermissionsBackup(@NonNull android.os.UserHandle, @NonNull java.io.InputStream, @NonNull Runnable);
+6 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ import java.nio.ByteOrder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -2169,6 +2170,11 @@ class ContextImpl extends Context {
        return checkPermission(permission, pid, uid);
    }

    @Override
    public void selfRevokePermissions(@NonNull Collection<String> permissions) {
        getSystemService(PermissionManager.class).selfRevokePermissions(permissions);
    }

    @Override
    public int checkCallingPermission(String permission) {
        if (permission == null) {
+40 −0
Original line number Diff line number Diff line
@@ -94,8 +94,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * Interface to global information about an application environment.  This is
@@ -6407,6 +6410,43 @@ public abstract class Context {
            @Nullable String writePermission, int pid, int uid, @Intent.AccessUriMode int modeFlags,
            @Nullable String message);


    /**
     * Triggers the asynchronous revocation of a permission.
     *
     * @param permName The name of the permission to be revoked.
     * @see #selfRevokePermissions(Collection)
     */
    public void selfRevokePermission(@NonNull String permName) {
        selfRevokePermissions(Collections.singletonList(permName));
    }

    /**
     * Triggers the revocation of one or more permissions for the calling package. A package is only
     * able to revoke a permission under the following conditions:
     * <ul>
     * <li>Each permission in {@code permissions} must be granted to the calling package.
     * <li>Each permission in {@code permissions} must be a runtime permission.
     * </ul>
     * <p>
     * For every permission in {@code permissions}, the entire permission group it belongs to will
     * be revoked. The revocation happens asynchronously and kills all processes running in the
     * calling UID. It will be triggered once it is safe to do so. In particular, it will not be
     * triggered as long as the package remains in the foreground, or has any active manifest
     * components (e.g. when another app is accessing a content provider in the package).
     * <p>
     * If you want to revoke the permissions right away, you could call {@code System.exit()}, but
     * this could affect other apps that are accessing your app at the moment. For example, apps
     * accessing a content provider in your app will all crash.
     *
     * @param permissions Collection of permissions to be revoked.
     * @see PackageManager#getGroupOfPlatformPermission(String, Executor, Consumer)
     * @see PackageManager#getPlatformPermissionsForGroup(String, Executor, Consumer)
     */
    public void selfRevokePermissions(@NonNull Collection<String> permissions) {
        throw new AbstractMethodError("Must be overridden in implementing class");
    }

    /** @hide */
    @IntDef(flag = true, prefix = { "CONTEXT_" }, value = {
            CONTEXT_INCLUDE_CODE,
+6 −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.Collection;
import java.util.List;
import java.util.concurrent.Executor;

@@ -1014,6 +1015,11 @@ public class ContextWrapper extends Context {
                message);
    }

    @Override
    public void selfRevokePermissions(@NonNull Collection<String> permissions) {
        mBase.selfRevokePermissions(permissions);
    }

    @Override
    public Context createPackageContext(String packageName, int flags)
        throws PackageManager.NameNotFoundException {
Loading