Fix: "adb install -s" adaptation for session based install
am: 4f26cb5a36

Change-Id: I65d94a002a382c2a2b91d6b8348c003b9e6ab859
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 32a8088..5f83d19 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -41,6 +41,10 @@
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.PackageInstaller.SessionParams;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.ApkLite;
+import android.content.pm.PackageParser.PackageLite;
+import android.content.pm.PackageParser.PackageParserException;
 import android.content.pm.UserInfo;
 import android.net.Uri;
 import android.os.Binder;
@@ -362,11 +366,27 @@
      */
     private int runInstall() throws RemoteException {
         final InstallParams params = makeInstallParams();
+        final String inPath = nextArg();
+        if (params.sessionParams.sizeBytes < 0 && inPath != null) {
+            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));
+                } catch (PackageParserException | IOException e) {
+                    System.err.println("Error: Failed to parse APK file : " + e);
+                    return 1;
+                }
+            }
+        }
+
         final int sessionId = doCreateSession(params.sessionParams,
                 params.installerPackageName, params.userId);
 
         try {
-            final String inPath = nextArg();
             if (inPath == null && params.sessionParams.sizeBytes == 0) {
                 System.err.println("Error: must either specify a package size or an APK file");
                 return 1;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 0b8a347..2ece99f 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -439,7 +439,13 @@
             if (!FileUtils.isValidExtFilename(name)) {
                 throw new IllegalArgumentException("Invalid name: " + name);
             }
-            final File target = new File(resolveStageDir(), name);
+            final File target;
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                target = new File(resolveStageDir(), name);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
 
             // TODO: this should delegate to DCS so the system process avoids
             // holding open FDs into containers.
@@ -1084,7 +1090,12 @@
                 if (stageDir != null) {
                     prepareStageDir(stageDir);
                 } else if (stageCid != null) {
-                    prepareExternalStageCid(stageCid, params.sizeBytes);
+                    final long identity = Binder.clearCallingIdentity();
+                    try {
+                        prepareExternalStageCid(stageCid, params.sizeBytes);
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
 
                     // TODO: deliver more granular progress for ASEC allocation
                     mInternalProgress = 0.25f;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index b6cecc9..e18d4e0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -30,6 +30,10 @@
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageItemInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.ApkLite;
+import android.content.pm.PackageParser.PackageLite;
+import android.content.pm.PackageParser.PackageParserException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
@@ -48,6 +52,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.PrintWriterPrinter;
+import com.android.internal.content.PackageHelper;
 import com.android.internal.util.SizedInputStream;
 
 import dalvik.system.DexFile;
@@ -137,11 +142,26 @@
     private int runInstall() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final InstallParams params = makeInstallParams();
+        final String inPath = getNextArg();
+        if (params.sessionParams.sizeBytes < 0 && inPath != null) {
+            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));
+                } catch (PackageParserException | IOException e) {
+                    pw.println("Error: Failed to parse APK file : " + e);
+                    return 1;
+                }
+            }
+        }
+
         final int sessionId = doCreateSession(params.sessionParams,
                 params.installerPackageName, params.userId);
         boolean abandonSession = true;
         try {
-            final String inPath = getNextArg();
             if (inPath == null && params.sessionParams.sizeBytes == 0) {
                 pw.println("Error: must either specify a package size or an APK file");
                 return 1;