Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e09e976d authored by Ben Murdoch's avatar Ben Murdoch
Browse files

Allow switching to the Chromium WebViewFactoryProvider at runtime.

Currently, WebViewFactory is hardcoded to always load
android.webkit.WebViewClassic$Factory.  This change allows us to
load the Chromium powered WebView by setting the
"webview.use_chromium" system propery to true.

Change-Id: Icebfc4d5c4a61230c5e5dccac1ec5eca59f650ac
parent 2bbc19dd
Loading
Loading
Loading
Loading
+42 −6
Original line number Diff line number Diff line
@@ -16,14 +16,23 @@

package android.webkit;

import android.os.Build;
import android.os.StrictMode;
import android.os.SystemProperties;
import android.util.Log;

import dalvik.system.PathClassLoader;

/**
 * Top level factory, used creating all the main WebView implementation classes.
 */
class WebViewFactory {
    // Default Provider factory class name.
    private static final String DEFAULT_WEB_VIEW_FACTORY = "android.webkit.WebViewClassic$Factory";
    // TODO: When the Chromium powered WebView is ready, it should be the default factory class.
    private static final String DEFAULT_WEBVIEW_FACTORY = "android.webkit.WebViewClassic$Factory";
    private static final String CHROMIUM_WEBVIEW_FACTORY =
            "com.android.webviewchromium.WebViewChromiumFactoryProvider";
    private static final String CHROMIUM_WEBVIEW_JAR = "/system/framework/webviewchromium.jar";

    private static final String LOGTAG = "WebViewFactory";

@@ -38,18 +47,45 @@ class WebViewFactory {
        // us honest and minimize usage of WebViewClassic internals when binding the proxy.
        if (sProviderInstance != null) return sProviderInstance;

        sProviderInstance = getFactoryByName(DEFAULT_WEB_VIEW_FACTORY);
        // For debug builds, we allow a system property to specify that we should use the
        // Chromium powered WebView. This enables us to switch between implementations
        // at runtime. For user (release) builds, don't allow this.
        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("webview.use_chromium", false)) {
            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
            try {
                sProviderInstance = loadChromiumProvider();
                if (DEBUG) Log.v(LOGTAG, "Loaded Chromium provider: " + sProviderInstance);
            } finally {
                StrictMode.setThreadPolicy(oldPolicy);
            }
        }

        if (sProviderInstance == null) {
            if (DEBUG) Log.v(LOGTAG, "Falling back to default provider: "
                    + DEFAULT_WEBVIEW_FACTORY);
            sProviderInstance = getFactoryByName(DEFAULT_WEBVIEW_FACTORY,
                    WebViewFactory.class.getClassLoader());
            if (sProviderInstance == null) {
                if (DEBUG) Log.v(LOGTAG, "Falling back to explicit linkage");
                sProviderInstance = new WebViewClassic.Factory();
            }
        }
        return sProviderInstance;
    }

    private static WebViewFactoryProvider getFactoryByName(String providerName) {
    // TODO: This allows us to have the legacy and Chromium WebView coexist for development
    // and side-by-side testing. After transition, remove this when no longer required.
    private static WebViewFactoryProvider loadChromiumProvider() {
        ClassLoader clazzLoader = new PathClassLoader(CHROMIUM_WEBVIEW_JAR, null,
                WebViewFactory.class.getClassLoader());
        return getFactoryByName(CHROMIUM_WEBVIEW_FACTORY, clazzLoader);
    }

    private static WebViewFactoryProvider getFactoryByName(String providerName,
            ClassLoader loader) {
        try {
            if (DEBUG) Log.v(LOGTAG, "attempt to load class " + providerName);
            Class<?> c = Class.forName(providerName);
            Class<?> c = Class.forName(providerName, true, loader);
            if (DEBUG) Log.v(LOGTAG, "instantiating factory");
            return (WebViewFactoryProvider) c.newInstance();
        } catch (ClassNotFoundException e) {