OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/browser_plugin/browser_plugin_guest.h" | 5 #include "content/browser/browser_plugin/browser_plugin_guest.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 } | 399 } |
400 // All pending windows should be removed from the set after Destroy() is | 400 // All pending windows should be removed from the set after Destroy() is |
401 // called on all of them. | 401 // called on all of them. |
402 DCHECK(pending_new_windows_.empty()); | 402 DCHECK(pending_new_windows_.empty()); |
403 } | 403 } |
404 | 404 |
405 void BrowserPluginGuest::LoadURLWithParams(const GURL& url, | 405 void BrowserPluginGuest::LoadURLWithParams(const GURL& url, |
406 const Referrer& referrer, | 406 const Referrer& referrer, |
407 PageTransition transition_type, | 407 PageTransition transition_type, |
408 WebContents* web_contents) { | 408 WebContents* web_contents) { |
409 NavigationController::LoadURLParams load_url_params(url); | 409 // Do not allow navigating a guest to schemes other than known safe schemes. |
| 410 // This will block the embedder trying to load unwanted schemes, e.g. |
| 411 // chrome://settings. |
| 412 bool scheme_is_blocked = |
| 413 (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme( |
| 414 url.scheme()) && |
| 415 !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme( |
| 416 url.scheme())) || |
| 417 url.SchemeIs(kJavaScriptScheme); |
| 418 bool can_commit = |
| 419 GetContentClient()->browser()->CanCommitURL( |
| 420 GetWebContents()->GetRenderProcessHost(), url); |
| 421 if (scheme_is_blocked || !url.is_valid() || !can_commit) { |
| 422 if (delegate_) { |
| 423 // TODO(fsamuel): Need better error reporting here. |
| 424 std::string error_type; |
| 425 base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::", |
| 426 &error_type); |
| 427 delegate_->LoadAbort(true /* is_top_level */, url, error_type); |
| 428 } |
| 429 return; |
| 430 } |
| 431 |
| 432 GURL validated_url(url); |
| 433 GetWebContents()->GetRenderProcessHost()->FilterURL(false, &validated_url); |
| 434 |
| 435 NavigationController::LoadURLParams load_url_params(validated_url); |
410 load_url_params.referrer = referrer; | 436 load_url_params.referrer = referrer; |
411 load_url_params.transition_type = transition_type; | 437 load_url_params.transition_type = transition_type; |
412 load_url_params.extra_headers = std::string(); | 438 load_url_params.extra_headers = std::string(); |
413 if (delegate_ && delegate_->IsOverridingUserAgent()) { | 439 if (delegate_ && delegate_->IsOverridingUserAgent()) { |
414 load_url_params.override_user_agent = | 440 load_url_params.override_user_agent = |
415 NavigationController::UA_OVERRIDE_TRUE; | 441 NavigationController::UA_OVERRIDE_TRUE; |
416 } | 442 } |
417 web_contents->GetController().LoadURLWithParams(load_url_params); | 443 web_contents->GetController().LoadURLWithParams(load_url_params); |
418 } | 444 } |
419 | 445 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // For GTK and Aura this is necessary to get proper renderer configuration | 623 // For GTK and Aura this is necessary to get proper renderer configuration |
598 // values for caret blinking interval, colors related to selection and | 624 // values for caret blinking interval, colors related to selection and |
599 // focus. | 625 // focus. |
600 *renderer_prefs = *embedder_web_contents_->GetMutableRendererPrefs(); | 626 *renderer_prefs = *embedder_web_contents_->GetMutableRendererPrefs(); |
601 renderer_prefs->user_agent_override = guest_user_agent_override; | 627 renderer_prefs->user_agent_override = guest_user_agent_override; |
602 | 628 |
603 // We would like the guest to report changes to frame names so that we can | 629 // We would like the guest to report changes to frame names so that we can |
604 // update the BrowserPlugin's corresponding 'name' attribute. | 630 // update the BrowserPlugin's corresponding 'name' attribute. |
605 // TODO(fsamuel): Remove this once http://crbug.com/169110 is addressed. | 631 // TODO(fsamuel): Remove this once http://crbug.com/169110 is addressed. |
606 renderer_prefs->report_frame_name_changes = true; | 632 renderer_prefs->report_frame_name_changes = true; |
607 // Navigation is disabled in Chrome Apps. We want to make sure guest-initiated | 633 // Top-level guest-initiated navigations are all plumbed through |
608 // navigations still continue to function inside the app. | 634 // BrowserPluginGuest::OpenURLFromTab. There, it is determined whether a |
609 renderer_prefs->browser_handles_all_top_level_requests = false; | 635 // particular navigation will be allowed to proceed or whether it is aborted. |
| 636 renderer_prefs->browser_handles_all_top_level_requests = true; |
610 // Disable "client blocked" error page for browser plugin. | 637 // Disable "client blocked" error page for browser plugin. |
611 renderer_prefs->disable_client_blocked_error_page = true; | 638 renderer_prefs->disable_client_blocked_error_page = true; |
612 | 639 |
613 embedder_web_contents_observer_.reset(new EmbedderWebContentsObserver(this)); | 640 embedder_web_contents_observer_.reset(new EmbedderWebContentsObserver(this)); |
614 | 641 |
615 OnSetSize(instance_id_, params.auto_size_params, params.resize_guest_params); | 642 OnSetSize(instance_id_, params.auto_size_params, params.resize_guest_params); |
616 | 643 |
617 // Create a swapped out RenderView for the guest in the embedder render | 644 // Create a swapped out RenderView for the guest in the embedder render |
618 // process, so that the embedder can access the guest's window object. | 645 // process, so that the embedder can access the guest's window object. |
619 int guest_routing_id = | 646 int guest_routing_id = |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 const OpenURLParams& params) { | 848 const OpenURLParams& params) { |
822 // If the guest wishes to navigate away prior to attachment then we save the | 849 // If the guest wishes to navigate away prior to attachment then we save the |
823 // navigation to perform upon attachment. Navigation initializes a lot of | 850 // navigation to perform upon attachment. Navigation initializes a lot of |
824 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest. | 851 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest. |
825 // Navigation also resumes resource loading which we don't want to allow | 852 // Navigation also resumes resource loading which we don't want to allow |
826 // until attachment. | 853 // until attachment. |
827 if (!attached()) { | 854 if (!attached()) { |
828 PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this); | 855 PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this); |
829 if (it == opener()->pending_new_windows_.end()) | 856 if (it == opener()->pending_new_windows_.end()) |
830 return NULL; | 857 return NULL; |
831 const NewWindowInfo& old_target_url = it->second; | 858 const NewWindowInfo& old_info = it->second; |
832 NewWindowInfo new_window_info(params.url, old_target_url.name); | 859 it->second = NewWindowInfo(params.url, old_info.name); |
833 new_window_info.changed = new_window_info.url != old_target_url.url; | |
834 it->second = new_window_info; | |
835 return NULL; | 860 return NULL; |
836 } | 861 } |
837 if (params.disposition == CURRENT_TAB) { | 862 if (params.disposition == CURRENT_TAB) { |
838 // This can happen for cross-site redirects. | 863 // This can happen for cross-site redirects and top-level frame navigations. |
839 LoadURLWithParams(params.url, params.referrer, params.transition, source); | 864 LoadURLWithParams(params.url, params.referrer, params.transition, source); |
840 return source; | 865 return source; |
841 } | 866 } |
842 | 867 |
843 return CreateNewGuestWindow(params)->GetWebContents(); | 868 return CreateNewGuestWindow(params)->GetWebContents(); |
844 } | 869 } |
845 | 870 |
846 void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents, | 871 void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents, |
847 int64 source_frame_id, | 872 int64 source_frame_id, |
848 const base::string16& frame_name, | 873 const base::string16& frame_name, |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 // to initialize the browser-side state now so that the RenderFrameHostManager | 1270 // to initialize the browser-side state now so that the RenderFrameHostManager |
1246 // does not create a new RenderView on navigation. | 1271 // does not create a new RenderView on navigation. |
1247 if (has_render_view_) { | 1272 if (has_render_view_) { |
1248 static_cast<RenderViewHostImpl*>( | 1273 static_cast<RenderViewHostImpl*>( |
1249 GetWebContents()->GetRenderViewHost())->Init(); | 1274 GetWebContents()->GetRenderViewHost())->Init(); |
1250 WebContentsViewGuest* new_view = | 1275 WebContentsViewGuest* new_view = |
1251 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView()); | 1276 static_cast<WebContentsViewGuest*>(GetWebContents()->GetView()); |
1252 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost()); | 1277 new_view->CreateViewForWidget(web_contents()->GetRenderViewHost()); |
1253 } | 1278 } |
1254 | 1279 |
1255 // We need to do a navigation here if the target URL has changed between | 1280 // Grab the URL for the initial navigation. |
1256 // the time the WebContents was created and the time it was attached. | |
1257 // We also need to do an initial navigation if a RenderView was never | |
1258 // created for the new window in cases where there is no referrer. | |
1259 PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this); | 1281 PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this); |
1260 if (it != opener()->pending_new_windows_.end()) { | 1282 if (it != opener()->pending_new_windows_.end()) { |
1261 const NewWindowInfo& new_window_info = it->second; | 1283 params.src = it->second.url.spec(); |
1262 if (new_window_info.changed || !has_render_view_) | |
1263 params.src = it->second.url.spec(); | |
1264 } else { | 1284 } else { |
1265 NOTREACHED(); | 1285 NOTREACHED(); |
1266 } | 1286 } |
1267 | 1287 |
1268 // Once a new guest is attached to the DOM of the embedder page, then the | 1288 // Once a new guest is attached to the DOM of the embedder page, then the |
1269 // lifetime of the new guest is no longer managed by the opener guest. | 1289 // lifetime of the new guest is no longer managed by the opener guest. |
1270 opener()->pending_new_windows_.erase(this); | 1290 opener()->pending_new_windows_.erase(this); |
1271 | 1291 |
1272 // The guest's frame name takes precedence over the BrowserPlugin's name. | 1292 // The guest's frame name takes precedence over the BrowserPlugin's name. |
1273 // The guest's frame name is assigned in | 1293 // The guest's frame name is assigned in |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 pending_lock_request_ = false; | 1465 pending_lock_request_ = false; |
1446 if (succeeded) | 1466 if (succeeded) |
1447 mouse_locked_ = true; | 1467 mouse_locked_ = true; |
1448 } | 1468 } |
1449 | 1469 |
1450 void BrowserPluginGuest::OnNavigateGuest( | 1470 void BrowserPluginGuest::OnNavigateGuest( |
1451 int instance_id, | 1471 int instance_id, |
1452 const std::string& src) { | 1472 const std::string& src) { |
1453 GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src); | 1473 GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src); |
1454 | 1474 |
1455 // Do not allow navigating a guest to schemes other than known safe schemes. | |
1456 // This will block the embedder trying to load unwanted schemes, e.g. | |
1457 // chrome://settings. | |
1458 bool scheme_is_blocked = | |
1459 (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme( | |
1460 url.scheme()) && | |
1461 !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme( | |
1462 url.scheme())) || | |
1463 url.SchemeIs(kJavaScriptScheme); | |
1464 if (scheme_is_blocked || !url.is_valid()) { | |
1465 if (delegate_) { | |
1466 std::string error_type; | |
1467 base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::", | |
1468 &error_type); | |
1469 delegate_->LoadAbort(true /* is_top_level */, url, error_type); | |
1470 } | |
1471 return; | |
1472 } | |
1473 | |
1474 GURL validated_url(url); | |
1475 GetWebContents()->GetRenderProcessHost()->FilterURL(false, &validated_url); | |
1476 // As guests do not swap processes on navigation, only navigations to | 1475 // As guests do not swap processes on navigation, only navigations to |
1477 // normal web URLs are supported. No protocol handlers are installed for | 1476 // normal web URLs are supported. No protocol handlers are installed for |
1478 // other schemes (e.g., WebUI or extensions), and no permissions or bindings | 1477 // other schemes (e.g., WebUI or extensions), and no permissions or bindings |
1479 // can be granted to the guest process. | 1478 // can be granted to the guest process. |
1480 LoadURLWithParams(validated_url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL, | 1479 LoadURLWithParams(url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL, |
1481 GetWebContents()); | 1480 GetWebContents()); |
1482 } | 1481 } |
1483 | 1482 |
1484 void BrowserPluginGuest::OnPluginDestroyed(int instance_id) { | 1483 void BrowserPluginGuest::OnPluginDestroyed(int instance_id) { |
1485 Destroy(); | 1484 Destroy(); |
1486 } | 1485 } |
1487 | 1486 |
1488 void BrowserPluginGuest::OnResizeGuest( | 1487 void BrowserPluginGuest::OnResizeGuest( |
1489 int instance_id, | 1488 int instance_id, |
1490 const BrowserPluginHostMsg_ResizeGuest_Params& params) { | 1489 const BrowserPluginHostMsg_ResizeGuest_Params& params) { |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1884 base::Value::CreateStringValue(request_method)); | 1883 base::Value::CreateStringValue(request_method)); |
1885 request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue(url)); | 1884 request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue(url)); |
1886 | 1885 |
1887 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_DOWNLOAD, | 1886 RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_DOWNLOAD, |
1888 new DownloadRequest(weak_ptr_factory_.GetWeakPtr(), | 1887 new DownloadRequest(weak_ptr_factory_.GetWeakPtr(), |
1889 callback), | 1888 callback), |
1890 request_info); | 1889 request_info); |
1891 } | 1890 } |
1892 | 1891 |
1893 } // namespace content | 1892 } // namespace content |
OLD | NEW |