1, 概述
AppOps全称是 Application Operations,类似平时常说的应用程序的操作(权限)管理。AppOps是Google原生Android包含的功能,但是Google在每次版本更新时都会隐藏掉AppOps的入口。
2, AppOps命令
命令格式:
Appops <command>
命令列表:
命令 |
功能 |
实现方法 |
set allow |
允许 权限 |
appOpsService.setMode |
set deny |
拒绝 |
appOpsService.setMode |
set ignore |
忽略 |
appOpsService.setMode |
set default |
默认 |
appOpsService.setMode |
get |
获取 |
appOpsService.getOpsForPackage |
reset |
重置 |
appOpsService.resetAllModes |
3, 详细流程
所有adb命令的AppOps方法最后都会通过AppOpsCommand.java执行,然后通过跨进程
调用AppOpsService的方法完成,至于android系统中的AppOps原理在此就不论述了。
AppOpsCommand的main方法如下,
public static void main(String[] args) {
new AppOpsCommand().run(args);
}
调用父类的run方法,然后调用onRun方法, onRun方法如下,
@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;
}
}
3个不同的指令分别对应不同的方法,例如, set命令会调用runSet方法, runSet方法如下,
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);
}
最后调用AppOpsService 的setMode方法完成权限的设置