From 7c8cadb9683ce4be53807cfa1cb022c5646e4f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Kongstad?= Date: Tue, 8 Mar 2022 16:11:05 +0000 Subject: [PATCH] pm install: clarify when --multi-package can be used The package manager shell commands 'install', 'install-streaming', 'install-incremental' and 'install-create' all use the same method to parse their command line options, but the commands expect slightly different input. Passing in an unexpected option will lead to implementation defined behaviour: 'pm install --multi-package' will try (and fail) to write a file to the root directory, which is reported to the end user as: Error: failed to write; open failed: EROFS (Read-only file system) Reduce confusion by explicitly preventing --multi-package outside of 'install-create'. Also, remove -w from the usage text: -w was replaced by --restrict-permissions in commit 83a3a4a9db7. Bug: 223171705 Test: adb shell pm install --multi-package /path/to/apk # fails and complains about --multi-package Test: adb shell pm install /path/to/apk # succeeds Test: atest PackageManagerServiceTest Change-Id: Idb098e2197f02de2a42cc3d010ffb8968a6fbd29 --- .../server/pm/PackageManagerShellCommand.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 5b4084e9b2297..265e6062f1d60 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -129,6 +129,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; @@ -142,6 +143,10 @@ class PackageManagerShellCommand extends ShellCommand { private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/"; private static final int DEFAULT_STAGED_READY_TIMEOUT_MS = 60 * 1000; private static final String TAG = "PackageManagerShellCommand"; + private static final Set UNSUPPORTED_INSTALL_CMD_OPTS = Set.of( + "--multi-package" + ); + private static final Set UNSUPPORTED_SESSION_CREATE_OPTS = Collections.emptySet(); final IPackageManager mInterface; final LegacyPermissionManagerInternal mLegacyPermissionManager; @@ -1282,7 +1287,7 @@ class PackageManagerShellCommand extends ShellCommand { } private int runStreamingInstall() throws RemoteException { - final InstallParams params = makeInstallParams(); + final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS); if (params.sessionParams.dataLoaderParams == null) { params.sessionParams.setDataLoaderParams( PackageManagerShellCommandDataLoader.getStreamingDataLoaderParams(this)); @@ -1291,7 +1296,7 @@ class PackageManagerShellCommand extends ShellCommand { } private int runIncrementalInstall() throws RemoteException { - final InstallParams params = makeInstallParams(); + final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS); if (params.sessionParams.dataLoaderParams == null) { params.sessionParams.setDataLoaderParams( PackageManagerShellCommandDataLoader.getIncrementalDataLoaderParams(this)); @@ -1300,7 +1305,7 @@ class PackageManagerShellCommand extends ShellCommand { } private int runInstall() throws RemoteException { - return doRunInstall(makeInstallParams()); + return doRunInstall(makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS)); } private int doRunInstall(final InstallParams params) throws RemoteException { @@ -1452,7 +1457,7 @@ class PackageManagerShellCommand extends ShellCommand { private int runInstallCreate() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); - final InstallParams installParams = makeInstallParams(); + final InstallParams installParams = makeInstallParams(UNSUPPORTED_SESSION_CREATE_OPTS); final int sessionId = doCreateSession(installParams.sessionParams, installParams.installerPackageName, installParams.userId); @@ -2764,7 +2769,7 @@ class PackageManagerShellCommand extends ShellCommand { long stagedReadyTimeoutMs = DEFAULT_STAGED_READY_TIMEOUT_MS; } - private InstallParams makeInstallParams() { + private InstallParams makeInstallParams(Set unsupportedOptions) { final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL); final InstallParams params = new InstallParams(); @@ -2776,6 +2781,9 @@ class PackageManagerShellCommand extends ShellCommand { boolean replaceExisting = true; boolean forceNonStaged = false; while ((opt = getNextOption()) != null) { + if (unsupportedOptions.contains(opt)) { + throw new IllegalArgumentException("Unsupported option " + opt); + } switch (opt) { case "-r": // ignore break; @@ -3674,7 +3682,7 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" [--user USER_ID] INTENT"); pw.println(" Prints all broadcast receivers that can handle the given INTENT."); pw.println(""); - pw.println(" install [-rtfdgw] [-i PACKAGE] [--user USER_ID|all|current]"); + pw.println(" install [-rtfdg] [-i PACKAGE] [--user USER_ID|all|current]"); pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]"); pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]"); pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");