1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
6 #include "xwalk/runtime/browser/xwalk_browser_context.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/path_service.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "components/visitedlink/browser/visitedlink_master.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/render_process_host.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 "content/public/common/content_switches.h"
23 #include "xwalk/application/browser/application.h"
24 #include "xwalk/application/browser/application_protocols.h"
25 #include "xwalk/application/browser/application_service.h"
26 #include "xwalk/application/browser/application_system.h"
27 #include "xwalk/application/common/constants.h"
28 #include "xwalk/runtime/browser/runtime_download_manager_delegate.h"
29 #include "xwalk/runtime/browser/runtime_geolocation_permission_context.h"
30 #include "xwalk/runtime/browser/runtime_url_request_context_getter.h"
31 #include "xwalk/runtime/browser/xwalk_runner.h"
32 #include "xwalk/runtime/common/xwalk_paths.h"
33 #include "xwalk/runtime/common/xwalk_switches.h"
35 #if defined(OS_ANDROID)
36 #include "base/strings/string_split.h"
39 using content::BrowserThread;
40 using content::DownloadManager;
44 class XWalkBrowserContext::RuntimeResourceContext :
45 public content::ResourceContext {
47 RuntimeResourceContext() : getter_(NULL) {}
48 virtual ~RuntimeResourceContext() {}
50 // ResourceContext implementation:
51 virtual net::HostResolver* GetHostResolver() OVERRIDE {
53 return getter_->host_resolver();
55 virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
57 return getter_->GetURLRequestContext();
60 void set_url_request_context_getter(RuntimeURLRequestContextGetter* getter) {
65 RuntimeURLRequestContextGetter* getter_;
67 DISALLOW_COPY_AND_ASSIGN(RuntimeResourceContext);
70 XWalkBrowserContext::XWalkBrowserContext()
71 : resource_context_(new RuntimeResourceContext) {
73 #if defined(OS_ANDROID)
74 InitVisitedLinkMaster();
78 XWalkBrowserContext::~XWalkBrowserContext() {
79 if (resource_context_.get()) {
80 BrowserThread::DeleteSoon(
81 BrowserThread::IO, FROM_HERE, resource_context_.release());
86 XWalkBrowserContext* XWalkBrowserContext::FromWebContents(
87 content::WebContents* web_contents) {
88 // This is safe; this is the only implementation of the browser context.
89 return static_cast<XWalkBrowserContext*>(
90 web_contents->GetBrowserContext());
93 void XWalkBrowserContext::InitWhileIOAllowed() {
94 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
95 if (cmd_line->HasSwitch(switches::kXWalkDataPath)) {
97 cmd_line->GetSwitchValuePath(switches::kXWalkDataPath);
98 PathService::OverrideAndCreateIfNeeded(
99 DIR_DATA_PATH, path, false, true);
103 base::FilePath XWalkBrowserContext::GetPath() const {
104 base::FilePath result;
105 #if defined(OS_ANDROID)
106 CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &result));
107 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
108 if (cmd_line->HasSwitch(switches::kXWalkProfileName))
109 result = result.Append(
110 cmd_line->GetSwitchValuePath(switches::kXWalkProfileName));
112 CHECK(PathService::Get(DIR_DATA_PATH, &result));
117 bool XWalkBrowserContext::IsOffTheRecord() const {
118 // We don't consider off the record scenario.
122 content::DownloadManagerDelegate*
123 XWalkBrowserContext::GetDownloadManagerDelegate() {
124 content::DownloadManager* manager = BrowserContext::GetDownloadManager(this);
126 if (!download_manager_delegate_.get()) {
127 download_manager_delegate_ = new RuntimeDownloadManagerDelegate();
128 download_manager_delegate_->SetDownloadManager(manager);
131 return download_manager_delegate_.get();
134 net::URLRequestContextGetter* XWalkBrowserContext::GetRequestContext() {
135 return GetDefaultStoragePartition(this)->GetURLRequestContext();
138 net::URLRequestContextGetter*
139 XWalkBrowserContext::GetRequestContextForRenderProcess(
140 int renderer_child_id) {
141 #if defined(OS_ANDROID)
142 return GetRequestContext();
144 content::RenderProcessHost* rph =
145 content::RenderProcessHost::FromID(renderer_child_id);
146 return rph->GetStoragePartition()->GetURLRequestContext();
150 net::URLRequestContextGetter* XWalkBrowserContext::GetMediaRequestContext() {
151 return GetRequestContext();
154 net::URLRequestContextGetter*
155 XWalkBrowserContext::GetMediaRequestContextForRenderProcess(
156 int renderer_child_id) {
157 #if defined(OS_ANDROID)
158 return GetRequestContext();
160 content::RenderProcessHost* rph =
161 content::RenderProcessHost::FromID(renderer_child_id);
162 return rph->GetStoragePartition()->GetURLRequestContext();
166 net::URLRequestContextGetter*
167 XWalkBrowserContext::GetMediaRequestContextForStoragePartition(
168 const base::FilePath& partition_path,
170 #if defined(OS_ANDROID)
171 return GetRequestContext();
173 PartitionPathContextGetterMap::iterator iter =
174 context_getters_.find(partition_path.value());
175 CHECK(iter != context_getters_.end());
176 return iter->second.get();
180 content::ResourceContext* XWalkBrowserContext::GetResourceContext() {
181 return resource_context_.get();
184 content::BrowserPluginGuestManager*
185 XWalkBrowserContext::GetGuestManager() {
189 storage::SpecialStoragePolicy* XWalkBrowserContext::GetSpecialStoragePolicy() {
193 content::PushMessagingService* XWalkBrowserContext::GetPushMessagingService() {
197 content::SSLHostStateDelegate* XWalkBrowserContext::GetSSLHostStateDelegate() {
201 RuntimeURLRequestContextGetter*
202 XWalkBrowserContext::GetURLRequestContextGetterById(
203 const std::string& pkg_id) {
204 for (PartitionPathContextGetterMap::iterator it = context_getters_.begin();
205 it != context_getters_.end(); ++it) {
206 if (it->first.find(pkg_id))
207 return it->second.get();
212 net::URLRequestContextGetter* XWalkBrowserContext::CreateRequestContext(
213 content::ProtocolHandlerMap* protocol_handlers,
214 content::URLRequestInterceptorScopedVector request_interceptors) {
215 DCHECK(!url_request_getter_.get());
217 application::ApplicationService* service =
218 XWalkRunner::GetInstance()->app_system()->application_service();
219 protocol_handlers->insert(std::pair<std::string,
220 linked_ptr<net::URLRequestJobFactory::ProtocolHandler> >(
221 application::kApplicationScheme,
222 application::CreateApplicationProtocolHandler(service)));
224 url_request_getter_ = new RuntimeURLRequestContextGetter(
225 false, /* ignore_certificate_error = false */
227 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
228 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
229 protocol_handlers, request_interceptors.Pass());
230 resource_context_->set_url_request_context_getter(url_request_getter_.get());
231 return url_request_getter_.get();
234 net::URLRequestContextGetter*
235 XWalkBrowserContext::CreateRequestContextForStoragePartition(
236 const base::FilePath& partition_path,
238 content::ProtocolHandlerMap* protocol_handlers,
239 content::URLRequestInterceptorScopedVector request_interceptors) {
240 #if defined(OS_ANDROID)
243 PartitionPathContextGetterMap::iterator iter =
244 context_getters_.find(partition_path.value());
245 if (iter != context_getters_.end())
246 return iter->second.get();
248 application::ApplicationService* service =
249 XWalkRunner::GetInstance()->app_system()->application_service();
250 protocol_handlers->insert(std::pair<std::string,
251 linked_ptr<net::URLRequestJobFactory::ProtocolHandler> >(
252 application::kApplicationScheme,
253 application::CreateApplicationProtocolHandler(service)));
255 scoped_refptr<RuntimeURLRequestContextGetter>
256 context_getter = new RuntimeURLRequestContextGetter(
257 false, /* ignore_certificate_error = false */
259 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
260 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
261 protocol_handlers, request_interceptors.Pass());
263 context_getters_.insert(
264 std::make_pair(partition_path.value(), context_getter));
265 // Make sure that the default url request getter has been initialized,
266 // please refer to https://crosswalk-project.org/jira/browse/XWALK-2890
268 if (!url_request_getter_.get())
269 CreateRequestContext(protocol_handlers, request_interceptors.Pass());
271 return context_getter.get();
275 #if defined(OS_ANDROID)
276 void XWalkBrowserContext::SetCSPString(const std::string& csp) {
277 // Check format of csp string.
278 std::vector<std::string> policies;
279 base::SplitString(csp, ';', &policies);
280 for (size_t i = 0; i < policies.size(); ++i) {
281 size_t found = policies[i].find(' ');
282 if (found == std::string::npos) {
283 LOG(INFO) << "Invalid value of directive: " << policies[i];
290 std::string XWalkBrowserContext::GetCSPString() const {
294 void XWalkBrowserContext::InitVisitedLinkMaster() {
295 visitedlink_master_.reset(
296 new visitedlink::VisitedLinkMaster(this, this, false));
297 visitedlink_master_->Init();
300 void XWalkBrowserContext::AddVisitedURLs(const std::vector<GURL>& urls) {
301 DCHECK(visitedlink_master_.get());
302 visitedlink_master_->AddURLs(urls);
305 void XWalkBrowserContext::RebuildTable(
306 const scoped_refptr<URLEnumerator>& enumerator) {
307 // XWalkView rebuilds from XWalkWebChromeClient.getVisitedHistory. The client
308 // can change in the lifetime of this XWalkView and may not yet be set here.
309 // Therefore this initialization path is not used.
310 enumerator->OnComplete(true);