Merge changes I7ce670f5,I0bd2de38
* changes:
Preload with RELRO sharing in the WebView zygote.
Make WebViewLibraryLoader interface more flexible.
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 57418c8..ca4c796 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -493,11 +493,12 @@
* Instructs the zygote to pre-load the classes and native libraries at the given paths
* for the specified abi. Not all zygotes support this function.
*/
- public boolean preloadPackageForAbi(String packagePath, String libsPath, String cacheKey,
- String abi) throws ZygoteStartFailedEx, IOException {
+ public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName,
+ String cacheKey, String abi) throws ZygoteStartFailedEx,
+ IOException {
synchronized(mLock) {
ZygoteState state = openZygoteSocketIfNeeded(abi);
- state.writer.write("4");
+ state.writer.write("5");
state.writer.newLine();
state.writer.write("--preload-package");
@@ -509,6 +510,9 @@
state.writer.write(libsPath);
state.writer.newLine();
+ state.writer.write(libFileName);
+ state.writer.newLine();
+
state.writer.write(cacheKey);
state.writer.newLine();
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index e9fe481..e0ccda9 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -205,25 +205,21 @@
}
PackageManager packageManager = AppGlobals.getInitialApplication().getPackageManager();
- PackageInfo packageInfo;
+ String libraryFileName;
try {
- packageInfo = packageManager.getPackageInfo(packageName,
+ PackageInfo packageInfo = packageManager.getPackageInfo(packageName,
PackageManager.GET_META_DATA | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
+ libraryFileName = getWebViewLibrary(packageInfo.applicationInfo);
} catch (PackageManager.NameNotFoundException e) {
Log.e(LOGTAG, "Couldn't find package " + packageName);
return LIBLOAD_WRONG_PACKAGE_NAME;
}
- try {
- int loadNativeRet = WebViewLibraryLoader.loadNativeLibrary(clazzLoader, packageInfo);
- // If we failed waiting for relro we want to return that fact even if we successfully
- // load the relro file.
- if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
- return loadNativeRet;
- } catch (MissingWebViewPackageException e) {
- Log.e(LOGTAG, "Couldn't load native library: " + e);
- return LIBLOAD_FAILED_TO_LOAD_LIBRARY;
- }
+ int loadNativeRet = WebViewLibraryLoader.loadNativeLibrary(clazzLoader, libraryFileName);
+ // If we failed waiting for relro we want to return that fact even if we successfully
+ // load the relro file.
+ if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
+ return loadNativeRet;
}
static WebViewFactoryProvider getProvider() {
@@ -454,7 +450,8 @@
ClassLoader clazzLoader = webViewContext.getClassLoader();
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()");
- WebViewLibraryLoader.loadNativeLibrary(clazzLoader, sPackageInfo);
+ WebViewLibraryLoader.loadNativeLibrary(clazzLoader,
+ getWebViewLibrary(sPackageInfo.applicationInfo));
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
diff --git a/core/java/android/webkit/WebViewLibraryLoader.java b/core/java/android/webkit/WebViewLibraryLoader.java
index eb2b6bc..cabba06 100644
--- a/core/java/android/webkit/WebViewLibraryLoader.java
+++ b/core/java/android/webkit/WebViewLibraryLoader.java
@@ -234,17 +234,14 @@
* <p class="note"><b>Note:</b> Assumes that we have waited for relro creation.
*
* @param clazzLoader class loader used to find the linker namespace to load the library into.
- * @param packageInfo the package from which WebView is loaded.
+ * @param libraryFileName the filename of the library to load.
*/
- static int loadNativeLibrary(ClassLoader clazzLoader, PackageInfo packageInfo)
- throws WebViewFactory.MissingWebViewPackageException {
+ public static int loadNativeLibrary(ClassLoader clazzLoader, String libraryFileName) {
if (!sAddressSpaceReserved) {
Log.e(LOGTAG, "can't load with relro file; address space not reserved");
return WebViewFactory.LIBLOAD_ADDRESS_SPACE_NOT_RESERVED;
}
- final String libraryFileName =
- WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo);
String relroPath = VMRuntime.getRuntime().is64Bit() ? CHROMIUM_WEBVIEW_NATIVE_RELRO_64 :
CHROMIUM_WEBVIEW_NATIVE_RELRO_32;
int result = nativeLoadWithRelroFile(libraryFileName, relroPath, clazzLoader);
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index 63fbef3..4167ad4 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -169,6 +169,8 @@
final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
TextUtils.join(File.pathSeparator, zipPaths);
+ String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo);
+
// In the case where the ApplicationInfo has been modified by the stub WebView,
// we need to use the original ApplicationInfo to determine what the original classpath
// would have been to use as a cache key.
@@ -179,7 +181,7 @@
ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress());
Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
- sZygote.preloadPackageForAbi(zip, librarySearchPath, cacheKey,
+ sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey,
Build.SUPPORTED_ABIS[0]);
} catch (Exception e) {
Log.e(LOGTAG, "Error connecting to webview zygote", e);
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index 32b580c..9f2434e 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -27,6 +27,7 @@
import android.util.Log;
import android.webkit.WebViewFactory;
import android.webkit.WebViewFactoryProvider;
+import android.webkit.WebViewLibraryLoader;
import java.io.DataOutputStream;
import java.io.File;
@@ -71,7 +72,8 @@
}
@Override
- protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
+ protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName,
+ String cacheKey) {
Log.i(TAG, "Beginning package preload");
// Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that
// our children will reuse the same classloader instead of creating their own.
@@ -80,6 +82,10 @@
ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader(
packagePath, libsPath, cacheKey);
+ // Load the native library using WebViewLibraryLoader to share the RELRO data with other
+ // processes.
+ WebViewLibraryLoader.loadNativeLibrary(loader, libFileName);
+
// Add the APK to the Zygote's list of allowed files for children.
String[] packageList = TextUtils.split(packagePath, File.pathSeparator);
for (String packageEntry : packageList) {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index a32fb43..cd83c57 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -155,7 +155,7 @@
if (parsedArgs.preloadPackage != null) {
handlePreloadPackage(parsedArgs.preloadPackage, parsedArgs.preloadPackageLibs,
- parsedArgs.preloadPackageCacheKey);
+ parsedArgs.preloadPackageLibFileName, parsedArgs.preloadPackageCacheKey);
return null;
}
@@ -290,7 +290,8 @@
return mSocketOutStream;
}
- protected void handlePreloadPackage(String packagePath, String libsPath, String cacheKey) {
+ protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName,
+ String cacheKey) {
throw new RuntimeException("Zyogte does not support package preloading");
}
@@ -402,10 +403,24 @@
String appDataDir;
/**
- * Whether to preload a package, with the package path in the remainingArgs.
+ * The APK path of the package to preload, when using --preload-package.
*/
String preloadPackage;
+
+ /**
+ * The native library path of the package to preload, when using --preload-package.
+ */
String preloadPackageLibs;
+
+ /**
+ * The filename of the native library to preload, when using --preload-package.
+ */
+ String preloadPackageLibFileName;
+
+ /**
+ * The cache key under which to enter the preloaded package into the classloader cache,
+ * when using --preload-package.
+ */
String preloadPackageCacheKey;
/**
@@ -571,6 +586,7 @@
} else if (arg.equals("--preload-package")) {
preloadPackage = args[++curArg];
preloadPackageLibs = args[++curArg];
+ preloadPackageLibFileName = args[++curArg];
preloadPackageCacheKey = args[++curArg];
} else if (arg.equals("--preload-default")) {
preloadDefault = true;