WebViewChromiumFactoryProvider.java revision f0f355514e4420755c15491fe3b21a2eeaa42654
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)
32f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan 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;
3746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentSettings;
3846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentViewStatics;
3946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ResourceExtractor;
4046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
4146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
4246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
4346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private final Object mLock = new Object();
4446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
45009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen    private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs";
46009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen
4746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // Initialization guarded by mLock.
48009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen    private SharedPreferences mWebViewChromiumSharedPreferences;
49aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private Statics mStaticMethods;
50aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private GeolocationPermissionsAdapter mGeolocationPermissions;
51aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private CookieManagerAdapter mCookieManager;
52aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private WebIconDatabaseAdapter mWebIconDatabase;
53aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private WebStorageAdapter mWebStorage;
54aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon    private WebViewDatabaseAdapter mWebViewDatabase;
5546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
56e49b38ed53e1b3be1530e4eb1b49ce6ba6f62db1Bo Liu    // Read/write protected by mLock.
57f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon    private boolean mChromiumStarted;
583053d8bc3be48b0cbc6f33e1975c03a10ac303a5Jonathan Dixon
59f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon    public WebViewChromiumFactoryProvider() {
60f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // Only do the minimum initialization here that we know:
61f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        //   a) is safe to do prior to the zygote forking the app-specific process, and
62f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        //   b) gives the maximum benefit w.r.t. cross app memory and startup savings.
63f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        loadLibraries();
64f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon    }
65f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon
66f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon    private void loadLibraries() {
67f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // We don't need to extract any paks because for WebView, they are
68f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // in the system image.
69f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        ResourceExtractor.setMandatoryPaksToExtract("");
70f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // Load the main chromium native library.
71f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        AwBrowserProcess.loadLibrary();
72a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon        // Load glue-layer support library.
73a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon        System.loadLibrary("webviewchromium_plat_support");
74f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // Connect them up.
75a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon        DrawGLFunctor.setChromiumAwDrawGLFunction(AwContents.getAwDrawGLFunction());
76991b0c63bb8c0b0d8577a255b026117e9f37ceceJonathan Dixon        AwContents.setAwDrawSWFunctionTable(GraphicsUtils.getDrawSWFunctionTable());
77a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon    }
78a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon
79f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon    private void ensureChromiumStartedLocked() {
8046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        assert Thread.holdsLock(mLock);
8146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
82f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        if (mChromiumStarted) return;
833053d8bc3be48b0cbc6f33e1975c03a10ac303a5Jonathan Dixon
84f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        PathService.override(PathService.DIR_MODULE, "/system/lib/");
85f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // TODO: DIR_RESOURCE_PAKS_ANDROID needs to live somewhere sensible,
86f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // inlined here for simplicity setting up the HTMLViewer demo. Unfortunately
87f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // it can't go into base.PathService, as the native constant it refers to
88f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // lives in the ui/ layer. See ui/base/ui_base_paths.h
89f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        final int DIR_RESOURCE_PAKS_ANDROID = 3003;
90f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        PathService.override(DIR_RESOURCE_PAKS_ANDROID,
91f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                "/system/framework/webview/paks");
92f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon
93f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        // Caching for later use, possibly from other threads
94f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        mWebViewChromiumSharedPreferences = ActivityThread.currentApplication().
95f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                getSharedPreferences(CHROMIUM_PREFS_NAME, Context.MODE_PRIVATE);
96f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon
97f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        AwBrowserProcess.start(ActivityThread.currentApplication());
98f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon        mChromiumStarted = true;
9946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
10046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
10146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
10246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public Statics getStatics() {
10346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        synchronized (mLock) {
10446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (mStaticMethods == null) {
10546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                mStaticMethods = new WebViewFactoryProvider.Statics() {
10646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    @Override
10746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    public String findAddress(String addr) {
10846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                        return ContentViewStatics.findAddress(addr);
10946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    }
11046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
11146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    @Override
11246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    public void setPlatformNotificationsEnabled(boolean enable) {
11346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                        // noop
11446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    }
11546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
116f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                    @Override
11746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    public String getDefaultUserAgent(Context context) {
118f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                        // TODO(perf): Optimization potential: avoid starting chromium up here
119f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                        // by routing this call to AwSettings -> AwContentClient::GetUserAgent.
120f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                        synchronized (mLock) {
121f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                            ensureChromiumStartedLocked();
122f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                        }
12346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                        return ContentSettings.getDefaultUserAgent();
12446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    }
12546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                };
12646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
12746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
12846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        return mStaticMethods;
12946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
13046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
13146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
13246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
13346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        assert Looper.myLooper() == Looper.getMainLooper();
13446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        synchronized (mLock) {
135f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon            ensureChromiumStartedLocked();
13646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            ResourceProvider.registerResources(webView.getContext());
13746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
13846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        return new WebViewChromium(webView, privateAccess);
13946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
14046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
14146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
14246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public GeolocationPermissions getGeolocationPermissions() {
143009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen        synchronized (mLock) {
144aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mGeolocationPermissions == null) {
145f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                ensureChromiumStartedLocked();
146f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                mGeolocationPermissions = new GeolocationPermissionsAdapter(
147009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen                        new AwGeolocationPermissions(mWebViewChromiumSharedPreferences));
148009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen            }
149009ed27511c4606dcd16b352489b2d3f70b4b513Kristian Monsen        }
150aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mGeolocationPermissions;
15146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
15246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
15346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
15446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public CookieManager getCookieManager() {
15546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        synchronized (mLock) {
156aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mCookieManager == null) {
157f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                ensureChromiumStartedLocked();
158d5f17bbd8703a56ac084a64b1ce2f673f67bd72dKristian Monsen                mCookieManager = new CookieManagerAdapter(new AwCookieManager());
15946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
16046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
161aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mCookieManager;
16246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
16346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
16446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
16546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebIconDatabase getWebIconDatabase() {
166aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        synchronized (mLock) {
167aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mWebIconDatabase == null) {
168f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                ensureChromiumStartedLocked();
169aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon                mWebIconDatabase = new WebIconDatabaseAdapter();
170aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            }
171aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        }
172aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mWebIconDatabase;
17346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
17446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
17546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
17646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebStorage getWebStorage() {
177aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        synchronized (mLock) {
178aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mWebStorage == null) {
179f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                ensureChromiumStartedLocked();
180aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon                mWebStorage = new WebStorageAdapter();
181aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            }
182aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        }
183aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mWebStorage;
18446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
18546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
18646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
18746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public WebViewDatabase getWebViewDatabase(Context context) {
18846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        synchronized (mLock) {
189aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            if (mWebViewDatabase == null) {
190f0f355514e4420755c15491fe3b21a2eeaa42654Jonathan Dixon                ensureChromiumStartedLocked();
191aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon                mWebViewDatabase = new WebViewDatabaseAdapter();
192aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon            }
19346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
194aadb04e4198e1f0dce390e9434cb189603b8e713Jonathan Dixon        return mWebViewDatabase;
19546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
19646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)}
197