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