Index: base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java |
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java |
index d68fb4a814a19f1e187fd0afe77a2227b5df40e4..d3568bee8eb9c7bf77dc18fd28cefb50cb9216f4 100644 |
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java |
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java |
@@ -5,6 +5,8 @@ |
package org.chromium.base.library_loader; |
import android.content.Context; |
+import android.content.pm.ApplicationInfo; |
+import android.os.AsyncTask; |
import android.os.SystemClock; |
import android.util.Log; |
@@ -13,6 +15,8 @@ import org.chromium.base.CommandLine; |
import org.chromium.base.JNINamespace; |
import org.chromium.base.TraceEvent; |
+import java.io.File; |
+import java.util.HashMap; |
import java.util.Locale; |
import javax.annotation.Nullable; |
@@ -83,6 +87,9 @@ public class LibraryLoader { |
// The type of process the shared library is loaded in. |
private int mLibraryProcessType; |
+ // Library -> Location it has been loaded from. |
+ private HashMap<String, String> mLoadedFrom; |
+ |
/** |
* @param libraryProcessType the process the shared library is loaded in. refer to |
* LibraryProcessType for possible values. |
@@ -102,6 +109,53 @@ public class LibraryLoader { |
private LibraryLoader(int libraryProcessType) { |
mLibraryProcessType = libraryProcessType; |
+ mLoadedFrom = new HashMap<String, String>(); |
+ } |
+ |
+ private void prefaultLibrary(final Context context, String library) { |
+ ApplicationInfo applicationInfo = context.getApplicationInfo(); |
+ String apkFilePath = context.getApplicationInfo().sourceDir; |
+ |
+ String pathToLibrary = mLoadedFrom.get(library); |
+ |
+ if (pathToLibrary == null) { |
+ Log.w(TAG, "Tried to find " + library + " before its load"); |
+ return; |
+ } |
+ long tick = SystemClock.elapsedRealtime(); |
+ boolean ok; |
+ if (pathToLibrary.equals(apkFilePath)) { |
+ ok = Linker.nativePrefaultLibraryInZipFile(apkFilePath, library); |
+ } else { |
+ ok = Linker.nativePrefaultLibraryInFile(pathToLibrary); |
+ } |
+ if (!ok) { |
+ Log.w(TAG, "Error while prefaulting the native library " + pathToLibrary); |
+ return; |
+ } |
+ long tock = SystemClock.elapsedRealtime(); |
+ Log.w(TAG, "Touching the native library " + library + " took " |
+ + String.valueOf(tock - tick) + "ms"); |
+ } |
+ |
+ /** |
+ * Asynchronously pre-faults the pages from the native library. |
+ * |
+ * @param context The application context |
+ */ |
+ public void asyncPrefaultLibraries(final Context context) { |
+ new AsyncTask<Void, Void, Void>() { |
+ @Override |
+ protected Void doInBackground(Void... params) { |
+ for (String library : NativeLibraries.LIBRARIES) { |
+ if (Linker.isChromiumLinkerLibrary(library)) { |
+ continue; |
+ } |
+ prefaultLibrary(context, library); |
+ } |
+ return null; |
+ } |
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
} |
/** |
@@ -261,6 +315,7 @@ public class LibraryLoader { |
? "using no map executable support fallback" |
: "directly") |
+ " from within " + apkFilePath); |
+ mLoadedFrom.put(library, apkFilePath); |
} else { |
// Unpack library fallback. |
Log.i(TAG, "Loading " + library |
@@ -270,10 +325,14 @@ public class LibraryLoader { |
context, library); |
fallbackWasUsed = true; |
Log.i(TAG, "Built fallback library " + libFilePath); |
+ mLoadedFrom.put(library, libFilePath); |
} |
} else { |
// The library is in its own file. |
Log.i(TAG, "Loading " + library); |
+ final ApplicationInfo applicationInfo = context.getApplicationInfo(); |
+ mLoadedFrom.put(library, new File(applicationInfo.nativeLibraryDir, |
+ libFilePath).getAbsolutePath()); |
} |
// Load the library. |