/* ** Copyright 2014, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ package com.android.commands.appops; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.AppOpsManager; import android.content.Context; 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. */ public class AppOpsCommand extends BaseCommand { public static void main(String[] args) { new AppOpsCommand().run(args); } @Override public void onShowUsage(PrintStream out) { 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 { String command = nextArgRequired(); switch (command) { case COMMAND_SET: runSet(); break; case COMMAND_GET: runGet(); break; case COMMAND_RESET: runReset(); break; default: System.err.println("Error: Unknown command: '" + command + "'."); break; } } private static final String ARGUMENT_USER = "--user"; // Modes private static final String MODE_ALLOW = "allow"; private static final String MODE_DENY = "deny"; 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; String mode = 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 if (mode == null) { mode = argument; } else { System.err.println("Error: Unsupported argument: " + argument); return; } } } if (packageName == null) { System.err.println("Error: Package name not specified."); return; } else if (op == null) { System.err.println("Error: Operation not specified."); return; } else if (mode == null) { System.err.println("Error: Mode not specified."); return; } final int opInt = strOpToOp(op); if (opInt < 0) { return; } final int modeInt; switch (mode) { case MODE_ALLOW: modeInt = AppOpsManager.MODE_ALLOWED; break; case MODE_DENY: modeInt = AppOpsManager.MODE_ERRORED; break; case MODE_IGNORE: modeInt = AppOpsManager.MODE_IGNORED; break; case MODE_DEFAULT: modeInt = AppOpsManager.MODE_DEFAULT; break; default: System.err.println("Error: Mode " + mode + " is not valid,"); return; } // 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; } 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); } } }