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/runtime_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 RuntimeContext::RuntimeResourceContext : public content::ResourceContext {
46 RuntimeResourceContext() : getter_(NULL) {}
47 virtual ~RuntimeResourceContext() {}
49 // ResourceContext implementation:
50 virtual net::HostResolver* GetHostResolver() OVERRIDE {
52 return getter_->host_resolver();
54 virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
56 return getter_->GetURLRequestContext();
59 void set_url_request_context_getter(RuntimeURLRequestContextGetter* getter) {
64 RuntimeURLRequestContextGetter* getter_;
66 DISALLOW_COPY_AND_ASSIGN(RuntimeResourceContext);
69 RuntimeContext::RuntimeContext()
70 : resource_context_(new RuntimeResourceContext) {
72 #if defined(OS_ANDROID)
73 InitVisitedLinkMaster();
77 RuntimeContext::~RuntimeContext() {
78 if (resource_context_.get()) {
79 BrowserThread::DeleteSoon(
80 BrowserThread::IO, FROM_HERE, resource_context_.release());
85 RuntimeContext* RuntimeContext::FromWebContents(
86 content::WebContents* web_contents) {
87 // This is safe; this is the only implementation of the browser context.
88 return static_cast<RuntimeContext*>(web_contents->GetBrowserContext());
91 void RuntimeContext::InitWhileIOAllowed() {
92 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
93 if (cmd_line->HasSwitch(switches::kXWalkDataPath)) {
95 cmd_line->GetSwitchValuePath(switches::kXWalkDataPath);
96 PathService::OverrideAndCreateIfNeeded(
97 xwalk::DIR_DATA_PATH, path, false, true);
101 base::FilePath RuntimeContext::GetPath() const {
102 base::FilePath result;
103 #if defined(OS_ANDROID)
104 CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &result));
105 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
106 if (cmd_line->HasSwitch(switches::kXWalkProfileName))
107 result = result.Append(
108 cmd_line->GetSwitchValuePath(switches::kXWalkProfileName));
110 CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &result));
115 bool RuntimeContext::IsOffTheRecord() const {
116 // We don't consider off the record scenario.
120 content::DownloadManagerDelegate* RuntimeContext::GetDownloadManagerDelegate() {
121 content::DownloadManager* manager = BrowserContext::GetDownloadManager(this);
123 if (!download_manager_delegate_.get()) {
124 download_manager_delegate_ = new RuntimeDownloadManagerDelegate();
125 download_manager_delegate_->SetDownloadManager(manager);
128 return download_manager_delegate_.get();
131 net::URLRequestContextGetter* RuntimeContext::GetRequestContext() {
132 return GetDefaultStoragePartition(this)->GetURLRequestContext();
135 net::URLRequestContextGetter*
136 RuntimeContext::GetRequestContextForRenderProcess(
137 int renderer_child_id) {
138 #if defined(OS_ANDROID)
139 return GetRequestContext();
141 content::RenderProcessHost* rph =
142 content::RenderProcessHost::FromID(renderer_child_id);
143 return rph->GetStoragePartition()->GetURLRequestContext();
147 net::URLRequestContextGetter* RuntimeContext::GetMediaRequestContext() {
148 return GetRequestContext();
151 net::URLRequestContextGetter*
152 RuntimeContext::GetMediaRequestContextForRenderProcess(
153 int renderer_child_id) {
154 #if defined(OS_ANDROID)
155 return GetRequestContext();
157 content::RenderProcessHost* rph =
158 content::RenderProcessHost::FromID(renderer_child_id);
159 return rph->GetStoragePartition()->GetURLRequestContext();
163 net::URLRequestContextGetter*
164 RuntimeContext::GetMediaRequestContextForStoragePartition(
165 const base::FilePath& partition_path,
167 #if defined(OS_ANDROID)
168 return GetRequestContext();
170 PartitionPathContextGetterMap::iterator iter =
171 context_getters_.find(partition_path.value());
172 CHECK(iter != context_getters_.end());
173 return iter->second.get();
177 content::ResourceContext* RuntimeContext::GetResourceContext() {
178 return resource_context_.get();
181 content::BrowserPluginGuestManager*
182 RuntimeContext::GetGuestManager() {
186 storage::SpecialStoragePolicy* RuntimeContext::GetSpecialStoragePolicy() {
190 content::PushMessagingService* RuntimeContext::GetPushMessagingService() {
194 content::SSLHostStateDelegate* RuntimeContext::GetSSLHostStateDelegate() {
198 RuntimeURLRequestContextGetter* RuntimeContext::GetURLRequestContextGetterById(
199 const std::string& pkg_id) {
200 for (PartitionPathContextGetterMap::iterator it = context_getters_.begin();
201 it != context_getters_.end(); ++it) {
202 if (it->first.find(pkg_id))
203 return it->second.get();
208 net::URLRequestContextGetter* RuntimeContext::CreateRequestContext(
209 content::ProtocolHandlerMap* protocol_handlers,
210 content::URLRequestInterceptorScopedVector request_interceptors) {
211 DCHECK(!url_request_getter_.get());
213 application::ApplicationService* service =
214 XWalkRunner::GetInstance()->app_system()->application_service();
215 protocol_handlers->insert(std::pair<std::string,
216 linked_ptr<net::URLRequestJobFactory::ProtocolHandler> >(
217 application::kApplicationScheme,
218 application::CreateApplicationProtocolHandler(service)));
220 url_request_getter_ = new RuntimeURLRequestContextGetter(
221 false, /* ignore_certificate_error = false */
223 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
224 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
225 protocol_handlers, request_interceptors.Pass());
226 resource_context_->set_url_request_context_getter(url_request_getter_.get());
227 return url_request_getter_.get();
230 net::URLRequestContextGetter*
231 RuntimeContext::CreateRequestContextForStoragePartition(
232 const base::FilePath& partition_path,
234 content::ProtocolHandlerMap* protocol_handlers,
235 content::URLRequestInterceptorScopedVector request_interceptors) {
236 #if defined(OS_ANDROID)
239 PartitionPathContextGetterMap::iterator iter =
240 context_getters_.find(partition_path.value());
241 if (iter != context_getters_.end())
242 return iter->second.get();
244 application::ApplicationService* service =
245 XWalkRunner::GetInstance()->app_system()->application_service();
246 protocol_handlers->insert(std::pair<std::string,
247 linked_ptr<net::URLRequestJobFactory::ProtocolHandler> >(
248 application::kApplicationScheme,
249 application::CreateApplicationProtocolHandler(service)));
251 scoped_refptr<RuntimeURLRequestContextGetter>
252 context_getter = new RuntimeURLRequestContextGetter(
253 false, /* ignore_certificate_error = false */
255 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
256 BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
257 protocol_handlers, request_interceptors.Pass());
259 context_getters_.insert(
260 std::make_pair(partition_path.value(), context_getter));
261 // Make sure that the default url request getter has been initialized,
262 // please refer to https://crosswalk-project.org/jira/browse/XWALK-2890
264 if (!url_request_getter_.get())
265 CreateRequestContext(protocol_handlers, request_interceptors.Pass());
267 return context_getter.get();
271 #if defined(OS_ANDROID)
272 void RuntimeContext::SetCSPString(const std::string& csp) {
273 // Check format of csp string.
274 std::vector<std::string> policies;
275 base::SplitString(csp, ';', &policies);
276 for (size_t i = 0; i < policies.size(); ++i) {
277 size_t found = policies[i].find(' ');
278 if (found == std::string::npos) {
279 LOG(INFO) << "Invalid value of directive: " << policies[i];
286 std::string RuntimeContext::GetCSPString() const {
290 void RuntimeContext::InitVisitedLinkMaster() {
291 visitedlink_master_.reset(
292 new visitedlink::VisitedLinkMaster(this, this, false));
293 visitedlink_master_->Init();
296 void RuntimeContext::AddVisitedURLs(const std::vector<GURL>& urls) {
297 DCHECK(visitedlink_master_.get());
298 visitedlink_master_->AddURLs(urls);
301 void RuntimeContext::RebuildTable(
302 const scoped_refptr<URLEnumerator>& enumerator) {
303 // XWalkView rebuilds from XWalkWebChromeClient.getVisitedHistory. The client
304 // can change in the lifetime of this XWalkView and may not yet be set here.
305 // Therefore this initialization path is not used.
306 enumerator->OnComplete(true);