WebViewChromiumFactoryProvider.java revision 8166110add693878f19ab0551c630a22caa2e30c
146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)/* 246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Copyright (C) 2012 The Android Open Source Project 346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * you may not use this file except in compliance with the License. 646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * You may obtain a copy of the License at 746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 1046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 1146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 1246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * See the License for the specific language governing permissions and 1446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * limitations under the License. 1546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 1646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 1746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)package com.android.webview.chromium; 1846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 1946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.ActivityThread; 2046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.Context; 21009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsenimport android.content.SharedPreferences; 2246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Looper; 2346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.CookieManager; 2446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.GeolocationPermissions; 2546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebIconDatabase; 2646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebStorage; 2746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebView; 2846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewDatabase; 2946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewFactoryProvider; 3046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewProvider; 3146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 32f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixonimport org.chromium.android_webview.AwBrowserProcess; 33a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport org.chromium.android_webview.AwContents; 34d5f17bbd8703a56ac084a64b1ce2f673f67bd72dKristian Monsenimport org.chromium.android_webview.AwCookieManager; 35009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsenimport org.chromium.android_webview.AwGeolocationPermissions; 3646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.base.PathService; 377b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixonimport org.chromium.base.ThreadUtils; 387b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixonimport org.chromium.content.app.LibraryLoader; 3946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentSettings; 4046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentViewStatics; 4146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ResourceExtractor; 4246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 4346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { 4446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 4546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private final Object mLock = new Object(); 4646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 47009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs"; 48009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen 4946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Initialization guarded by mLock. 50009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen private SharedPreferences mWebViewChromiumSharedPreferences; 51aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private Statics mStaticMethods; 52aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private GeolocationPermissionsAdapter mGeolocationPermissions; 53aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private CookieManagerAdapter mCookieManager; 54aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private WebIconDatabaseAdapter mWebIconDatabase; 55aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private WebStorageAdapter mWebStorage; 56aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private WebViewDatabaseAdapter mWebViewDatabase; 5746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 589aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon // Read/write protected by mLock. 599aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon private boolean mStarted; 60f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon 61f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon public WebViewChromiumFactoryProvider() { 62f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon // Load chromium library. 63f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon AwBrowserProcess.loadLibrary(); 64a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Load glue-layer support library. 65a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon System.loadLibrary("webviewchromium_plat_support"); 66f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon } 67f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon 68f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon private void initPlatSupportLibrary() { 699aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon DrawGLFunctor.setChromiumAwDrawGLFunction(AwContents.getAwDrawGLFunction()); 709aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon AwContents.setAwDrawSWFunctionTable(GraphicsUtils.getDrawSWFunctionTable()); 71a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 72a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 73f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon private void ensureChromiumStartedLocked() { 7446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) assert Thread.holdsLock(mLock); 7546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 769aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon if (mStarted) { 779aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon return; 789aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon } 793053d8bc3be48b0cbc6f33e1975c03a10ac303a5Jonathan Dixon 809aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon // We must post to the UI thread to cover the case that the user 819aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon // has invoked Chromium startup by using the (thread-safe) 829aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon // CookieManager rather than creating a WebView. 837b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon ThreadUtils.runOnUiThreadBlocking(new Runnable() { 847b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon @Override 857b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon public void run() { 869aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon // We don't need to extract any paks because for WebView, they are 879aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon // in the system image. 889aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon ResourceExtractor.setMandatoryPaksToExtract(""); 899aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon 90979b73ce2c37f98f70f482489b3977876ea2e6faKristian Monsen try { 91979b73ce2c37f98f70f482489b3977876ea2e6faKristian Monsen LibraryLoader.ensureInitialized(); 9210e88eb5c30d54aa9dbc588a84fb04a2b5fedb7cKristian Monsen } catch(Exception e) { 93979b73ce2c37f98f70f482489b3977876ea2e6faKristian Monsen // TODO: handle the exception 94979b73ce2c37f98f70f482489b3977876ea2e6faKristian Monsen } 957b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon 967b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon PathService.override(PathService.DIR_MODULE, "/system/lib/"); 977b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon // TODO: DIR_RESOURCE_PAKS_ANDROID needs to live somewhere sensible, 987b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon // inlined here for simplicity setting up the HTMLViewer demo. Unfortunately 997b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon // it can't go into base.PathService, as the native constant it refers to 1007b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon // lives in the ui/ layer. See ui/base/ui_base_paths.h 1017b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon final int DIR_RESOURCE_PAKS_ANDROID = 3003; 1027b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon PathService.override(DIR_RESOURCE_PAKS_ANDROID, 1037b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon "/system/framework/webview/paks"); 1047b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon 1057b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon // Caching for later use, possibly from other threads 1067b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon mWebViewChromiumSharedPreferences = ActivityThread.currentApplication(). 1077b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon getSharedPreferences(CHROMIUM_PREFS_NAME, Context.MODE_PRIVATE); 1087b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon 109f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon AwBrowserProcess.start(ActivityThread.currentApplication()); 1109aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon 111f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon initPlatSupportLibrary(); 1127b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon } 1137b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon }); 1149aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon mStarted = true; 11546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 11646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 11746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 11846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public Statics getStatics() { 11946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 12046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mStaticMethods == null) { 1219aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon // TODO: Optimization potential: most these methods only need the native library 122f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon // loaded and initialized, not the entire browser process started. 123f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon // See also http://b/7009882 1249aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon ensureChromiumStartedLocked(); 12546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStaticMethods = new WebViewFactoryProvider.Statics() { 12646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 12746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String findAddress(String addr) { 12846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return ContentViewStatics.findAddress(addr); 12946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 13046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 13146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 13246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void setPlatformNotificationsEnabled(boolean enable) { 13346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // noop 13446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 13546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 136f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon @Override 13746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String getDefaultUserAgent(Context context) { 13846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return ContentSettings.getDefaultUserAgent(); 13946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) }; 14146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return mStaticMethods; 14446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 14646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 14746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) { 14846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) assert Looper.myLooper() == Looper.getMainLooper(); 14946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 150f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon ensureChromiumStartedLocked(); 15146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) ResourceProvider.registerResources(webView.getContext()); 15246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 1538166110add693878f19ab0551c630a22caa2e30cKristian Monsen // Make sure GeolocationPermissions is created before creating a webview 1548166110add693878f19ab0551c630a22caa2e30cKristian Monsen getGeolocationPermissions(); 15546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return new WebViewChromium(webView, privateAccess); 15646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 15746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 15846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 15946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public GeolocationPermissions getGeolocationPermissions() { 160009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen synchronized (mLock) { 161aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mGeolocationPermissions == null) { 162f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon ensureChromiumStartedLocked(); 16350a184c1e058bc62f659fb80e09e7507ef13d6c9Jonathan Dixon mGeolocationPermissions = new GeolocationPermissionsAdapter( 164009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen new AwGeolocationPermissions(mWebViewChromiumSharedPreferences)); 165009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen } 166009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen } 1670df758101bdd74c264b69ca69a397088833b8cbbJonathan Dixon // TODO: return mGeolocationPermissions when http://b/7929330 is fixed. 1680df758101bdd74c264b69ca69a397088833b8cbbJonathan Dixon return null; 16946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 17046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 17146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 17246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public CookieManager getCookieManager() { 17346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 174aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mCookieManager == null) { 175f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon ensureChromiumStartedLocked(); 176d5f17bbd8703a56ac084a64b1ce2f673f67bd72dKristian Monsen mCookieManager = new CookieManagerAdapter(new AwCookieManager()); 17746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 17846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 179aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mCookieManager; 18046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 18146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 18246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 18346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebIconDatabase getWebIconDatabase() { 184aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon synchronized (mLock) { 185aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mWebIconDatabase == null) { 186f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon ensureChromiumStartedLocked(); 187aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon mWebIconDatabase = new WebIconDatabaseAdapter(); 188aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 189aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 190aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mWebIconDatabase; 19146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 19246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 19346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 19446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebStorage getWebStorage() { 195aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon synchronized (mLock) { 196aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mWebStorage == null) { 197f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon ensureChromiumStartedLocked(); 198aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon mWebStorage = new WebStorageAdapter(); 199aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 200aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 201aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mWebStorage; 20246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 20346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 20446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 20546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebViewDatabase getWebViewDatabase(Context context) { 20646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 207aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mWebViewDatabase == null) { 208f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon ensureChromiumStartedLocked(); 209e21ee6e79c57596d44737139b97c093167b58808Ben Murdoch mWebViewDatabase = new WebViewDatabaseAdapter(context); 210aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 21146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 212aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mWebViewDatabase; 21346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 21446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)} 215