1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "android_webview/browser/aw_browser_context.h"
6
7 #include "android_webview/browser/aw_form_database_service.h"
8 #include "android_webview/browser/aw_pref_store.h"
9 #include "android_webview/browser/aw_quota_manager_bridge.h"
10 #include "android_webview/browser/aw_resource_context.h"
11 #include "android_webview/browser/jni_dependency_factory.h"
12 #include "android_webview/browser/net/aw_url_request_context_getter.h"
13 #include "android_webview/browser/net/init_native_callback.h"
14 #include "base/bind.h"
15 #include "base/prefs/pref_registry_simple.h"
16 #include "base/prefs/pref_service.h"
17 #include "base/prefs/pref_service_factory.h"
18 #include "components/autofill/core/common/autofill_pref_names.h"
19 #include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
20 #include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
21 #include "components/data_reduction_proxy/browser/data_reduction_proxy_prefs.h"
22 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
23 #include "components/data_reduction_proxy/browser/data_reduction_proxy_statistics_prefs.h"
24 #include "components/user_prefs/user_prefs.h"
25 #include "components/visitedlink/browser/visitedlink_master.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/ssl_host_state_delegate.h"
28 #include "content/public/browser/storage_partition.h"
29 #include "content/public/browser/web_contents.h"
30 #include "net/cookies/cookie_store.h"
31 #include "net/proxy/proxy_config_service_android.h"
32 #include "net/proxy/proxy_service.h"
33
34 using base::FilePath;
35 using content::BrowserThread;
36 using data_reduction_proxy::DataReductionProxyConfigService;
37 using data_reduction_proxy::DataReductionProxySettings;
38
39 namespace android_webview {
40
41 namespace {
42
43 // Shows notifications which correspond to PersistentPrefStore's reading errors.
HandleReadError(PersistentPrefStore::PrefReadError error)44 void HandleReadError(PersistentPrefStore::PrefReadError error) {
45 }
46
47 AwBrowserContext* g_browser_context = NULL;
48
CreateProxyConfigService()49 net::ProxyConfigService* CreateProxyConfigService() {
50 net::ProxyConfigServiceAndroid* config_service =
51 static_cast<net::ProxyConfigServiceAndroid*>(
52 net::ProxyService::CreateSystemProxyConfigService(
53 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
54 nullptr /* Ignored on Android */ ));
55 config_service->set_exclude_pac_url(true);
56 return config_service;
57 }
58
59 } // namespace
60
61 // Data reduction proxy is disabled by default.
62 bool AwBrowserContext::data_reduction_proxy_enabled_ = false;
63
AwBrowserContext(const FilePath path,JniDependencyFactory * native_factory)64 AwBrowserContext::AwBrowserContext(
65 const FilePath path,
66 JniDependencyFactory* native_factory)
67 : context_storage_path_(path),
68 native_factory_(native_factory) {
69 DCHECK(!g_browser_context);
70 g_browser_context = this;
71
72 // This constructor is entered during the creation of ContentBrowserClient,
73 // before browser threads are created. Therefore any checks to enforce
74 // threading (such as BrowserThread::CurrentlyOn()) will fail here.
75 }
76
~AwBrowserContext()77 AwBrowserContext::~AwBrowserContext() {
78 DCHECK_EQ(this, g_browser_context);
79 g_browser_context = NULL;
80 }
81
82 // static
GetDefault()83 AwBrowserContext* AwBrowserContext::GetDefault() {
84 // TODO(joth): rather than store in a global here, lookup this instance
85 // from the Java-side peer.
86 return g_browser_context;
87 }
88
89 // static
FromWebContents(content::WebContents * web_contents)90 AwBrowserContext* AwBrowserContext::FromWebContents(
91 content::WebContents* web_contents) {
92 // This is safe; this is the only implementation of the browser context.
93 return static_cast<AwBrowserContext*>(web_contents->GetBrowserContext());
94 }
95
96 // static
SetDataReductionProxyEnabled(bool enabled)97 void AwBrowserContext::SetDataReductionProxyEnabled(bool enabled) {
98 // Cache the setting value. It is possible that data reduction proxy is
99 // not created yet.
100 data_reduction_proxy_enabled_ = enabled;
101 AwBrowserContext* context = AwBrowserContext::GetDefault();
102 // Can't enable Data reduction proxy if user pref service is not ready.
103 if (context == NULL || context->user_pref_service_.get() == NULL)
104 return;
105 DataReductionProxySettings* proxy_settings =
106 context->GetDataReductionProxySettings();
107 if (proxy_settings == NULL)
108 return;
109
110 context->CreateDataReductionProxyStatisticsIfNecessary();
111 proxy_settings->SetDataReductionProxyStatisticsPrefs(
112 context->data_reduction_proxy_statistics_.get());
113 proxy_settings->SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
114 }
115
PreMainMessageLoopRun()116 void AwBrowserContext::PreMainMessageLoopRun() {
117 cookie_store_ = CreateCookieStore(this);
118 data_reduction_proxy_settings_.reset(
119 new DataReductionProxySettings(
120 new data_reduction_proxy::DataReductionProxyParams(
121 data_reduction_proxy::DataReductionProxyParams::kAllowed)));
122 scoped_ptr<DataReductionProxyConfigService>
123 data_reduction_proxy_config_service(
124 new DataReductionProxyConfigService(
125 scoped_ptr<net::ProxyConfigService>(
126 CreateProxyConfigService()).Pass()));
127 if (data_reduction_proxy_settings_.get()) {
128 data_reduction_proxy_configurator_.reset(
129 new data_reduction_proxy::DataReductionProxyConfigTracker(
130 base::Bind(&DataReductionProxyConfigService::UpdateProxyConfig,
131 base::Unretained(
132 data_reduction_proxy_config_service.get())),
133 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
134 data_reduction_proxy_settings_->SetProxyConfigurator(
135 data_reduction_proxy_configurator_.get());
136 }
137
138 url_request_context_getter_ =
139 new AwURLRequestContextGetter(GetPath(),
140 cookie_store_.get(),
141 data_reduction_proxy_config_service.Pass());
142
143 visitedlink_master_.reset(
144 new visitedlink::VisitedLinkMaster(this, this, false));
145 visitedlink_master_->Init();
146
147 form_database_service_.reset(
148 new AwFormDatabaseService(context_storage_path_));
149 }
150
AddVisitedURLs(const std::vector<GURL> & urls)151 void AwBrowserContext::AddVisitedURLs(const std::vector<GURL>& urls) {
152 DCHECK(visitedlink_master_);
153 visitedlink_master_->AddURLs(urls);
154 }
155
CreateRequestContext(content::ProtocolHandlerMap * protocol_handlers,content::URLRequestInterceptorScopedVector request_interceptors)156 net::URLRequestContextGetter* AwBrowserContext::CreateRequestContext(
157 content::ProtocolHandlerMap* protocol_handlers,
158 content::URLRequestInterceptorScopedVector request_interceptors) {
159 // This function cannot actually create the request context because
160 // there is a reentrant dependency on GetResourceContext() via
161 // content::StoragePartitionImplMap::Create(). This is not fixable
162 // until http://crbug.com/159193. Until then, assert that the context
163 // has already been allocated and just handle setting the protocol_handlers.
164 DCHECK(url_request_context_getter_);
165 url_request_context_getter_->SetHandlersAndInterceptors(
166 protocol_handlers, request_interceptors.Pass());
167 return url_request_context_getter_;
168 }
169
170 net::URLRequestContextGetter*
CreateRequestContextForStoragePartition(const base::FilePath & partition_path,bool in_memory,content::ProtocolHandlerMap * protocol_handlers,content::URLRequestInterceptorScopedVector request_interceptors)171 AwBrowserContext::CreateRequestContextForStoragePartition(
172 const base::FilePath& partition_path,
173 bool in_memory,
174 content::ProtocolHandlerMap* protocol_handlers,
175 content::URLRequestInterceptorScopedVector request_interceptors) {
176 NOTREACHED();
177 return NULL;
178 }
179
GetQuotaManagerBridge()180 AwQuotaManagerBridge* AwBrowserContext::GetQuotaManagerBridge() {
181 if (!quota_manager_bridge_.get()) {
182 quota_manager_bridge_ = native_factory_->CreateAwQuotaManagerBridge(this);
183 }
184 return quota_manager_bridge_.get();
185 }
186
GetFormDatabaseService()187 AwFormDatabaseService* AwBrowserContext::GetFormDatabaseService() {
188 return form_database_service_.get();
189 }
190
GetDataReductionProxySettings()191 DataReductionProxySettings* AwBrowserContext::GetDataReductionProxySettings() {
192 return data_reduction_proxy_settings_.get();
193 }
194
GetAwURLRequestContext()195 AwURLRequestContextGetter* AwBrowserContext::GetAwURLRequestContext() {
196 return url_request_context_getter_.get();
197 }
198
199 // Create user pref service for autofill functionality.
CreateUserPrefServiceIfNecessary()200 void AwBrowserContext::CreateUserPrefServiceIfNecessary() {
201 if (user_pref_service_)
202 return;
203
204 PrefRegistrySimple* pref_registry = new PrefRegistrySimple();
205 // We only use the autocomplete feature of the Autofill, which is
206 // controlled via the manager_delegate. We don't use the rest
207 // of autofill, which is why it is hardcoded as disabled here.
208 pref_registry->RegisterBooleanPref(
209 autofill::prefs::kAutofillEnabled, false);
210 pref_registry->RegisterDoublePref(
211 autofill::prefs::kAutofillPositiveUploadRate, 0.0);
212 pref_registry->RegisterDoublePref(
213 autofill::prefs::kAutofillNegativeUploadRate, 0.0);
214 data_reduction_proxy::RegisterSimpleProfilePrefs(pref_registry);
215 data_reduction_proxy::RegisterPrefs(pref_registry);
216
217 base::PrefServiceFactory pref_service_factory;
218 pref_service_factory.set_user_prefs(make_scoped_refptr(new AwPrefStore()));
219 pref_service_factory.set_read_error_callback(base::Bind(&HandleReadError));
220 user_pref_service_ = pref_service_factory.Create(pref_registry).Pass();
221
222 user_prefs::UserPrefs::Set(this, user_pref_service_.get());
223
224 if (data_reduction_proxy_settings_.get()) {
225 data_reduction_proxy_settings_->InitDataReductionProxySettings(
226 user_pref_service_.get(),
227 GetRequestContext());
228
229 SetDataReductionProxyEnabled(data_reduction_proxy_enabled_);
230 }
231 }
232
GetPath() const233 base::FilePath AwBrowserContext::GetPath() const {
234 return context_storage_path_;
235 }
236
IsOffTheRecord() const237 bool AwBrowserContext::IsOffTheRecord() const {
238 // Android WebView does not support off the record profile yet.
239 return false;
240 }
241
GetRequestContext()242 net::URLRequestContextGetter* AwBrowserContext::GetRequestContext() {
243 return GetDefaultStoragePartition(this)->GetURLRequestContext();
244 }
245
246 net::URLRequestContextGetter*
GetRequestContextForRenderProcess(int renderer_child_id)247 AwBrowserContext::GetRequestContextForRenderProcess(
248 int renderer_child_id) {
249 return GetRequestContext();
250 }
251
GetMediaRequestContext()252 net::URLRequestContextGetter* AwBrowserContext::GetMediaRequestContext() {
253 return GetRequestContext();
254 }
255
256 net::URLRequestContextGetter*
GetMediaRequestContextForRenderProcess(int renderer_child_id)257 AwBrowserContext::GetMediaRequestContextForRenderProcess(
258 int renderer_child_id) {
259 return GetRequestContext();
260 }
261
262 net::URLRequestContextGetter*
GetMediaRequestContextForStoragePartition(const base::FilePath & partition_path,bool in_memory)263 AwBrowserContext::GetMediaRequestContextForStoragePartition(
264 const base::FilePath& partition_path,
265 bool in_memory) {
266 NOTREACHED();
267 return NULL;
268 }
269
GetResourceContext()270 content::ResourceContext* AwBrowserContext::GetResourceContext() {
271 if (!resource_context_) {
272 resource_context_.reset(
273 new AwResourceContext(url_request_context_getter_.get()));
274 }
275 return resource_context_.get();
276 }
277
278 content::DownloadManagerDelegate*
GetDownloadManagerDelegate()279 AwBrowserContext::GetDownloadManagerDelegate() {
280 return &download_manager_delegate_;
281 }
282
GetGuestManager()283 content::BrowserPluginGuestManager* AwBrowserContext::GetGuestManager() {
284 return NULL;
285 }
286
GetSpecialStoragePolicy()287 storage::SpecialStoragePolicy* AwBrowserContext::GetSpecialStoragePolicy() {
288 // Intentionally returning NULL as 'Extensions' and 'Apps' not supported.
289 return NULL;
290 }
291
GetPushMessagingService()292 content::PushMessagingService* AwBrowserContext::GetPushMessagingService() {
293 // TODO(johnme): Support push messaging in WebView.
294 return NULL;
295 }
296
GetSSLHostStateDelegate()297 content::SSLHostStateDelegate* AwBrowserContext::GetSSLHostStateDelegate() {
298 if (!ssl_host_state_delegate_.get()) {
299 ssl_host_state_delegate_.reset(new AwSSLHostStateDelegate());
300 }
301 return ssl_host_state_delegate_.get();
302 }
303
RebuildTable(const scoped_refptr<URLEnumerator> & enumerator)304 void AwBrowserContext::RebuildTable(
305 const scoped_refptr<URLEnumerator>& enumerator) {
306 // Android WebView rebuilds from WebChromeClient.getVisitedHistory. The client
307 // can change in the lifetime of this WebView and may not yet be set here.
308 // Therefore this initialization path is not used.
309 enumerator->OnComplete(true);
310 }
311
CreateDataReductionProxyStatisticsIfNecessary()312 void AwBrowserContext::CreateDataReductionProxyStatisticsIfNecessary() {
313 DCHECK(user_pref_service_.get());
314
315 if (!data_reduction_proxy_statistics_.get()) {
316 // We don't care about commit_delay for now. It is just a dummy value.
317 base::TimeDelta commit_delay = base::TimeDelta::FromMinutes(60);
318 data_reduction_proxy_statistics_ =
319 scoped_ptr<data_reduction_proxy::DataReductionProxyStatisticsPrefs>(
320 new data_reduction_proxy::DataReductionProxyStatisticsPrefs(
321 user_pref_service_.get(),
322 base::MessageLoopProxy::current(),
323 commit_delay));
324 }
325 }
326
327 } // namespace android_webview
328