• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.webkit;
18 
19 import android.os.Build;
20 import android.os.StrictMode;
21 import android.os.SystemProperties;
22 import android.util.Log;
23 
24 import dalvik.system.PathClassLoader;
25 
26 /**
27  * Top level factory, used creating all the main WebView implementation classes.
28  */
29 class WebViewFactory {
30     // Default Provider factory class name.
31     // TODO: When the Chromium powered WebView is ready, it should be the default factory class.
32     private static final String DEFAULT_WEBVIEW_FACTORY = "android.webkit.WebViewClassic$Factory";
33     private static final String CHROMIUM_WEBVIEW_FACTORY =
34             "com.android.webviewchromium.WebViewChromiumFactoryProvider";
35     private static final String CHROMIUM_WEBVIEW_JAR = "/system/framework/webviewchromium.jar";
36 
37     private static final String LOGTAG = "WebViewFactory";
38 
39     private static final boolean DEBUG = false;
40 
41     // Cache the factory both for efficiency, and ensure any one process gets all webviews from the
42     // same provider.
43     private static WebViewFactoryProvider sProviderInstance;
44     private static final Object sProviderLock = new Object();
45 
getProvider()46     static WebViewFactoryProvider getProvider() {
47         synchronized (sProviderLock) {
48             // For now the main purpose of this function (and the factory abstraction) is to keep
49             // us honest and minimize usage of WebViewClassic internals when binding the proxy.
50             if (sProviderInstance != null) return sProviderInstance;
51 
52             // For debug builds, we allow a system property to specify that we should use the
53             // Chromium powered WebView. This enables us to switch between implementations
54             // at runtime. For user (release) builds, don't allow this.
55             if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("webview.use_chromium", false)) {
56                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
57                 try {
58                     sProviderInstance = loadChromiumProvider();
59                     if (DEBUG) Log.v(LOGTAG, "Loaded Chromium provider: " + sProviderInstance);
60                 } finally {
61                     StrictMode.setThreadPolicy(oldPolicy);
62                 }
63             }
64 
65             if (sProviderInstance == null) {
66                 if (DEBUG) Log.v(LOGTAG, "Falling back to default provider: "
67                         + DEFAULT_WEBVIEW_FACTORY);
68                 sProviderInstance = getFactoryByName(DEFAULT_WEBVIEW_FACTORY,
69                         WebViewFactory.class.getClassLoader());
70                 if (sProviderInstance == null) {
71                     if (DEBUG) Log.v(LOGTAG, "Falling back to explicit linkage");
72                     sProviderInstance = new WebViewClassic.Factory();
73                 }
74             }
75             return sProviderInstance;
76         }
77     }
78 
79     // TODO: This allows us to have the legacy and Chromium WebView coexist for development
80     // and side-by-side testing. After transition, remove this when no longer required.
loadChromiumProvider()81     private static WebViewFactoryProvider loadChromiumProvider() {
82         ClassLoader clazzLoader = new PathClassLoader(CHROMIUM_WEBVIEW_JAR, null,
83                 WebViewFactory.class.getClassLoader());
84         return getFactoryByName(CHROMIUM_WEBVIEW_FACTORY, clazzLoader);
85     }
86 
getFactoryByName(String providerName, ClassLoader loader)87     private static WebViewFactoryProvider getFactoryByName(String providerName,
88             ClassLoader loader) {
89         try {
90             if (DEBUG) Log.v(LOGTAG, "attempt to load class " + providerName);
91             Class<?> c = Class.forName(providerName, true, loader);
92             if (DEBUG) Log.v(LOGTAG, "instantiating factory");
93             return (WebViewFactoryProvider) c.newInstance();
94         } catch (ClassNotFoundException e) {
95             Log.e(LOGTAG, "error loading " + providerName, e);
96         } catch (IllegalAccessException e) {
97             Log.e(LOGTAG, "error loading " + providerName, e);
98         } catch (InstantiationException e) {
99             Log.e(LOGTAG, "error loading " + providerName, e);
100         }
101         return null;
102     }
103 }
104