WebViewChromiumFactoryProvider.java revision 54b3666a044d576394424822704d21dace02dc7c
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)
19b7f8bdb39f5ddfba3394d5335e728d9bf416f0caPrimiano Tucciimport android.app.ActivityManager;
2046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.ActivityThread;
21b7f8bdb39f5ddfba3394d5335e728d9bf416f0caPrimiano Tucciimport android.content.ComponentCallbacks2;
2246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.Context;
23009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsenimport android.content.SharedPreferences;
24970a2065df4f96ceaa9bc38d82caea9221dfa4c9Jonathan Dixonimport android.os.Build;
2546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Looper;
26fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdochimport android.util.Log;
2746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.CookieManager;
2846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.GeolocationPermissions;
2946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebIconDatabase;
3046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebStorage;
3146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebView;
3246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewDatabase;
3346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewFactoryProvider;
3446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewProvider;
3546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
36aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsenimport org.chromium.android_webview.AwBrowserContext;
37f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixonimport org.chromium.android_webview.AwBrowserProcess;
38a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport org.chromium.android_webview.AwContents;
39d5f17bbd8703a56ac084a64b1ce2f673f67bd72dKristian Monsenimport org.chromium.android_webview.AwCookieManager;
409d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganovimport org.chromium.android_webview.AwDevToolsServer;
4109e718bac5900c84b8402b774d306dca7f7fdf09Selim Gurunimport org.chromium.android_webview.AwFormDatabase;
42009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsenimport org.chromium.android_webview.AwGeolocationPermissions;
435d20093562806fbce9cc0d3eb4a411ed6c5ce1c0Bo Liuimport org.chromium.android_webview.AwQuotaManagerBridge;
44d6b56ff89338d0b3a6ba0cb413b1fe559d6284e0Mikhail Naganovimport org.chromium.android_webview.AwSettings;
452fbdaa7353e16996e874ea99f050a7b857dd92c4Ben Murdochimport org.chromium.base.CommandLine;
46b7f8bdb39f5ddfba3394d5335e728d9bf416f0caPrimiano Tucciimport org.chromium.base.MemoryPressureListener;
4746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.base.PathService;
487b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixonimport org.chromium.base.ThreadUtils;
4954b3666a044d576394424822704d21dace02dc7cMarcin Kosibaimport org.chromium.base.library_loader.LibraryLoader;
5054b3666a044d576394424822704d21dace02dc7cMarcin Kosibaimport org.chromium.base.library_loader.ProcessInitException;
518be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)import org.chromium.content.app.ContentMain;
5246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentViewStatics;
5346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ResourceExtractor;
5446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
55fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdochimport java.lang.ref.WeakReference;
56fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdochimport java.util.ArrayList;
57fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch
5846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
5946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
6057f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    private final String TAG = "WebViewChromiumFactoryProvider";
6157f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
62009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen    private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs";
637962d3fa1b66ed25aba03a2d48f6c47528d7d95cPrimiano Tucci    private static final String COMMAND_LINE_FILE = "/data/local/tmp/webview-command-line";
64009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen
6572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon    // Guards accees to the other members, and is notifyAll() signalled on the UI thread
6672db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon    // when the chromium process has been started.
6772db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon    private final Object mLock = new Object();
6872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon
6946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // Initialization guarded by mLock.
70aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen    private AwBrowserContext mBrowserContext;
71aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private Statics mStaticMethods;
72aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private GeolocationPermissionsAdapter mGeolocationPermissions;
73aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private CookieManagerAdapter mCookieManager;
74aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private WebIconDatabaseAdapter mWebIconDatabase;
75aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private WebStorageAdapter mWebStorage;
76aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private WebViewDatabaseAdapter mWebViewDatabase;
779d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov    private AwDevToolsServer mDevToolsServer;
7846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
79fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch    private ArrayList<WeakReference<WebViewChromium>> mWebViewsToStart =
80fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch              new ArrayList<WeakReference<WebViewChromium>>();
81fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch
829aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon    // Read/write protected by mLock.
839aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon    private boolean mStarted;
84f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon
8511f7c1b02e49a6a8eaec26111f08edec45feb01aTorne (Richard Coles)    public WebViewChromiumFactoryProvider() {
86f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon        // Load chromium library.
87f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon        AwBrowserProcess.loadLibrary();
88a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon        // Load glue-layer support library.
89a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon        System.loadLibrary("webviewchromium_plat_support");
90fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        ThreadUtils.setWillOverrideUiThread();
91f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon    }
92f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon
93f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon    private void initPlatSupportLibrary() {
949aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon        DrawGLFunctor.setChromiumAwDrawGLFunction(AwContents.getAwDrawGLFunction());
959aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon        AwContents.setAwDrawSWFunctionTable(GraphicsUtils.getDrawSWFunctionTable());
96c5cde8c18df853e11d1ec528508fd0fe2e742d5cKaan Baloglu        AwContents.setAwDrawGLFunctionTable(GraphicsUtils.getDrawGLFunctionTable());
97a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon    }
98a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon
99fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch    private void ensureChromiumStartedLocked(boolean onMainThread) {
10046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        assert Thread.holdsLock(mLock);
10146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
10272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        if (mStarted) {  // Early-out for the common case.
10372db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            return;
10472db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        }
10572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon
106fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        Looper looper = !onMainThread ? Looper.myLooper() : Looper.getMainLooper();
10757f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        Log.v(TAG, "Binding Chromium to " +
10857f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch                (Looper.getMainLooper().equals(looper) ? "main":"background") +
10957f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch                " looper " + looper);
110fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        ThreadUtils.setUiThread(looper);
111fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch
11272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        if (ThreadUtils.runningOnUiThread()) {
11372db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            startChromiumLocked();
1149aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon            return;
1159aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon        }
1163053d8bc3be48b0cbc6f33e1975c03a10ac303a5Jonathan Dixon
11772db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // We must post to the UI thread to cover the case that the user has invoked Chromium
11872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // startup by using the (thread-safe) CookieManager rather than creating a WebView.
11972db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        ThreadUtils.postOnUiThread(new Runnable() {
1207b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon            @Override
1217b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon            public void run() {
12272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon                synchronized (mLock) {
12372db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon                    startChromiumLocked();
124970a2065df4f96ceaa9bc38d82caea9221dfa4c9Jonathan Dixon                }
12572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            }
12672db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        });
12772db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        while (!mStarted) {
12872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            try {
12972db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon                // Important: wait() releases |mLock| so the UI thread can take it :-)
13072db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon                mLock.wait();
13172db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            } catch (InterruptedException e) {
13272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon                // Keep trying... eventually the UI thread will process the task we sent it.
13372db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            }
13472db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        }
13572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon    }
136970a2065df4f96ceaa9bc38d82caea9221dfa4c9Jonathan Dixon
13772db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon    private void startChromiumLocked() {
13872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        assert Thread.holdsLock(mLock) && ThreadUtils.runningOnUiThread();
1391e5325bde6fb074ce556a4e2833114d890ed21f3Jonathan Dixon
14072db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // The post-condition of this method is everything is ready, so notify now to cover all
14172db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // return paths. (Other threads will not wake-up until we release |mLock|, whatever).
14272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        mLock.notifyAll();
143970a2065df4f96ceaa9bc38d82caea9221dfa4c9Jonathan Dixon
14472db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        if (mStarted) {
14572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            return;
14672db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        }
1479aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon
14872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        if (Build.IS_DEBUGGABLE) {
14972db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            CommandLine.initFromFile(COMMAND_LINE_FILE);
15072db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        } else {
15172db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            CommandLine.init(null);
15272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        }
1537b77b2fb0f7148bc31e23cabadb234231699ff93Jonathan Dixon
15472db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        CommandLine cl = CommandLine.getInstance();
15572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // TODO: currently in a relase build the DCHECKs only log. We either need to insall
15672db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // a report handler with SetLogReportHandler to make them assert, or else compile
15772db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // them out of the build altogether (b/8284203). Either way, so long they're
15872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // compiled in, we may as unconditionally enable them here.
15972db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        cl.appendSwitch("enable-dcheck");
16072db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon
16172db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // TODO: Remove when GL is supported by default in the upstream code.
16272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        if (!cl.hasSwitch("disable-webview-gl-mode")) {
16372db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            cl.appendSwitch("testing-webview-gl-mode");
16472db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        }
16572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon
16672db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // We don't need to extract any paks because for WebView, they are
16772db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // in the system image.
16872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        ResourceExtractor.setMandatoryPaksToExtract("");
16972db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon
17072db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        try {
17172db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            LibraryLoader.ensureInitialized();
17272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        } catch(ProcessInitException e) {
17372db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon            throw new RuntimeException("Error initializing WebView library", e);
17472db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        }
17572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon
17672db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        PathService.override(PathService.DIR_MODULE, "/system/lib/");
17772db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // TODO: DIR_RESOURCE_PAKS_ANDROID needs to live somewhere sensible,
17872db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // inlined here for simplicity setting up the HTMLViewer demo. Unfortunately
17972db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // it can't go into base.PathService, as the native constant it refers to
18072db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        // lives in the ui/ layer. See ui/base/ui_base_paths.h
18172db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        final int DIR_RESOURCE_PAKS_ANDROID = 3003;
18272db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        PathService.override(DIR_RESOURCE_PAKS_ANDROID,
18372db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon                "/system/framework/webview/paks");
18472db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon
18572db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        AwBrowserProcess.start(ActivityThread.currentApplication());
18672db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon        initPlatSupportLibrary();
1879d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov
1889d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov        if (Build.IS_DEBUGGABLE) {
1899d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov            setWebContentsDebuggingEnabled(true);
1909d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov        }
1919aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon        mStarted = true;
192fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch
193fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        for (WeakReference<WebViewChromium> wvc : mWebViewsToStart) {
194fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch            WebViewChromium w = wvc.get();
195fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch            if (w != null) {
196fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch                w.startYourEngine();
197fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch            }
198fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        }
199fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        mWebViewsToStart.clear();
200fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        mWebViewsToStart = null;
20146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
20246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
20357f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    boolean hasStarted() {
20457f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        return mStarted;
20557f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    }
20657f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
20757f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    void startYourEngines(boolean onMainThread) {
20857f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        synchronized (mLock) {
20957f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch            ensureChromiumStartedLocked(onMainThread);
21057f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
21157f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        }
21257f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    }
21357f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
21457f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    AwBrowserContext getBrowserContext() {
21557f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        synchronized (mLock) {
21657f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch            return getBrowserContextLocked();
21757f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        }
21857f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    }
21957f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
22057f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    private AwBrowserContext getBrowserContextLocked() {
22157f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        assert Thread.holdsLock(mLock);
22257f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        assert mStarted;
22357f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        if (mBrowserContext == null) {
22457f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch            mBrowserContext = new AwBrowserContext(
22557f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch                    ActivityThread.currentApplication().getSharedPreferences(
22657f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch                            CHROMIUM_PREFS_NAME, Context.MODE_PRIVATE));
22757f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        }
22857f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        return mBrowserContext;
22957f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    }
23057f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
23157f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    private void setWebContentsDebuggingEnabled(boolean enable) {
23257f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        if (Looper.myLooper() != ThreadUtils.getUiThreadLooper()) {
23357f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch            throw new RuntimeException(
23457f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch                    "Toggling of Web Contents Debugging must be done on the UI thread");
23557f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        }
23657f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        if (mDevToolsServer == null) {
23757f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch            if (!enable) return;
23857f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch            mDevToolsServer = new AwDevToolsServer();
23957f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        }
24057f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch        mDevToolsServer.setRemoteDebuggingEnabled(enable);
24157f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch    }
24257f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
24357f39b97561187c13c4903afdae51c3c9c1cc209Ben Murdoch
24446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
24546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public Statics getStatics() {
24646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        synchronized (mLock) {
24746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (mStaticMethods == null) {
2489aa44b4e29be9f4b271edb3f4d438d806d4cc176Jonathan Dixon                // TODO: Optimization potential: most these methods only need the native library
249f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon                // loaded and initialized, not the entire browser process started.
250f3e3e4e6b6c5798f435c1d14379edeb479e3b25dJonathan Dixon                // See also http://b/7009882
251fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch                ensureChromiumStartedLocked(true);
25246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                mStaticMethods = new WebViewFactoryProvider.Statics() {
25346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    @Override
25446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    public String findAddress(String addr) {
25546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                        return ContentViewStatics.findAddress(addr);
25646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    }
25746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
25846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    @Override
25946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    public void setPlatformNotificationsEnabled(boolean enable) {
26046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                        // noop
26146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    }
26246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
263f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                    @Override
26446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    public String getDefaultUserAgent(Context context) {
265d6b56ff89338d0b3a6ba0cb413b1fe559d6284e0Mikhail Naganov                        return AwSettings.getDefaultUserAgent();
26646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    }
267b7f8bdb39f5ddfba3394d5335e728d9bf416f0caPrimiano Tucci
268b7f8bdb39f5ddfba3394d5335e728d9bf416f0caPrimiano Tucci                    @Override
2699d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                    public void setWebContentsDebuggingEnabled(boolean enable) {
2709d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                        // Web Contents debugging is always enabled on debug builds.
2719d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                        if (!Build.IS_DEBUGGABLE) {
2729d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                            WebViewChromiumFactoryProvider.this.
2739d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                                    setWebContentsDebuggingEnabled(enable);
2749d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                        }
2759d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                    }
2769d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov
2779d0315cd966ad486abfcb51afa6692249461d14cMikhail Naganov                    @Override
278b7f8bdb39f5ddfba3394d5335e728d9bf416f0caPrimiano Tucci                    public void freeMemoryForTests() {
27917cd884446d243f8ef74b99ef9d617699953419aPrimiano Tucci                        if (ActivityManager.isRunningInTestHarness()) {
28017cd884446d243f8ef74b99ef9d617699953419aPrimiano Tucci                            MemoryPressureListener.maybeNotifyMemoryPresure(
28117cd884446d243f8ef74b99ef9d617699953419aPrimiano Tucci                                    ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
28217cd884446d243f8ef74b99ef9d617699953419aPrimiano Tucci                        }
283b7f8bdb39f5ddfba3394d5335e728d9bf416f0caPrimiano Tucci                    }
28446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                };
28546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
28646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
28746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        return mStaticMethods;
28846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
28946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
29046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
29146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
292fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        WebViewChromium wvc = new WebViewChromium(this, webView, privateAccess);
293fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch
294fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        synchronized (mLock) {
295fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch            if (mWebViewsToStart != null) {
296fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch                mWebViewsToStart.add(new WeakReference<WebViewChromium>(wvc));
297fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch            }
298fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        }
299fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        ResourceProvider.registerResources(webView.getContext());
300fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch        return wvc;
301fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch    }
302fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch
30346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
30446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public GeolocationPermissions getGeolocationPermissions() {
305009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen        synchronized (mLock) {
306aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mGeolocationPermissions == null) {
307fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch                ensureChromiumStartedLocked(true);
30850a184c1e058bc62f659fb80e09e7507ef13d6c9Jonathan Dixon                mGeolocationPermissions = new GeolocationPermissionsAdapter(
309aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen                        getBrowserContextLocked().getGeolocationPermissions());
310009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen            }
311009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen        }
312ff2704e614eb490baea0acb5c8ab22e061033694Kristian Monsen        return mGeolocationPermissions;
31346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
31446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
31546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
31646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public CookieManager getCookieManager() {
31746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        synchronized (mLock) {
318aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mCookieManager == null) {
3198be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)                if (!mStarted) {
3208be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)                    // We can use CookieManager without starting Chromium; the native code
3218be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)                    // will bring up just the parts it needs to make this work on a temporary
3228be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)                    // basis until Chromium is started for real. The temporary cookie manager
3238be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)                    // needs the application context to have been set.
3248be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)                    ContentMain.initApplicationContext(ActivityThread.currentApplication());
3258be908c9c3af0debd0aeb0e4ff511dd16bcecf7bTorne (Richard Coles)                }
326d5f17bbd8703a56ac084a64b1ce2f673f67bd72dKristian Monsen                mCookieManager = new CookieManagerAdapter(new AwCookieManager());
32746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
32846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
329aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mCookieManager;
33046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
33146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
33246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
33346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebIconDatabase getWebIconDatabase() {
334aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        synchronized (mLock) {
335aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mWebIconDatabase == null) {
336fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch                ensureChromiumStartedLocked(true);
337aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon                mWebIconDatabase = new WebIconDatabaseAdapter();
338aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            }
339aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        }
340aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mWebIconDatabase;
34146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
34246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
34346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
34446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebStorage getWebStorage() {
345aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        synchronized (mLock) {
346aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mWebStorage == null) {
347fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch                ensureChromiumStartedLocked(true);
3485d20093562806fbce9cc0d3eb4a411ed6c5ce1c0Bo Liu                mWebStorage = new WebStorageAdapter(AwQuotaManagerBridge.getInstance());
349aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            }
350aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        }
351aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mWebStorage;
35246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
35346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
35446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
35546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebViewDatabase getWebViewDatabase(Context context) {
35646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        synchronized (mLock) {
357aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mWebViewDatabase == null) {
358fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch                ensureChromiumStartedLocked(true);
35972db47d0508d6733072c38ee44883ecfaf612ca6Jonathan Dixon                AwBrowserContext browserContext = getBrowserContextLocked();
360a6f2939f98aeaf67533a7fd3f5c999f207451f1cSelim Gurun                mWebViewDatabase = new WebViewDatabaseAdapter(
361a6f2939f98aeaf67533a7fd3f5c999f207451f1cSelim Gurun                        browserContext.getFormDatabase(),
362a6f2939f98aeaf67533a7fd3f5c999f207451f1cSelim Gurun                        browserContext.getHttpAuthDatabase(context));
363aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            }
36446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
365aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mWebViewDatabase;
36646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
36746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)}
368