• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017 Mockito contributors
3  * This program is made available under the terms of the MIT License.
4  */
5 package org.mockito.android.internal.creation;
6 
7 import java.io.File;
8 import java.lang.reflect.Field;
9 import java.util.ArrayList;
10 import java.util.List;
11 
12 class AndroidTempFileLocator {
13 
14     final static File target;
15 
16     static {
17         File t = null;
18         try {
19             String user = System.getProperty("org.mockito.android.target");
20             if (user != null) {
21                 t = new File(user);
22             }
23         } catch (Throwable ignored) {
24         }
25         if (t == null) {
26             t = getCacheDirFromInstrumentationRegistry("android.support.test.InstrumentationRegistry");
27         }
28         if (t == null) {
29             t = getCacheDirFromInstrumentationRegistry("androidx.test.InstrumentationRegistry");
30         }
31         if (t == null) {
32             try {
33                 Class<?> clazz = Class.forName("dalvik.system.PathClassLoader");
34                 Field pathField = clazz.getDeclaredField("path");
35                 pathField.setAccessible(true);
36                 String pathFromThisClassLoader = (String) pathField.get(AndroidTempFileLocator.class.getClassLoader());
37                 File[] results = guessPath(pathFromThisClassLoader);
38                 if (results.length > 0) {
39                     t = results[0];
40                 }
41             } catch (Throwable ignored) {
42             }
43         }
44         target = t;
45     }
46 
getCacheDirFromInstrumentationRegistry(String className)47     private static File getCacheDirFromInstrumentationRegistry(String className) {
48         try {
49             Class<?> clazz = Class.forName(className);
50             Object context = clazz.getDeclaredMethod("getTargetContext").invoke(clazz);
51             return (File) context.getClass().getMethod("getCacheDir").invoke(context);
52         } catch (Throwable ignored) {
53         }
54         return null;
55     }
56 
guessPath(String input)57     private static File[] guessPath(String input) {
58         List<File> results = new ArrayList<File>();
59         for (String potential : splitPathList(input)) {
60             if (!potential.startsWith("/data/app/")) {
61                 continue;
62             }
63             int start = "/data/app/".length();
64             int end = potential.lastIndexOf(".apk");
65             if (end != potential.length() - 4) {
66                 continue;
67             }
68             int dash = potential.indexOf("-");
69             if (dash != -1) {
70                 end = dash;
71             }
72             String packageName = potential.substring(start, end);
73             File dataDir = new File("/data/data/" + packageName);
74             if (isWritableDirectory(dataDir)) {
75                 File cacheDir = new File(dataDir, "cache");
76                 if (fileOrDirExists(cacheDir) || cacheDir.mkdir()) {
77                     if (isWritableDirectory(cacheDir)) {
78                         results.add(cacheDir);
79                     }
80                 }
81             }
82         }
83         return results.toArray(new File[results.size()]);
84     }
85 
splitPathList(String input)86     private static String[] splitPathList(String input) {
87         String trimmed = input;
88         if (input.startsWith("dexPath=")) {
89             int start = "dexPath=".length();
90             int end = input.indexOf(',');
91 
92             trimmed = (end == -1) ? input.substring(start) : input.substring(start, end);
93         }
94 
95         return trimmed.split(":");
96     }
97 
fileOrDirExists(File file)98     private static boolean fileOrDirExists(File file) {
99         return file.exists();
100     }
101 
isWritableDirectory(File file)102     private static boolean isWritableDirectory(File file) {
103         return file.isDirectory() && file.canWrite();
104     }
105 }
106