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..94d9be575845a4cf3e0528c738ca628a82bb424c 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,29 @@ 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. |
| + public static boolean sNativeLibraryHackWasUsed = false; |
|
Yaron
2014/03/20 18:34:47
Does this still need to be public?
|
| + |
| /** |
| * 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() throws ProcessInitException { |
| + 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 +87,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 +108,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 +124,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( |
| + context, library, useNativeLibraryHack)) { |
| + sNativeLibraryHackWasUsed = true; |
| + } else { |
| + throw e; |
| + } |
| + } |
| } |
| } |
| if (useChromiumLinker) Linker.finishLibraryLoad(); |
| @@ -154,6 +184,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 +206,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); |
| } |