blob: a79816c4f5e5ee093c6926f2f936c0e85796ffaa [file] [log] [blame]
/*
* Copyright (c) 2017 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito.android.internal.creation;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
class AndroidTempFileLocator {
final static File target;
static {
File t = null;
try {
String user = System.getProperty("org.mockito.android.target");
if (user != null) {
t = new File(user);
}
} catch (Throwable ignored) {
}
if (t == null) {
try {
Class<?> clazz = Class.forName("android.support.test.InstrumentationRegistry");
Object context = clazz.getDeclaredMethod("getTargetContext").invoke(clazz);
t = (File) context.getClass().getMethod("getCacheDir").invoke(context);
} catch (Throwable ignored) {
}
}
if (t == null) {
try {
Class<?> clazz = Class.forName("dalvik.system.PathClassLoader");
Field pathField = clazz.getDeclaredField("path");
pathField.setAccessible(true);
String pathFromThisClassLoader = (String) pathField.get(AndroidTempFileLocator.class.getClassLoader());
File[] results = guessPath(pathFromThisClassLoader);
if (results.length > 0) {
t = results[0];
}
} catch (Throwable ignored) {
}
}
target = t;
}
private static File[] guessPath(String input) {
List<File> results = new ArrayList<File>();
for (String potential : splitPathList(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;
}
String packageName = potential.substring(start, end);
File dataDir = new File("/data/data/" + packageName);
if (isWriteableDirectory(dataDir)) {
File cacheDir = new File(dataDir, "cache");
if (fileOrDirExists(cacheDir) || cacheDir.mkdir()) {
if (isWriteableDirectory(cacheDir)) {
results.add(cacheDir);
}
}
}
}
return results.toArray(new File[results.size()]);
}
private static String[] splitPathList(String input) {
String trimmed = input;
if (input.startsWith("dexPath=")) {
int start = "dexPath=".length();
int end = input.indexOf(',');
trimmed = (end == -1) ? input.substring(start) : input.substring(start, end);
}
return trimmed.split(":");
}
private static boolean fileOrDirExists(File file) {
return file.exists();
}
private static boolean isWriteableDirectory(File file) {
return file.isDirectory() && file.canWrite();
}
}