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

Commit 4f8cd5ab authored by Nate Myren's avatar Nate Myren Committed by Android (Google) Code Review
Browse files

Merge "Add command to allow setting of some permission flags from shell" into tm-dev

parents d248c681 826767b9
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
@@ -17,6 +17,11 @@
package com.android.server.pm;

import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;

import android.accounts.IAccountManager;
import android.annotation.NonNull;
@@ -92,6 +97,7 @@ import android.system.ErrnoException;
import android.system.Os;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
import android.util.PrintWriterPrinter;
@@ -150,6 +156,17 @@ class PackageManagerShellCommand extends ShellCommand {
            "--multi-package"
    );
    private static final Set<String> UNSUPPORTED_SESSION_CREATE_OPTS = Collections.emptySet();
    private static final Map<String, Integer> SUPPORTED_PERMISSION_FLAGS = new ArrayMap<>();
    private static final List<String> SUPPORTED_PERMISSION_FLAGS_LIST;
    static {
        SUPPORTED_PERMISSION_FLAGS.put("user-set", FLAG_PERMISSION_USER_SET);
        SUPPORTED_PERMISSION_FLAGS.put("user-fixed", FLAG_PERMISSION_USER_FIXED);
        SUPPORTED_PERMISSION_FLAGS.put("revoked-compat", FLAG_PERMISSION_REVOKED_COMPAT);
        SUPPORTED_PERMISSION_FLAGS.put("review-required", FLAG_PERMISSION_REVIEW_REQUIRED);
        SUPPORTED_PERMISSION_FLAGS.put("revoke-when-requested",
                FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
        SUPPORTED_PERMISSION_FLAGS_LIST = new ArrayList<>(SUPPORTED_PERMISSION_FLAGS.keySet());
    }

    final IPackageManager mInterface;
    final LegacyPermissionManagerInternal mLegacyPermissionManager;
@@ -276,6 +293,10 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runGrantRevokePermission(false);
                case "reset-permissions":
                    return runResetPermissions();
                case "set-permission-flags":
                    return setOrClearPermissionFlags(true);
                case "clear-permission-flags":
                    return setOrClearPermissionFlags(false);
                case "set-permission-enforced":
                    return runSetPermissionEnforced();
                case "get-privapp-permissions":
@@ -2500,6 +2521,50 @@ class PackageManagerShellCommand extends ShellCommand {
        return 0;
    }

    private int setOrClearPermissionFlags(boolean setFlags) {
        int userId = UserHandle.USER_SYSTEM;

        String opt;
        while ((opt = getNextOption()) != null) {
            if (opt.equals("--user")) {
                userId = UserHandle.parseUserArg(getNextArgRequired());
            }
        }

        String pkg = getNextArg();
        if (pkg == null) {
            getErrPrintWriter().println("Error: no package specified");
            return 1;
        }
        String perm = getNextArg();
        if (perm == null) {
            getErrPrintWriter().println("Error: no permission specified");
            return 1;
        }

        int flagMask = 0;
        String flagName = getNextArg();
        if (flagName == null) {
            getErrPrintWriter().println("Error: no permission flags specified");
            return 1;
        }
        while (flagName != null) {
            if (!SUPPORTED_PERMISSION_FLAGS.containsKey(flagName)) {
                getErrPrintWriter().println("Error: specified flag " + flagName + " is not one of "
                        + SUPPORTED_PERMISSION_FLAGS_LIST);
                return 1;
            }
            flagMask |= SUPPORTED_PERMISSION_FLAGS.get(flagName);
            flagName = getNextArg();
        }

        final UserHandle translatedUser = UserHandle.of(translateUserId(userId,
                UserHandle.USER_NULL, "runGrantRevokePermission"));
        int flagSet = setFlags ? flagMask : 0;
        mPermissionManager.updatePermissionFlags(pkg, perm, flagMask, flagSet, translatedUser);
        return 0;
    }

    private int runSetPermissionEnforced() throws RemoteException {
        final String permission = getNextArg();
        if (permission == null) {
@@ -3997,6 +4062,13 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("    must be declared as used in the app's manifest, be runtime permissions");
        pw.println("    (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
        pw.println("");
        pw.println("  set-permission-flags [--user USER_ID] PACKAGE PERMISSION [FLAGS..]");
        pw.println("  clear-permission-flags [--user USER_ID] PACKAGE PERMISSION [FLAGS..]");
        pw.println("    These commands either set or clear permission flags on apps.  The permissions");
        pw.println("    must be declared as used in the app's manifest, be runtime permissions");
        pw.println("    (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
        pw.println("    The flags must be one or more of " + SUPPORTED_PERMISSION_FLAGS_LIST);
        pw.println("");
        pw.println("  reset-permissions");
        pw.println("    Revert all runtime permissions to their default state.");
        pw.println("");
+4 −2
Original line number Diff line number Diff line
@@ -767,8 +767,10 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
            flagValues &= ~FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
            flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
            // REVIEW_REQUIRED can only be set by non-system apps for for POST_NOTIFICATIONS
            if (!POST_NOTIFICATIONS.equals(permName)) {
            // REVIEW_REQUIRED can only be set by non-system apps for POST_NOTIFICATIONS, or by the
            // shell or root UID.
            if (!POST_NOTIFICATIONS.equals(permName) && callingUid != Process.SHELL_UID
                    && callingUid != Process.ROOT_UID) {
                flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
            }
        }