Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c22b83ab authored by Jiakai Zhang's avatar Jiakai Zhang
Browse files

Forward some root-level PM shell commands to ART Service.

Bug: 263247832
Test: adb shell pm help
Test: -
  1. adb shell setprop dalvik.vm.useartservice true
  2. adb shell pm compile
Change-Id: I83865249e761f3e37ee96feda7bca66bb0344d1e
parent 3845d2eb
Loading
Loading
Loading
Loading
+122 −76
Original line number Diff line number Diff line
@@ -172,6 +172,11 @@ class PackageManagerShellCommand extends ShellCommand {
        SUPPORTED_PERMISSION_FLAGS.put("revoke-when-requested",
                FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
    }
    // For backward compatibility. DO NOT add new commands here. New ART Service commands should be
    // added under the "art" namespace.
    private static final Set<String> ART_SERVICE_COMMANDS = Set.of("compile",
            "reconcile-secondary-dex-files", "force-dex-opt", "bg-dexopt-job",
            "cancel-bg-dexopt-job", "delete-dexopt", "dump-profiles", "snapshot-profile", "art");

    final IPackageManager mInterface;
    final LegacyPermissionManagerInternal mLegacyPermissionManager;
@@ -250,22 +255,6 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runMovePackage();
                case "move-primary-storage":
                    return runMovePrimaryStorage();
                case "compile":
                    return runCompile();
                case "reconcile-secondary-dex-files":
                    return runreconcileSecondaryDexFiles();
                case "force-dex-opt":
                    return runForceDexOpt();
                case "bg-dexopt-job":
                    return runBgDexOpt();
                case "cancel-bg-dexopt-job":
                    return cancelBgDexOptJob();
                case "delete-dexopt":
                    return runDeleteDexOpt();
                case "dump-profiles":
                    return runDumpProfiles();
                case "snapshot-profile":
                    return runSnapshotProfile();
                case "uninstall":
                    return runUninstall();
                case "clear":
@@ -355,9 +344,19 @@ class PackageManagerShellCommand extends ShellCommand {
                    return runBypassAllowedApexUpdateCheck();
                case "set-silent-updates-policy":
                    return runSetSilentUpdatesPolicy();
                case "art":
                    return runArtSubCommand();
                default: {
                    if (ART_SERVICE_COMMANDS.contains(cmd)) {
                        if (DexOptHelper.useArtService()) {
                            return runArtServiceCommand();
                        } else {
                            try {
                                return runLegacyDexoptCommand(cmd);
                            } catch (LegacyDexoptDisabledException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }

                    Boolean domainVerificationResult =
                            mDomainVerificationShell.runCommand(this, cmd);
                    if (domainVerificationResult != null) {
@@ -381,12 +380,39 @@ class PackageManagerShellCommand extends ShellCommand {
            }
        } catch (RemoteException e) {
            pw.println("Remote exception: " + e);
        } catch (ManagerNotFoundException e) {
            pw.println(e);
        }
        return -1;
    }

    private int runLegacyDexoptCommand(@NonNull String cmd)
            throws RemoteException, LegacyDexoptDisabledException {
        Installer.checkLegacyDexoptDisabled();
        switch (cmd) {
            case "compile":
                return runCompile();
            case "reconcile-secondary-dex-files":
                return runreconcileSecondaryDexFiles();
            case "force-dex-opt":
                return runForceDexOpt();
            case "bg-dexopt-job":
                return runBgDexOpt();
            case "cancel-bg-dexopt-job":
                return cancelBgDexOptJob();
            case "delete-dexopt":
                return runDeleteDexOpt();
            case "dump-profiles":
                return runDumpProfiles();
            case "snapshot-profile":
                return runSnapshotProfile();
            case "art":
                getOutPrintWriter().println("ART Service not enabled");
                return -1;
            default:
                // Can't happen.
                throw new IllegalArgumentException();
        }
    }

    /**
     * Shows module info
     *
@@ -3483,17 +3509,18 @@ class PackageManagerShellCommand extends ShellCommand {
        return 1;
    }

    private int runArtSubCommand() throws ManagerNotFoundException {
        // Remove the first arg "art" and forward to ART module.
        String[] args = getAllArgs();
        args = Arrays.copyOfRange(args, 1, args.length);
    private int runArtServiceCommand() {
        try (var in = ParcelFileDescriptor.dup(getInFileDescriptor());
                var out = ParcelFileDescriptor.dup(getOutFileDescriptor());
                var err = ParcelFileDescriptor.dup(getErrFileDescriptor())) {
            return LocalManagerRegistry.getManagerOrThrow(ArtManagerLocal.class)
                    .handleShellCommand(getTarget(), in, out, err, args);
                    .handleShellCommand(getTarget(), in, out, err, getAllArgs());
        } catch (IOException e) {
            throw new IllegalStateException(e);
        } catch (ManagerNotFoundException e) {
            PrintWriter epw = getErrPrintWriter();
            epw.println("ART Service is not ready. Please try again later");
            return -1;
        }
    }

@@ -4261,6 +4288,76 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("");
        pw.println("  get-max-running-users");
        pw.println("");
        pw.println("  set-home-activity [--user USER_ID] TARGET-COMPONENT");
        pw.println("    Set the default home activity (aka launcher).");
        pw.println("    TARGET-COMPONENT can be a package name (com.package.my) or a full");
        pw.println("    component (com.package.my/component.name). However, only the package name");
        pw.println("    matters: the actual component used will be determined automatically from");
        pw.println("    the package.");
        pw.println("");
        pw.println("  set-installer PACKAGE INSTALLER");
        pw.println("    Set installer package name");
        pw.println("");
        pw.println("  get-instantapp-resolver");
        pw.println(
                "    Return the name of the component that is the current instant app installer.");
        pw.println("");
        pw.println("  set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
        pw.println("    Mark the app as harmful with the given warning message.");
        pw.println("");
        pw.println("  get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
        pw.println("    Return the harmful app warning message for the given app, if present");
        pw.println();
        pw.println("  uninstall-system-updates [<PACKAGE>]");
        pw.println("    Removes updates to the given system application and falls back to its");
        pw.println("    /system version. Does nothing if the given package is not a system app.");
        pw.println("    If no package is specified, removes updates to all system applications.");
        pw.println("");
        pw.println("  get-moduleinfo [--all | --installed] [module-name]");
        pw.println("    Displays module info. If module-name is specified only that info is shown");
        pw.println("    By default, without any argument only installed modules are shown.");
        pw.println("      --all: show all module info");
        pw.println("      --installed: show only installed modules");
        pw.println("");
        pw.println("  log-visibility [--enable|--disable] <PACKAGE>");
        pw.println("    Turns on debug logging when visibility is blocked for the given package.");
        pw.println("      --enable: turn on debug logging (default)");
        pw.println("      --disable: turn off debug logging");
        pw.println("");
        pw.println("  set-silent-updates-policy [--allow-unlimited-silent-updates <INSTALLER>]");
        pw.println("                            [--throttle-time <SECONDS>] [--reset]");
        pw.println("    Sets the policies of the silent updates.");
        pw.println("      --allow-unlimited-silent-updates: allows unlimited silent updated");
        pw.println("        installation requests from the installer without the throttle time.");
        pw.println("      --throttle-time: update the silent updates throttle time in seconds.");
        pw.println("      --reset: restore the installer and throttle time to the default, and");
        pw.println("        clear tracks of silent updates in the system.");
        pw.println("");
        if (DexOptHelper.useArtService()) {
            printArtServiceHelp();
        } else {
            printLegacyDexoptHelp();
        }
        pw.println("");
        mDomainVerificationShell.printHelp(pw);
        pw.println("");
        Intent.printIntentArgsHelp(pw, "");
    }

    private void printArtServiceHelp() {
        final var ipw = new IndentingPrintWriter(getOutPrintWriter(), "  " /* singleIndent */);
        ipw.increaseIndent();
        try {
            LocalManagerRegistry.getManagerOrThrow(ArtManagerLocal.class)
                    .printShellCommandHelp(ipw);
        } catch (ManagerNotFoundException e) {
            ipw.println("ART Service is not ready. Please try again later");
        }
        ipw.decreaseIndent();
    }

    private void printLegacyDexoptHelp() {
        final PrintWriter pw = getOutPrintWriter();
        pw.println("  compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
        pw.println("          [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
        pw.println("    Trigger compilation of TARGET-PACKAGE or all packages if \"-a\".  Options are:");
@@ -4333,57 +4430,6 @@ class PackageManagerShellCommand extends ShellCommand {
        pw.println("    " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
                + "TARGET-PACKAGE[-code-path].prof");
        pw.println("    If TARGET-PACKAGE=android it will take a snapshot of the boot image");
        pw.println("");
        pw.println("  set-home-activity [--user USER_ID] TARGET-COMPONENT");
        pw.println("    Set the default home activity (aka launcher).");
        pw.println("    TARGET-COMPONENT can be a package name (com.package.my) or a full");
        pw.println("    component (com.package.my/component.name). However, only the package name");
        pw.println("    matters: the actual component used will be determined automatically from");
        pw.println("    the package.");
        pw.println("");
        pw.println("  set-installer PACKAGE INSTALLER");
        pw.println("    Set installer package name");
        pw.println("");
        pw.println("  get-instantapp-resolver");
        pw.println("    Return the name of the component that is the current instant app installer.");
        pw.println("");
        pw.println("  set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
        pw.println("    Mark the app as harmful with the given warning message.");
        pw.println("");
        pw.println("  get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
        pw.println("    Return the harmful app warning message for the given app, if present");
        pw.println();
        pw.println("  uninstall-system-updates [<PACKAGE>]");
        pw.println("    Removes updates to the given system application and falls back to its");
        pw.println("    /system version. Does nothing if the given package is not a system app.");
        pw.println("    If no package is specified, removes updates to all system applications.");
        pw.println("");
        pw.println("  get-moduleinfo [--all | --installed] [module-name]");
        pw.println("    Displays module info. If module-name is specified only that info is shown");
        pw.println("    By default, without any argument only installed modules are shown.");
        pw.println("      --all: show all module info");
        pw.println("      --installed: show only installed modules");
        pw.println("");
        pw.println("  log-visibility [--enable|--disable] <PACKAGE>");
        pw.println("    Turns on debug logging when visibility is blocked for the given package.");
        pw.println("      --enable: turn on debug logging (default)");
        pw.println("      --disable: turn off debug logging");
        pw.println("");
        pw.println("  set-silent-updates-policy [--allow-unlimited-silent-updates <INSTALLER>]");
        pw.println("                            [--throttle-time <SECONDS>] [--reset]");
        pw.println("    Sets the policies of the silent updates.");
        pw.println("      --allow-unlimited-silent-updates: allows unlimited silent updated");
        pw.println("        installation requests from the installer without the throttle time.");
        pw.println("      --throttle-time: update the silent updates throttle time in seconds.");
        pw.println("      --reset: restore the installer and throttle time to the default, and");
        pw.println("        clear tracks of silent updates in the system.");
        pw.println("");
        pw.println("  art [<SUB-COMMANDS>]");
        pw.println("    Invokes ART services commands. (Run `pm art help` for details.)");
        pw.println("");
        mDomainVerificationShell.printHelp(pw);
        pw.println("");
        Intent.printIntentArgsHelp(pw , "");
    }

    private static class LocalIntentReceiver {