Android N(O) adb shell pm uninstall package 流程分析

Android N(O) adb shell pm uninstall package 流程分析


1、alps/frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java

public static void main(String[] args) {
    int exitCode = 1;
    try {
        exitCode = new Pm().run(args);/////step1
    } catch (Exception e) {
   **********************************
}
public int run(String[] args) throws RemoteException {
    boolean validCommand = false;
    if (args.length < 1) {
        return showUsage();
    }
    ****************************
  if ("uninstall".equals(op)) {
    return runUninstall(); //////////step2
  }
  *****************************
}
private int runUninstall() {
    return runShellCommand("package", mArgs); /////////////step3
}
private int runShellCommand(String serviceName, String[] args) {
    final HandlerThread handlerThread = new HandlerThread("results");
    handlerThread.start();
    try {
        ServiceManager.getService(serviceName).shellCommand(
                FileDescriptor.in, FileDescriptor.out, FileDescriptor.err,
                args, new MyShellCallback(),
                new ResultReceiver(new Handler(handlerThread.getLooper())));//////////step4
    ******************************************
}

2、apls/frameworks/base/core/java/android/os/Binder.java

public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
        @Nullable FileDescriptor err,
        @NonNull String[] args, @Nullable ShellCallback callback,
        @NonNull ResultReceiver resultReceiver) throws RemoteException {
    onShellCommand(in, out, err, args, callback, resultReceiver);///////////////step5
}
public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
        @Nullable FileDescriptor err,
        @NonNull String[] args, @Nullable ShellCallback callback,
        @NonNull ResultReceiver resultReceiver) throws RemoteException {
    FileOutputStream fout = new FileOutputStream(err != null ? err : out);
    PrintWriter pw = new FastPrintWriter(fout);
    pw.println("No shell command implementation.");
    pw.flush();
    resultReceiver.send(0, null);/////////////////step6
}

3、alpsk/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out,
        FileDescriptor err, String[] args, ShellCallback callback,
        ResultReceiver resultReceiver) {
    (new PackageManagerShellCommand(this)).exec(
            this, in, out, err, args, callback, resultReceiver);//////////step7
}

4、alps/frameworks/base/core/java/android/os/ShellCommand.java

public int exec(Binder target, FileDescriptor in, FileDescriptor out, FileDescriptor err,
        String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
    *******************************************
    int res = -1;
    try {
        res = onCommand(mCmd);////////////////////step8
        if (DEBUG) Slog.d(TAG, "Executed command " + mCmd + " on " + mTarget);
    *************************************
}

5、alps/frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java

@Override
public int onCommand(String cmd) {
    if (cmd == null) {
        return handleDefaultCommands(cmd);
    }

    final PrintWriter pw = getOutPrintWriter();
    try {
        switch(cmd) {
            case "install":
                return runInstall();
            case "uninstall":
                return runUninstall();//////////////step9
    ****************************************************
}
private int runUninstall() throws RemoteException {
    final PrintWriter pw = getOutPrintWriter();
    int flags = 0;
    int userId = UserHandle.USER_ALL;
    int versionCode = PackageManager.VERSION_CODE_HIGHEST;

    String opt;
    while ((opt = getNextOption()) != null) {
        switch (opt) {
            case "-k":
                flags |= PackageManager.DELETE_KEEP_DATA;
                break;
            case "--user":
                userId = UserHandle.parseUserArg(getNextArgRequired());
                break;
            case "--versionCode":
                versionCode = Integer.parseInt(getNextArgRequired());
                break;
            default:
                pw.println("Error: Unknown option: " + opt);
                return 1; }
    }
    ************************************************
  if (status == PackageInstaller.STATUS_SUCCESS) {
    pw.println("Success");
    return 0;
  } else {
    pw.println("Failure ["
            + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
    return 1;
  }
}