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 97afbea788877ac640dbef61857c71b9c045bed2..28c688dae29c0654db4da036ee202c97a015bc89 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 |
@@ -55,17 +55,17 @@ public class LibraryLoader { |
private static boolean sIsUsingBrowserSharedRelros = false; |
private static boolean sLoadAtFixedAddressFailed = false; |
- // 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 device supports memory mapping the |
+ // APK file with executable permissions. |
+ private static boolean sMapApkWithExecPermission = 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 |
- // directly from the APK file but it was not aligned. |
- private static boolean sLibraryWasAlignedInApk = true; |
+ // directly from the APK file but it was compressed or not aligned. |
+ private static boolean sLibraryIsMappableInApk = true; |
// One-way switch becomes true if the system library loading failed, |
// and the right native library was found and loaded by the hack. |
@@ -176,12 +176,20 @@ public class LibraryLoader { |
if (useChromiumLinker) { |
String apkFilePath = null; |
+ boolean useMapExecSupportFallback = false; |
- // Check if the device supports loading a library directly from the APK file. |
+ // Check if the device supports memory mapping the APK file |
+ // with executable permissions. |
if (context != null) { |
apkFilePath = context.getApplicationInfo().sourceDir; |
- sLibraryLoadFromApkSupported = Linker.checkLibraryLoadFromApkSupport( |
- apkFilePath); |
+ sMapApkWithExecPermission = Linker.checkMapExecSupport(apkFilePath); |
+ if (!sMapApkWithExecPermission && Linker.isInZipFile()) { |
+ Log.w(TAG, "the no map executable support fallback will be used because" |
+ + " memory mapping the APK file with executable permissions is" |
+ + " not supported"); |
+ Linker.enableNoMapExecSupportFallback(); |
+ useMapExecSupportFallback = true; |
+ } |
} else { |
Log.w(TAG, "could not check load from APK support due to null context"); |
} |
@@ -203,18 +211,22 @@ public class LibraryLoader { |
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 (!Linker.checkLibraryIsMappableInApk(apkFilePath, libFilePath)) { |
+ sLibraryIsMappableInApk = 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); |
+ if (sLibraryIsMappableInApk || useMapExecSupportFallback) { |
+ // Load directly from the APK (or use the no map executable |
+ // support fallback, see crazy_linker_elf_loader.cpp). |
zipFilePath = apkFilePath; |
+ Log.i(TAG, "Loading " + library + " " |
+ + (useMapExecSupportFallback |
+ ? "using no map executable support fallback" |
+ : "directly") |
+ + " from within " + apkFilePath); |
} else { |
- // Fallback. |
- Log.i(TAG, "Loading " + library + " using fallback from within " |
+ // Unpack library fallback. |
+ Log.i(TAG, "Loading " + library |
+ + " using unpack library fallback from within " |
+ apkFilePath); |
libFilePath = LibraryLoaderHelper.buildFallbackLibrary( |
context, library); |
@@ -299,10 +311,10 @@ 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) { |
+ Linker.loadLibrary(zipFilePath, libFilePath); |
if (zipFilePath != null) { |
sLibraryWasLoadedFromApk = true; |
} |
- Linker.loadLibrary(zipFilePath, libFilePath); |
} |
// The WebView requires the Command Line to be switched over before |
@@ -380,11 +392,13 @@ public class LibraryLoader { |
assert Linker.isUsed(); |
if (sLibraryWasLoadedFromApk) { |
- return LibraryLoadFromApkStatusCodes.SUCCESSFUL; |
+ return sMapApkWithExecPermission |
+ ? LibraryLoadFromApkStatusCodes.SUCCESSFUL |
+ : LibraryLoadFromApkStatusCodes.USED_NO_MAP_EXEC_SUPPORT_FALLBACK; |
} |
- if (!sLibraryWasAlignedInApk) { |
- return LibraryLoadFromApkStatusCodes.NOT_ALIGNED; |
+ if (!sLibraryIsMappableInApk) { |
+ return LibraryLoadFromApkStatusCodes.USED_UNPACK_LIBRARY_FALLBACK; |
} |
if (context == null) { |
@@ -392,7 +406,7 @@ public class LibraryLoader { |
return LibraryLoadFromApkStatusCodes.UNKNOWN; |
} |
- return Linker.checkLibraryLoadFromApkSupport(context.getApplicationInfo().sourceDir) |
+ return sMapApkWithExecPermission |
? LibraryLoadFromApkStatusCodes.SUPPORTED |
: LibraryLoadFromApkStatusCodes.NOT_SUPPORTED; |
} |