File[] guessPath(String input) {
    List<File> results = new ArrayList<>();
    String apkPathRoot = "/data/app/";
    for (String potential : splitPathList(input)) {
      if (!potential.startsWith(apkPathRoot)) {
        continue;
      }
      int end = potential.lastIndexOf(".apk");
      if (end != potential.length() - 4) {
        continue;
      }
      int endSlash = potential.lastIndexOf("/", end);
      if (endSlash == apkPathRoot.length() - 1) {
        // Apks cannot be directly under /data/app
        continue;
      }
      int startSlash = potential.lastIndexOf("/", endSlash - 1);
      if (startSlash == -1) {
        continue;
      }
      // Look for the first dash after the package name
      int dash = potential.indexOf("-", startSlash);
      if (dash == -1) {
        continue;
      }
      end = dash;
      String packageName = potential.substring(startSlash + 1, end);
      File dataDir = getWriteableDirectory("/data/data/" + packageName);

      if (dataDir == null) {
        // If we can't access "/data/data", try to guess user specific data directory.
        dataDir = guessUserDataDirectory(packageName);
      }

      if (dataDir != null) {
        File cacheDir = new File(dataDir, "cache");
        // The cache directory might not exist -- create if necessary
        if (fileOrDirExists(cacheDir) || cacheDir.mkdir()) {
          if (isWriteableDirectory(cacheDir)) {
            results.add(cacheDir);
          }
        }
      }
    }
    return results.toArray(new File[results.size()]);
  }
Given the result of a ClassLoader.toString() call, process the result so that guessPath can use
it. There are currently two variants. For Android 4.3 and later, the string "DexPathList"
should be recognized and the array of dex path elements is parsed. for earlier versions, the
last nested array ('[' ... ']') is enclosing the string we are interested in.
android/android_framework/dex-maker/src/main/java/com/android/dx/AppDataDirGuesser.java