diff options
Diffstat (limited to 'core/java/android/webkit')
-rw-r--r-- | core/java/android/webkit/WebViewClassic.java | 14 | ||||
-rw-r--r-- | core/java/android/webkit/WebViewFactory.java | 79 |
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; } } |