| 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 |