| /* |
| * 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(); |
| } |
| } |