From 698637455f830a166ae32625c16a5bf618d3a7d9 Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Thu, 23 Jan 2020 12:10:46 -0800 Subject: [PATCH] guessPath not to depend on the first level of app directory We are updating apps' apk path to have a two-level structure. Default apk path of an installed app: Before: /data/app/[packageName]-[randomString]/base.apk After: /data/app/[randomStringA]/[packageName]-[randomStringB]/base.apk This CL fixes the path guessing assumption the apk dir is only one level below the /data/app dir. Fixes #155. --- .../com/android/dx/AppDataDirGuesserTest.java | 38 +++++++++++++++---- .../com/android/dx/AppDataDirGuesser.java | 10 +++-- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java b/dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java index b2128d75..0348baa1 100644 --- a/dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java +++ b/dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java @@ -32,26 +32,28 @@ public final class AppDataDirGuesserTest { @Test public void testGuessCacheDir_SimpleExample() { - guessCacheDirFor("/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache"); - guessCacheDirFor("/data/app/a.b.c.tests.apk").shouldGive("/data/data/a.b.c.tests/cache"); + guessCacheDirFor("/data/app/a.b.c-xxx/base.apk") + .shouldGive("/data/data/a.b.c/cache"); + guessCacheDirFor("/data/app/a.b.c.tests-xxx/base.apk") + .shouldGive("/data/data/a.b.c.tests/cache"); } @Test public void testGuessCacheDir_MultipleResultsSeparatedByColon() { - guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk") + guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk") .shouldGive("/data/data/a.b.c/cache", "/data/data/d.e.f/cache"); } @Test public void testGuessCacheDir_NotWriteableSkipped() { - guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk") + guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk") .withNonWriteable("/data/data/a.b.c/cache") .shouldGive("/data/data/d.e.f/cache"); } @Test public void testGuessCacheDir_ForSecondaryUser() { - guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk") + guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk") .withNonWriteable("/data/data/a.b.c", "/data/data/d.e.f") .withProcessUid(1110009) .shouldGive("/data/user/11/a.b.c/cache", "/data/user/11/d.e.f/cache"); @@ -64,8 +66,10 @@ public void testGuessCacheDir_StripHyphenatedSuffixes() { @Test public void testGuessCacheDir_LeadingAndTrailingColonsIgnored() { - guessCacheDirFor("/data/app/a.b.c.apk:asdf:").shouldGive("/data/data/a.b.c/cache"); - guessCacheDirFor(":asdf:/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache"); + guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:asdf:") + .shouldGive("/data/data/a.b.c/cache"); + guessCacheDirFor(":asdf:/data/app/a.b.c-xxx/base.apk") + .shouldGive("/data/data/a.b.c/cache"); } @Test @@ -89,6 +93,26 @@ public void testGuessCacheDir_RealWorldExample() { .shouldGive("/data/data/com.google.android.voicesearch/cache"); } + @Test + public void testGuessCacheDir_RealWorldExampleWithOneLevelSubDirectories() { + String realPath = "/system/framework/android.test.runner.jar:" + + "/data/app/com.google.android.voicesearch.tests-abcde/base.apk:" + + "/data/app/com.google.android.voicesearch-fghij/base.apk"; + guessCacheDirFor(realPath) + .withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache") + .shouldGive("/data/data/com.google.android.voicesearch/cache"); + } + + @Test + public void testGuessCacheDir_RealWorldExampleWithTwoLevelSubDirectories() { + String realPath = "/system/framework/android.test.runner.jar:" + + "/data/app/abcde/com.google.android.voicesearch.tests-fghij/base.apk:" + + "/data/app/klmno/com.google.android.voicesearch-pqrst/base.apk"; + guessCacheDirFor(realPath) + .withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache") + .shouldGive("/data/data/com.google.android.voicesearch/cache"); + } + @Test public void testSplitPathList() { final String[] expected = { "foo", "bar" }; diff --git a/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java b/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java index cc1d8030..b6ab4607 100644 --- a/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java +++ b/dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java @@ -140,14 +140,18 @@ File[] guessPath(String input) { if (!potential.startsWith("/data/app/")) { continue; } - int start = "/data/app/".length(); int end = potential.lastIndexOf(".apk"); if (end != potential.length() - 4) { continue; } int dash = potential.indexOf("-"); - if (dash != -1) { - end = dash; + if (dash == -1) { + continue; + } + end = dash; + int start = potential.lastIndexOf("/", dash) + 1; + if (start == 0) { + continue; } String packageName = potential.substring(start, end); File dataDir = getWriteableDirectory("/data/data/" + packageName);