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_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"
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"
42 #if defined(OS_MACOSX)
43 #include "xwalk/runtime/browser/xwalk_browser_main_parts_mac.h"
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"
61 // The application-wide singleton of ContentBrowserClient impl.
62 XWalkContentBrowserClient* g_browser_client = NULL;
67 XWalkContentBrowserClient* XWalkContentBrowserClient::Get() {
68 return g_browser_client;
72 XWalkContentBrowserClient::XWalkContentBrowserClient(XWalkRunner* xwalk_runner)
73 : xwalk_runner_(xwalk_runner),
74 url_request_context_getter_(NULL),
76 DCHECK(!g_browser_client);
77 g_browser_client = this;
80 XWalkContentBrowserClient::~XWalkContentBrowserClient() {
81 DCHECK(g_browser_client);
82 g_browser_client = NULL;
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);
94 main_parts_ = new XWalkBrowserMainParts(parameters);
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_;
109 net::URLRequestContextGetter*
110 XWalkContentBrowserClient::CreateRequestContextForStoragePartition(
111 content::BrowserContext* browser_context,
112 const base::FilePath& partition_path,
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());
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
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]);
138 content::QuotaPermissionContext*
139 XWalkContentBrowserClient::CreateQuotaPermissionContext() {
140 return new RuntimeQuotaPermissionContext();
143 content::AccessTokenStore* XWalkContentBrowserClient::CreateAccessTokenStore() {
144 return new XWalkAccessTokenStore(url_request_context_getter_);
147 content::WebContentsViewDelegate*
148 XWalkContentBrowserClient::GetWebContentsViewDelegate(
149 content::WebContents* web_contents) {
150 #if defined(OS_ANDROID)
151 return new XWalkWebContentsViewDelegate(web_contents);
157 void XWalkContentBrowserClient::RenderProcessWillLaunch(
158 content::RenderProcessHost* host) {
159 xwalk_runner_->OnRenderProcessWillLaunch(host);
160 host->AddFilter(new XWalkRenderMessageFilter);
163 content::MediaObserver* XWalkContentBrowserClient::GetMediaObserver() {
164 return XWalkMediaCaptureDevicesDispatcher::GetInstance();
167 bool XWalkContentBrowserClient::AllowGetCookie(
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(
187 bool XWalkContentBrowserClient::AllowSetCookie(
189 const GURL& first_party,
190 const std::string& cookie_line,
191 content::ResourceContext* context,
192 int render_process_id,
194 net::CookieOptions* options) {
195 #if defined(OS_ANDROID)
196 return XWalkCookieAccessPolicy::GetInstance()->AllowSetCookie(
209 void XWalkContentBrowserClient::AllowCertificateError(
210 int render_process_id,
213 const net::SSLInfo& ssl_info,
214 const GURL& request_url,
215 ResourceType::Type resource_type,
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,
226 bool cancel_request = true;
228 client->AllowCertificateError(cert_error,
234 *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY;
238 void XWalkContentBrowserClient::RequestDesktopNotificationPermission(
239 const GURL& source_origin,
240 int callback_context,
241 int render_process_id,
242 int render_view_id) {
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;
253 return blink::WebNotificationPresenter::PermissionNotAllowed;
257 void XWalkContentBrowserClient::ShowDesktopNotification(
258 const content::ShowDesktopNotificationHostMsgParams& params,
259 int render_process_id,
262 #if defined(OS_ANDROID)
263 XWalkContentsClientBridgeBase* bridge =
264 XWalkContentsClientBridgeBase::FromRenderViewID(render_process_id,
266 bridge->ShowNotification(params, worker, render_process_id, render_view_id);
270 void XWalkContentBrowserClient::CancelDesktopNotification(
271 int render_process_id,
273 int notification_id) {
274 #if defined(OS_ANDROID)
275 XWalkContentsClientBridgeBase* bridge =
276 XWalkContentsClientBridgeBase::FromRenderViewID(render_process_id,
278 bridge->CancelNotification(
279 notification_id, render_process_id, render_view_id);
283 #if defined(OS_ANDROID)
284 void XWalkContentBrowserClient::ResourceDispatcherHostCreated() {
285 RuntimeResourceDispatcherHostDelegateAndroid::
286 ResourceDispatcherHostCreated();
290 content::SpeechRecognitionManagerDelegate*
291 XWalkContentBrowserClient::GetSpeechRecognitionManagerDelegate() {
292 return new xwalk::XWalkSpeechRecognitionManagerDelegate();
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());
302 const application::ApplicationData* app_data =app->data();
303 if (!app_data->HasCSPDefined() ||
304 (url.SchemeIs(application::kApplicationScheme) &&
305 url.host() == app_data->ID()))
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);
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
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();
330 if (url.host() == *it) {
331 LOG(INFO) << "[Allow] Navigation link: " << url.spec();
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);