1 // Copyright 2014 Samsung Electronics. 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.
5 #include "browser_context_efl.h"
7 #include "android_webview/browser/aw_pref_store.h"
9 #include "base/files/file_util.h"
10 #include "base/path_service.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/prefs/pref_service_factory.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "browser/autofill/personal_data_manager_factory.h"
16 #include "browser/geolocation/geolocation_permission_context_efl.h"
17 #include "browser/permission_manager_efl.h"
18 #include "browser/webdata/web_data_service_factory.h"
19 #include "browser/scoped_allow_wait_for_legacy_web_view_api.h"
20 #include "components/autofill/core/browser/personal_data_manager.h"
21 #include "components/autofill/core/common/autofill_pref_names.h"
22 #include "components/password_manager/core/common/password_manager_pref_names.h"
23 #include "components/user_prefs/user_prefs.h"
24 #include "components/visitedlink/browser/visitedlink_master.h"
25 #include "content/common/paths_efl.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/web_contents.h"
29 #include "eweb_context.h"
30 #include "network_delegate_efl.h"
32 using namespace autofill::prefs;
33 using namespace password_manager::prefs;
37 // Shows notifications which correspond to PersistentPrefStore's reading errors.
38 void HandleReadError(PersistentPrefStore::PrefReadError error) {
46 static void CreateNetworkDelegateOnIOThread(BrowserContextEfl* context,
47 base::WaitableEvent* completion) {
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
49 context->CreateNetworkDelegate();
53 BrowserContextEfl::ResourceContextEfl::ResourceContextEfl(scoped_refptr<CookieManager> cookie_manager)
55 cookie_manager_(cookie_manager) {
58 BrowserContextEfl::~BrowserContextEfl() {
59 #if defined(TIZEN_AUTOFILL_SUPPORT)
60 autofill::PersonalDataManagerFactory::GetInstance()
61 ->PersonalDataManagerRemove(this);
64 if (resource_context_) {
65 resource_context_->set_url_request_context_getter(NULL);
66 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, resource_context_);
70 BrowserContextEfl::ResourceContextEfl::~ResourceContextEfl() {
73 bool BrowserContextEfl::ResourceContextEfl::HTTPCustomHeaderAdd(
74 const std::string& name, const std::string& value) {
78 base::AutoLock locker(http_custom_headers_lock_);
79 return http_custom_headers_.insert(
80 std::make_pair(name, value)).second;
83 bool BrowserContextEfl::ResourceContextEfl::HTTPCustomHeaderRemove(
84 const std::string& name) {
85 base::AutoLock locker(http_custom_headers_lock_);
86 return http_custom_headers_.erase(name);
89 void BrowserContextEfl::ResourceContextEfl::HTTPCustomHeaderClear() {
90 base::AutoLock locker(http_custom_headers_lock_);
91 http_custom_headers_.clear();
94 const HTTPCustomHeadersEflMap
95 BrowserContextEfl::ResourceContextEfl::GetHTTPCustomHeadersEflMap() const {
96 base::AutoLock locker(http_custom_headers_lock_);
97 return http_custom_headers_;
101 net::HostResolver* BrowserContextEfl::ResourceContextEfl::GetHostResolver() {
102 CHECK(getter_.get());
103 return getter_->host_resolver();
106 net::URLRequestContext* BrowserContextEfl::ResourceContextEfl::GetRequestContext() {
107 CHECK(getter_.get());
108 return getter_->GetURLRequestContext();
111 void BrowserContextEfl::ResourceContextEfl::set_url_request_context_getter(
112 URLRequestContextGetterEfl* getter) {
116 scoped_refptr<CookieManager>
117 BrowserContextEfl::ResourceContextEfl::GetCookieManager() const {
118 return cookie_manager_;
121 BrowserContextEfl::BrowserContextEfl(EWebContext* web_context, bool incognito)
122 : resource_context_(NULL),
123 web_context_(web_context),
124 temp_dir_creation_attempted_(false),
125 incognito_(incognito) {
126 InitVisitedLinkMaster();
128 PrefRegistrySimple* pref_registry = new PrefRegistrySimple();
130 pref_registry->RegisterBooleanPref(kAutofillEnabled, true);
131 pref_registry->RegisterBooleanPref(kAutofillWalletSyncExperimentEnabled, false);
132 pref_registry->RegisterBooleanPref(kAutofillWalletImportEnabled, true);
133 pref_registry->RegisterBooleanPref(kPasswordManagerSavingEnabled, true);
135 base::PrefServiceFactory pref_service_factory;
136 pref_service_factory.set_user_prefs(make_scoped_refptr(new AwPrefStore));
137 pref_service_factory.set_read_error_callback(base::Bind(&HandleReadError));
138 user_pref_service_ = std::move(pref_service_factory.Create(pref_registry));
140 user_prefs::UserPrefs::Set(this, user_pref_service_.get());
142 #if defined(TIZEN_AUTOFILL_SUPPORT)
143 autofill::PersonalDataManagerFactory::GetInstance()
144 ->PersonalDataManagerAdd(this);
148 net::URLRequestContextGetter* BrowserContextEfl::GetRequestContext() {
149 if (!request_context_getter_.get()) {
150 // this will trigger a call to CreateRequestContext
151 GetStoragePartition(this, NULL);
152 DCHECK(request_context_getter_.get());
154 return request_context_getter_.get();
157 scoped_ptr<ZoomLevelDelegate> BrowserContextEfl::CreateZoomLevelDelegate(
158 const base::FilePath&) {
159 return scoped_ptr<ZoomLevelDelegate>();
162 ResourceContext* BrowserContextEfl::GetResourceContext() {
163 return GetResourceContextEfl();
166 BrowserContextEfl::ResourceContextEfl* BrowserContextEfl::GetResourceContextEfl() {
167 if (!resource_context_) {
168 resource_context_ = new ResourceContextEfl(web_context_->cookieManager());
170 return resource_context_;
173 // TODO Can this API be called from multiple threads?
174 base::FilePath BrowserContextEfl::GetPath() const {
175 if (IsOffTheRecord()) {
176 // Empty path indicates in memory storage. All data that would be persistent
177 // are stored in memory and are gone when closing browser, what is a
178 // requirement for the incognito mode (being off the record)
179 return base::FilePath();
182 // TODO: Figure out something better for data storage.
184 static base::FilePath path;
186 PathService::Get(PathsEfl::DIR_USER_DATA, &path);
190 PermissionManager* BrowserContextEfl::GetPermissionManager() {
191 if (!permission_manager_.get()) {
192 permission_manager_.reset(new PermissionManagerEfl());
194 return permission_manager_.get();
197 BackgroundSyncController* BrowserContextEfl::GetBackgroundSyncController() {
201 void BrowserContextEfl::CreateNetworkDelegate() {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
203 DCHECK(!network_delegate_for_getter_.get());
204 network_delegate_for_getter_.reset(
205 new net::NetworkDelegateEfl(web_context_->cookieManager()->GetWeakPtr()));
208 net::URLRequestContextGetter* BrowserContextEfl::CreateRequestContext(
209 content::ProtocolHandlerMap* protocol_handlers,
210 URLRequestInterceptorScopedVector request_interceptors) {
211 // TODO: Implement support for chromium network log
213 base::FilePath cache_base_path;
214 if (!PathService::Get(base::DIR_CACHE, &cache_base_path)) {
215 LOG(ERROR) << "Could not retrieve path to the cache directory";
219 if (!network_delegate_for_getter_.get()) {
220 // NetWorkDelegate must be created on IO thread
221 base::WaitableEvent done(false, false);
222 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
223 base::Bind(CreateNetworkDelegateOnIOThread, this, &done));
224 ScopedAllowWaitForLegacyWebViewApi allow_wait;
228 request_context_getter_ = new URLRequestContextGetterEfl(
229 std::move(network_delegate_for_getter_), false, cache_base_path,
230 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
231 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
232 protocol_handlers, std::move(request_interceptors), NULL);
233 web_context_->cookieManager()->SetRequestContextGetter(
234 request_context_getter_);
235 resource_context_->set_url_request_context_getter(
236 request_context_getter_.get());
237 return request_context_getter_.get();
240 void BrowserContextEfl::SetCertificate(const char* certificate_file) {
241 base::FilePath* certificate_path = new base::FilePath(certificate_file);
242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
243 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
244 base::Bind(&BrowserContextEfl::ReadCertificateAndAdd, base::Owned(certificate_path)));
247 void BrowserContextEfl::ReadCertificateAndAdd(base::FilePath* file_path) {
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
249 std::string cert_contents;
250 base::ReadFileToString(*file_path, &cert_contents);
251 scoped_refptr<net::X509Certificate> cert(net::X509Certificate::CreateFromBytes(
252 cert_contents.c_str(), cert_contents.size()));
254 DLOG(ERROR) << "User certificate could not be parsed.";
257 int err_code = net::CertDatabase::GetInstance()->CheckUserCert(cert.get());
258 if (net::OK != err_code) {
259 DLOG(ERROR) << "User certificate is not valid. Error code : " << err_code;
262 err_code = net::CertDatabase::GetInstance()->AddUserCert(cert.get());
263 if (net::OK != err_code) {
264 DLOG(ERROR) << "User certificate could not be added. Error code : " << err_code;
269 void BrowserContextEfl::InitVisitedLinkMaster() {
270 if (!IsOffTheRecord()) {
271 visitedlink_master_.reset(new visitedlink::VisitedLinkMaster(this, this, false));
272 visitedlink_master_->Init();
276 void BrowserContextEfl::AddVisitedURLs(const std::vector<GURL>& urls) {
277 if (!IsOffTheRecord()) {
278 DCHECK(visitedlink_master_);
279 visitedlink_master_->AddURLs(urls);
283 void BrowserContextEfl::RebuildTable(const scoped_refptr<URLEnumerator>& enumerator) {
284 if (!IsOffTheRecord()) {
285 // WebView rebuilds from WebChromeClient.getVisitedHistory. The client
286 // can change in the lifetime of this WebView and may not yet be set here.
287 // Therefore this initialization path is not used.
288 enumerator->OnComplete(true);
292 SSLHostStateDelegate* BrowserContextEfl::GetSSLHostStateDelegate() {
293 if (!ssl_host_state_delegate_.get())
294 ssl_host_state_delegate_.reset(new SSLHostStateDelegateEfl());
296 return ssl_host_state_delegate_.get();
299 const GeolocationPermissionContextEfl&
300 BrowserContextEfl::GetGeolocationPermissionContext() const {
301 if (!geolocation_permission_context_.get()) {
302 geolocation_permission_context_.reset(
303 new GeolocationPermissionContextEfl());
306 return *(geolocation_permission_context_.get());