Upstream version 11.39.256.0
[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/files/file.h"
13 #include "content/public/browser/browser_child_process_host.h"
14 #include "content/public/browser/browser_main_parts.h"
15 #include "content/public/browser/browser_ppapi_host.h"
16 #include "content/public/browser/child_process_data.h"
17 #include "content/public/browser/render_frame_host.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/resource_context.h"
20 #include "content/public/browser/resource_dispatcher_host.h"
21 #include "content/public/browser/storage_partition.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/common/main_function_params.h"
24 #include "content/public/common/show_desktop_notification_params.h"
25 #include "net/ssl/ssl_info.h"
26 #include "net/url_request/url_request_context_getter.h"
27 #include "ppapi/host/ppapi_host.h"
28 #include "xwalk/extensions/common/xwalk_extension_switches.h"
29 #include "xwalk/application/common/constants.h"
30 #include "xwalk/runtime/browser/devtools/xwalk_devtools_delegate.h"
31 #include "xwalk/runtime/browser/geolocation/xwalk_access_token_store.h"
32 #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h"
33 #include "xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h"
34 #include "xwalk/runtime/browser/runtime_quota_permission_context.h"
35 #include "xwalk/runtime/browser/speech/speech_recognition_manager_delegate.h"
36 #include "xwalk/runtime/browser/xwalk_browser_context.h"
37 #include "xwalk/runtime/browser/xwalk_browser_main_parts.h"
38 #include "xwalk/runtime/browser/xwalk_render_message_filter.h"
39 #include "xwalk/runtime/browser/xwalk_runner.h"
40 #include "xwalk/runtime/common/xwalk_paths.h"
41
42 #if !defined(DISABLE_NACL)
43 #include "components/nacl/browser/nacl_browser.h"
44 #include "components/nacl/browser/nacl_host_message_filter.h"
45 #include "components/nacl/browser/nacl_process_host.h"
46 #include "components/nacl/common/nacl_process_type.h"
47 #endif
48
49 #if defined(OS_ANDROID)
50 #include "base/android/path_utils.h"
51 #include "base/base_paths_android.h"
52 #include "xwalk/runtime/browser/android/xwalk_cookie_access_policy.h"
53 #include "xwalk/runtime/browser/android/xwalk_contents_client_bridge.h"
54 #include "xwalk/runtime/browser/android/xwalk_web_contents_view_delegate.h"
55 #include "xwalk/runtime/browser/xwalk_browser_main_parts_android.h"
56 #include "xwalk/runtime/common/android/xwalk_globals_android.h"
57 #else
58 #include "xwalk/application/browser/application_system.h"
59 #include "xwalk/application/browser/application_service.h"
60 #include "xwalk/application/browser/application.h"
61 #endif
62
63 #if defined(OS_MACOSX)
64 #include "xwalk/runtime/browser/xwalk_browser_main_parts_mac.h"
65 #endif
66
67 #if defined(OS_TIZEN)
68 #include "xwalk/application/common/application_manifest_constants.h"
69 #include "xwalk/runtime/browser/geolocation/tizen/location_provider_tizen.h"
70 #include "xwalk/runtime/browser/runtime_platform_util.h"
71 #include "xwalk/runtime/browser/tizen/xwalk_web_contents_view_delegate.h"
72 #include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"
73 #endif
74
75 namespace xwalk {
76
77 namespace {
78
79 // The application-wide singleton of ContentBrowserClient impl.
80 XWalkContentBrowserClient* g_browser_client = NULL;
81
82 }  // namespace
83
84 // static
85 XWalkContentBrowserClient* XWalkContentBrowserClient::Get() {
86   return g_browser_client;
87 }
88
89
90 XWalkContentBrowserClient::XWalkContentBrowserClient(XWalkRunner* xwalk_runner)
91     : xwalk_runner_(xwalk_runner),
92       url_request_context_getter_(NULL),
93       main_parts_(NULL),
94       browser_context_(NULL) {
95   DCHECK(!g_browser_client);
96   g_browser_client = this;
97 }
98
99 XWalkContentBrowserClient::~XWalkContentBrowserClient() {
100   DCHECK(g_browser_client);
101   g_browser_client = NULL;
102 }
103
104 content::BrowserMainParts* XWalkContentBrowserClient::CreateBrowserMainParts(
105     const content::MainFunctionParams& parameters) {
106 #if defined(OS_MACOSX)
107   main_parts_ = new XWalkBrowserMainPartsMac(parameters);
108 #elif defined(OS_ANDROID)
109   main_parts_ = new XWalkBrowserMainPartsAndroid(parameters);
110 #elif defined(OS_TIZEN)
111   main_parts_ = new XWalkBrowserMainPartsTizen(parameters);
112 #else
113   main_parts_ = new XWalkBrowserMainParts(parameters);
114 #endif
115
116   return main_parts_;
117 }
118
119 net::URLRequestContextGetter* XWalkContentBrowserClient::CreateRequestContext(
120     content::BrowserContext* browser_context,
121     content::ProtocolHandlerMap* protocol_handlers,
122     content::URLRequestInterceptorScopedVector request_interceptors) {
123   browser_context_ = static_cast<XWalkBrowserContext*>(browser_context);
124   url_request_context_getter_ = browser_context_->
125       CreateRequestContext(protocol_handlers, request_interceptors.Pass());
126   return url_request_context_getter_;
127 }
128
129 net::URLRequestContextGetter*
130 XWalkContentBrowserClient::CreateRequestContextForStoragePartition(
131     content::BrowserContext* browser_context,
132     const base::FilePath& partition_path,
133     bool in_memory,
134     content::ProtocolHandlerMap* protocol_handlers,
135     content::URLRequestInterceptorScopedVector request_interceptors) {
136   return static_cast<XWalkBrowserContext*>(browser_context)->
137       CreateRequestContextForStoragePartition(
138           partition_path, in_memory, protocol_handlers,
139           request_interceptors.Pass());
140 }
141
142 // This allow us to append extra command line switches to the child
143 // process we launch.
144 void XWalkContentBrowserClient::AppendExtraCommandLineSwitches(
145     CommandLine* command_line, int child_process_id) {
146   CommandLine* browser_process_cmd_line = CommandLine::ForCurrentProcess();
147   const int extra_switches_count = 1;
148   const char* extra_switches[extra_switches_count] = {
149     switches::kXWalkDisableExtensionProcess
150   };
151
152   for (int i = 0; i < extra_switches_count; i++) {
153     if (browser_process_cmd_line->HasSwitch(extra_switches[i]))
154       command_line->AppendSwitch(extra_switches[i]);
155   }
156 }
157
158 content::QuotaPermissionContext*
159 XWalkContentBrowserClient::CreateQuotaPermissionContext() {
160   return new RuntimeQuotaPermissionContext();
161 }
162
163 content::AccessTokenStore* XWalkContentBrowserClient::CreateAccessTokenStore() {
164   return new XWalkAccessTokenStore(url_request_context_getter_);
165 }
166
167 content::WebContentsViewDelegate*
168 XWalkContentBrowserClient::GetWebContentsViewDelegate(
169     content::WebContents* web_contents) {
170 #if defined(OS_ANDROID)
171   return new XWalkWebContentsViewDelegate(web_contents);
172 #elif defined(OS_TIZEN)
173   return new XWalkWebContentsViewDelegate(
174       web_contents, xwalk_runner_->app_system()->application_service());
175 #else
176   return NULL;
177 #endif
178 }
179
180 void XWalkContentBrowserClient::RenderProcessWillLaunch(
181     content::RenderProcessHost* host) {
182 #if !defined(DISABLE_NACL)
183   int id = host->GetID();
184   net::URLRequestContextGetter* context =
185       host->GetStoragePartition()->GetURLRequestContext();
186
187   host->AddFilter(new nacl::NaClHostMessageFilter(
188       id,
189       // TODO(Halton): IsOffTheRecord?
190       false,
191       host->GetBrowserContext()->GetPath(),
192       context));
193 #endif
194   xwalk_runner_->OnRenderProcessWillLaunch(host);
195   host->AddFilter(new XWalkRenderMessageFilter);
196 }
197
198 content::MediaObserver* XWalkContentBrowserClient::GetMediaObserver() {
199   return XWalkMediaCaptureDevicesDispatcher::GetInstance();
200 }
201
202 bool XWalkContentBrowserClient::AllowGetCookie(
203     const GURL& url,
204     const GURL& first_party,
205     const net::CookieList& cookie_list,
206     content::ResourceContext* context,
207     int render_process_id,
208     int render_frame_id) {
209 #if defined(OS_ANDROID)
210   return XWalkCookieAccessPolicy::GetInstance()->AllowGetCookie(
211       url,
212       first_party,
213       cookie_list,
214       context,
215       render_process_id,
216       render_frame_id);
217 #else
218   return true;
219 #endif
220 }
221
222 bool XWalkContentBrowserClient::AllowSetCookie(
223     const GURL& url,
224     const GURL& first_party,
225     const std::string& cookie_line,
226     content::ResourceContext* context,
227     int render_process_id,
228     int render_frame_id,
229     net::CookieOptions* options) {
230 #if defined(OS_ANDROID)
231   return XWalkCookieAccessPolicy::GetInstance()->AllowSetCookie(
232       url,
233       first_party,
234       cookie_line,
235       context,
236       render_process_id,
237       render_frame_id,
238       options);
239 #else
240   return true;
241 #endif
242 }
243
244 void XWalkContentBrowserClient::AllowCertificateError(
245     int render_process_id,
246     int render_frame_id,
247     int cert_error,
248     const net::SSLInfo& ssl_info,
249     const GURL& request_url,
250     content::ResourceType resource_type,
251     bool overridable,
252     bool strict_enforcement,
253     bool expired_previous_decision,
254     const base::Callback<void(bool)>& callback, // NOLINT
255     content::CertificateRequestResultType* result) {
256   // Currently only Android handles it.
257   // TODO(yongsheng): applies it for other platforms?
258 #if defined(OS_ANDROID)
259   XWalkContentsClientBridgeBase* client =
260       XWalkContentsClientBridgeBase::FromRenderFrameID(render_process_id,
261           render_frame_id);
262   bool cancel_request = true;
263   if (client)
264     client->AllowCertificateError(cert_error,
265                                   ssl_info.cert.get(),
266                                   request_url,
267                                   callback,
268                                   &cancel_request);
269   if (cancel_request)
270     *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
271 #endif
272 }
273
274 void XWalkContentBrowserClient::RequestDesktopNotificationPermission(
275     const GURL& source_origin,
276     content::RenderFrameHost* render_frame_host,
277     const base::Callback<void(blink::WebNotificationPermission)>& callback) {
278 }
279
280 blink::WebNotificationPermission
281 XWalkContentBrowserClient::CheckDesktopNotificationPermission(
282     const GURL& source_url,
283     content::ResourceContext* context,
284     int render_process_id) {
285 #if defined(OS_ANDROID)
286   return blink::WebNotificationPermissionAllowed;
287 #else
288   return blink::WebNotificationPermissionDenied;
289 #endif
290 }
291
292 void XWalkContentBrowserClient::ShowDesktopNotification(
293     const content::ShowDesktopNotificationHostMsgParams& params,
294     content::RenderFrameHost* render_frame_host,
295     scoped_ptr<content::DesktopNotificationDelegate> delegate,
296     base::Closure* cancel_callback) {
297 #if defined(OS_ANDROID)
298   XWalkContentsClientBridgeBase* bridge =
299       XWalkContentsClientBridgeBase::FromRenderFrameHost(render_frame_host);
300   bridge->ShowNotification(params, render_frame_host,
301       delegate.Pass(), cancel_callback);
302 #endif
303 }
304
305 void XWalkContentBrowserClient::RequestGeolocationPermission(
306     content::WebContents* web_contents,
307     int bridge_id,
308     const GURL& requesting_frame,
309     bool user_gesture,
310     base::Callback<void(bool)> result_callback,
311     base::Closure* cancel_callback) {
312 #if defined(OS_ANDROID) || defined(OS_TIZEN)
313   if (!geolocation_permission_context_.get()) {
314     geolocation_permission_context_ =
315       new RuntimeGeolocationPermissionContext();
316   }
317   geolocation_permission_context_->RequestGeolocationPermission(
318     web_contents,
319     requesting_frame,
320     result_callback,
321     cancel_callback);
322 #else
323   result_callback.Run(false);
324 #endif
325 }
326
327 void XWalkContentBrowserClient::DidCreatePpapiPlugin(
328     content::BrowserPpapiHost* browser_host) {
329 #if defined(ENABLE_PLUGINS)
330   browser_host->GetPpapiHost()->AddHostFactoryFilter(
331       scoped_ptr<ppapi::host::HostFactory>(
332           new XWalkBrowserPepperHostFactory(browser_host)));
333 #endif
334 }
335
336 content::BrowserPpapiHost*
337     XWalkContentBrowserClient::GetExternalBrowserPpapiHost(
338         int plugin_process_id) {
339 #if !defined(DISABLE_NACL)
340   content::BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_LOADER);
341   while (!iter.Done()) {
342     nacl::NaClProcessHost* host = static_cast<nacl::NaClProcessHost*>(
343         iter.GetDelegate());
344     if (host->process() &&
345         host->process()->GetData().id == plugin_process_id) {
346       // Found the plugin.
347       return host->browser_ppapi_host();
348     }
349     ++iter;
350   }
351 #endif
352   return NULL;
353 }
354
355 #if defined(OS_ANDROID) || defined(OS_TIZEN)  || defined(OS_LINUX)
356 void XWalkContentBrowserClient::ResourceDispatcherHostCreated() {
357   resource_dispatcher_host_delegate_ =
358       (RuntimeResourceDispatcherHostDelegate::Create()).Pass();
359   content::ResourceDispatcherHost::Get()->SetDelegate(
360       resource_dispatcher_host_delegate_.get());
361 }
362 #endif
363
364 content::SpeechRecognitionManagerDelegate*
365     XWalkContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
366   return new xwalk::XWalkSpeechRecognitionManagerDelegate();
367 }
368
369 #if !defined(OS_ANDROID)
370 bool XWalkContentBrowserClient::CanCreateWindow(const GURL& opener_url,
371                              const GURL& opener_top_level_frame_url,
372                              const GURL& source_origin,
373                              WindowContainerType container_type,
374                              const GURL& target_url,
375                              const content::Referrer& referrer,
376                              WindowOpenDisposition disposition,
377                              const blink::WebWindowFeatures& features,
378                              bool user_gesture,
379                              bool opener_suppressed,
380                              content::ResourceContext* context,
381                              int render_process_id,
382                              int opener_id,
383                              bool* no_javascript_access) {
384   *no_javascript_access = false;
385   application::Application* app = xwalk_runner_->app_system()->
386       application_service()->GetApplicationByRenderHostID(render_process_id);
387   if (!app)
388     // If it's not a request from an application, always enable this action.
389     return true;
390
391   if (app->CanRequestURL(target_url)) {
392     LOG(INFO) << "[ALLOW] CreateWindow: " << target_url.spec();
393     return true;
394   }
395
396   LOG(INFO) << "[BlOCK] CreateWindow: " << target_url.spec();
397 #if defined(OS_TIZEN)
398   platform_util::OpenExternal(target_url);
399 #endif
400   return false;
401 }
402 #endif
403
404 content::LocationProvider*
405 XWalkContentBrowserClient::OverrideSystemLocationProvider() {
406 #if defined(OS_TIZEN)
407   return new LocationProviderTizen();
408 #else
409   return nullptr;
410 #endif
411 }
412
413 void XWalkContentBrowserClient::GetStoragePartitionConfigForSite(
414     content::BrowserContext* browser_context,
415     const GURL& site,
416     bool can_be_default,
417     std::string* partition_domain,
418     std::string* partition_name,
419     bool* in_memory) {
420   *in_memory = false;
421   partition_domain->clear();
422   partition_name->clear();
423
424 #if !defined(OS_ANDROID)
425   if (site.SchemeIs(application::kApplicationScheme))
426     *partition_domain = site.host();
427 #endif
428 }
429
430 content::DevToolsManagerDelegate*
431   XWalkContentBrowserClient::GetDevToolsManagerDelegate() {
432   return new XWalkDevToolsDelegate(browser_context_);
433 }
434
435 }  // namespace xwalk