WebViewChromiumFactoryProvider.java revision 991b0c63bb8c0b0d8577a255b026117e9f37cece
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) 32a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport org.chromium.android_webview.AwContents; 33d5f17bbd8703a56ac084a64b1ce2f673f67bd72dKristian Monsenimport org.chromium.android_webview.AwCookieManager; 34009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsenimport org.chromium.android_webview.AwGeolocationPermissions; 3546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.base.PathService; 36e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liuimport org.chromium.base.PathUtils; 37e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liuimport org.chromium.base.ThreadUtils; 38e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liuimport org.chromium.content.app.LibraryLoader; 39e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liuimport org.chromium.content.browser.AndroidBrowserProcess; 4046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentSettings; 4146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentViewStatics; 4246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ResourceExtractor; 4346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 4446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { 4546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 4646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private final Object mLock = new Object(); 4746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 48009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs"; 49009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen 5046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Initialization guarded by mLock. 51009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen private SharedPreferences mWebViewChromiumSharedPreferences; 52aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private Statics mStaticMethods; 53aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private GeolocationPermissionsAdapter mGeolocationPermissions; 54aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private CookieManagerAdapter mCookieManager; 55aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private WebIconDatabaseAdapter mWebIconDatabase; 56aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private WebStorageAdapter mWebStorage; 57aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon private WebViewDatabaseAdapter mWebViewDatabase; 5846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 59e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // Initialization guarded by mLock. 60e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu private GeolocationPermissionsAdapter mGeolocationPermissionsAdapter; 6146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 62e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // Read/write protected by mLock. 63e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu private boolean mInitialized; 643053d8bc3be48b0cbc6f33e1975c03a10ac303a5Jonathan Dixon 65e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu private void loadPlatSupportLibrary() { 66a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Load glue-layer support library. 67a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon System.loadLibrary("webviewchromium_plat_support"); 68a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon DrawGLFunctor.setChromiumAwDrawGLFunction(AwContents.getAwDrawGLFunction()); 69991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon AwContents.setAwDrawSWFunctionTable(GraphicsUtils.getDrawSWFunctionTable()); 70a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 71a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 72e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // TODO(joth): Much of this initialization logic could be moved into the chromium tree. 73e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu private void ensureChromiumNativeInitializedLocked() { 7446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) assert Thread.holdsLock(mLock); 7546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 76e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu if (mInitialized) { 77e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu return; 78e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu } 793053d8bc3be48b0cbc6f33e1975c03a10ac303a5Jonathan Dixon 80e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // We must post to the UI thread to cover the case that the user 81e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // has invoked Chromium startup by using the (thread-safe) 82e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // CookieManager rather than creating a WebView. 83e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ThreadUtils.runOnUiThreadBlocking(new Runnable() { 84e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu @Override 85e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu public void run() { 86e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu PathUtils.setPrivateDataDirectorySuffix("webview"); 87e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // We don't need to extract any paks because for WebView, they are 88e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // in the system image. 89e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ResourceExtractor.setMandatoryPaksToExtract(""); 90e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu 91e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu LibraryLoader.setLibraryToLoad("webviewchromium"); 92e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu 93e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // TODO: Ultimately we want to do this step in the zygote 94e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // process, so we should split this init step into two parts - 95e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // one generic bit that loads the library and another that performs 96e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // the app specific parts. 97e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu LibraryLoader.loadAndInitSync(); 98e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu 99e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu PathService.override(PathService.DIR_MODULE, "/system/lib/"); 100e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // TODO: DIR_RESOURCE_PAKS_ANDROID needs to live somewhere sensible, 101e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // inlined here for simplicity setting up the HTMLViewer demo. Unfortunately 102e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // it can't go into base.PathService, as the native constant it refers to 103e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // lives in the ui/ layer. See ui/base/ui_base_paths.h 104e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu final int DIR_RESOURCE_PAKS_ANDROID = 3003; 105e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu PathService.override(DIR_RESOURCE_PAKS_ANDROID, 106e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu "/system/framework/webview/paks"); 107e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu 108e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // Caching for later use, possibly from other threads 109e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu mWebViewChromiumSharedPreferences = ActivityThread.currentApplication(). 110e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu getSharedPreferences(CHROMIUM_PREFS_NAME, Context.MODE_PRIVATE); 111e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu 112e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu AndroidBrowserProcess.initContentViewProcess(ActivityThread.currentApplication(), 113e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu AndroidBrowserProcess.MAX_RENDERERS_SINGLE_PROCESS); 114e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu 115e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu loadPlatSupportLibrary(); 116e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu } 117e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu }); 118e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu mInitialized = true; 11946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 12046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 12146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 12246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public Statics getStatics() { 12346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 12446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mStaticMethods == null) { 125e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // TODO: Optimization potential: most these methods only need the native library 126e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // loaded, not the entire browser process initialized. See also http://b/7009882 127e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ensureChromiumNativeInitializedLocked(); 12846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mStaticMethods = new WebViewFactoryProvider.Statics() { 12946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 13046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String findAddress(String addr) { 13146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return ContentViewStatics.findAddress(addr); 13246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 13346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 13446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 13546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void setPlatformNotificationsEnabled(boolean enable) { 13646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // noop 13746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 13846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 139e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // TODO: There's no @Override to keep the build green for folks building 140e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu // against jb-dev or an out of date master. At some point, add @Override. 14146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String getDefaultUserAgent(Context context) { 14246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return ContentSettings.getDefaultUserAgent(); 14346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) }; 14546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return mStaticMethods; 14846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 15046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 15146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) { 15246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) assert Looper.myLooper() == Looper.getMainLooper(); 15346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 154e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ensureChromiumNativeInitializedLocked(); 15546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) ResourceProvider.registerResources(webView.getContext()); 15646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 15746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return new WebViewChromium(webView, privateAccess); 15846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 15946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 16046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 16146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public GeolocationPermissions getGeolocationPermissions() { 162009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen synchronized (mLock) { 163aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mGeolocationPermissions == null) { 164e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ensureChromiumNativeInitializedLocked(); 165e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu mGeolocationPermissionsAdapter = new GeolocationPermissionsAdapter( 166009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen new AwGeolocationPermissions(mWebViewChromiumSharedPreferences)); 167009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen } 168009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen } 169aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mGeolocationPermissions; 17046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 17146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 17246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 17346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public CookieManager getCookieManager() { 17446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 175aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mCookieManager == null) { 176e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ensureChromiumNativeInitializedLocked(); 177d5f17bbd8703a56ac084a64b1ce2f673f67bd72dKristian Monsen mCookieManager = new CookieManagerAdapter(new AwCookieManager()); 17846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 17946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 180aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mCookieManager; 18146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 18246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 18346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 18446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebIconDatabase getWebIconDatabase() { 185aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon synchronized (mLock) { 186aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mWebIconDatabase == null) { 187e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ensureChromiumNativeInitializedLocked(); 188aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon mWebIconDatabase = new WebIconDatabaseAdapter(); 189aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 190aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 191aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mWebIconDatabase; 19246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 19346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 19446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 19546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebStorage getWebStorage() { 196aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon synchronized (mLock) { 197aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mWebStorage == null) { 198e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ensureChromiumNativeInitializedLocked(); 199aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon mWebStorage = new WebStorageAdapter(); 200aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 201aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 202aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mWebStorage; 20346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 20446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 20546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) @Override 20646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public WebViewDatabase getWebViewDatabase(Context context) { 20746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) synchronized (mLock) { 208aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon if (mWebViewDatabase == null) { 209e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu ensureChromiumNativeInitializedLocked(); 210aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon mWebViewDatabase = new WebViewDatabaseAdapter(); 211aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon } 21246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 213aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon return mWebViewDatabase; 21446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 21546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)} 216