1e99918cde88bfe98b34842d8df8b60f3302c806
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / xwalk_content_browser_client.cc
1 // Copyright (c) 2013 Intel Corporation. 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 "xwalk/runtime/browser/xwalk_content_browser_client.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/command_line.h"
11 #include "base/path_service.h"
12 #include "base/platform_file.h"
13 #include "content/public/browser/browser_main_parts.h"
14 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/resource_context.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/common/main_function_params.h"
18 #include "content/public/common/show_desktop_notification_params.h"
19 #include "net/ssl/ssl_info.h"
20 #include "net/url_request/url_request_context_getter.h"
21 #include "xwalk/extensions/common/xwalk_extension_switches.h"
22 #include "xwalk/runtime/browser/xwalk_browser_main_parts.h"
23 #include "xwalk/runtime/browser/geolocation/xwalk_access_token_store.h"
24 #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h"
25 #include "xwalk/runtime/browser/runtime_context.h"
26 #include "xwalk/runtime/browser/runtime_quota_permission_context.h"
27 #include "xwalk/runtime/browser/speech/speech_recognition_manager_delegate.h"
28 #include "xwalk/runtime/browser/xwalk_render_message_filter.h"
29 #include "xwalk/runtime/browser/xwalk_runner.h"
30
31 #if defined(OS_ANDROID)
32 #include "base/android/path_utils.h"
33 #include "base/base_paths_android.h"
34 #include "xwalk/runtime/browser/android/xwalk_cookie_access_policy.h"
35 #include "xwalk/runtime/browser/android/xwalk_contents_client_bridge.h"
36 #include "xwalk/runtime/browser/android/xwalk_web_contents_view_delegate.h"
37 #include "xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h"
38 #include "xwalk/runtime/browser/xwalk_browser_main_parts_android.h"
39 #include "xwalk/runtime/common/android/xwalk_globals_android.h"
40 #endif
41
42 #if defined(OS_MACOSX)
43 #include "xwalk/runtime/browser/xwalk_browser_main_parts_mac.h"
44 #endif
45
46 #if defined(OS_TIZEN)
47 #include "xwalk/application/browser/application_system.h"
48 #include "xwalk/application/browser/application_service.h"
49 #include "xwalk/application/browser/application.h"
50 #include "xwalk/application/common/application_manifest_constants.h"
51 #include "xwalk/application/common/manifest_handlers/navigation_handler.h"
52 #include "xwalk/application/common/constants.h"
53 #include "xwalk/runtime/browser/runtime_platform_util.h"
54 #include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"
55 #endif
56
57 namespace xwalk {
58
59 namespace {
60
61 // The application-wide singleton of ContentBrowserClient impl.
62 XWalkContentBrowserClient* g_browser_client = NULL;
63
64 }  // namespace
65
66 // static
67 XWalkContentBrowserClient* XWalkContentBrowserClient::Get() {
68   return g_browser_client;
69 }
70
71
72 XWalkContentBrowserClient::XWalkContentBrowserClient(XWalkRunner* xwalk_runner)
73     : xwalk_runner_(xwalk_runner),
74       url_request_context_getter_(NULL),
75       main_parts_(NULL) {
76   DCHECK(!g_browser_client);
77   g_browser_client = this;
78 }
79
80 XWalkContentBrowserClient::~XWalkContentBrowserClient() {
81   DCHECK(g_browser_client);
82   g_browser_client = NULL;
83 }
84
85 content::BrowserMainParts* XWalkContentBrowserClient::CreateBrowserMainParts(
86     const content::MainFunctionParams& parameters) {
87 #if defined(OS_MACOSX)
88   main_parts_ = new XWalkBrowserMainPartsMac(parameters);
89 #elif defined(OS_ANDROID)
90   main_parts_ = new XWalkBrowserMainPartsAndroid(parameters);
91 #elif defined(OS_TIZEN)
92   main_parts_ = new XWalkBrowserMainPartsTizen(parameters);
93 #else
94   main_parts_ = new XWalkBrowserMainParts(parameters);
95 #endif
96
97   return main_parts_;
98 }
99
100 net::URLRequestContextGetter* XWalkContentBrowserClient::CreateRequestContext(
101     content::BrowserContext* browser_context,
102     content::ProtocolHandlerMap* protocol_handlers,
103     content::ProtocolHandlerScopedVector protocol_interceptors) {
104   url_request_context_getter_ = static_cast<RuntimeContext*>(browser_context)->
105       CreateRequestContext(protocol_handlers, protocol_interceptors.Pass());
106   return url_request_context_getter_;
107 }
108
109 net::URLRequestContextGetter*
110 XWalkContentBrowserClient::CreateRequestContextForStoragePartition(
111     content::BrowserContext* browser_context,
112     const base::FilePath& partition_path,
113     bool in_memory,
114     content::ProtocolHandlerMap* protocol_handlers,
115     content::ProtocolHandlerScopedVector protocol_interceptors) {
116   return static_cast<RuntimeContext*>(browser_context)->
117       CreateRequestContextForStoragePartition(
118           partition_path, in_memory, protocol_handlers,
119           protocol_interceptors.Pass());
120 }
121
122 // This allow us to append extra command line switches to the child
123 // process we launch.
124 void XWalkContentBrowserClient::AppendExtraCommandLineSwitches(
125     CommandLine* command_line, int child_process_id) {
126   CommandLine* browser_process_cmd_line = CommandLine::ForCurrentProcess();
127   const int extra_switches_count = 1;
128   const char* extra_switches[extra_switches_count] = {
129     switches::kXWalkDisableExtensionProcess
130   };
131
132   for (int i = 0; i < extra_switches_count; i++) {
133     if (browser_process_cmd_line->HasSwitch(extra_switches[i]))
134       command_line->AppendSwitch(extra_switches[i]);
135   }
136 }
137
138 content::QuotaPermissionContext*
139 XWalkContentBrowserClient::CreateQuotaPermissionContext() {
140   return new RuntimeQuotaPermissionContext();
141 }
142
143 content::AccessTokenStore* XWalkContentBrowserClient::CreateAccessTokenStore() {
144   return new XWalkAccessTokenStore(url_request_context_getter_);
145 }
146
147 content::WebContentsViewDelegate*
148 XWalkContentBrowserClient::GetWebContentsViewDelegate(
149     content::WebContents* web_contents) {
150 #if defined(OS_ANDROID)
151   return new XWalkWebContentsViewDelegate(web_contents);
152 #else
153   return NULL;
154 #endif
155 }
156
157 void XWalkContentBrowserClient::RenderProcessWillLaunch(
158     content::RenderProcessHost* host) {
159   xwalk_runner_->OnRenderProcessWillLaunch(host);
160   host->AddFilter(new XWalkRenderMessageFilter);
161 }
162
163 content::MediaObserver* XWalkContentBrowserClient::GetMediaObserver() {
164   return XWalkMediaCaptureDevicesDispatcher::GetInstance();
165 }
166
167 bool XWalkContentBrowserClient::AllowGetCookie(
168     const GURL& url,
169     const GURL& first_party,
170     const net::CookieList& cookie_list,
171     content::ResourceContext* context,
172     int render_process_id,
173     int render_frame_id) {
174 #if defined(OS_ANDROID)
175   return XWalkCookieAccessPolicy::GetInstance()->AllowGetCookie(
176       url,
177       first_party,
178       cookie_list,
179       context,
180       render_process_id,
181       render_frame_id);
182 #else
183   return true;
184 #endif
185 }
186
187 bool XWalkContentBrowserClient::AllowSetCookie(
188     const GURL& url,
189     const GURL& first_party,
190     const std::string& cookie_line,
191     content::ResourceContext* context,
192     int render_process_id,
193     int render_frame_id,
194     net::CookieOptions* options) {
195 #if defined(OS_ANDROID)
196   return XWalkCookieAccessPolicy::GetInstance()->AllowSetCookie(
197       url,
198       first_party,
199       cookie_line,
200       context,
201       render_process_id,
202       render_frame_id,
203       options);
204 #else
205   return true;
206 #endif
207 }
208
209 void XWalkContentBrowserClient::AllowCertificateError(
210     int render_process_id,
211     int render_frame_id,
212     int cert_error,
213     const net::SSLInfo& ssl_info,
214     const GURL& request_url,
215     ResourceType::Type resource_type,
216     bool overridable,
217     bool strict_enforcement,
218     const base::Callback<void(bool)>& callback, // NOLINT
219     content::CertificateRequestResultType* result) {
220   // Currently only Android handles it.
221   // TODO(yongsheng): applies it for other platforms?
222 #if defined(OS_ANDROID)
223   XWalkContentsClientBridgeBase* client =
224       XWalkContentsClientBridgeBase::FromRenderFrameID(render_process_id,
225           render_frame_id);
226   bool cancel_request = true;
227   if (client)
228     client->AllowCertificateError(cert_error,
229                                   ssl_info.cert.get(),
230                                   request_url,
231                                   callback,
232                                   &cancel_request);
233   if (cancel_request)
234     *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
235 #endif
236 }
237
238 void XWalkContentBrowserClient::RequestDesktopNotificationPermission(
239     const GURL& source_origin,
240     int callback_context,
241     int render_process_id,
242     int render_view_id) {
243 }
244
245 blink::WebNotificationPresenter::Permission
246 XWalkContentBrowserClient::CheckDesktopNotificationPermission(
247     const GURL& source_url,
248     content::ResourceContext* context,
249     int render_process_id) {
250 #if defined(OS_ANDROID)
251   return blink::WebNotificationPresenter::PermissionAllowed;
252 #else
253   return blink::WebNotificationPresenter::PermissionNotAllowed;
254 #endif
255 }
256
257 void XWalkContentBrowserClient::ShowDesktopNotification(
258     const content::ShowDesktopNotificationHostMsgParams& params,
259     int render_process_id,
260     int render_view_id,
261     bool worker) {
262 #if defined(OS_ANDROID)
263   XWalkContentsClientBridgeBase* bridge =
264       XWalkContentsClientBridgeBase::FromRenderViewID(render_process_id,
265           render_view_id);
266   bridge->ShowNotification(params, worker, render_process_id, render_view_id);
267 #endif
268 }
269
270 void XWalkContentBrowserClient::CancelDesktopNotification(
271     int render_process_id,
272     int render_view_id,
273     int notification_id) {
274 #if defined(OS_ANDROID)
275   XWalkContentsClientBridgeBase* bridge =
276       XWalkContentsClientBridgeBase::FromRenderViewID(render_process_id,
277           render_view_id);
278   bridge->CancelNotification(
279       notification_id, render_process_id, render_view_id);
280 #endif
281 }
282
283 #if defined(OS_ANDROID)
284 void XWalkContentBrowserClient::ResourceDispatcherHostCreated() {
285   RuntimeResourceDispatcherHostDelegateAndroid::
286   ResourceDispatcherHostCreated();
287 }
288 #endif
289
290 content::SpeechRecognitionManagerDelegate*
291     XWalkContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
292   return new xwalk::XWalkSpeechRecognitionManagerDelegate();
293 }
294
295 #if defined(OS_TIZEN)
296 bool XWalkContentBrowserClient::CanCommitURL(
297     content::RenderProcessHost* process_host, const GURL& url) {
298   application::Application* app = xwalk_runner_->app_system()->
299       application_service()->GetApplicationByRenderHostID(
300           process_host->GetID());
301   DCHECK(app);
302   const application::ApplicationData* app_data =app->data();
303   if (!app_data->HasCSPDefined() ||
304       (url.SchemeIs(application::kApplicationScheme) &&
305        url.host() == app_data->ID()))
306     return true;
307
308   application::NavigationInfo* info = static_cast<application::NavigationInfo*>(
309       app_data->GetManifestData(application_widget_keys::kAllowNavigationKey));
310   if (!info || !url.SchemeIsHTTPOrHTTPS()) {
311     LOG(INFO) << "[Block] Navigation link: " << url.spec();
312     // FIXME: Blocked navigation link should be opened in system web browser,
313     // add corresponding code like this:
314     // platform_util::OpenExternal(url);
315     return false;
316   }
317
318   // Check whether the navigation url domain is listed in WGT <allow-navigation>
319   // element, if yes, display it in web application, otherwise block the
320   // request.
321   const std::vector<std::string>& allowed_list = info->GetAllowedDomains();
322   for (std::vector<std::string>::const_iterator it = allowed_list.begin();
323        it != allowed_list.end(); ++it) {
324     if ((*it).find("*.") == 0 &&
325         url.DomainIs((*it).substr(2).c_str())) {
326       LOG(INFO) << "[Allow] Navigation link: " << url.spec();
327       return true;
328     }
329
330     if (url.host() == *it) {
331       LOG(INFO) << "[Allow] Navigation link: " << url.spec();
332       return true;
333     }
334   }
335   LOG(INFO) << "[Block] navigation link: " << url.spec();
336   // FIXME: Should open blocked link in system web browser, need to add:
337   // platform_util::OpenExternal(url);
338   return false;
339 }
340 #endif
341
342 }  // namespace xwalk