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

Commit 7d7a26e1 authored by Yuting Fang's avatar Yuting Fang
Browse files

New permission system APIs with persistent device Id

Create 4 system APIs in PermissionManager that take persistentDeviceId as a param:
* grantRuntimePermission
* revokeRuntimePermission
* getPermissionFlags
* updatePermissionFlags
Also change corresponding methods in .aidl to take persistentDeviceId instead of VDID

Bug: b/315356442
Test: ag/26168815, atest DevicePermissionsTest
Change-Id: I6cbc98cdd283e886248ac199724e65325a1ea9af
parent 781c51ac
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -11284,12 +11284,16 @@ package android.permission {
    method public void finishDataDelivery(@NonNull String, @NonNull android.content.AttributionSource);
    method @NonNull @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public java.util.Set<java.lang.String> getAutoRevokeExemptionGrantedPackages();
    method @NonNull @RequiresPermission(android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY) public java.util.Set<java.lang.String> getAutoRevokeExemptionRequestedPackages();
    method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public int getPermissionFlags(@NonNull String, @NonNull String, @NonNull String);
    method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public int getRuntimePermissionsVersion();
    method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
    method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull String);
    method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull String, @Nullable String);
    method @RequiresPermission(anyOf={android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public void setRuntimePermissionsVersion(@IntRange(from=0) int);
    method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS) public void startOneTimePermissionSession(@NonNull String, long, int, int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS) public void startOneTimePermissionSession(@NonNull String, long, long, int, int);
    method @RequiresPermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS) public void stopOneTimePermissionSession(@NonNull String);
    method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public void updatePermissionFlags(@NonNull String, @NonNull String, @NonNull String, int, int);
    field @RequiresPermission(android.Manifest.permission.START_REVIEW_PERMISSION_DECISIONS) public static final String ACTION_REVIEW_PERMISSION_DECISIONS = "android.permission.action.REVIEW_PERMISSION_DECISIONS";
    field public static final String EXTRA_PERMISSION_USAGES = "android.permission.extra.PERMISSION_USAGES";
    field public static final int PERMISSION_GRANTED = 0; // 0x0
+3 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.accessibilityservice.IAccessibilityServiceClient;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.Rect;
@@ -363,7 +364,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
        final long identity = Binder.clearCallingIdentity();
        try {
            mPermissionManager.grantRuntimePermission(packageName, permission,
                    Context.DEVICE_ID_DEFAULT, userId);
                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
@@ -383,7 +384,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
        final long identity = Binder.clearCallingIdentity();
        try {
            mPermissionManager.revokeRuntimePermission(packageName, permission,
                    Context.DEVICE_ID_DEFAULT, userId, null);
                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId, null);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
+8 −5
Original line number Diff line number Diff line
@@ -42,10 +42,12 @@ interface IPermissionManager {

    void removePermission(String permissionName);

    int getPermissionFlags(String packageName, String permissionName, int deviceId, int userId);
    int getPermissionFlags(String packageName, String permissionName, String persistentDeviceId,
            int userId);

    void updatePermissionFlags(String packageName, String permissionName, int flagMask,
            int flagValues, boolean checkAdjustPolicyFlagPermission, int deviceId, int userId);
            int flagValues, boolean checkAdjustPolicyFlagPermission, String persistentDeviceId,
            int userId);

    void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);

@@ -62,10 +64,11 @@ interface IPermissionManager {
    boolean removeAllowlistedRestrictedPermission(String packageName, String permissionName,
            int flags, int userId);

    void grantRuntimePermission(String packageName, String permissionName, int deviceId, int userId);
    void grantRuntimePermission(String packageName, String permissionName,
            String persistentDeviceId, int userId);

    void revokeRuntimePermission(String packageName, String permissionName, int deviceId,
            int userId, String reason);
    void revokeRuntimePermission(String packageName, String permissionName,
            String persistentDeviceId, int userId, String reason);

    void revokePostNotificationPermissionWithoutKillForTest(String packageName, int userId);

+166 −14
Original line number Diff line number Diff line
@@ -623,15 +623,50 @@ public final class PermissionManager {
    //@SystemApi
    public void grantRuntimePermission(@NonNull String packageName,
            @NonNull String permissionName, @NonNull UserHandle user) {
        String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
        if (persistentDeviceId == null) {
            return;
        }

        grantRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, user);
    }

    /**
     * Grant a runtime permission to an application which the application does not already have. The
     * permission must have been requested by the application. If the application is not allowed to
     * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
     * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
     *
     * @param packageName the package to which to grant the permission
     * @param permissionName the permission name to grant
     * @param persistentDeviceId the device Id to which to grant the permission
     *
     * @see #revokeRuntimePermission(String, String, String, String)
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
    @SystemApi
    @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
    public void grantRuntimePermission(@NonNull String packageName,
            @NonNull String permissionName, @NonNull String persistentDeviceId) {
        grantRuntimePermissionInternal(packageName, permissionName, persistentDeviceId,
                mContext.getUser());
    }

    private void grantRuntimePermissionInternal(@NonNull String packageName,
            @NonNull String permissionName, @NonNull String persistentDeviceId,
            @NonNull UserHandle user) {
        if (DEBUG_TRACE_GRANTS
                && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
            Log.i(LOG_TAG_TRACE_GRANTS, "App " + mContext.getPackageName() + " is granting "
                    + packageName + " "
                    + permissionName + " for user " + user.getIdentifier(), new RuntimeException());
                    + permissionName + " for user " + user.getIdentifier()
                    + " for persistent device " + persistentDeviceId, new RuntimeException());
        }
        try {
            mPermissionManager.grantRuntimePermission(packageName, permissionName,
                    mContext.getDeviceId(), user.getIdentifier());
                    persistentDeviceId, user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -649,7 +684,7 @@ public final class PermissionManager {
     * user {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
     *
     * @param packageName the package from which to revoke the permission
     * @param permName the permission name to revoke
     * @param permissionName the permission name to revoke
     * @param user the user for which to revoke the permission
     * @param reason the reason for the revoke, or {@code null} for unspecified
     *
@@ -660,16 +695,56 @@ public final class PermissionManager {
    @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
    //@SystemApi
    public void revokeRuntimePermission(@NonNull String packageName,
            @NonNull String permName, @NonNull UserHandle user, @Nullable String reason) {
            @NonNull String permissionName, @NonNull UserHandle user, @Nullable String reason) {
        String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
        if (persistentDeviceId == null) {
            return;
        }

        revokeRuntimePermissionInternal(packageName, permissionName, persistentDeviceId, user,
                reason);
    }

    /**
     * Revoke a runtime permission that was previously granted by
     * {@link #grantRuntimePermission(String, String, String)}. The permission must
     * have been requested by and granted to the application. If the application is not allowed to
     * hold the permission, a {@link java.lang.SecurityException} is thrown. If the package or
     * permission is invalid, a {@link java.lang.IllegalArgumentException} is thrown.
     *
     * @param packageName the package from which to revoke the permission
     * @param permissionName the permission name to revoke
     * @param persistentDeviceId the persistent device id for which to revoke the permission
     * @param reason the reason for the revoke, or {@code null} for unspecified
     *
     * @see #grantRuntimePermission(String, String, String)
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
    @SystemApi
    @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
    public void revokeRuntimePermission(@NonNull String packageName,
            @NonNull String permissionName, @NonNull String persistentDeviceId,
            @Nullable String reason) {
        revokeRuntimePermissionInternal(packageName, permissionName, persistentDeviceId,
                mContext.getUser(), reason);
    }

    private void revokeRuntimePermissionInternal(@NonNull String packageName,
            @NonNull String permissionName, @NonNull String persistentDeviceId,
            @NonNull UserHandle user, @Nullable String reason) {
        if (DEBUG_TRACE_PERMISSION_UPDATES
                && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
                && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
            Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is revoking " + packageName + " "
                    + permName + " for user " + user.getIdentifier() + " with reason "
                    + permissionName + " for user " + user.getIdentifier()
                    + " for persistent device "
                    + persistentDeviceId + " with reason "
                    + reason, new RuntimeException());
        }
        try {
            mPermissionManager.revokeRuntimePermission(packageName, permName,
                    mContext.getDeviceId(), user.getIdentifier(), reason);
            mPermissionManager.revokeRuntimePermission(packageName, permissionName,
                    persistentDeviceId, user.getIdentifier(), reason);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -694,9 +769,44 @@ public final class PermissionManager {
    //@SystemApi
    public int getPermissionFlags(@NonNull String packageName, @NonNull String permissionName,
            @NonNull UserHandle user) {
        String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
        if (persistentDeviceId == null) {
            return 0;
        }

        return getPermissionFlagsInternal(packageName, permissionName, persistentDeviceId, user);
    }

    /**
     * Gets the state flags associated with a permission.
     *
     * @param packageName the package name for which to get the flags
     * @param permissionName the permission for which to get the flags
     * @param persistentDeviceId the persistent device Id for which to get permission flags
     * @return the permission flags
     *
     * @hide
     */
    @PackageManager.PermissionFlags
    @RequiresPermission(anyOf = {
            android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
            android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
            android.Manifest.permission.GET_RUNTIME_PERMISSIONS
    })
    @SystemApi
    @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
    public int getPermissionFlags(@NonNull String packageName, @NonNull String permissionName,
            @NonNull String persistentDeviceId) {
        return getPermissionFlagsInternal(packageName, permissionName, persistentDeviceId,
                mContext.getUser());
    }

    private int getPermissionFlagsInternal(@NonNull String packageName,
            @NonNull String permissionName, @NonNull String persistentDeviceId,
            @NonNull UserHandle user) {
        try {
            return mPermissionManager.getPermissionFlags(packageName, permissionName,
                    mContext.getDeviceId(), user.getIdentifier());
                    persistentDeviceId, user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -722,13 +832,55 @@ public final class PermissionManager {
    public void updatePermissionFlags(@NonNull String packageName, @NonNull String permissionName,
            @PackageManager.PermissionFlags int flagMask,
            @PackageManager.PermissionFlags int flagValues, @NonNull UserHandle user) {
        String persistentDeviceId = getPersistentDeviceId(mContext.getDeviceId());
        if (persistentDeviceId == null) {
            return;
        }

        updatePermissionFlagsInternal(packageName, permissionName, flagMask, flagValues,
                persistentDeviceId, user);
    }

    /**
     * Updates the flags associated with a permission by replacing the flags in the specified mask
     * with the provided flag values.
     *
     * @param packageName The package name for which to update the flags
     * @param permissionName The permission for which to update the flags
     * @param persistentDeviceId The persistent device for which to update the permission flags
     * @param flagMask The flags which to replace
     * @param flagValues The flags with which to replace
     *
     * @hide
     */
    @RequiresPermission(anyOf = {
            android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
            android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
    })
    @SystemApi
    @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
    public void updatePermissionFlags(@NonNull String packageName, @NonNull String permissionName,
            @NonNull String persistentDeviceId,
            @PackageManager.PermissionFlags int flagMask,
            @PackageManager.PermissionFlags int flagValues
    ) {
        updatePermissionFlagsInternal(packageName, permissionName, flagMask, flagValues,
                persistentDeviceId, mContext.getUser());
    }

    private void updatePermissionFlagsInternal(@NonNull String packageName,
            @NonNull String permissionName,
            @PackageManager.PermissionFlags int flagMask,
            @PackageManager.PermissionFlags int flagValues, @NonNull String persistentDeviceId,
            @NonNull UserHandle user
    ) {
        if (DEBUG_TRACE_PERMISSION_UPDATES && shouldTraceGrant(packageName, permissionName,
                user.getIdentifier())) {
            Log.i(LOG_TAG, "App " + mContext.getPackageName() + " is updating flags for "
                    + packageName + " " + permissionName + " for user "
                    + user.getIdentifier() + ": " + DebugUtils.flagsToString(
                    PackageManager.class, "FLAG_PERMISSION_", flagMask) + " := "
                    + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_",
                    + user.getIdentifier() + " for persistentDeviceId " + persistentDeviceId + ": "
                    + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask)
                    + " := " + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_",
                            flagValues), new RuntimeException());
        }
        try {
@@ -736,7 +888,7 @@ public final class PermissionManager {
                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
            mPermissionManager.updatePermissionFlags(packageName, permissionName, flagMask,
                    flagValues, checkAdjustPolicyFlagPermission,
                    mContext.getDeviceId(), user.getIdentifier());
                    persistentDeviceId, user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+10 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.companion.virtual.VirtualDeviceManager;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
@@ -196,18 +197,20 @@ public final class PermissionHelper {
            boolean currentlyGranted = hasPermission(uid);
            if (grant && !currentlyGranted) {
                mPermManager.grantRuntimePermission(packageName, NOTIFICATION_PERMISSION,
                        Context.DEVICE_ID_DEFAULT, userId);
                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
            } else if (!grant && currentlyGranted) {
                mPermManager.revokeRuntimePermission(packageName, NOTIFICATION_PERMISSION,
                        Context.DEVICE_ID_DEFAULT, userId, TAG);
                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId, TAG);
            }
            int flagMask = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED;
            if (userSet) {
                mPermManager.updatePermissionFlags(packageName, NOTIFICATION_PERMISSION, flagMask,
                        FLAG_PERMISSION_USER_SET, true, Context.DEVICE_ID_DEFAULT, userId);
                        FLAG_PERMISSION_USER_SET, true,
                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
            } else {
                mPermManager.updatePermissionFlags(packageName, NOTIFICATION_PERMISSION,
                        flagMask, 0, true, Context.DEVICE_ID_DEFAULT, userId);
                        flagMask, 0, true, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
                        userId);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Could not reach system server", e);
@@ -235,7 +238,7 @@ public final class PermissionHelper {
        try {
            try {
                int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
                        Context.DEVICE_ID_DEFAULT, userId);
                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
                return (flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
                        || (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
            } catch (RemoteException e) {
@@ -252,7 +255,7 @@ public final class PermissionHelper {
        try {
            try {
                int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
                        Context.DEVICE_ID_DEFAULT, userId);
                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
                return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
                        | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
            } catch (RemoteException e) {
@@ -269,7 +272,7 @@ public final class PermissionHelper {
        try {
            try {
                int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
                        Context.DEVICE_ID_DEFAULT, userId);
                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
                return (flags & (PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT
                        | PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE)) != 0;
            } catch (RemoteException e) {
Loading