AppOps命令分析

1, 概述

AppOps全称是 Application Operations,类似平时常说的应用程序的操作(权限)管理。AppOps是Google原生Android包含的功能,但是Google在每次版本更新时都会隐藏掉AppOps的入口。

 

2, AppOps命令

命令格式:

Appops

 

命令列表:

命令

功能

实现方法

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方法完成权限的设置

你可能感兴趣的:(---【adb命令分析】)