diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-12-02 18:32:20 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2014-12-03 10:01:14 -0800 |
commit | 7b7c58b3842d47c4c8df4876e2e2248c58477d97 (patch) | |
tree | d925059e01f7d7a7f0c3c85fa05a9e3fee33e7a1 /cmds/appops/src | |
parent | 76de89820c51c4bc288b440a82374b9d6c806244 (diff) | |
download | frameworks_base-7b7c58b3842d47c4c8df4876e2e2248c58477d97.zip frameworks_base-7b7c58b3842d47c4c8df4876e2e2248c58477d97.tar.gz frameworks_base-7b7c58b3842d47c4c8df4876e2e2248c58477d97.tar.bz2 |
Work on issue #18572506: AppOps in-memory state is invalid after...
...uninstalling updates to a system app
Things seem to be working fine, however we were not as aggressive at
writing out the current state in this case as we probably should be.
Also introduce more features to the appops command, which are useful
for testing this.
Change-Id: I177a9cc0e16e98b76fee0d052d742e06842bb3f9
Diffstat (limited to 'cmds/appops/src')
-rw-r--r-- | cmds/appops/src/com/android/commands/appops/AppOpsCommand.java | 207 |
1 files changed, 197 insertions, 10 deletions
diff --git a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java index c414f58..3ec63b4 100644 --- a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java +++ b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java @@ -24,10 +24,12 @@ import android.content.pm.IPackageManager; import android.os.ServiceManager; import android.os.UserHandle; +import android.util.TimeUtils; import com.android.internal.app.IAppOpsService; import com.android.internal.os.BaseCommand; import java.io.PrintStream; +import java.util.List; /** * This class is a command line utility for manipulating AppOps permissions. @@ -40,15 +42,19 @@ public class AppOpsCommand extends BaseCommand { @Override public void onShowUsage(PrintStream out) { - out.println("usage: adb shell appops set <PACKAGE> <OP> " - + "<allow|ignore|deny|default> [--user <USER_ID>]\n" + out.println("usage: appops set [--user <USER_ID>] <PACKAGE> <OP> <MODE>\n" + + " appops get [--user <USER_ID>] <PACKAGE> [<OP>]\n" + + " appops reset [--user <USER_ID>] [<PACKAGE>]\n" + " <PACKAGE> an Android package name.\n" + " <OP> an AppOps operation.\n" + + " <MODE> one of allow, ignore, deny, or default\n" + " <USER_ID> the user id under which the package is installed. If --user is not\n" + " specified, the current user is assumed.\n"); } private static final String COMMAND_SET = "set"; + private static final String COMMAND_GET = "get"; + private static final String COMMAND_RESET = "reset"; @Override public void onRun() throws Exception { @@ -58,8 +64,17 @@ public class AppOpsCommand extends BaseCommand { runSet(); break; + case COMMAND_GET: + runGet(); + break; + + case COMMAND_RESET: + runReset(); + break; + default: - throw new IllegalArgumentException("Unknown command '" + command + "'."); + System.err.println("Error: Unknown command: '" + command + "'."); + break; } } @@ -71,6 +86,23 @@ public class AppOpsCommand extends BaseCommand { private static final String MODE_IGNORE = "ignore"; private static final String MODE_DEFAULT = "default"; + private int strOpToOp(String op) { + try { + return AppOpsManager.strOpToOp(op); + } catch (IllegalArgumentException e) { + } + try { + return Integer.parseInt(op); + } catch (NumberFormatException e) { + } + try { + return AppOpsManager.strDebugOpToOp(op); + } catch (IllegalArgumentException e) { + System.err.println("Error: " + e.getMessage()); + return -1; + } + } + private void runSet() throws Exception { String packageName = null; String op = null; @@ -87,20 +119,27 @@ public class AppOpsCommand extends BaseCommand { } else if (mode == null) { mode = argument; } else { - throw new IllegalArgumentException("Unsupported argument: " + argument); + System.err.println("Error: Unsupported argument: " + argument); + return; } } } if (packageName == null) { - throw new IllegalArgumentException("Package name not specified."); + System.err.println("Error: Package name not specified."); + return; } else if (op == null) { - throw new IllegalArgumentException("Operation not specified."); + System.err.println("Error: Operation not specified."); + return; } else if (mode == null) { - throw new IllegalArgumentException("Mode not specified."); + System.err.println("Error: Mode not specified."); + return; } - final int opInt = AppOpsManager.strOpToOp(op); + final int opInt = strOpToOp(op); + if (opInt < 0) { + return; + } final int modeInt; switch (mode) { case MODE_ALLOW: @@ -116,7 +155,8 @@ public class AppOpsCommand extends BaseCommand { modeInt = AppOpsManager.MODE_DEFAULT; break; default: - throw new IllegalArgumentException("Mode is invalid."); + System.err.println("Error: Mode " + mode + " is not valid,"); + return; } // Parsing complete, let's execute the command. @@ -130,8 +170,155 @@ public class AppOpsCommand extends BaseCommand { ServiceManager.getService(Context.APP_OPS_SERVICE)); final int uid = pm.getPackageUid(packageName, userId); if (uid < 0) { - throw new Exception("No UID for " + packageName + " for user " + userId); + System.err.println("Error: No UID for " + packageName + " in user " + userId); + return; } appOpsService.setMode(opInt, uid, packageName, modeInt); } + + private void runGet() throws Exception { + String packageName = null; + String op = null; + int userId = UserHandle.USER_CURRENT; + for (String argument; (argument = nextArg()) != null;) { + if (ARGUMENT_USER.equals(argument)) { + userId = Integer.parseInt(nextArgRequired()); + } else { + if (packageName == null) { + packageName = argument; + } else if (op == null) { + op = argument; + } else { + System.err.println("Error: Unsupported argument: " + argument); + return; + } + } + } + + if (packageName == null) { + System.err.println("Error: Package name not specified."); + return; + } + + final int opInt = op != null ? strOpToOp(op) : 0; + + // Parsing complete, let's execute the command. + + if (userId == UserHandle.USER_CURRENT) { + userId = ActivityManager.getCurrentUser(); + } + + final IPackageManager pm = ActivityThread.getPackageManager(); + final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface( + ServiceManager.getService(Context.APP_OPS_SERVICE)); + final int uid = pm.getPackageUid(packageName, userId); + if (uid < 0) { + System.err.println("Error: No UID for " + packageName + " in user " + userId); + return; + } + List<AppOpsManager.PackageOps> ops = appOpsService.getOpsForPackage(uid, packageName, + op != null ? new int[] {opInt} : null); + if (ops == null || ops.size() <= 0) { + System.out.println("No operations."); + return; + } + final long now = System.currentTimeMillis(); + for (int i=0; i<ops.size(); i++) { + List<AppOpsManager.OpEntry> entries = ops.get(i).getOps(); + for (int j=0; j<entries.size(); j++) { + AppOpsManager.OpEntry ent = entries.get(j); + System.out.print(AppOpsManager.opToName(ent.getOp())); + System.out.print(": "); + switch (ent.getMode()) { + case AppOpsManager.MODE_ALLOWED: + System.out.print("allow"); + break; + case AppOpsManager.MODE_IGNORED: + System.out.print("ignore"); + break; + case AppOpsManager.MODE_ERRORED: + System.out.print("deny"); + break; + case AppOpsManager.MODE_DEFAULT: + System.out.print("default"); + break; + default: + System.out.print("mode="); + System.out.print(ent.getMode()); + break; + } + if (ent.getTime() != 0) { + System.out.print("; time="); + StringBuilder sb = new StringBuilder(); + TimeUtils.formatDuration(now - ent.getTime(), sb); + System.out.print(sb); + System.out.print(" ago"); + } + if (ent.getRejectTime() != 0) { + System.out.print("; rejectTime="); + StringBuilder sb = new StringBuilder(); + TimeUtils.formatDuration(now - ent.getRejectTime(), sb); + System.out.print(sb); + System.out.print(" ago"); + } + if (ent.getDuration() == -1) { + System.out.print(" (running)"); + } else if (ent.getDuration() != 0) { + System.out.print("; duration="); + StringBuilder sb = new StringBuilder(); + TimeUtils.formatDuration(ent.getDuration(), sb); + System.out.print(sb); + } + System.out.println(); + } + } + } + + private void runReset() throws Exception { + String packageName = null; + int userId = UserHandle.USER_CURRENT; + for (String argument; (argument = nextArg()) != null;) { + if (ARGUMENT_USER.equals(argument)) { + String userStr = nextArgRequired(); + if ("all".equals(userStr)) { + userId = UserHandle.USER_ALL; + } else if ("current".equals(userStr)) { + userId = UserHandle.USER_CURRENT; + } else if ("owner".equals(userStr)) { + userId = UserHandle.USER_OWNER; + } else { + userId = Integer.parseInt(nextArgRequired()); + } + } else { + if (packageName == null) { + packageName = argument; + } else { + System.err.println("Error: Unsupported argument: " + argument); + return; + } + } + } + + // Parsing complete, let's execute the command. + + if (userId == UserHandle.USER_CURRENT) { + userId = ActivityManager.getCurrentUser(); + } + + final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface( + ServiceManager.getService(Context.APP_OPS_SERVICE)); + appOpsService.resetAllModes(userId, packageName); + System.out.print("Reset all modes for: "); + if (userId == UserHandle.USER_ALL) { + System.out.print("all users"); + } else { + System.out.print("user "); System.out.print(userId); + } + System.out.print(", "); + if (packageName == null) { + System.out.println("all packages"); + } else { + System.out.print("package "); System.out.println(packageName); + } + } } |