diff options
-rw-r--r-- | cmds/pm/src/com/android/commands/pm/Pm.java | 18 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerShellCommand.java | 61 |
2 files changed, 59 insertions, 20 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index aba53dcdca4d..718f1414c93d 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -84,6 +84,7 @@ import java.util.concurrent.TimeUnit; public final class Pm { private static final String TAG = "Pm"; + private static final String STDIN_PATH = "-"; IPackageManager mPm; IPackageInstaller mInstaller; @@ -403,7 +404,7 @@ public final class Pm { private int runInstall() throws RemoteException { final InstallParams params = makeInstallParams(); final String inPath = nextArg(); - if (params.sessionParams.sizeBytes < 0 && inPath != null) { + if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) { File file = new File(inPath); if (file.isFile()) { try { @@ -413,9 +414,12 @@ public final class Pm { PackageHelper.calculateInstalledSize(pkgLite, false, params.sessionParams.abiOverride)); } catch (PackageParserException | IOException e) { - System.err.println("Error: Failed to parse APK file : " + e); + System.err.println("Error: Failed to parse APK file: " + e); return 1; } + } else { + System.err.println("Error: Can't open non-file: " + inPath); + return 1; } } @@ -423,7 +427,7 @@ public final class Pm { params.installerPackageName, params.userId); try { - if (inPath == null && params.sessionParams.sizeBytes == 0) { + if (inPath == null && params.sessionParams.sizeBytes == -1) { System.err.println("Error: must either specify a package size or an APK file"); return 1; } @@ -540,7 +544,11 @@ public final class Pm { } break; case "-S": - sessionParams.setSize(Long.parseLong(nextOptionData())); + final long sizeBytes = Long.parseLong(nextOptionData()); + if (sizeBytes <= 0) { + throw new IllegalArgumentException("Size must be positive"); + } + sessionParams.setSize(sizeBytes); break; case "--abi": sessionParams.abiOverride = checkAbiArgument(nextOptionData()); @@ -585,7 +593,7 @@ public final class Pm { private int doWriteSession(int sessionId, String inPath, long sizeBytes, String splitName, boolean logSuccess) throws RemoteException { - if ("-".equals(inPath)) { + if (STDIN_PATH.equals(inPath)) { inPath = null; } else if (inPath != null) { final File file = new File(inPath); diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index a24217e35087..834d343e2649 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -75,6 +75,11 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; class PackageManagerShellCommand extends ShellCommand { + /** Path for streaming APK content */ + private static final String STDIN_PATH = "-"; + /** Whether or not APK content must be streamed from stdin */ + private static final boolean FORCE_STREAM_INSTALL = true; + final IPackageManager mInterface; final private WeakHashMap<String, Resources> mResourceCache = new WeakHashMap<String, Resources>(); @@ -139,30 +144,45 @@ class PackageManagerShellCommand extends ShellCommand { return -1; } - private int runInstall() throws RemoteException { + private void setParamsSize(InstallParams params, String inPath) { + // If we're forced to stream the package, the params size + // must be set via command-line argument. There's nothing + // to do here. + if (FORCE_STREAM_INSTALL) { + return; + } final PrintWriter pw = getOutPrintWriter(); - final InstallParams params = makeInstallParams(); - final String inPath = getNextArg(); - if (params.sessionParams.sizeBytes < 0 && inPath != null) { + if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) { File file = new File(inPath); if (file.isFile()) { try { ApkLite baseApk = PackageParser.parseApkLite(file, 0); PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null); - params.sessionParams.setSize( - PackageHelper.calculateInstalledSize(pkgLite,false, params.sessionParams.abiOverride)); + params.sessionParams.setSize(PackageHelper.calculateInstalledSize( + pkgLite, false, params.sessionParams.abiOverride)); } catch (PackageParserException | IOException e) { - pw.println("Error: Failed to parse APK file : " + e); - return 1; + pw.println("Error: Failed to parse APK file: " + file); + throw new IllegalArgumentException( + "Error: Failed to parse APK file: " + file, e); } + } else { + pw.println("Error: Can't open non-file: " + inPath); + throw new IllegalArgumentException("Error: Can't open non-file: " + inPath); } } + } + private int runInstall() throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + final InstallParams params = makeInstallParams(); + final String inPath = getNextArg(); + + setParamsSize(params, inPath); final int sessionId = doCreateSession(params.sessionParams, params.installerPackageName, params.userId); boolean abandonSession = true; try { - if (inPath == null && params.sessionParams.sizeBytes == 0) { + if (inPath == null && params.sessionParams.sizeBytes == -1) { pw.println("Error: must either specify a package size or an APK file"); return 1; } @@ -1075,7 +1095,11 @@ class PackageManagerShellCommand extends ShellCommand { } break; case "-S": - sessionParams.setSize(Long.parseLong(getNextArg())); + final long sizeBytes = Long.parseLong(getNextArg()); + if (sizeBytes <= 0) { + throw new IllegalArgumentException("Size must be positive"); + } + sessionParams.setSize(sizeBytes); break; case "--abi": sessionParams.abiOverride = checkAbiArgument(getNextArg()); @@ -1180,15 +1204,22 @@ class PackageManagerShellCommand extends ShellCommand { private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, boolean logSuccess) throws RemoteException { final PrintWriter pw = getOutPrintWriter(); - if (sizeBytes <= 0) { - pw.println("Error: must specify a APK size"); + if (FORCE_STREAM_INSTALL && inPath != null && !STDIN_PATH.equals(inPath)) { + pw.println("Error: APK content must be streamed"); return 1; } - if (inPath != null && !"-".equals(inPath)) { - pw.println("Error: APK content must be streamed"); + if (STDIN_PATH.equals(inPath)) { + inPath = null; + } else if (inPath != null) { + final File file = new File(inPath); + if (file.isFile()) { + sizeBytes = file.length(); + } + } + if (sizeBytes <= 0) { + pw.println("Error: must specify a APK size"); return 1; } - inPath = null; final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId); |