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/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/storage_partition.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/common/main_function_params.h"
23 #include "content/public/common/show_desktop_notification_params.h"
24 #include "net/ssl/ssl_info.h"
25 #include "net/url_request/url_request_context_getter.h"
26 #include "ppapi/host/ppapi_host.h"
27 #include "xwalk/extensions/common/xwalk_extension_switches.h"
28 #include "xwalk/application/common/constants.h"
29 #include "xwalk/runtime/browser/devtools/xwalk_devtools_delegate.h"
30 #include "xwalk/runtime/browser/geolocation/xwalk_access_token_store.h"
31 #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h"
32 #include "xwalk/runtime/browser/renderer_host/pepper/xwalk_browser_pepper_host_factory.h"
33 #include "xwalk/runtime/browser/runtime_context.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_main_parts.h"
37 #include "xwalk/runtime/browser/xwalk_render_message_filter.h"
38 #include "xwalk/runtime/browser/xwalk_runner.h"
39 #include "xwalk/runtime/common/xwalk_paths.h"
41 #if !defined(DISABLE_NACL)
42 #include "components/nacl/browser/nacl_browser.h"
43 #include "components/nacl/browser/nacl_host_message_filter.h"
44 #include "components/nacl/browser/nacl_process_host.h"
45 #include "components/nacl/common/nacl_process_type.h"
48 #if defined(OS_ANDROID)
49 #include "base/android/path_utils.h"
50 #include "base/base_paths_android.h"
51 #include "xwalk/runtime/browser/android/xwalk_cookie_access_policy.h"
52 #include "xwalk/runtime/browser/android/xwalk_contents_client_bridge.h"
53 #include "xwalk/runtime/browser/android/xwalk_web_contents_view_delegate.h"
54 #include "xwalk/runtime/browser/runtime_resource_dispatcher_host_delegate_android.h"
55 #include "xwalk/runtime/browser/xwalk_browser_main_parts_android.h"
56 #include "xwalk/runtime/common/android/xwalk_globals_android.h"
58 #include "xwalk/application/browser/application_system.h"
59 #include "xwalk/application/browser/application_service.h"
60 #include "xwalk/application/browser/application.h"
63 #if defined(OS_MACOSX)
64 #include "xwalk/runtime/browser/xwalk_browser_main_parts_mac.h"
68 #include "xwalk/application/common/application_manifest_constants.h"
69 #include "xwalk/application/common/manifest_handlers/navigation_handler.h"
70 #include "xwalk/runtime/browser/runtime_platform_util.h"
71 #include "xwalk/runtime/browser/xwalk_browser_main_parts_tizen.h"
78 // The application-wide singleton of ContentBrowserClient impl.
79 XWalkContentBrowserClient* g_browser_client = NULL;
84 XWalkContentBrowserClient* XWalkContentBrowserClient::Get() {
85 return g_browser_client;
89 XWalkContentBrowserClient::XWalkContentBrowserClient(XWalkRunner* xwalk_runner)
90 : xwalk_runner_(xwalk_runner),
91 url_request_context_getter_(NULL),
93 runtime_context_(NULL) {
94 DCHECK(!g_browser_client);
95 g_browser_client = this;
98 XWalkContentBrowserClient::~XWalkContentBrowserClient() {
99 DCHECK(g_browser_client);
100 g_browser_client = NULL;
103 content::BrowserMainParts* XWalkContentBrowserClient::CreateBrowserMainParts(
104 const content::MainFunctionParams& parameters) {
105 #if defined(OS_MACOSX)
106 main_parts_ = new XWalkBrowserMainPartsMac(parameters);
107 #elif defined(OS_ANDROID)
108 main_parts_ = new XWalkBrowserMainPartsAndroid(parameters);
109 #elif defined(OS_TIZEN)
110 main_parts_ = new XWalkBrowserMainPartsTizen(parameters);
112 main_parts_ = new XWalkBrowserMainParts(parameters);
118 net::URLRequestContextGetter* XWalkContentBrowserClient::CreateRequestContext(
119 content::BrowserContext* browser_context,
120 content::ProtocolHandlerMap* protocol_handlers,
121 content::URLRequestInterceptorScopedVector request_interceptors) {
122 runtime_context_ = static_cast<RuntimeContext*>(browser_context);
123 url_request_context_getter_ = runtime_context_->
124 CreateRequestContext(protocol_handlers, request_interceptors.Pass());
125 return url_request_context_getter_;
128 net::URLRequestContextGetter*
129 XWalkContentBrowserClient::CreateRequestContextForStoragePartition(
130 content::BrowserContext* browser_context,
131 const base::FilePath& partition_path,
133 content::ProtocolHandlerMap* protocol_handlers,
134 content::URLRequestInterceptorScopedVector request_interceptors) {
135 return static_cast<RuntimeContext*>(browser_context)->
136 CreateRequestContextForStoragePartition(
137 partition_path, in_memory, protocol_handlers,
138 request_interceptors.Pass());
141 // This allow us to append extra command line switches to the child
142 // process we launch.
143 void XWalkContentBrowserClient::AppendExtraCommandLineSwitches(
144 CommandLine* command_line, int child_process_id) {
145 CommandLine* browser_process_cmd_line = CommandLine::ForCurrentProcess();
146 const int extra_switches_count = 1;
147 const char* extra_switches[extra_switches_count] = {
148 switches::kXWalkDisableExtensionProcess
151 for (int i = 0; i < extra_switches_count; i++) {
152 if (browser_process_cmd_line->HasSwitch(extra_switches[i]))
153 command_line->AppendSwitch(extra_switches[i]);
157 content::QuotaPermissionContext*
158 XWalkContentBrowserClient::CreateQuotaPermissionContext() {
159 return new RuntimeQuotaPermissionContext();
162 content::AccessTokenStore* XWalkContentBrowserClient::CreateAccessTokenStore() {
163 return new XWalkAccessTokenStore(url_request_context_getter_);
166 content::WebContentsViewDelegate*
167 XWalkContentBrowserClient::GetWebContentsViewDelegate(
168 content::WebContents* web_contents) {
169 #if defined(OS_ANDROID)
170 return new XWalkWebContentsViewDelegate(web_contents);
176 void XWalkContentBrowserClient::RenderProcessWillLaunch(
177 content::RenderProcessHost* host) {
178 #if !defined(DISABLE_NACL)
179 int id = host->GetID();
180 net::URLRequestContextGetter* context =
181 host->GetStoragePartition()->GetURLRequestContext();
183 host->AddFilter(new nacl::NaClHostMessageFilter(
185 // TODO(Halton): IsOffTheRecord?
187 host->GetBrowserContext()->GetPath(),
190 xwalk_runner_->OnRenderProcessWillLaunch(host);
191 host->AddFilter(new XWalkRenderMessageFilter);
194 content::MediaObserver* XWalkContentBrowserClient::GetMediaObserver() {
195 return XWalkMediaCaptureDevicesDispatcher::GetInstance();
198 bool XWalkContentBrowserClient::AllowGetCookie(
200 const GURL& first_party,
201 const net::CookieList& cookie_list,
202 content::ResourceContext* context,
203 int render_process_id,
204 int render_frame_id) {
205 #if defined(OS_ANDROID)
206 return XWalkCookieAccessPolicy::GetInstance()->AllowGetCookie(
218 bool XWalkContentBrowserClient::AllowSetCookie(
220 const GURL& first_party,
221 const std::string& cookie_line,
222 content::ResourceContext* context,
223 int render_process_id,
225 net::CookieOptions* options) {
226 #if defined(OS_ANDROID)
227 return XWalkCookieAccessPolicy::GetInstance()->AllowSetCookie(
240 void XWalkContentBrowserClient::AllowCertificateError(
241 int render_process_id,
244 const net::SSLInfo& ssl_info,
245 const GURL& request_url,
246 content::ResourceType resource_type,
248 bool strict_enforcement,
249 bool expired_previous_decision,
250 const base::Callback<void(bool)>& callback, // NOLINT
251 content::CertificateRequestResultType* result) {
252 // Currently only Android handles it.
253 // TODO(yongsheng): applies it for other platforms?
254 #if defined(OS_ANDROID)
255 XWalkContentsClientBridgeBase* client =
256 XWalkContentsClientBridgeBase::FromRenderFrameID(render_process_id,
258 bool cancel_request = true;
260 client->AllowCertificateError(cert_error,
266 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
270 void XWalkContentBrowserClient::RequestDesktopNotificationPermission(
271 const GURL& source_origin,
272 content::RenderFrameHost* render_frame_host,
273 const base::Callback<void(blink::WebNotificationPermission)>& callback) {
276 blink::WebNotificationPermission
277 XWalkContentBrowserClient::CheckDesktopNotificationPermission(
278 const GURL& source_url,
279 content::ResourceContext* context,
280 int render_process_id) {
281 #if defined(OS_ANDROID)
282 return blink::WebNotificationPermissionAllowed;
284 return blink::WebNotificationPermissionDenied;
288 void XWalkContentBrowserClient::ShowDesktopNotification(
289 const content::ShowDesktopNotificationHostMsgParams& params,
290 content::RenderFrameHost* render_frame_host,
291 scoped_ptr<content::DesktopNotificationDelegate> delegate,
292 base::Closure* cancel_callback) {
293 #if defined(OS_ANDROID)
294 XWalkContentsClientBridgeBase* bridge =
295 XWalkContentsClientBridgeBase::FromRenderFrameHost(render_frame_host);
296 bridge->ShowNotification(params, render_frame_host,
297 delegate.Pass(), cancel_callback);
301 void XWalkContentBrowserClient::RequestGeolocationPermission(
302 content::WebContents* web_contents,
304 const GURL& requesting_frame,
306 base::Callback<void(bool)> result_callback,
307 base::Closure* cancel_callback) {
308 #if defined(OS_ANDROID) || defined(OS_TIZEN)
309 if (!geolocation_permission_context_.get()) {
310 geolocation_permission_context_ =
311 new RuntimeGeolocationPermissionContext();
313 geolocation_permission_context_->RequestGeolocationPermission(
319 result_callback.Run(false);
323 void XWalkContentBrowserClient::DidCreatePpapiPlugin(
324 content::BrowserPpapiHost* browser_host) {
325 #if defined(ENABLE_PLUGINS)
326 browser_host->GetPpapiHost()->AddHostFactoryFilter(
327 scoped_ptr<ppapi::host::HostFactory>(
328 new XWalkBrowserPepperHostFactory(browser_host)));
332 content::BrowserPpapiHost*
333 XWalkContentBrowserClient::GetExternalBrowserPpapiHost(
334 int plugin_process_id) {
335 #if !defined(DISABLE_NACL)
336 content::BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_LOADER);
337 while (!iter.Done()) {
338 nacl::NaClProcessHost* host = static_cast<nacl::NaClProcessHost*>(
340 if (host->process() &&
341 host->process()->GetData().id == plugin_process_id) {
343 return host->browser_ppapi_host();
351 #if defined(OS_ANDROID)
352 void XWalkContentBrowserClient::ResourceDispatcherHostCreated() {
353 RuntimeResourceDispatcherHostDelegateAndroid::
354 ResourceDispatcherHostCreated();
358 content::SpeechRecognitionManagerDelegate*
359 XWalkContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
360 return new xwalk::XWalkSpeechRecognitionManagerDelegate();
363 #if !defined(OS_ANDROID)
364 bool XWalkContentBrowserClient::CanCreateWindow(const GURL& opener_url,
365 const GURL& opener_top_level_frame_url,
366 const GURL& source_origin,
367 WindowContainerType container_type,
368 const GURL& target_url,
369 const content::Referrer& referrer,
370 WindowOpenDisposition disposition,
371 const blink::WebWindowFeatures& features,
373 bool opener_suppressed,
374 content::ResourceContext* context,
375 int render_process_id,
377 bool* no_javascript_access) {
378 *no_javascript_access = false;
379 application::Application* app = xwalk_runner_->app_system()->
380 application_service()->GetApplicationByRenderHostID(render_process_id);
382 // If it's not a request from an application, always enable this action.
385 if (app->CanRequestURL(target_url)) {
386 LOG(INFO) << "[ALLOW] CreateWindow: " << target_url.spec();
390 LOG(INFO) << "[BlOCK] CreateWindow: " << target_url.spec();
391 #if defined(OS_TIZEN)
392 platform_util::OpenExternal(target_url);
399 void XWalkContentBrowserClient::GetStoragePartitionConfigForSite(
400 content::BrowserContext* browser_context,
403 std::string* partition_domain,
404 std::string* partition_name,
407 partition_domain->clear();
408 partition_name->clear();
410 #if !defined(OS_ANDROID)
411 if (site.SchemeIs(application::kApplicationScheme))
412 *partition_domain = site.host();
416 content::DevToolsManagerDelegate*
417 XWalkContentBrowserClient::GetDevToolsManagerDelegate() {
418 return new XWalkDevToolsDelegate(runtime_context_);