Skip to content

Commit 1bb921e

Browse files
ttanxuschfan-1
andauthored
guessPath not to depend on the first level of app directory (#156)
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. Co-authored-by: schfan-1 <[email protected]>
1 parent 6317546 commit 1bb921e

File tree

2 files changed

+62
-16
lines changed

2 files changed

+62
-16
lines changed

dexmaker-tests/src/androidTest/java/com/android/dx/AppDataDirGuesserTest.java

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,40 +32,45 @@
3232
public final class AppDataDirGuesserTest {
3333
@Test
3434
public void testGuessCacheDir_SimpleExample() {
35-
guessCacheDirFor("/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
36-
guessCacheDirFor("/data/app/a.b.c.tests.apk").shouldGive("/data/data/a.b.c.tests/cache");
35+
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk")
36+
.shouldGive("/data/data/a.b.c/cache");
37+
guessCacheDirFor("/data/app/a.b.c.tests-xxx/base.apk")
38+
.shouldGive("/data/data/a.b.c.tests/cache");
3739
}
3840

3941
@Test
4042
public void testGuessCacheDir_MultipleResultsSeparatedByColon() {
41-
guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
43+
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk")
4244
.shouldGive("/data/data/a.b.c/cache", "/data/data/d.e.f/cache");
4345
}
4446

4547
@Test
4648
public void testGuessCacheDir_NotWriteableSkipped() {
47-
guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
49+
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk")
4850
.withNonWriteable("/data/data/a.b.c/cache")
4951
.shouldGive("/data/data/d.e.f/cache");
5052
}
5153

5254
@Test
5355
public void testGuessCacheDir_ForSecondaryUser() {
54-
guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
56+
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:/data/app/d.e.f-xxx/base.apk")
5557
.withNonWriteable("/data/data/a.b.c", "/data/data/d.e.f")
5658
.withProcessUid(1110009)
5759
.shouldGive("/data/user/11/a.b.c/cache", "/data/user/11/d.e.f/cache");
5860
}
5961

6062
@Test
6163
public void testGuessCacheDir_StripHyphenatedSuffixes() {
62-
guessCacheDirFor("/data/app/a.b.c-2.apk").shouldGive("/data/data/a.b.c/cache");
64+
guessCacheDirFor("/data/app/a.b.c-2/base.apk")
65+
.shouldGive("/data/data/a.b.c/cache");
6366
}
6467

6568
@Test
6669
public void testGuessCacheDir_LeadingAndTrailingColonsIgnored() {
67-
guessCacheDirFor("/data/app/a.b.c.apk:asdf:").shouldGive("/data/data/a.b.c/cache");
68-
guessCacheDirFor(":asdf:/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
70+
guessCacheDirFor("/data/app/a.b.c-xxx/base.apk:asdf:")
71+
.shouldGive("/data/data/a.b.c/cache");
72+
guessCacheDirFor(":asdf:/data/app/a.b.c-xxx/base.apk")
73+
.shouldGive("/data/data/a.b.c/cache");
6974
}
7075

7176
@Test
@@ -82,8 +87,38 @@ public void testGuessCacheDir_JarsIgnored() {
8287
@Test
8388
public void testGuessCacheDir_RealWorldExample() {
8489
String realPath = "/system/framework/android.test.runner.jar:" +
85-
"/data/app/com.google.android.voicesearch.tests-2.apk:" +
86-
"/data/app/com.google.android.voicesearch-1.apk";
90+
"/data/app/com.google.android.voicesearch.tests-2/base.apk:" +
91+
"/data/app/com.google.android.voicesearch-1/base.apk";
92+
guessCacheDirFor(realPath)
93+
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
94+
.shouldGive("/data/data/com.google.android.voicesearch/cache");
95+
}
96+
97+
@Test
98+
public void testGuessCacheDir_RealWorldExampleWithOneLevelSubDirectories() {
99+
String realPath = "/system/framework/android.test.runner.jar:" +
100+
"/data/app/com.google.android.voicesearch.tests-abcde/base.apk:" +
101+
"/data/app/com.google.android.voicesearch-fghij/base.apk";
102+
guessCacheDirFor(realPath)
103+
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
104+
.shouldGive("/data/data/com.google.android.voicesearch/cache");
105+
}
106+
107+
@Test
108+
public void testGuessCacheDir_RealWorldExampleWithTwoLevelSubDirectories() {
109+
String realPath = "/system/framework/android.test.runner.jar:" +
110+
"/data/app/abcde/com.google.android.voicesearch.tests-fghij/base.apk:" +
111+
"/data/app/klmno/com.google.android.voicesearch-pqrst/base.apk";
112+
guessCacheDirFor(realPath)
113+
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
114+
.shouldGive("/data/data/com.google.android.voicesearch/cache");
115+
}
116+
117+
@Test
118+
public void testGuessCacheDir_RealWorldExampleWithHyphensInPath() {
119+
String realPath = "/system/framework/android.test.runner.jar:" +
120+
"/data/app/a-b-c/com.google.android.voicesearch.tests-e-f-g/base.apk:" +
121+
"/data/app/com.google.android.voicesearch-k-l-n/base.apk";
87122
guessCacheDirFor(realPath)
88123
.withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
89124
.shouldGive("/data/data/com.google.android.voicesearch/cache");

dexmaker/src/main/java/com/android/dx/AppDataDirGuesser.java

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,31 @@ private static String processClassLoaderString43OrLater(String input) {
136136

137137
File[] guessPath(String input) {
138138
List<File> results = new ArrayList<>();
139+
String apkPathRoot = "/data/app/";
139140
for (String potential : splitPathList(input)) {
140-
if (!potential.startsWith("/data/app/")) {
141+
if (!potential.startsWith(apkPathRoot)) {
141142
continue;
142143
}
143-
int start = "/data/app/".length();
144144
int end = potential.lastIndexOf(".apk");
145145
if (end != potential.length() - 4) {
146146
continue;
147147
}
148-
int dash = potential.indexOf("-");
149-
if (dash != -1) {
150-
end = dash;
148+
int endSlash = potential.lastIndexOf("/", end);
149+
if (endSlash == apkPathRoot.length() - 1) {
150+
// Apks cannot be directly under /data/app
151+
continue;
152+
}
153+
int startSlash = potential.lastIndexOf("/", endSlash - 1);
154+
if (startSlash == -1) {
155+
continue;
156+
}
157+
// Look for the first dash after the package name
158+
int dash = potential.indexOf("-", startSlash);
159+
if (dash == -1) {
160+
continue;
151161
}
152-
String packageName = potential.substring(start, end);
162+
end = dash;
163+
String packageName = potential.substring(startSlash + 1, end);
153164
File dataDir = getWriteableDirectory("/data/data/" + packageName);
154165

155166
if (dataDir == null) {

0 commit comments

Comments
 (0)