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.
5 #include "xwalk/runtime/browser/xwalk_content_browser_client.h"
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"
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"
52 #include "xwalk/application/browser/application_system.h"
53 #include "xwalk/application/browser/application_service.h"
54 #include "xwalk/application/browser/application.h"
57 #if defined(OS_MACOSX)
58 #include "xwalk/runtime/browser/xwalk_browser_main_parts_mac.h"
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"
69 using content::BrowserChildProcessHostIterator;
75 // The application-wide singleton of ContentBrowserClient impl.
76 XWalkContentBrowserClient* g_browser_client = NULL;
81 XWalkContentBrowserClient* XWalkContentBrowserClient::Get() {
82 return g_browser_client;
86 XWalkContentBrowserClient::XWalkContentBrowserClient(XWalkRunner* xwalk_runner)
87 : xwalk_runner_(xwalk_runner),
88 url_request_context_getter_(NULL),
90 DCHECK(!g_browser_client);
91 g_browser_client = this;
94 XWalkContentBrowserClient::~XWalkContentBrowserClient() {
95 DCHECK(g_browser_client);
96 g_browser_client = NULL;
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);
108 main_parts_ = new XWalkBrowserMainParts(parameters);
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_;
123 net::URLRequestContextGetter*
124 XWalkContentBrowserClient::CreateRequestContextForStoragePartition(
125 content::BrowserContext* browser_context,
126 const base::FilePath& partition_path,
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());
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
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]);
152 content::QuotaPermissionContext*
153 XWalkContentBrowserClient::CreateQuotaPermissionContext() {
154 return new RuntimeQuotaPermissionContext();
157 content::AccessTokenStore* XWalkContentBrowserClient::CreateAccessTokenStore() {
158 return new XWalkAccessTokenStore(url_request_context_getter_);
161 content::WebContentsViewDelegate*
162 XWalkContentBrowserClient::GetWebContentsViewDelegate(
163 content::WebContents* web_contents) {
164 #if defined(OS_ANDROID)
165 return new XWalkWebContentsViewDelegate(web_contents);
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();
178 host->AddFilter(new nacl::NaClHostMessageFilter(
180 // TODO(Halton): IsOffTheRecord?
182 host->GetBrowserContext()->GetPath(),
185 xwalk_runner_->OnRenderProcessWillLaunch(host);
186 host->AddFilter(new XWalkRenderMessageFilter);
189 content::MediaObserver* XWalkContentBrowserClient::GetMediaObserver() {
190 return XWalkMediaCaptureDevicesDispatcher::GetInstance();
193 bool XWalkContentBrowserClient::AllowGetCookie(
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(
213 bool XWalkContentBrowserClient::AllowSetCookie(
215 const GURL& first_party,
216 const std::string& cookie_line,
217 content::ResourceContext* context,
218 int render_process_id,
220 net::CookieOptions* options) {
221 #if defined(OS_ANDROID)
222 return XWalkCookieAccessPolicy::GetInstance()->AllowSetCookie(
235 void XWalkContentBrowserClient::AllowCertificateError(
236 int render_process_id,
239 const net::SSLInfo& ssl_info,
240 const GURL& request_url,
241 ResourceType::Type resource_type,
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,
252 bool cancel_request = true;
254 client->AllowCertificateError(cert_error,
260 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
264 void XWalkContentBrowserClient::RequestDesktopNotificationPermission(
265 const GURL& source_origin,
266 int callback_context,
267 int render_process_id,
268 int render_view_id) {
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;
279 return blink::WebNotificationPresenter::PermissionNotAllowed;
283 void XWalkContentBrowserClient::ShowDesktopNotification(
284 const content::ShowDesktopNotificationHostMsgParams& params,
285 int render_process_id,
288 #if defined(OS_ANDROID)
289 XWalkContentsClientBridgeBase* bridge =
290 XWalkContentsClientBridgeBase::FromRenderViewID(render_process_id,
292 bridge->ShowNotification(params, worker, render_process_id, render_view_id);
296 void XWalkContentBrowserClient::CancelDesktopNotification(
297 int render_process_id,
299 int notification_id) {
300 #if defined(OS_ANDROID)
301 XWalkContentsClientBridgeBase* bridge =
302 XWalkContentsClientBridgeBase::FromRenderViewID(render_process_id,
304 bridge->CancelNotification(
305 notification_id, render_process_id, render_view_id);
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)));
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*>(
326 if (host->process() &&
327 host->process()->GetData().id == plugin_process_id) {
329 return host->browser_ppapi_host();
337 #if defined(OS_ANDROID)
338 void XWalkContentBrowserClient::ResourceDispatcherHostCreated() {
339 RuntimeResourceDispatcherHostDelegateAndroid::
340 ResourceDispatcherHostCreated();
344 content::SpeechRecognitionManagerDelegate*
345 XWalkContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
346 return new xwalk::XWalkSpeechRecognitionManagerDelegate();
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,
359 bool opener_suppressed,
360 content::ResourceContext* context,
361 int render_process_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);
369 // If it's not a request from an application, always enable this action.
372 if (app->CanRequestURL(target_url)) {
373 LOG(INFO) << "[ALLOW] CreateWindow: " << target_url.spec();
377 LOG(INFO) << "[BlOCK] CreateWindow: " << target_url.spec();
378 #if defined(OS_TIZEN)
379 platform_util::OpenExternal(target_url);