1616
1717package android .webkit ;
1818
19+ import android .os .Build ;
20+ import android .os .StrictMode ;
21+ import android .os .SystemProperties ;
1922import android .util .Log ;
2023
24+ import dalvik .system .PathClassLoader ;
25+
2126/**
2227 * Top level factory, used creating all the main WebView implementation classes.
2328 */
2429class WebViewFactory {
2530 // Default Provider factory class name.
26- private static final String DEFAULT_WEB_VIEW_FACTORY = "android.webkit.WebViewClassic$Factory" ;
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" ;
2736
2837 private static final String LOGTAG = "WebViewFactory" ;
2938
@@ -38,18 +47,45 @@ static synchronized WebViewFactoryProvider getProvider() {
3847 // us honest and minimize usage of WebViewClassic internals when binding the proxy.
3948 if (sProviderInstance != null ) return sProviderInstance ;
4049
41- sProviderInstance = getFactoryByName (DEFAULT_WEB_VIEW_FACTORY );
50+ // For debug builds, we allow a system property to specify that we should use the
51+ // Chromium powered WebView. This enables us to switch between implementations
52+ // at runtime. For user (release) builds, don't allow this.
53+ if (Build .IS_DEBUGGABLE && SystemProperties .getBoolean ("webview.use_chromium" , false )) {
54+ StrictMode .ThreadPolicy oldPolicy = StrictMode .allowThreadDiskReads ();
55+ try {
56+ sProviderInstance = loadChromiumProvider ();
57+ if (DEBUG ) Log .v (LOGTAG , "Loaded Chromium provider: " + sProviderInstance );
58+ } finally {
59+ StrictMode .setThreadPolicy (oldPolicy );
60+ }
61+ }
62+
4263 if (sProviderInstance == null ) {
43- if (DEBUG ) Log .v (LOGTAG , "Falling back to explicit linkage" );
44- sProviderInstance = new WebViewClassic .Factory ();
64+ if (DEBUG ) Log .v (LOGTAG , "Falling back to default provider: "
65+ + DEFAULT_WEBVIEW_FACTORY );
66+ sProviderInstance = getFactoryByName (DEFAULT_WEBVIEW_FACTORY ,
67+ WebViewFactory .class .getClassLoader ());
68+ if (sProviderInstance == null ) {
69+ if (DEBUG ) Log .v (LOGTAG , "Falling back to explicit linkage" );
70+ sProviderInstance = new WebViewClassic .Factory ();
71+ }
4572 }
4673 return sProviderInstance ;
4774 }
4875
49- private static WebViewFactoryProvider getFactoryByName (String providerName ) {
76+ // TODO: This allows us to have the legacy and Chromium WebView coexist for development
77+ // and side-by-side testing. After transition, remove this when no longer required.
78+ private static WebViewFactoryProvider loadChromiumProvider () {
79+ ClassLoader clazzLoader = new PathClassLoader (CHROMIUM_WEBVIEW_JAR , null ,
80+ WebViewFactory .class .getClassLoader ());
81+ return getFactoryByName (CHROMIUM_WEBVIEW_FACTORY , clazzLoader );
82+ }
83+
84+ private static WebViewFactoryProvider getFactoryByName (String providerName ,
85+ ClassLoader loader ) {
5086 try {
5187 if (DEBUG ) Log .v (LOGTAG , "attempt to load class " + providerName );
52- Class <?> c = Class .forName (providerName );
88+ Class <?> c = Class .forName (providerName , true , loader );
5389 if (DEBUG ) Log .v (LOGTAG , "instantiating factory" );
5490 return (WebViewFactoryProvider ) c .newInstance ();
5591 } catch (ClassNotFoundException e ) {
0 commit comments