| 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 e4290267998e16f2cdd0d215ffea22617b94030b..97afbea788877ac640dbef61857c71b9c045bed2 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
|
| @@ -12,6 +12,8 @@ import org.chromium.base.CommandLine;
|
| import org.chromium.base.JNINamespace;
|
| import org.chromium.base.TraceEvent;
|
|
|
| +import javax.annotation.Nullable;
|
| +
|
| /**
|
| * This class provides functionality to load and register the native libraries.
|
| * Callers are allowed to separate loading the libraries from initializing them.
|
| @@ -53,8 +55,12 @@ public class LibraryLoader {
|
| private static boolean sIsUsingBrowserSharedRelros = false;
|
| private static boolean sLoadAtFixedAddressFailed = false;
|
|
|
| - // One-way switch becomes true if the library was loaded from the APK file
|
| - // directly.
|
| + // One-way switch becomes true if the device supports loading the Chromium
|
| + // library directly from the APK.
|
| + private static boolean sLibraryLoadFromApkSupported = false;
|
| +
|
| + // One-way switch becomes true if the Chromium library was loaded from the
|
| + // APK file directly.
|
| private static boolean sLibraryWasLoadedFromApk = false;
|
|
|
| // One-way switch becomes false if the Chromium library should be loaded
|
| @@ -91,7 +97,7 @@ public class LibraryLoader {
|
| * http://b/13216167.
|
| *
|
| * @param shouldDeleteOldWorkaroundLibraries The flag tells whether the method
|
| - * should delete the old workaround libraries or not.
|
| + * should delete the old workaround and fallback libraries or not.
|
| */
|
| public static void ensureInitialized(
|
| Context context, boolean shouldDeleteOldWorkaroundLibraries)
|
| @@ -134,7 +140,7 @@ public class LibraryLoader {
|
| *
|
| * @param context The context the code is running, or null if it doesn't have one.
|
| * @param shouldDeleteOldWorkaroundLibraries The flag tells whether the method
|
| - * should delete the old workaround libraries or not.
|
| + * should delete the old workaround and fallback libraries or not.
|
| *
|
| * @throws ProcessInitException if the native library failed to load.
|
| */
|
| @@ -166,8 +172,20 @@ public class LibraryLoader {
|
|
|
| long startTime = SystemClock.uptimeMillis();
|
| boolean useChromiumLinker = Linker.isUsed();
|
| + boolean fallbackWasUsed = false;
|
|
|
| if (useChromiumLinker) {
|
| + String apkFilePath = null;
|
| +
|
| + // Check if the device supports loading a library directly from the APK file.
|
| + if (context != null) {
|
| + apkFilePath = context.getApplicationInfo().sourceDir;
|
| + sLibraryLoadFromApkSupported = Linker.checkLibraryLoadFromApkSupport(
|
| + apkFilePath);
|
| + } else {
|
| + Log.w(TAG, "could not check load from APK support due to null context");
|
| + }
|
| +
|
| // Load libraries using the Chromium linker.
|
| Linker.prepareLibraryLoad();
|
|
|
| @@ -180,26 +198,40 @@ public class LibraryLoader {
|
| continue;
|
| }
|
|
|
| - String zipfile = null;
|
| - if (Linker.isInZipFile()) {
|
| - zipfile = context.getApplicationInfo().sourceDir;
|
| - sLibraryWasAlignedInApk = Linker.checkLibraryAlignedInApk(
|
| - zipfile, System.mapLibraryName(library));
|
| - Log.i(TAG, "Loading " + library + " from within " + zipfile);
|
| + // Determine where the library should be loaded from.
|
| + String zipFilePath = null;
|
| + String libFilePath = System.mapLibraryName(library);
|
| + if (apkFilePath != null && Linker.isInZipFile()) {
|
| + // The library is in the APK file.
|
| + if (!Linker.checkLibraryAlignedInApk(apkFilePath, libFilePath)) {
|
| + sLibraryWasAlignedInApk = false;
|
| + }
|
| + if (!sLibraryLoadFromApkSupported || sLibraryWasAlignedInApk) {
|
| + // Load directly from the APK (or use memory fallback, see
|
| + // crazy_linker_elf_loader.cpp).
|
| + Log.i(TAG, "Loading " + library + " directly from within "
|
| + + apkFilePath);
|
| + zipFilePath = apkFilePath;
|
| + } else {
|
| + // Fallback.
|
| + Log.i(TAG, "Loading " + library + " using fallback from within "
|
| + + apkFilePath);
|
| + libFilePath = LibraryLoaderHelper.buildFallbackLibrary(
|
| + context, library);
|
| + fallbackWasUsed = true;
|
| + Log.i(TAG, "Built fallback library " + libFilePath);
|
| + }
|
| } else {
|
| - Log.i(TAG, "Loading: " + library);
|
| + // The library is in its own file.
|
| + Log.i(TAG, "Loading " + library);
|
| }
|
|
|
| + // Load the library.
|
| boolean isLoaded = false;
|
| if (Linker.isUsingBrowserSharedRelros()) {
|
| sIsUsingBrowserSharedRelros = true;
|
| try {
|
| - if (zipfile != null) {
|
| - Linker.loadLibraryInZipFile(zipfile, library);
|
| - sLibraryWasLoadedFromApk = true;
|
| - } else {
|
| - Linker.loadLibrary(library);
|
| - }
|
| + loadLibrary(zipFilePath, libFilePath);
|
| isLoaded = true;
|
| } catch (UnsatisfiedLinkError e) {
|
| Log.w(TAG, "Failed to load native library with shared RELRO, "
|
| @@ -209,12 +241,7 @@ public class LibraryLoader {
|
| }
|
| }
|
| if (!isLoaded) {
|
| - if (zipfile != null) {
|
| - Linker.loadLibraryInZipFile(zipfile, library);
|
| - sLibraryWasLoadedFromApk = true;
|
| - } else {
|
| - Linker.loadLibrary(library);
|
| - }
|
| + loadLibrary(zipFilePath, libFilePath);
|
| }
|
| }
|
|
|
| @@ -227,7 +254,7 @@ public class LibraryLoader {
|
| } catch (UnsatisfiedLinkError e) {
|
| if (context != null
|
| && LibraryLoaderHelper.tryLoadLibraryUsingWorkaround(context,
|
| - library)) {
|
| + library)) {
|
| sNativeLibraryHackWasUsed = true;
|
| } else {
|
| throw e;
|
| @@ -236,11 +263,15 @@ public class LibraryLoader {
|
| }
|
| }
|
|
|
| - if (context != null
|
| - && shouldDeleteOldWorkaroundLibraries
|
| - && !sNativeLibraryHackWasUsed) {
|
| - LibraryLoaderHelper.deleteWorkaroundLibrariesAsynchronously(
|
| - context);
|
| + if (context != null && shouldDeleteOldWorkaroundLibraries) {
|
| + if (!sNativeLibraryHackWasUsed) {
|
| + LibraryLoaderHelper.deleteLibrariesAsynchronously(
|
| + context, LibraryLoaderHelper.PACKAGE_MANAGER_WORKAROUND_DIR);
|
| + }
|
| + if (!fallbackWasUsed) {
|
| + LibraryLoaderHelper.deleteLibrariesAsynchronously(
|
| + context, LibraryLoaderHelper.LOAD_FROM_APK_FALLBACK_DIR);
|
| + }
|
| }
|
|
|
| long stopTime = SystemClock.uptimeMillis();
|
| @@ -265,6 +296,15 @@ public class LibraryLoader {
|
| }
|
| }
|
|
|
| + // Load a native shared library with the Chromium linker. If the zip file
|
| + // path is not null, the library is loaded directly from the zip file.
|
| + private static void loadLibrary(@Nullable String zipFilePath, String libFilePath) {
|
| + if (zipFilePath != null) {
|
| + sLibraryWasLoadedFromApk = true;
|
| + }
|
| + Linker.loadLibrary(zipFilePath, libFilePath);
|
| + }
|
| +
|
| // The WebView requires the Command Line to be switched over before
|
| // initialization is done. This is okay in the WebView's case since the
|
| // JNI is already loaded by this point.
|
|
|