WebViewChromiumFactoryProvider.java revision d5f17bbd8703a56ac084a64b1ce2f673f67bd72d
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.webview.chromium;
18
19import android.app.ActivityThread;
20import android.content.Context;
21import android.content.SharedPreferences;
22import android.os.Looper;
23import android.webkit.CookieManager;
24import android.webkit.GeolocationPermissions;
25import android.webkit.WebIconDatabase;
26import android.webkit.WebStorage;
27import android.webkit.WebView;
28import android.webkit.WebViewDatabase;
29import android.webkit.WebViewFactoryProvider;
30import android.webkit.WebViewProvider;
31
32import org.chromium.android_webview.AwContents;
33import org.chromium.android_webview.AwCookieManager;
34import org.chromium.android_webview.AwGeolocationPermissions;
35import org.chromium.base.PathService;
36import org.chromium.base.PathUtils;
37import org.chromium.base.ThreadUtils;
38import org.chromium.content.app.LibraryLoader;
39import org.chromium.content.browser.AndroidBrowserProcess;
40import org.chromium.content.browser.ContentSettings;
41import org.chromium.content.browser.ContentViewStatics;
42import org.chromium.content.browser.ResourceExtractor;
43
44public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
45
46    private final Object mLock = new Object();
47
48    private static final String CHROMIUM_PREFS_NAME = "WebViewChromiumPrefs";
49
50    // Initialization guarded by mLock.
51    private SharedPreferences mWebViewChromiumSharedPreferences;
52    private Statics mStaticMethods;
53    private GeolocationPermissionsAdapter mGeolocationPermissions;
54    private CookieManagerAdapter mCookieManager;
55    private WebIconDatabaseAdapter mWebIconDatabase;
56    private WebStorageAdapter mWebStorage;
57    private WebViewDatabaseAdapter mWebViewDatabase;
58
59    // Initialization guarded by mLock.
60    private GeolocationPermissionsAdapter mGeolocationPermissionsAdapter;
61
62    // Read/write protected by mLock.
63    private boolean mInitialized;
64
65    private void loadPlatSupportLibrary() {
66        // Load glue-layer support library.
67        System.loadLibrary("webviewchromium_plat_support");
68        DrawGLFunctor.setChromiumAwDrawGLFunction(AwContents.getAwDrawGLFunction());
69    }
70
71    // TODO(joth): Much of this initialization logic could be moved into the chromium tree.
72    private void ensureChromiumNativeInitializedLocked() {
73        assert Thread.holdsLock(mLock);
74
75        if (mInitialized) {
76            return;
77        }
78
79        // We must post to the UI thread to cover the case that the user
80        // has invoked Chromium startup by using the (thread-safe)
81        // CookieManager rather than creating a WebView.
82        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
83            @Override
84            public void run() {
85                PathUtils.setPrivateDataDirectorySuffix("webview");
86                // We don't need to extract any paks because for WebView, they are
87                // in the system image.
88                ResourceExtractor.setMandatoryPaksToExtract("");
89
90                LibraryLoader.setLibraryToLoad("webviewchromium");
91
92                // TODO: Ultimately we want to do this step in the zygote
93                // process, so we should split this init step into two parts -
94                // one generic bit that loads the library and another that performs
95                // the app specific parts.
96                LibraryLoader.loadAndInitSync();
97
98                PathService.override(PathService.DIR_MODULE, "/system/lib/");
99                // TODO: DIR_RESOURCE_PAKS_ANDROID needs to live somewhere sensible,
100                // inlined here for simplicity setting up the HTMLViewer demo. Unfortunately
101                // it can't go into base.PathService, as the native constant it refers to
102                // lives in the ui/ layer. See ui/base/ui_base_paths.h
103                final int DIR_RESOURCE_PAKS_ANDROID = 3003;
104                PathService.override(DIR_RESOURCE_PAKS_ANDROID,
105                        "/system/framework/webview/paks");
106
107                // Caching for later use, possibly from other threads
108                mWebViewChromiumSharedPreferences = ActivityThread.currentApplication().
109                        getSharedPreferences(CHROMIUM_PREFS_NAME, Context.MODE_PRIVATE);
110
111                AndroidBrowserProcess.initContentViewProcess(ActivityThread.currentApplication(),
112                        AndroidBrowserProcess.MAX_RENDERERS_SINGLE_PROCESS);
113
114                loadPlatSupportLibrary();
115            }
116        });
117        mInitialized = true;
118    }
119
120    @Override
121    public Statics getStatics() {
122        synchronized (mLock) {
123            if (mStaticMethods == null) {
124                // TODO: Optimization potential: most these methods only need the native library
125                // loaded, not the entire browser process initialized. See also http://b/7009882
126                ensureChromiumNativeInitializedLocked();
127                mStaticMethods = new WebViewFactoryProvider.Statics() {
128                    @Override
129                    public String findAddress(String addr) {
130                        return ContentViewStatics.findAddress(addr);
131                    }
132
133                    @Override
134                    public void setPlatformNotificationsEnabled(boolean enable) {
135                        // noop
136                    }
137
138                    // TODO: There's no @Override to keep the build green for folks building
139                    // against jb-dev or an out of date master. At some point, add @Override.
140                    public String getDefaultUserAgent(Context context) {
141                        return ContentSettings.getDefaultUserAgent();
142                    }
143                };
144            }
145        }
146        return mStaticMethods;
147    }
148
149    @Override
150    public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
151        assert Looper.myLooper() == Looper.getMainLooper();
152        synchronized (mLock) {
153            ensureChromiumNativeInitializedLocked();
154            ResourceProvider.registerResources(webView.getContext());
155        }
156        return new WebViewChromium(webView, privateAccess);
157    }
158
159    @Override
160    public GeolocationPermissions getGeolocationPermissions() {
161        synchronized (mLock) {
162            if (mGeolocationPermissions == null) {
163                ensureChromiumNativeInitializedLocked();
164                mGeolocationPermissionsAdapter = new GeolocationPermissionsAdapter(
165                        new AwGeolocationPermissions(mWebViewChromiumSharedPreferences));
166            }
167        }
168        return mGeolocationPermissions;
169    }
170
171    @Override
172    public CookieManager getCookieManager() {
173        synchronized (mLock) {
174            if (mCookieManager == null) {
175                ensureChromiumNativeInitializedLocked();
176                mCookieManager = new CookieManagerAdapter(new AwCookieManager());
177            }
178        }
179        return mCookieManager;
180    }
181
182    @Override
183    public WebIconDatabase getWebIconDatabase() {
184        synchronized (mLock) {
185            if (mWebIconDatabase == null) {
186                ensureChromiumNativeInitializedLocked();
187                mWebIconDatabase = new WebIconDatabaseAdapter();
188            }
189        }
190        return mWebIconDatabase;
191    }
192
193    @Override
194    public WebStorage getWebStorage() {
195        synchronized (mLock) {
196            if (mWebStorage == null) {
197                ensureChromiumNativeInitializedLocked();
198                mWebStorage = new WebStorageAdapter();
199            }
200        }
201        return mWebStorage;
202    }
203
204    @Override
205    public WebViewDatabase getWebViewDatabase(Context context) {
206        synchronized (mLock) {
207            if (mWebViewDatabase == null) {
208                ensureChromiumNativeInitializedLocked();
209                mWebViewDatabase = new WebViewDatabaseAdapter();
210            }
211        }
212        return mWebViewDatabase;
213    }
214}
215