Upstream version 11.39.252.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / runtime_context.cc
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.
5
6 #include "xwalk/runtime/browser/runtime_context.h"
7
8 #include <string>
9 #include <utility>
10 #include <vector>
11
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"
34
35 #if defined(OS_ANDROID)
36 #include "base/strings/string_split.h"
37 #endif
38
39 using content::BrowserThread;
40 using content::DownloadManager;
41
42 namespace xwalk {
43
44 class RuntimeContext::RuntimeResourceContext : public content::ResourceContext {
45  public:
46   RuntimeResourceContext() : getter_(NULL) {}
47   virtual ~RuntimeResourceContext() {}
48
49   // ResourceContext implementation:
50   virtual net::HostResolver* GetHostResolver() OVERRIDE {
51     CHECK(getter_);
52     return getter_->host_resolver();
53   }
54   virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
55     CHECK(getter_);
56     return getter_->GetURLRequestContext();
57   }
58
59   void set_url_request_context_getter(RuntimeURLRequestContextGetter* getter) {
60     getter_ = getter;
61   }
62
63  private:
64   RuntimeURLRequestContextGetter* getter_;
65
66   DISALLOW_COPY_AND_ASSIGN(RuntimeResourceContext);
67 };
68
69 RuntimeContext::RuntimeContext()
70   : resource_context_(new RuntimeResourceContext) {
71   InitWhileIOAllowed();
72 #if defined(OS_ANDROID)
73   InitVisitedLinkMaster();
74 #endif
75 }
76
77 RuntimeContext::~RuntimeContext() {
78   if (resource_context_.get()) {
79     BrowserThread::DeleteSoon(
80         BrowserThread::IO, FROM_HERE, resource_context_.release());
81   }
82 }
83
84 // static
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());
89 }
90
91 void RuntimeContext::InitWhileIOAllowed() {
92   CommandLine* cmd_line = CommandLine::ForCurrentProcess();
93   if (cmd_line->HasSwitch(switches::kXWalkDataPath)) {
94     base::FilePath path =
95         cmd_line->GetSwitchValuePath(switches::kXWalkDataPath);
96     PathService::OverrideAndCreateIfNeeded(
97         xwalk::DIR_DATA_PATH, path, false, true);
98   }
99 }
100
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));
109 #else
110   CHECK(PathService::Get(xwalk::DIR_DATA_PATH, &result));
111 #endif
112   return result;
113 }
114
115 bool RuntimeContext::IsOffTheRecord() const {
116   // We don't consider off the record scenario.
117   return false;
118 }
119
120 content::DownloadManagerDelegate* RuntimeContext::GetDownloadManagerDelegate() {
121   content::DownloadManager* manager = BrowserContext::GetDownloadManager(this);
122
123   if (!download_manager_delegate_.get()) {
124     download_manager_delegate_ = new RuntimeDownloadManagerDelegate();
125     download_manager_delegate_->SetDownloadManager(manager);
126   }
127
128   return download_manager_delegate_.get();
129 }
130
131 net::URLRequestContextGetter* RuntimeContext::GetRequestContext() {
132   return GetDefaultStoragePartition(this)->GetURLRequestContext();
133 }
134
135 net::URLRequestContextGetter*
136     RuntimeContext::GetRequestContextForRenderProcess(
137         int renderer_child_id) {
138 #if defined(OS_ANDROID)
139   return GetRequestContext();
140 #else
141   content::RenderProcessHost* rph =
142       content::RenderProcessHost::FromID(renderer_child_id);
143   return rph->GetStoragePartition()->GetURLRequestContext();
144 #endif
145 }
146
147 net::URLRequestContextGetter* RuntimeContext::GetMediaRequestContext() {
148   return GetRequestContext();
149 }
150
151 net::URLRequestContextGetter*
152     RuntimeContext::GetMediaRequestContextForRenderProcess(
153         int renderer_child_id) {
154 #if defined(OS_ANDROID)
155   return GetRequestContext();
156 #else
157   content::RenderProcessHost* rph =
158       content::RenderProcessHost::FromID(renderer_child_id);
159   return rph->GetStoragePartition()->GetURLRequestContext();
160 #endif
161 }
162
163 net::URLRequestContextGetter*
164     RuntimeContext::GetMediaRequestContextForStoragePartition(
165         const base::FilePath& partition_path,
166         bool in_memory) {
167 #if defined(OS_ANDROID)
168   return GetRequestContext();
169 #else
170   PartitionPathContextGetterMap::iterator iter =
171       context_getters_.find(partition_path.value());
172   CHECK(iter != context_getters_.end());
173   return iter->second.get();
174 #endif
175 }
176
177 content::ResourceContext* RuntimeContext::GetResourceContext()  {
178   return resource_context_.get();
179 }
180
181 content::BrowserPluginGuestManager*
182 RuntimeContext::GetGuestManager() {
183   return NULL;
184 }
185
186 storage::SpecialStoragePolicy* RuntimeContext::GetSpecialStoragePolicy() {
187   return NULL;
188 }
189
190 content::PushMessagingService* RuntimeContext::GetPushMessagingService() {
191   return NULL;
192 }
193
194 content::SSLHostStateDelegate* RuntimeContext::GetSSLHostStateDelegate() {
195   return NULL;
196 }
197
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();
204   }
205   return 0;
206 }
207
208 net::URLRequestContextGetter* RuntimeContext::CreateRequestContext(
209     content::ProtocolHandlerMap* protocol_handlers,
210     content::URLRequestInterceptorScopedVector request_interceptors) {
211   DCHECK(!url_request_getter_.get());
212
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)));
219
220   url_request_getter_ = new RuntimeURLRequestContextGetter(
221       false, /* ignore_certificate_error = false */
222       GetPath(),
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();
228 }
229
230 net::URLRequestContextGetter*
231   RuntimeContext::CreateRequestContextForStoragePartition(
232       const base::FilePath& partition_path,
233       bool in_memory,
234       content::ProtocolHandlerMap* protocol_handlers,
235       content::URLRequestInterceptorScopedVector request_interceptors) {
236 #if defined(OS_ANDROID)
237     return NULL;
238 #else
239   PartitionPathContextGetterMap::iterator iter =
240     context_getters_.find(partition_path.value());
241   if (iter != context_getters_.end())
242     return iter->second.get();
243
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)));
250
251   scoped_refptr<RuntimeURLRequestContextGetter>
252   context_getter = new RuntimeURLRequestContextGetter(
253       false, /* ignore_certificate_error = false */
254       partition_path,
255       BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
256       BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
257       protocol_handlers, request_interceptors.Pass());
258
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
263   // for more details.
264   if (!url_request_getter_.get())
265     CreateRequestContext(protocol_handlers, request_interceptors.Pass());
266
267   return context_getter.get();
268 #endif
269 }
270
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];
280       return;
281     }
282   }
283   csp_ = csp;
284 }
285
286 std::string RuntimeContext::GetCSPString() const {
287   return csp_;
288 }
289
290 void RuntimeContext::InitVisitedLinkMaster() {
291   visitedlink_master_.reset(
292       new visitedlink::VisitedLinkMaster(this, this, false));
293   visitedlink_master_->Init();
294 }
295
296 void RuntimeContext::AddVisitedURLs(const std::vector<GURL>& urls) {
297   DCHECK(visitedlink_master_.get());
298   visitedlink_master_->AddURLs(urls);
299 }
300
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);
307 }
308 #endif
309
310 }  // namespace xwalk