OSDN Git Service

Perform a non strict matching of .dm files when computing the size
authorCalin Juravle <calin@google.com>
Mon, 22 Jan 2018 20:50:01 +0000 (12:50 -0800)
committerCalin Juravle <calin@google.com>
Mon, 22 Jan 2018 22:14:39 +0000 (14:14 -0800)
'adb shell pm install' creates the PackageLite structure without
validating or renaming the input files to '.apk'.

Be more permissive in DexMetadataHeler when computing the size of the
package to allow for this scenario.

Test: atest
core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
Bug: 72267410

Change-Id: Ica446b0822be71826d02d01ada015a43d8133c68

core/java/android/content/pm/dex/DexMetadataHelper.java
core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java

index c5f1c85..5d10b88 100644 (file)
@@ -107,8 +107,8 @@ public class DexMetadataHelper {
      * For each code path (.apk) the method checks if a matching dex metadata file (.dm) exists.
      * If it does it adds the pair to the returned map.
      *
-     * Note that this method will do a strict
-     * matching based on the extension ('foo.dm' will only match 'foo.apk').
+     * Note that this method will do a loose
+     * matching based on the extension ('foo.dm' will match 'foo.apk' or 'foo').
      *
      * This should only be used for code paths extracted from a package structure after the naming
      * was enforced in the installer.
@@ -118,7 +118,7 @@ public class DexMetadataHelper {
         ArrayMap<String, String> result = new ArrayMap<>();
         for (int i = codePaths.size() - 1; i >= 0; i--) {
             String codePath = codePaths.get(i);
-            String dexMetadataPath = buildDexMetadataPathForApk(codePath);
+            String dexMetadataPath = buildDexMetadataPathForFile(new File(codePath));
 
             if (Files.exists(Paths.get(dexMetadataPath))) {
                 result.put(codePath, dexMetadataPath);
index 4b84429..584257b 100644 (file)
@@ -24,7 +24,9 @@ import static org.junit.Assert.fail;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.ApkLite;
 import android.content.pm.PackageParser.Package;
+import android.content.pm.PackageParser.PackageLite;
 import android.content.pm.PackageParser.PackageParserException;
 import android.os.FileUtils;
 import android.support.test.InstrumentationRegistry;
@@ -34,6 +36,7 @@ import android.test.suitebuilder.annotation.SmallTest;
 import com.android.frameworks.coretests.R;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -45,6 +48,7 @@ import java.util.zip.ZipOutputStream;
 import libcore.io.IoUtils;
 
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -201,6 +205,31 @@ public class DexMetadataHelperTest {
         }
     }
 
+    @Test
+    public void testPackageSizeWithDmFile()
+            throws IOException, PackageParserException {
+        copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base);
+        File dm = createDexMetadataFile("install_split_base.apk");
+        PackageParser.PackageLite pkg = new PackageParser().parsePackageLite(mTmpDir,
+                0 /* flags */);
+
+        Assert.assertEquals(dm.length(), DexMetadataHelper.getPackageDexMetadataSize(pkg));
+    }
+
+    // This simulates the 'adb shell pm install' flow.
+    @Test
+    public void testPackageSizeWithPartialPackageLite() throws IOException, PackageParserException {
+        File base = copyApkToToTmpDir("install_split_base", R.raw.install_split_base);
+        File dm = createDexMetadataFile("install_split_base.apk");
+        try (FileInputStream is = new FileInputStream(base)) {
+            ApkLite baseApk = PackageParser.parseApkLite(is.getFD(), base.getAbsolutePath(), 0);
+            PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
+                    null, null);
+            Assert.assertEquals(dm.length(), DexMetadataHelper.getPackageDexMetadataSize(pkgLite));
+        }
+
+    }
+
     private static boolean isDexMetadataForApk(String dmaPath, String apkPath) {
         return apkPath.substring(0, apkPath.length() - APK_FILE_EXTENSION.length()).equals(
                 dmaPath.substring(0, dmaPath.length() - DEX_METADATA_FILE_EXTENSION.length()));