summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/webkit/WebViewZygote.java56
-rw-r--r--core/java/com/android/internal/os/WebViewZygoteInit.java47
2 files changed, 69 insertions, 34 deletions
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index 3a1c4576ab3e..de1f3df61462 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -150,6 +150,7 @@ public class WebViewZygote {
}
try {
+ String abi = sPackage.applicationInfo.primaryCpuAbi;
sZygote = Process.ZYGOTE_PROCESS.startChildZygote(
"com.android.internal.os.WebViewZygoteInit",
"webview_zygote",
@@ -158,39 +159,40 @@ public class WebViewZygote {
null, // gids
0, // runtimeFlags
"webview_zygote", // seInfo
- sPackage.applicationInfo.primaryCpuAbi, // abi
+ abi, // abi
TextUtils.join(",", Build.SUPPORTED_ABIS),
null, // instructionSet
Process.FIRST_ISOLATED_UID,
Process.LAST_ISOLATED_UID);
-
- // All the work below is usually done by LoadedApk, but the zygote can't talk to
- // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so
- // doesn't have an ActivityThread and can't use Binder.
- // Instead, figure out the paths here, in the system server where we have access to
- // the package manager. Reuse the logic from LoadedApk to determine the correct
- // paths and pass them to the zygote as strings.
- final List<String> zipPaths = new ArrayList<>(10);
- final List<String> libPaths = new ArrayList<>(10);
- LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths);
- final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
- 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.
- LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null);
- final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) :
- TextUtils.join(File.pathSeparator, zipPaths);
-
ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress());
- Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
- sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey,
- Build.SUPPORTED_ABIS[0]);
+ if (sPackageOriginalAppInfo.sourceDir.equals(sPackage.applicationInfo.sourceDir)) {
+ // No stub WebView is involved here, so we can preload the package the "clean" way
+ // using the ApplicationInfo.
+ sZygote.preloadApp(sPackage.applicationInfo, abi);
+ } else {
+ // Legacy path to support the stub WebView.
+ // Reuse the logic from LoadedApk to determine the correct paths and pass them to
+ // the zygote as strings.
+ final List<String> zipPaths = new ArrayList<>(10);
+ final List<String> libPaths = new ArrayList<>(10);
+ LoadedApk.makePaths(null, false, sPackage.applicationInfo, zipPaths, libPaths);
+ final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
+ final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
+ TextUtils.join(File.pathSeparator, zipPaths);
+
+ String libFileName = WebViewFactory.getWebViewLibrary(sPackage.applicationInfo);
+
+ // Use the original ApplicationInfo to determine what the original classpath would
+ // have been to use as a cache key.
+ LoadedApk.makePaths(null, false, sPackageOriginalAppInfo, zipPaths, null);
+ final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) :
+ TextUtils.join(File.pathSeparator, zipPaths);
+
+ Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
+ sZygote.preloadPackageForAbi(zip, librarySearchPath, libFileName, cacheKey,
+ Build.SUPPORTED_ABIS[0]);
+ }
} catch (Exception e) {
Log.e(LOGTAG, "Error connecting to webview zygote", e);
stopZygoteLocked();
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index 0b329d70f7af..c8d30b27d4dc 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -17,8 +17,9 @@
package com.android.internal.os;
import android.app.ApplicationLoaders;
+import android.app.LoadedApk;
+import android.content.pm.ApplicationInfo;
import android.net.LocalSocket;
-import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebViewFactory;
@@ -66,6 +67,34 @@ class WebViewZygoteInit {
}
@Override
+ protected boolean canPreloadApp() {
+ return true;
+ }
+
+ @Override
+ protected void handlePreloadApp(ApplicationInfo appInfo) {
+ Log.i(TAG, "Beginning application preload for " + appInfo.packageName);
+ LoadedApk loadedApk = new LoadedApk(null, appInfo, null, null, false, true, false);
+ ClassLoader loader = loadedApk.getClassLoader();
+ doPreload(loader, WebViewFactory.getWebViewLibrary(appInfo));
+
+ // Add the APK to the Zygote's list of allowed files for children.
+ Zygote.nativeAllowFileAcrossFork(appInfo.sourceDir);
+ if (appInfo.splitSourceDirs != null) {
+ for (String path : appInfo.splitSourceDirs) {
+ Zygote.nativeAllowFileAcrossFork(path);
+ }
+ }
+ if (appInfo.sharedLibraryFiles != null) {
+ for (String path : appInfo.sharedLibraryFiles) {
+ Zygote.nativeAllowFileAcrossFork(path);
+ }
+ }
+
+ Log.i(TAG, "Application preload done");
+ }
+
+ @Override
protected void handlePreloadPackage(String packagePath, String libsPath, String libFileName,
String cacheKey) {
Log.i(TAG, "Beginning package preload");
@@ -76,16 +105,22 @@ class WebViewZygoteInit {
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) {
Zygote.nativeAllowFileAcrossFork(packageEntry);
}
+ doPreload(loader, libFileName);
+
+ Log.i(TAG, "Package preload done");
+ }
+
+ private void doPreload(ClassLoader loader, String libFileName) {
+ // Load the native library using WebViewLibraryLoader to share the RELRO data with other
+ // processes.
+ WebViewLibraryLoader.loadNativeLibrary(loader, libFileName);
+
// Once we have the classloader, look up the WebViewFactoryProvider implementation and
// call preloadInZygote() on it to give it the opportunity to preload the native library
// and perform any other initialisation work that should be shared among the children.
@@ -114,8 +149,6 @@ class WebViewZygoteInit {
} catch (IOException ioe) {
throw new IllegalStateException("Error writing to command socket", ioe);
}
-
- Log.i(TAG, "Package preload done");
}
}