Chromium Code Reviews| 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 4e159553d725d095b593ef8fe911264250873ba6..d649826fcf3d08393ebf38f0b040cc8734e8c326 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 |
| @@ -4,6 +4,7 @@ |
| package org.chromium.base.library_loader; |
| +import android.content.Context; |
| import android.os.SystemClock; |
| import android.util.Log; |
| @@ -41,16 +42,39 @@ public class LibraryLoader { |
| // library_loader_hooks.cc). |
| private static boolean sInitialized = false; |
| + // One-way switch becomes true if the system library loading failed, |
| + // and the right native library was found and loaded by the hack. |
| + // The flag is used to report UMA stats later. |
| + private static boolean sNativeLibraryHackWasUsed = false; |
| + |
| + |
| /** |
| - * This method blocks until the library is fully loaded and initialized. |
| + * TODO: http://crbug.com/354655 |
| + * remove this function once WebViewChromiumFactoryProvider.java |
| + * fixes the call to this method. |
| */ |
| public static void ensureInitialized() throws ProcessInitException { |
| + ensureInitialized(null, false); |
| + } |
| + |
| + /** |
| + * This method blocks until the library is fully loaded and initialized. |
| + * |
| + * @param context The context in which the method is called |
| + * @param shouldApplyNativeLibraryHack When true and a native library |
| + * was not extracted by Android package manager, the LibraryLoader class |
| + * will extract the native libraries from APK. This is a hack used to |
| + * work around some Sony devices with the following platform bug: |
| + * http://b/13216167. |
| + */ |
| + public static void ensureInitialized(Context context, boolean useNativeLibraryHack) |
| + throws ProcessInitException { |
| synchronized (sLock) { |
| if (sInitialized) { |
| // Already initialized, nothing to do. |
| return; |
| } |
| - loadAlreadyLocked(); |
| + loadAlreadyLocked(context, useNativeLibraryHack); |
| initializeAlreadyLocked(CommandLine.getJavaSwitchesOrNull()); |
| } |
| } |
| @@ -73,9 +97,10 @@ public class LibraryLoader { |
| * |
| * @throws ProcessInitException if the native library failed to load. |
| */ |
| - public static void loadNow() throws ProcessInitException { |
| + public static void loadNow(Context context, boolean useNativeLibraryHack) |
| + throws ProcessInitException { |
| synchronized (sLock) { |
| - loadAlreadyLocked(); |
| + loadAlreadyLocked(context, useNativeLibraryHack); |
| } |
| } |
| @@ -93,7 +118,8 @@ public class LibraryLoader { |
| } |
| // Invoke System.loadLibrary(...), triggering JNI_OnLoad in native code |
| - private static void loadAlreadyLocked() throws ProcessInitException { |
| + private static void loadAlreadyLocked(Context context, boolean useNativeLibraryHack) |
| + throws ProcessInitException { |
| try { |
| if (!sLoaded) { |
| assert !sInitialized; |
| @@ -108,7 +134,21 @@ public class LibraryLoader { |
| if (useChromiumLinker) { |
| Linker.loadLibrary(library); |
| } else { |
| - System.loadLibrary(library); |
| + try { |
| + System.loadLibrary(library); |
| + if (useNativeLibraryHack) { |
| + LibraryLoaderHelper.deleteWorkaroundLibrariesAsynchronously( |
| + context); |
| + } |
| + } catch (UnsatisfiedLinkError e) { |
| + // Try to load from backup directory. |
| + if (LibraryLoaderHelper.tryLoadLibraryUsingWorkaround( |
|
boliu
2014/03/20 23:27:12
Hmm, this will NPE with null context, but I guess
|
| + context, library, useNativeLibraryHack)) { |
| + sNativeLibraryHackWasUsed = true; |
| + } else { |
| + throw e; |
| + } |
| + } |
| } |
| } |
| if (useChromiumLinker) Linker.finishLibraryLoad(); |
| @@ -154,6 +194,8 @@ public class LibraryLoader { |
| nativeRecordChromiumAndroidLinkerHistogram(Linker.loadAtFixedAddressFailed(), |
| SysUtils.isLowEndDevice()); |
| } |
| + |
| + nativeRecordNativeLibraryHack(sNativeLibraryHackWasUsed); |
| } |
| // Only methods needed before or during normal JNI registration are during System.OnLoad. |
| @@ -174,4 +216,6 @@ public class LibraryLoader { |
| // Get the version of the native library. This is needed so that we can check we |
| // have the right version before initializing the (rest of the) JNI. |
| private static native String nativeGetVersionNumber(); |
| + |
| + private static native void nativeRecordNativeLibraryHack(boolean usedHack); |
| } |