Commit 8d51324a authored by Clark DuVall's avatar Clark DuVall Committed by Commit Bot

[WebLayer] Fix crash when loading native libraries in Android N

This effectively reverts https://crrev.com/c/2200082, which optimized
memory usage by re-creating the WebLayer context without INCLUDE_CODE.
This unfortunately leads to a bug where the library path is no longer
correct, and WebLayer cannot find the native libs.

For more info, see the discussion on https://crrev.com/c/2333305.

Bug: 1111508, 1061512
Change-Id: Ia17654bc760ec7f2fc7e3d25e323643de26151fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2335500
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#794262}
parent daead07c
...@@ -576,13 +576,6 @@ public class WebLayer { ...@@ -576,13 +576,6 @@ public class WebLayer {
return getWebLayerLoader(appContext).getIWebLayer(appContext); return getWebLayerLoader(appContext).getIWebLayer(appContext);
} }
/**
* Forces setting the cached remote context.
*/
static void setRemoteContext(Context remoteContext) {
sRemoteContext = remoteContext;
}
/** /**
* Creates a ClassLoader for the remote (weblayer implementation) side. * Creates a ClassLoader for the remote (weblayer implementation) side.
*/ */
......
...@@ -29,31 +29,15 @@ final class WebViewCompatibilityHelper { ...@@ -29,31 +29,15 @@ final class WebViewCompatibilityHelper {
appContext.getPackageManager().getPackageInfo(remoteContext.getPackageName(), appContext.getPackageManager().getPackageInfo(remoteContext.getPackageName(),
PackageManager.GET_SHARED_LIBRARY_FILES PackageManager.GET_SHARED_LIBRARY_FILES
| PackageManager.MATCH_UNINSTALLED_PACKAGES); | PackageManager.MATCH_UNINSTALLED_PACKAGES);
String[] libraryPaths = getLibraryPaths(remoteContext.getClassLoader());
if (parseMajorVersion(info.versionName) >= 84) {
// Recreate the context without code to avoid wasting memory by accidentally using the
// class loader.
remoteContext = appContext.createPackageContext(
remoteContext.getPackageName(), Context.CONTEXT_IGNORE_SECURITY);
WebLayer.setRemoteContext(remoteContext);
}
// Prepend "/." to all library paths. This changes the library path while still pointing to // Prepend "/." to all library paths. This changes the library path while still pointing to
// the same directory, allowing us to get around a check in the JVM. This is only necessary // the same directory, allowing us to get around a check in the JVM. This is only necessary
// for N+, where we rely on linker namespaces. // for N+, where we rely on linker namespaces.
String[] libraryPaths;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
// Even if the context was recreated without code above, on N+ the library path list
// still contains the necessary paths to load WebLayer.
libraryPaths = getLibraryPaths(remoteContext.getClassLoader());
for (int i = 0; i < libraryPaths.length; i++) { for (int i = 0; i < libraryPaths.length; i++) {
assert libraryPaths[i].startsWith("/"); assert libraryPaths[i].startsWith("/");
libraryPaths[i] = "/." + libraryPaths[i]; libraryPaths[i] = "/." + libraryPaths[i];
} }
} else {
// Android M- only need the native lib dir, since standalone WebView stores native libs
// compressed and they get extracted here. Standalone WebView also doesn't depend on any
// shared library APKs like Trichrome WebView.
libraryPaths = new String[] {info.applicationInfo.nativeLibraryDir};
} }
String dexPath = getAllApkPaths(info.applicationInfo); String dexPath = getAllApkPaths(info.applicationInfo);
...@@ -81,22 +65,6 @@ final class WebViewCompatibilityHelper { ...@@ -81,22 +65,6 @@ final class WebViewCompatibilityHelper {
} }
} }
/** Parses the version name into an integer version number. */
static int parseMajorVersion(String versionName) {
if (versionName == null) {
return -1;
}
String[] parts = versionName.split("\\.", -1);
if (parts.length < 4) {
return -1;
}
try {
return Integer.parseInt(parts[0]);
} catch (NumberFormatException e) {
return -1;
}
}
/** Returns the library paths the given class loader will search. */ /** Returns the library paths the given class loader will search. */
static String[] getLibraryPaths(ClassLoader classLoader) throws ReflectiveOperationException { static String[] getLibraryPaths(ClassLoader classLoader) throws ReflectiveOperationException {
// This seems to be the best way to reliably get both the native lib directory and the path // This seems to be the best way to reliably get both the native lib directory and the path
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment