Index: apk/hijack/org/chromium/deconstructed/NativeInstaller.java |
diff --git a/apk/hijack/org/chromium/deconstructed/NativeInstaller.java b/apk/hijack/org/chromium/deconstructed/NativeInstaller.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9663ade94d11d3eb982feccde9f87e66d29fe15f |
--- /dev/null |
+++ b/apk/hijack/org/chromium/deconstructed/NativeInstaller.java |
@@ -0,0 +1,75 @@ |
+package org.chromium.deconstructed; |
+ |
+import android.content.Context; |
+import android.content.pm.ApplicationInfo; |
+import android.util.Log; |
+ |
+import java.io.File; |
+import java.io.FileInputStream; |
+import java.io.FileOutputStream; |
+import java.io.IOException; |
+import java.io.InputStream; |
+import java.io.OutputStream; |
+import java.lang.reflect.InvocationTargetException; |
+ |
+public class NativeInstaller { |
+ private static final String TAG = "org.chromium.deconstructed.NativeInstaller"; |
+ private static final String NATIVE_LIB_DIR_NAME = |
+ "code_cache" + File.separator + "lib"; |
+ |
+ public static void install(Context context, File nativeDir) |
+ throws IOException, NoSuchFieldException { |
+ File[] nativeLibs = nativeDir.listFiles(); |
+ for (File f : nativeLibs) { |
+ if (!isValidLib(f)) { |
+ return; |
+ } |
+ } |
+ ApplicationInfo appInfo = context.getApplicationInfo(); |
+ File installDir = new File(appInfo.dataDir, NATIVE_LIB_DIR_NAME); |
+ installDir.mkdirs(); |
+ android.util.Log.e(TAG, installDir.toString()); |
+ for (File f : nativeLibs) { |
+ File e = new File(installDir, f.getName()); |
+ copyFile(f, e); |
+ e.setExecutable(true); |
+ } |
+ |
+ injectNativeLibDir(context.getClassLoader(), installDir); |
+ } |
+ |
+ private static boolean isValidLib(File f) { |
+ // TODO |
+ return true; |
+ } |
+ |
+ private static void copyFile(File in, File out) throws IOException { |
+ InputStream src = null; |
+ OutputStream dst = null; |
+ try { |
+ src = new FileInputStream(in); |
+ dst = new FileOutputStream(out); |
+ byte[] buf = new byte[1 << 14]; // 16k |
+ int len; |
+ while ((len = src.read(buf)) > 0) { |
+ dst.write(buf, 0, len); |
+ } |
+ } finally { |
+ // TODO: blegh |
+ if (src != null) { |
+ src.close(); |
+ } |
+ if (dst != null) { |
+ dst.close(); |
+ } |
+ } |
+ |
+ } |
+ |
+ private static void injectNativeLibDir(ClassLoader loader, File nativeLibDir) throws NoSuchFieldException { |
+ Object dexPathList = Reflect.getField(loader, "pathList"); |
+ Object[] currentDirs = (Object[]) Reflect.getField(dexPathList, "nativeLibraryDirectories"); |
+ Object[] newDirs = new Object[] {nativeLibDir}; |
+ Reflect.setField(dexPathList, "nativeLibraryDirectories", Reflect.concatArrays(currentDirs, newDirs)); |
+ } |
+} |