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