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/jni_dependency_factory.h"
11#include "android_webview/browser/net/aw_url_request_context_getter.h"
12#include "base/prefs/pref_registry_simple.h"
13#include "base/prefs/pref_service.h"
14#include "base/prefs/pref_service_builder.h"
15#include "components/autofill/core/common/autofill_pref_names.h"
16#include "components/user_prefs/user_prefs.h"
17#include "components/visitedlink/browser/visitedlink_master.h"
18#include "content/public/browser/browser_thread.h"
19#include "content/public/browser/resource_context.h"
20#include "content/public/browser/storage_partition.h"
21#include "content/public/browser/web_contents.h"
22#include "net/url_request/url_request_context.h"
23
24using content::BrowserThread;
25
26namespace android_webview {
27
28namespace {
29
30// Shows notifications which correspond to PersistentPrefStore's reading errors.
31void HandleReadError(PersistentPrefStore::PrefReadError error) {
32}
33
34class AwResourceContext : public content::ResourceContext {
35 public:
36  explicit AwResourceContext(net::URLRequestContextGetter* getter)
37      : getter_(getter) {}
38  virtual ~AwResourceContext() {}
39
40  // content::ResourceContext implementation.
41  virtual net::HostResolver* GetHostResolver() OVERRIDE {
42    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
43    return getter_->GetURLRequestContext()->host_resolver();
44  }
45  virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
46    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
47    return getter_->GetURLRequestContext();
48  }
49  virtual bool AllowMicAccess(const GURL& origin) OVERRIDE {
50    return false;
51  }
52  virtual bool AllowCameraAccess(const GURL& origin) OVERRIDE {
53    return false;
54  }
55
56 private:
57  net::URLRequestContextGetter* getter_;
58
59  DISALLOW_COPY_AND_ASSIGN(AwResourceContext);
60};
61
62AwBrowserContext* g_browser_context = NULL;
63
64}  // namespace
65
66AwBrowserContext::AwBrowserContext(
67    const base::FilePath path,
68    JniDependencyFactory* native_factory)
69    : context_storage_path_(path),
70      native_factory_(native_factory),
71      user_pref_service_ready_(false) {
72  DCHECK(g_browser_context == NULL);
73  g_browser_context = this;
74
75  // This constructor is entered during the creation of ContentBrowserClient,
76  // before browser threads are created. Therefore any checks to enforce
77  // threading (such as BrowserThread::CurrentlyOn()) will fail here.
78}
79
80AwBrowserContext::~AwBrowserContext() {
81  DCHECK(g_browser_context == this);
82  g_browser_context = NULL;
83}
84
85// static
86AwBrowserContext* AwBrowserContext::GetDefault() {
87  // TODO(joth): rather than store in a global here, lookup this instance
88  // from the Java-side peer.
89  return g_browser_context;
90}
91
92// static
93AwBrowserContext* AwBrowserContext::FromWebContents(
94    content::WebContents* web_contents) {
95  // This is safe; this is the only implementation of the browser context.
96  return static_cast<AwBrowserContext*>(web_contents->GetBrowserContext());
97}
98
99void AwBrowserContext::InitializeBeforeThreadCreation() {
100  DCHECK(!url_request_context_getter_.get());
101  url_request_context_getter_ = new AwURLRequestContextGetter(this);
102}
103
104void AwBrowserContext::PreMainMessageLoopRun() {
105  visitedlink_master_.reset(
106      new visitedlink::VisitedLinkMaster(this, this, false));
107  visitedlink_master_->Init();
108
109  form_database_service_.reset(
110      new AwFormDatabaseService(context_storage_path_));
111}
112
113void AwBrowserContext::AddVisitedURLs(const std::vector<GURL>& urls) {
114  DCHECK(visitedlink_master_);
115  visitedlink_master_->AddURLs(urls);
116}
117
118net::URLRequestContextGetter* AwBrowserContext::CreateRequestContext(
119    content::ProtocolHandlerMap* protocol_handlers) {
120  CHECK(url_request_context_getter_.get());
121  url_request_context_getter_->SetProtocolHandlers(protocol_handlers);
122  return url_request_context_getter_.get();
123}
124
125net::URLRequestContextGetter*
126AwBrowserContext::CreateRequestContextForStoragePartition(
127    const base::FilePath& partition_path,
128    bool in_memory,
129    content::ProtocolHandlerMap* protocol_handlers) {
130  CHECK(url_request_context_getter_.get());
131  return url_request_context_getter_.get();
132}
133
134AwQuotaManagerBridge* AwBrowserContext::GetQuotaManagerBridge() {
135  if (!quota_manager_bridge_.get()) {
136    quota_manager_bridge_ = native_factory_->CreateAwQuotaManagerBridge(this);
137  }
138  return quota_manager_bridge_.get();
139}
140
141AwFormDatabaseService* AwBrowserContext::GetFormDatabaseService() {
142  return form_database_service_.get();
143}
144
145// Create user pref service for autofill functionality.
146void AwBrowserContext::CreateUserPrefServiceIfNecessary() {
147  if (user_pref_service_ready_)
148    return;
149
150  user_pref_service_ready_ = true;
151  PrefRegistrySimple* pref_registry = new PrefRegistrySimple();
152  // We only use the autocomplete feature of the Autofill, which is
153  // controlled via the manager_delegate. We don't use the rest
154  // of autofill, which is why it is hardcoded as disabled here.
155  pref_registry->RegisterBooleanPref(
156      autofill::prefs::kAutofillEnabled, false);
157  pref_registry->RegisterDoublePref(
158      autofill::prefs::kAutofillPositiveUploadRate, 0.0);
159  pref_registry->RegisterDoublePref(
160      autofill::prefs::kAutofillNegativeUploadRate, 0.0);
161
162  PrefServiceBuilder pref_service_builder;
163  pref_service_builder.WithUserPrefs(new AwPrefStore());
164  pref_service_builder.WithReadErrorCallback(base::Bind(&HandleReadError));
165
166  user_prefs::UserPrefs::Set(this,
167                             pref_service_builder.Create(pref_registry));
168}
169
170base::FilePath AwBrowserContext::GetPath() const {
171  return context_storage_path_;
172}
173
174bool AwBrowserContext::IsOffTheRecord() const {
175  // Android WebView does not support off the record profile yet.
176  return false;
177}
178
179net::URLRequestContextGetter* AwBrowserContext::GetRequestContext() {
180  return GetDefaultStoragePartition(this)->GetURLRequestContext();
181}
182
183net::URLRequestContextGetter*
184AwBrowserContext::GetRequestContextForRenderProcess(
185    int renderer_child_id) {
186  return GetRequestContext();
187}
188
189net::URLRequestContextGetter* AwBrowserContext::GetMediaRequestContext() {
190  return GetRequestContext();
191}
192
193void AwBrowserContext::RequestMIDISysExPermission(
194      int render_process_id,
195      int render_view_id,
196      const GURL& requesting_frame,
197      const MIDISysExPermissionCallback& callback) {
198  // TODO(toyoshim): Android is not supported yet.
199  callback.Run(false);
200}
201
202net::URLRequestContextGetter*
203AwBrowserContext::GetMediaRequestContextForRenderProcess(
204    int renderer_child_id) {
205  return GetRequestContext();
206}
207
208net::URLRequestContextGetter*
209AwBrowserContext::GetMediaRequestContextForStoragePartition(
210    const base::FilePath& partition_path,
211    bool in_memory) {
212  return GetRequestContext();
213}
214
215content::ResourceContext* AwBrowserContext::GetResourceContext() {
216  if (!resource_context_) {
217    CHECK(url_request_context_getter_.get());
218    resource_context_.reset(
219        new AwResourceContext(url_request_context_getter_.get()));
220  }
221  return resource_context_.get();
222}
223
224content::DownloadManagerDelegate*
225AwBrowserContext::GetDownloadManagerDelegate() {
226  return &download_manager_delegate_;
227}
228
229content::GeolocationPermissionContext*
230AwBrowserContext::GetGeolocationPermissionContext() {
231  if (!geolocation_permission_context_.get()) {
232    geolocation_permission_context_ =
233        native_factory_->CreateGeolocationPermission(this);
234  }
235  return geolocation_permission_context_.get();
236}
237
238quota::SpecialStoragePolicy* AwBrowserContext::GetSpecialStoragePolicy() {
239  // Intentionally returning NULL as 'Extensions' and 'Apps' not supported.
240  return NULL;
241}
242
243void AwBrowserContext::RebuildTable(
244    const scoped_refptr<URLEnumerator>& enumerator) {
245  // Android WebView rebuilds from WebChromeClient.getVisitedHistory. The client
246  // can change in the lifetime of this WebView and may not yet be set here.
247  // Therefore this initialization path is not used.
248  enumerator->OnComplete(true);
249}
250
251}  // namespace android_webview
252