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