summaryrefslogtreecommitdiffstats
path: root/core/java/android/webkit
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/webkit')
-rw-r--r--core/java/android/webkit/WebViewClassic.java14
-rw-r--r--core/java/android/webkit/WebViewFactory.java79
2 files changed, 58 insertions, 35 deletions
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index a324502..3afab09 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -66,6 +66,7 @@ import android.text.Editable;
import android.text.InputType;
import android.text.Selection;
import android.text.TextUtils;
+import android.util.AndroidRuntimeException;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -1293,6 +1294,19 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// WebViewProvider bindings
static class Factory implements WebViewFactoryProvider, WebViewFactoryProvider.Statics {
+ Factory() {
+ // Touch JniUtil and WebViewCore in case this is being called from
+ // WebViewFactory.Preloader, to ensure that the JNI libraries that they use are
+ // preloaded in the zygote.
+ try {
+ Class.forName("android.webkit.JniUtil");
+ Class.forName("android.webkit.WebViewCore");
+ } catch (ClassNotFoundException e) {
+ Log.e(LOGTAG, "failed to load JNI libraries");
+ throw new AndroidRuntimeException(e);
+ }
+ }
+
@Override
public String findAddress(String addr) {
return WebViewClassic.findAddress(addr);
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index ea5187a..2ee0961 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -19,10 +19,9 @@ package android.webkit;
import android.os.Build;
import android.os.StrictMode;
import android.os.SystemProperties;
+import android.util.AndroidRuntimeException;
import android.util.Log;
-import dalvik.system.PathClassLoader;
-
/**
* Top level factory, used creating all the main WebView implementation classes.
*
@@ -45,6 +44,17 @@ public final class WebViewFactory {
private static final boolean DEBUG = false;
+ private static class Preloader {
+ static WebViewFactoryProvider sPreloadedProvider;
+ static {
+ try {
+ sPreloadedProvider = getFactoryClass().newInstance();
+ } catch (Exception e) {
+ Log.w(LOGTAG, "error preloading provider", e);
+ }
+ }
+ }
+
// Cache the factory both for efficiency, and ensure any one process gets all webviews from the
// same provider.
private static WebViewFactoryProvider sProviderInstance;
@@ -67,32 +77,39 @@ public final class WebViewFactory {
// us honest and minimize usage of WebViewClassic internals when binding the proxy.
if (sProviderInstance != null) return sProviderInstance;
- if (isExperimentalWebViewEnabled()) {
- StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- try {
- sProviderInstance = getFactoryByName(CHROMIUM_WEBVIEW_FACTORY);
- if (DEBUG) Log.v(LOGTAG, "Loaded Chromium provider: " + sProviderInstance);
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
- }
+ Class<WebViewFactoryProvider> providerClass;
+ try {
+ providerClass = getFactoryClass();
+ } catch (ClassNotFoundException e) {
+ Log.e(LOGTAG, "error loading provider", e);
+ throw new AndroidRuntimeException(e);
}
- if (sProviderInstance == null) {
- if (DEBUG) Log.v(LOGTAG, "Falling back to default provider: "
- + DEFAULT_WEBVIEW_FACTORY);
- sProviderInstance = getFactoryByName(DEFAULT_WEBVIEW_FACTORY);
- if (sProviderInstance == null) {
- if (DEBUG) Log.v(LOGTAG, "Falling back to explicit linkage");
- sProviderInstance = new WebViewClassic.Factory();
- }
+ // This implicitly loads Preloader even if it wasn't preloaded at boot.
+ if (Preloader.sPreloadedProvider != null &&
+ Preloader.sPreloadedProvider.getClass() == providerClass) {
+ sProviderInstance = Preloader.sPreloadedProvider;
+ if (DEBUG) Log.v(LOGTAG, "Using preloaded provider: " + sProviderInstance);
+ return sProviderInstance;
+ }
+
+ // The preloaded provider isn't the one we wanted; construct our own.
+ StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+ try {
+ sProviderInstance = providerClass.newInstance();
+ if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
+ return sProviderInstance;
+ } catch (Exception e) {
+ Log.e(LOGTAG, "error instantiating provider", e);
+ throw new AndroidRuntimeException(e);
+ } finally {
+ StrictMode.setThreadPolicy(oldPolicy);
}
- return sProviderInstance;
}
}
- // For debug builds, we allow a system property to specify that we should use the
- // experimtanl Chromium powered WebView. This enables us to switch between
- // implementations at runtime. For user (release) builds, don't allow this.
+ // We allow a system property to specify that we should use the experimental Chromium powered
+ // WebView. This enables us to switch between implementations at runtime.
private static boolean isExperimentalWebViewEnabled() {
if (!isExperimentalWebViewAvailable()) return false;
boolean use_experimental_webview = SystemProperties.getBoolean(
@@ -108,19 +125,11 @@ public final class WebViewFactory {
return use_experimental_webview;
}
- private static WebViewFactoryProvider getFactoryByName(String providerName) {
- try {
- if (DEBUG) Log.v(LOGTAG, "attempt to load class " + providerName);
- Class<?> c = Class.forName(providerName);
- if (DEBUG) Log.v(LOGTAG, "instantiating factory");
- return (WebViewFactoryProvider) c.newInstance();
- } catch (ClassNotFoundException e) {
- Log.e(LOGTAG, "error loading " + providerName, e);
- } catch (IllegalAccessException e) {
- Log.e(LOGTAG, "error loading " + providerName, e);
- } catch (InstantiationException e) {
- Log.e(LOGTAG, "error loading " + providerName, e);
+ private static Class<WebViewFactoryProvider> getFactoryClass() throws ClassNotFoundException {
+ if (isExperimentalWebViewEnabled()) {
+ return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY);
+ } else {
+ return (Class<WebViewFactoryProvider>) Class.forName(DEFAULT_WEBVIEW_FACTORY);
}
- return null;
}
}