Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/frame_host/render_frame_host_manager.h" | 5 #include "content/browser/frame_host/render_frame_host_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 62 render_widget_delegate_(render_widget_delegate), | 62 render_widget_delegate_(render_widget_delegate), |
| 63 interstitial_page_(NULL), | 63 interstitial_page_(NULL), |
| 64 weak_factory_(this) { | 64 weak_factory_(this) { |
| 65 DCHECK(frame_tree_node_); | 65 DCHECK(frame_tree_node_); |
| 66 } | 66 } |
| 67 | 67 |
| 68 RenderFrameHostManager::~RenderFrameHostManager() { | 68 RenderFrameHostManager::~RenderFrameHostManager() { |
| 69 if (pending_render_frame_host_) | 69 if (pending_render_frame_host_) |
| 70 CancelPending(); | 70 CancelPending(); |
| 71 | 71 |
| 72 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 73 switches::kEnableBrowserSideNavigation)) { | |
| 74 CleanUpCurrentNavigation(); | |
| 75 } | |
| 76 | |
| 72 // We should always have a current RenderFrameHost except in some tests. | 77 // We should always have a current RenderFrameHost except in some tests. |
| 73 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); | 78 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); |
| 74 | 79 |
| 75 // Delete any swapped out RenderFrameHosts. | 80 // Delete any swapped out RenderFrameHosts. |
| 76 STLDeleteValues(&proxy_hosts_); | 81 STLDeleteValues(&proxy_hosts_); |
| 77 } | 82 } |
| 78 | 83 |
| 79 void RenderFrameHostManager::Init(BrowserContext* browser_context, | 84 void RenderFrameHostManager::Init(BrowserContext* browser_context, |
| 80 SiteInstance* site_instance, | 85 SiteInstance* site_instance, |
| 81 int view_routing_id, | 86 int view_routing_id, |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 // is ok to do nothing here. | 305 // is ok to do nothing here. |
| 301 if (pending_render_frame_host_ && | 306 if (pending_render_frame_host_ && |
| 302 pending_render_frame_host_->are_navigations_suspended()) { | 307 pending_render_frame_host_->are_navigations_suspended()) { |
| 303 pending_render_frame_host_->SetNavigationsSuspended(false, | 308 pending_render_frame_host_->SetNavigationsSuspended(false, |
| 304 proceed_time); | 309 proceed_time); |
| 305 } | 310 } |
| 306 } else { | 311 } else { |
| 307 // Current page says to cancel. | 312 // Current page says to cancel. |
| 308 CancelPending(); | 313 CancelPending(); |
| 309 cross_navigation_pending_ = false; | 314 cross_navigation_pending_ = false; |
| 315 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 316 switches::kEnableBrowserSideNavigation)) { | |
| 317 CleanUpCurrentNavigation(); | |
| 318 } | |
| 310 } | 319 } |
| 311 } else { | 320 } else { |
| 312 // Non-cross site transition means closing the entire tab. | 321 // Non-cross site transition means closing the entire tab. |
| 313 bool proceed_to_fire_unload; | 322 bool proceed_to_fire_unload; |
| 314 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time, | 323 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time, |
| 315 &proceed_to_fire_unload); | 324 &proceed_to_fire_unload); |
| 316 | 325 |
| 317 if (proceed_to_fire_unload) { | 326 if (proceed_to_fire_unload) { |
| 318 // If we're about to close the tab and there's a pending RFH, cancel it. | 327 // If we're about to close the tab and there's a pending RFH, cancel it. |
| 319 // Otherwise, if the navigation in the pending RFH completes before the | 328 // Otherwise, if the navigation in the pending RFH completes before the |
| 320 // close in the current RFH, we'll lose the tab close. | 329 // close in the current RFH, we'll lose the tab close. |
| 321 if (pending_render_frame_host_) { | 330 if (pending_render_frame_host_) { |
| 322 CancelPending(); | 331 CancelPending(); |
| 323 cross_navigation_pending_ = false; | 332 cross_navigation_pending_ = false; |
| 333 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 334 switches::kEnableBrowserSideNavigation)) { | |
| 335 CleanUpCurrentNavigation(); | |
| 336 } | |
| 324 } | 337 } |
| 325 | 338 |
| 326 // This is not a cross-site navigation, the tab is being closed. | 339 // This is not a cross-site navigation, the tab is being closed. |
| 327 render_frame_host_->render_view_host()->ClosePage(); | 340 render_frame_host_->render_view_host()->ClosePage(); |
| 328 } | 341 } |
| 329 } | 342 } |
| 330 } | 343 } |
| 331 | 344 |
| 332 void RenderFrameHostManager::OnCrossSiteResponse( | 345 void RenderFrameHostManager::OnCrossSiteResponse( |
| 333 RenderFrameHostImpl* pending_render_frame_host, | 346 RenderFrameHostImpl* pending_render_frame_host, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 | 425 |
| 413 response_started_id_.reset(); | 426 response_started_id_.reset(); |
| 414 } | 427 } |
| 415 | 428 |
| 416 void RenderFrameHostManager::ClearNavigationTransitionData() { | 429 void RenderFrameHostManager::ClearNavigationTransitionData() { |
| 417 render_frame_host_->ClearPendingTransitionRequestData(); | 430 render_frame_host_->ClearPendingTransitionRequestData(); |
| 418 } | 431 } |
| 419 | 432 |
| 420 void RenderFrameHostManager::DidNavigateFrame( | 433 void RenderFrameHostManager::DidNavigateFrame( |
| 421 RenderFrameHostImpl* render_frame_host) { | 434 RenderFrameHostImpl* render_frame_host) { |
| 435 DCHECK(render_frame_host); | |
| 436 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 437 switches::kEnableBrowserSideNavigation)) { | |
| 438 if (speculative_render_frame_host_.get() == render_frame_host) { | |
| 439 CommitPending(true); | |
| 440 return; | |
| 441 } | |
| 442 CleanUpCurrentNavigation(); | |
| 443 } | |
| 444 | |
| 422 if (!cross_navigation_pending_) { | 445 if (!cross_navigation_pending_) { |
| 423 DCHECK(!pending_render_frame_host_); | 446 DCHECK(!pending_render_frame_host_); |
| 424 | 447 |
| 425 // We should only hear this from our current renderer. | 448 // We should only hear this from our current renderer. |
| 426 DCHECK_EQ(render_frame_host_, render_frame_host); | 449 DCHECK_EQ(render_frame_host_, render_frame_host); |
| 427 | 450 |
| 428 // Even when there is no pending RVH, there may be a pending Web UI. | 451 // Even when there is no pending RVH, there may be a pending Web UI. |
| 429 if (pending_web_ui()) | 452 if (pending_web_ui()) |
| 430 CommitPending(); | 453 CommitPending(false); |
| 431 return; | 454 return; |
| 432 } | 455 } |
| 433 | 456 |
| 434 if (render_frame_host == pending_render_frame_host_) { | 457 if (render_frame_host == pending_render_frame_host_) { |
| 435 // The pending cross-site navigation completed, so show the renderer. | 458 // The pending cross-site navigation completed, so show the renderer. |
| 436 CommitPending(); | 459 CommitPending(false); |
| 437 cross_navigation_pending_ = false; | 460 cross_navigation_pending_ = false; |
| 438 } else if (render_frame_host == render_frame_host_) { | 461 } else if (render_frame_host == render_frame_host_) { |
| 439 // A navigation in the original page has taken place. Cancel the pending | 462 // A navigation in the original page has taken place. Cancel the pending |
| 440 // one. | 463 // one. |
| 441 CancelPending(); | 464 CancelPending(); |
| 442 cross_navigation_pending_ = false; | 465 cross_navigation_pending_ = false; |
| 443 } else { | 466 } else { |
| 444 // No one else should be sending us DidNavigate in this state. | 467 // No one else should be sending us DidNavigate in this state. |
| 445 DCHECK(false); | 468 DCHECK(false); |
| 446 } | 469 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 // We shouldn't get here for subframes, since we only swap subframes when | 575 // We shouldn't get here for subframes, since we only swap subframes when |
| 553 // --site-per-process is used. | 576 // --site-per-process is used. |
| 554 DCHECK(is_main_frame); | 577 DCHECK(is_main_frame); |
| 555 | 578 |
| 556 // The old RenderFrameHost will stay alive inside the proxy so that existing | 579 // The old RenderFrameHost will stay alive inside the proxy so that existing |
| 557 // JavaScript window references to it stay valid. | 580 // JavaScript window references to it stay valid. |
| 558 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); | 581 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); |
| 559 } | 582 } |
| 560 } | 583 } |
| 561 | 584 |
| 585 void RenderFrameHostManager::RecycleRenderFrameHost( | |
| 586 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | |
| 587 // TODO(carlosk): this code is very similar to what can be found in | |
| 588 // SwapOutOldFrame and we should see that these are unified at some point. | |
|
carlosk
2014/11/05 16:45:44
SwapOutOldFrame does all of this (extracted from C
Charlie Reis
2014/11/05 17:50:01
I would also like to see this code unified. We ca
carlosk
2014/11/05 20:28:58
Acknowledged.
| |
| 589 | |
| 590 // If the SiteInstance for the pending RFH is being used by others, don't | |
| 591 // delete the RFH, just swap it out and it can be reused at a later point. | |
| 592 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); | |
| 593 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { | |
| 594 // Any currently suspended navigations are no longer needed. | |
| 595 render_frame_host->CancelSuspendedNavigations(); | |
| 596 | |
| 597 RenderFrameProxyHost* proxy = | |
| 598 new RenderFrameProxyHost(site_instance, frame_tree_node_); | |
| 599 proxy_hosts_[site_instance->GetId()] = proxy; | |
| 600 render_frame_host->SwapOut(proxy); | |
| 601 if (frame_tree_node_->IsMainFrame()) | |
| 602 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); | |
| 603 } else { | |
| 604 // We won't be coming back, so delete this one. | |
| 605 render_frame_host.reset(); | |
| 606 } | |
| 607 } | |
| 608 | |
| 562 void RenderFrameHostManager::MoveToPendingDeleteHosts( | 609 void RenderFrameHostManager::MoveToPendingDeleteHosts( |
| 563 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 610 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 564 // |render_frame_host| will be deleted when its SwapOut ACK is received, or | 611 // |render_frame_host| will be deleted when its SwapOut ACK is received, or |
| 565 // when the timer times out, or when the RFHM itself is deleted (whichever | 612 // when the timer times out, or when the RFHM itself is deleted (whichever |
| 566 // comes first). | 613 // comes first). |
| 567 pending_delete_hosts_.push_back( | 614 pending_delete_hosts_.push_back( |
| 568 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); | 615 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); |
| 569 } | 616 } |
| 570 | 617 |
| 571 bool RenderFrameHostManager::IsPendingDeletion( | 618 bool RenderFrameHostManager::IsPendingDeletion( |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 587 return true; | 634 return true; |
| 588 } | 635 } |
| 589 } | 636 } |
| 590 return false; | 637 return false; |
| 591 } | 638 } |
| 592 | 639 |
| 593 void RenderFrameHostManager::ResetProxyHosts() { | 640 void RenderFrameHostManager::ResetProxyHosts() { |
| 594 STLDeleteValues(&proxy_hosts_); | 641 STLDeleteValues(&proxy_hosts_); |
| 595 } | 642 } |
| 596 | 643 |
| 644 void RenderFrameHostManager::WillBeginNavigating( | |
| 645 const FrameHostMsg_BeginNavigation_Params& params, | |
| 646 const CommonNavigationParams& common_params) { | |
| 647 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
| 648 switches::kEnableBrowserSideNavigation)); | |
| 649 // If there is an ongoing navigation, just clean it up. | |
| 650 CleanUpCurrentNavigation(); | |
| 651 | |
| 652 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | |
| 653 // TODO(carlosk): Replace the default values by the right ones. | |
| 654 scoped_refptr<SiteInstanceImpl> new_instance = | |
| 655 static_cast<SiteInstanceImpl*>(GetSiteInstanceForNavigation( | |
| 656 common_params.url, NULL, common_params.transition, false, false, | |
| 657 true)); | |
| 658 | |
| 659 if (new_instance.get() != current_instance) { | |
| 660 // Navigating to a new SiteInstance -> speculatively create a new RFH | |
| 661 | |
| 662 // TODO(carlosk): what the TRACE_EVENT_INSTANT2 for New SiteInstance found | |
| 663 // in UpdateStateForNavigate be copied here? | |
| 664 | |
| 665 bool success = CreateSpeculativeRenderFrameHost( | |
| 666 common_params.url, current_instance, new_instance.get()); | |
| 667 if (!success) { | |
| 668 return; | |
| 669 } | |
| 670 } else { | |
| 671 // Navigating to the same SiteInstance -> make sure the current RFH is alive | |
| 672 | |
| 673 // TODO(carlosk): do I need to AddPendingView() in this case as well??? | |
| 674 DCHECK(render_frame_host_->GetSiteInstance() == new_instance); | |
| 675 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { | |
| 676 // Recreate the opener chain. | |
| 677 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | |
| 678 render_frame_host_->GetSiteInstance()); | |
| 679 if (!InitRenderView(render_frame_host_->render_view_host(), | |
| 680 opener_route_id, MSG_ROUTING_NONE, | |
| 681 frame_tree_node_->IsMainFrame())) { | |
| 682 return; | |
| 683 } | |
| 684 } | |
| 685 } | |
| 686 DCHECK(new_instance->GetProcess()->HasConnection()); | |
| 687 DCHECK(new_instance->GetProcess()->GetBrowserContext()); | |
| 688 } | |
| 689 | |
| 690 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( | |
| 691 const GURL& url, SiteInstance* old_instance, SiteInstance* new_instance) { | |
| 692 CHECK(new_instance); | |
| 693 CHECK_NE(old_instance, new_instance); | |
| 694 | |
| 695 // TODO(carlosk): should also try to reuse the current web_ui | |
| 696 // (ShouldReuseWebUI)? | |
| 697 scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url)); | |
| 698 // TODO(carlosk): confirm this next section copied from SetPendingWebUI | |
| 699 // is in fact needed... I need access to the respective navigation entry | |
| 700 // though. | |
| 701 // If we have assigned (zero or more) bindings to this NavigationEntry in the | |
| 702 // past, make sure we're not granting it different bindings than it had | |
| 703 // before. If so, note it and don't give it any bindings, to avoid a | |
| 704 // potential privilege escalation. | |
| 705 // if (new_web_ui && | |
| 706 // bindings != NavigationEntryImpl::kInvalidBindings && | |
| 707 // new_web_ui->GetBindings() != bindings) { | |
| 708 // RecordAction( | |
| 709 // base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); | |
| 710 // new_web_ui.reset(); | |
| 711 // } | |
| 712 | |
| 713 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; | |
| 714 | |
| 715 // Check if we've already created an RFH for this SiteInstance. If so, try | |
| 716 // to re-use the existing one, which has already been initialized. We'll | |
| 717 // remove it from the list of proxy hosts below if it will be active. | |
| 718 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(new_instance); | |
| 719 if (proxy && proxy->render_frame_host()) { | |
| 720 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | |
| 721 // Prevent the process from exiting while we're trying to use it. | |
| 722 new_render_frame_host = proxy->PassFrameHostOwnership(); | |
| 723 new_render_frame_host->GetProcess()->AddPendingView(); | |
| 724 | |
| 725 proxy_hosts_.erase(new_instance->GetId()); | |
| 726 delete proxy; | |
| 727 | |
| 728 // When a new render view is created by the renderer, the new WebContents | |
| 729 // gets a RenderViewHost in the SiteInstance of its opener WebContents. | |
| 730 // If not used in the first navigation, this RVH is swapped out and is not | |
| 731 // granted bindings, so we may need to grant them when swapping it in. | |
| 732 if (new_web_ui && !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { | |
| 733 int required_bindings = new_web_ui->GetBindings(); | |
| 734 RenderViewHost* rvh = new_render_frame_host->render_view_host(); | |
| 735 if ((rvh->GetEnabledBindings() & required_bindings) != | |
| 736 required_bindings) { | |
| 737 rvh->AllowBindings(required_bindings); | |
| 738 } | |
| 739 } | |
| 740 } else { | |
| 741 // Create a new RenderFrameHost if we don't find an existing one. | |
| 742 new_render_frame_host = | |
| 743 CreateRenderFrameHost(new_instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, | |
| 744 false, delegate_->IsHidden()); | |
| 745 DCHECK(new_render_frame_host); | |
| 746 RenderViewHostImpl* rvh = new_render_frame_host->render_view_host(); | |
| 747 | |
| 748 // Prevent the process from exiting while we're trying to navigate in it. | |
| 749 // Otherwise, if the new RFH is swapped out already, store it. | |
| 750 new_render_frame_host->GetProcess()->AddPendingView(); | |
| 751 | |
| 752 // Ensure that we have created RFHs for the new RFH's opener chain if | |
| 753 // we are staying in the same BrowsingInstance. This allows the new RFH | |
| 754 // to send cross-process script calls to its opener(s). | |
| 755 int opener_route_id = MSG_ROUTING_NONE; | |
| 756 if (new_instance->IsRelatedSiteInstance(old_instance)) { | |
| 757 opener_route_id = | |
| 758 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); | |
| 759 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 760 switches::kSitePerProcess)) { | |
| 761 // Ensure that the frame tree has RenderFrameProxyHosts for the new | |
| 762 // SiteInstance in all nodes except the current one. | |
| 763 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( | |
| 764 frame_tree_node_, new_instance); | |
| 765 } | |
| 766 } | |
| 767 | |
| 768 bool success = InitRenderView(rvh, opener_route_id, MSG_ROUTING_NONE, | |
| 769 frame_tree_node_->IsMainFrame()); | |
| 770 if (success) { | |
| 771 if (frame_tree_node_->IsMainFrame()) { | |
| 772 // Don't show the main frame's view until we know it will be used. | |
| 773 rvh->GetView()->Hide(); | |
| 774 } else { | |
| 775 // Init the RFH, so a RenderFrame is created in the renderer. | |
| 776 success = InitRenderFrame(new_render_frame_host.get()); | |
| 777 } | |
| 778 } | |
| 779 if (!success) { | |
| 780 return false; | |
| 781 } | |
| 782 // TODO(carlosk): find out if this should be called here or only later on. | |
|
carlosk
2014/11/05 16:45:45
This is also a question to reviewers...
| |
| 783 render_frame_delegate_->RenderFrameCreated(new_render_frame_host.get()); | |
| 784 } | |
| 785 | |
| 786 DCHECK(new_render_frame_host->GetSiteInstance() == new_instance); | |
| 787 speculative_render_frame_host_.reset(new_render_frame_host.release()); | |
| 788 speculative_web_ui_.reset(new_web_ui.release()); | |
| 789 return true; | |
| 790 } | |
| 791 | |
| 597 // PlzNavigate | 792 // PlzNavigate |
| 598 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( | 793 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( |
| 599 const GURL& url, | 794 const GURL& url, |
| 600 ui::PageTransition transition) { | 795 ui::PageTransition transition) { |
| 601 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | 796 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 602 switches::kEnableBrowserSideNavigation)); | 797 switches::kEnableBrowserSideNavigation)); |
| 603 // TODO(clamy): When we handle renderer initiated navigations, make sure not | 798 // TODO(clamy): When we handle renderer initiated navigations, make sure not |
| 604 // to use a different process for subframes if --site-per-process is not | 799 // to use a different process for subframes if --site-per-process is not |
| 605 // enabled. | 800 // enabled. |
| 606 | 801 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 controller.GetBrowserContext(), current_entry->GetURL()) == | 945 controller.GetBrowserContext(), current_entry->GetURL()) == |
| 751 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | 946 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( |
| 752 controller.GetBrowserContext(), new_url)); | 947 controller.GetBrowserContext(), new_url)); |
| 753 } | 948 } |
| 754 | 949 |
| 755 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( | 950 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( |
| 756 const GURL& dest_url, | 951 const GURL& dest_url, |
| 757 SiteInstance* dest_instance, | 952 SiteInstance* dest_instance, |
| 758 ui::PageTransition dest_transition, | 953 ui::PageTransition dest_transition, |
| 759 bool dest_is_restore, | 954 bool dest_is_restore, |
| 760 bool dest_is_view_source_mode) { | 955 bool dest_is_view_source_mode, |
| 956 bool create_unbounded_site_instance) { | |
| 761 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 957 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 762 SiteInstance* new_instance = current_instance; | 958 SiteInstance* new_instance = current_instance; |
| 763 | 959 |
| 764 // We do not currently swap processes for navigations in webview tag guests. | 960 // We do not currently swap processes for navigations in webview tag guests. |
| 765 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme)) | 961 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme)) |
| 766 return current_instance; | 962 return current_instance; |
| 767 | 963 |
| 768 // Determine if we need a new BrowsingInstance for this entry. If true, this | 964 // Determine if we need a new BrowsingInstance for this entry. If true, this |
| 769 // implies that it will get a new SiteInstance (and likely process), and that | 965 // implies that it will get a new SiteInstance (and likely process), and that |
| 770 // other tabs in the current BrowsingInstance will be unable to script it. | 966 // other tabs in the current BrowsingInstance will be unable to script it. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 782 bool current_is_view_source_mode = current_entry ? | 978 bool current_is_view_source_mode = current_entry ? |
| 783 current_entry->IsViewSourceMode() : dest_is_view_source_mode; | 979 current_entry->IsViewSourceMode() : dest_is_view_source_mode; |
| 784 bool force_swap = ShouldSwapBrowsingInstancesForNavigation( | 980 bool force_swap = ShouldSwapBrowsingInstancesForNavigation( |
| 785 current_effective_url, | 981 current_effective_url, |
| 786 current_is_view_source_mode, | 982 current_is_view_source_mode, |
| 787 dest_instance, | 983 dest_instance, |
| 788 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), | 984 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), |
| 789 dest_is_view_source_mode); | 985 dest_is_view_source_mode); |
| 790 if (ShouldTransitionCrossSite() || force_swap) { | 986 if (ShouldTransitionCrossSite() || force_swap) { |
| 791 new_instance = GetSiteInstanceForURL( | 987 new_instance = GetSiteInstanceForURL( |
| 792 dest_url, | 988 dest_url, dest_instance, dest_transition, dest_is_restore, |
| 793 dest_instance, | 989 dest_is_view_source_mode, current_instance, force_swap, |
| 794 dest_transition, | 990 create_unbounded_site_instance); |
| 795 dest_is_restore, | |
| 796 dest_is_view_source_mode, | |
| 797 current_instance, | |
| 798 force_swap); | |
| 799 } | 991 } |
| 800 | 992 |
| 801 // If force_swap is true, we must use a different SiteInstance. If we didn't, | 993 // If force_swap is true, we must use a different SiteInstance. If we didn't, |
| 802 // we would have two RenderFrameHosts in the same SiteInstance and the same | 994 // we would have two RenderFrameHosts in the same SiteInstance and the same |
| 803 // frame, resulting in page_id conflicts for their NavigationEntries. | 995 // frame, resulting in page_id conflicts for their NavigationEntries. |
| 804 if (force_swap) | 996 if (force_swap) |
| 805 CHECK_NE(new_instance, current_instance); | 997 CHECK_NE(new_instance, current_instance); |
| 806 return new_instance; | 998 return new_instance; |
| 807 } | 999 } |
| 808 | 1000 |
| 809 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( | 1001 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( |
| 810 const GURL& dest_url, | 1002 const GURL& dest_url, |
| 811 SiteInstance* dest_instance, | 1003 SiteInstance* dest_instance, |
| 812 ui::PageTransition dest_transition, | 1004 ui::PageTransition dest_transition, |
| 813 bool dest_is_restore, | 1005 bool dest_is_restore, |
| 814 bool dest_is_view_source_mode, | 1006 bool dest_is_view_source_mode, |
| 815 SiteInstance* current_instance, | 1007 SiteInstance* current_instance, |
| 816 bool force_browsing_instance_swap) { | 1008 bool force_browsing_instance_swap, |
| 1009 bool create_unbounded_site_instance) { | |
| 817 NavigationControllerImpl& controller = | 1010 NavigationControllerImpl& controller = |
| 818 delegate_->GetControllerForRenderManager(); | 1011 delegate_->GetControllerForRenderManager(); |
| 819 BrowserContext* browser_context = controller.GetBrowserContext(); | 1012 BrowserContext* browser_context = controller.GetBrowserContext(); |
| 820 | 1013 |
| 821 // If the entry has an instance already we should use it. | 1014 // If the entry has an instance already we should use it. |
| 822 if (dest_instance) { | 1015 if (dest_instance) { |
| 823 // If we are forcing a swap, this should be in a different BrowsingInstance. | 1016 // If we are forcing a swap, this should be in a different BrowsingInstance. |
| 824 if (force_browsing_instance_swap) { | 1017 if (force_browsing_instance_swap) { |
| 825 CHECK(!dest_instance->IsRelatedSiteInstance( | 1018 CHECK(!dest_instance->IsRelatedSiteInstance( |
| 826 render_frame_host_->GetSiteInstance())); | 1019 render_frame_host_->GetSiteInstance())); |
| 827 } | 1020 } |
| 828 return dest_instance; | 1021 return dest_instance; |
| 829 } | 1022 } |
| 830 | 1023 |
| 1024 SiteInstanceImpl* current_site_instance = | |
| 1025 static_cast<SiteInstanceImpl*>(current_instance); | |
| 1026 | |
| 831 // If a swap is required, we need to force the SiteInstance AND | 1027 // If a swap is required, we need to force the SiteInstance AND |
| 832 // BrowsingInstance to be different ones, using CreateForURL. | 1028 // BrowsingInstance to be different ones, using CreateForURL. |
| 833 if (force_browsing_instance_swap) | 1029 if (force_browsing_instance_swap) { |
| 834 return SiteInstance::CreateForURL(browser_context, dest_url); | 1030 return CreateSiteInstanceForURL(browser_context, dest_url, |
| 1031 create_unbounded_site_instance, | |
| 1032 current_site_instance); | |
| 1033 } | |
| 835 | 1034 |
| 836 // (UGLY) HEURISTIC, process-per-site only: | 1035 // (UGLY) HEURISTIC, process-per-site only: |
| 837 // | 1036 // |
| 838 // If this navigation is generated, then it probably corresponds to a search | 1037 // If this navigation is generated, then it probably corresponds to a search |
| 839 // query. Given that search results typically lead to users navigating to | 1038 // query. Given that search results typically lead to users navigating to |
| 840 // other sites, we don't really want to use the search engine hostname to | 1039 // other sites, we don't really want to use the search engine hostname to |
| 841 // determine the site instance for this navigation. | 1040 // determine the site instance for this navigation. |
| 842 // | 1041 // |
| 843 // NOTE: This can be removed once we have a way to transition between | 1042 // NOTE: This can be removed once we have a way to transition between |
| 844 // RenderViews in response to a link click. | 1043 // RenderViews in response to a link click. |
| 845 // | 1044 // |
| 846 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && | 1045 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && |
| 847 ui::PageTransitionCoreTypeIs( | 1046 ui::PageTransitionCoreTypeIs( |
| 848 dest_transition, ui::PAGE_TRANSITION_GENERATED)) { | 1047 dest_transition, ui::PAGE_TRANSITION_GENERATED)) { |
| 849 return current_instance; | 1048 return current_instance; |
| 850 } | 1049 } |
| 851 | 1050 |
| 852 SiteInstanceImpl* current_site_instance = | |
| 853 static_cast<SiteInstanceImpl*>(current_instance); | |
| 854 | |
| 855 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it | 1051 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it |
| 856 // for this entry. We won't commit the SiteInstance to this site until the | 1052 // for this entry. We won't commit the SiteInstance to this site until the |
| 857 // navigation commits (in DidNavigate), unless the navigation entry was | 1053 // navigation commits (in DidNavigate), unless the navigation entry was |
| 858 // restored or it's a Web UI as described below. | 1054 // restored or it's a Web UI as described below. |
| 859 if (!current_site_instance->HasSite()) { | 1055 if (!current_site_instance->HasSite()) { |
| 860 // If we've already created a SiteInstance for our destination, we don't | 1056 // If we've already created a SiteInstance for our destination, we don't |
| 861 // want to use this unused SiteInstance; use the existing one. (We don't | 1057 // want to use this unused SiteInstance; use the existing one. (We don't |
| 862 // do this check if the current_instance has a site, because for now, we | 1058 // do this check if the current_instance has a site, because for now, we |
| 863 // want to compare against the current URL and not the SiteInstance's site. | 1059 // want to compare against the current URL and not the SiteInstance's site. |
| 864 // In this case, there is no current URL, so comparing against the site is | 1060 // In this case, there is no current URL, so comparing against the site is |
| 865 // ok. See additional comments below.) | 1061 // ok. See additional comments below.) |
| 866 // | 1062 // |
| 867 // Also, if the URL should use process-per-site mode and there is an | 1063 // Also, if the URL should use process-per-site mode and there is an |
| 868 // existing process for the site, we should use it. We can call | 1064 // existing process for the site, we should use it. We can call |
| 869 // GetRelatedSiteInstance() for this, which will eagerly set the site and | 1065 // GetRelatedSiteInstance() for this, which will eagerly set the site and |
| 870 // thus use the correct process. | 1066 // thus use the correct process. |
| 871 bool use_process_per_site = | 1067 bool use_process_per_site = |
| 872 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) && | 1068 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) && |
| 873 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url); | 1069 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url); |
| 874 if (current_site_instance->HasRelatedSiteInstance(dest_url) || | 1070 if (current_site_instance->HasRelatedSiteInstance(dest_url) || |
| 875 use_process_per_site) { | 1071 use_process_per_site) { |
| 876 return current_site_instance->GetRelatedSiteInstance(dest_url); | 1072 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url, |
| 1073 create_unbounded_site_instance); | |
| 877 } | 1074 } |
| 878 | 1075 |
| 879 // For extensions, Web UI URLs (such as the new tab page), and apps we do | 1076 // For extensions, Web UI URLs (such as the new tab page), and apps we do |
| 880 // not want to use the current_instance if it has no site, since it will | 1077 // not want to use the current_instance if it has no site, since it will |
| 881 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for | 1078 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for |
| 882 // this URL instead (with the correct process type). | 1079 // this URL instead (with the correct process type). |
| 883 if (current_site_instance->HasWrongProcessForURL(dest_url)) | 1080 if (current_site_instance->HasWrongProcessForURL(dest_url)) { |
| 884 return current_site_instance->GetRelatedSiteInstance(dest_url); | 1081 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url, |
| 1082 create_unbounded_site_instance); | |
| 1083 } | |
| 885 | 1084 |
| 886 // View-source URLs must use a new SiteInstance and BrowsingInstance. | 1085 // View-source URLs must use a new SiteInstance and BrowsingInstance. |
| 887 // TODO(nasko): This is the same condition as later in the function. This | 1086 // TODO(nasko): This is the same condition as later in the function. This |
| 888 // should be taken into account when refactoring this method as part of | 1087 // should be taken into account when refactoring this method as part of |
| 889 // http://crbug.com/123007. | 1088 // http://crbug.com/123007. |
| 890 if (dest_is_view_source_mode) | 1089 if (dest_is_view_source_mode) { |
| 891 return SiteInstance::CreateForURL(browser_context, dest_url); | 1090 return CreateSiteInstanceForURL(browser_context, dest_url, |
| 1091 create_unbounded_site_instance, | |
| 1092 current_site_instance); | |
| 1093 } | |
| 892 | 1094 |
| 893 // If we are navigating from a blank SiteInstance to a WebUI, make sure we | 1095 // If we are navigating from a blank SiteInstance to a WebUI, make sure we |
| 894 // create a new SiteInstance. | 1096 // create a new SiteInstance. |
| 895 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( | 1097 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( |
| 896 browser_context, dest_url)) { | 1098 browser_context, dest_url)) { |
| 897 return SiteInstance::CreateForURL(browser_context, dest_url); | 1099 return CreateSiteInstanceForURL(browser_context, dest_url, |
| 1100 create_unbounded_site_instance, | |
| 1101 current_site_instance); | |
| 898 } | 1102 } |
| 899 | 1103 |
| 900 // Normally the "site" on the SiteInstance is set lazily when the load | 1104 // Normally the "site" on the SiteInstance is set lazily when the load |
| 901 // actually commits. This is to support better process sharing in case | 1105 // actually commits. This is to support better process sharing in case |
| 902 // the site redirects to some other site: we want to use the destination | 1106 // the site redirects to some other site: we want to use the destination |
| 903 // site in the site instance. | 1107 // site in the site instance. |
| 904 // | 1108 // |
| 905 // In the case of session restore, as it loads all the pages immediately | 1109 // In the case of session restore, as it loads all the pages immediately |
| 906 // we need to set the site first, otherwise after a restore none of the | 1110 // we need to set the site first, otherwise after a restore none of the |
| 907 // pages would share renderers in process-per-site. | 1111 // pages would share renderers in process-per-site. |
| 908 // | 1112 // |
| 909 // The embedder can request some urls never to be assigned to SiteInstance | 1113 // The embedder can request some urls never to be assigned to SiteInstance |
| 910 // through the ShouldAssignSiteForURL() content client method, so that | 1114 // through the ShouldAssignSiteForURL() content client method, so that |
| 911 // renderers created for particular chrome urls (e.g. the chrome-native:// | 1115 // renderers created for particular chrome urls (e.g. the chrome-native:// |
| 912 // scheme) can be reused for subsequent navigations in the same WebContents. | 1116 // scheme) can be reused for subsequent navigations in the same WebContents. |
| 913 // See http://crbug.com/386542. | 1117 // See http://crbug.com/386542. |
| 914 if (dest_is_restore && | 1118 if (dest_is_restore && |
| 915 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) { | 1119 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) { |
| 916 current_site_instance->SetSite(dest_url); | 1120 current_site_instance->SetSite(dest_url); |
| 917 } | 1121 } |
| 918 | |
|
carlosk
2014/11/05 16:45:44
I already added this back locally.
| |
| 919 return current_site_instance; | 1122 return current_site_instance; |
| 920 } | 1123 } |
| 921 | 1124 |
| 922 // Otherwise, only create a new SiteInstance for a cross-site navigation. | 1125 // Otherwise, only create a new SiteInstance for a cross-site navigation. |
| 923 | 1126 |
| 924 // TODO(creis): Once we intercept links and script-based navigations, we | 1127 // TODO(creis): Once we intercept links and script-based navigations, we |
| 925 // will be able to enforce that all entries in a SiteInstance actually have | 1128 // will be able to enforce that all entries in a SiteInstance actually have |
| 926 // the same site, and it will be safe to compare the URL against the | 1129 // the same site, and it will be safe to compare the URL against the |
| 927 // SiteInstance's site, as follows: | 1130 // SiteInstance's site, as follows: |
| 928 // const GURL& current_url = current_instance->site(); | 1131 // const GURL& current_url = current_instance->site(); |
| 929 // For now, though, we're in a hybrid model where you only switch | 1132 // For now, though, we're in a hybrid model where you only switch |
| 930 // SiteInstances if you type in a cross-site URL. This means we have to | 1133 // SiteInstances if you type in a cross-site URL. This means we have to |
| 931 // compare the entry's URL to the last committed entry's URL. | 1134 // compare the entry's URL to the last committed entry's URL. |
| 932 NavigationEntry* current_entry = controller.GetLastCommittedEntry(); | 1135 NavigationEntry* current_entry = controller.GetLastCommittedEntry(); |
| 933 if (interstitial_page_) { | 1136 if (interstitial_page_) { |
| 934 // The interstitial is currently the last committed entry, but we want to | 1137 // The interstitial is currently the last committed entry, but we want to |
| 935 // compare against the last non-interstitial entry. | 1138 // compare against the last non-interstitial entry. |
| 936 current_entry = controller.GetEntryAtOffset(-1); | 1139 current_entry = controller.GetEntryAtOffset(-1); |
| 937 } | 1140 } |
| 938 | 1141 |
| 939 // View-source URLs must use a new SiteInstance and BrowsingInstance. | 1142 // View-source URLs must use a new SiteInstance and BrowsingInstance. |
| 940 // We don't need a swap when going from view-source to a debug URL like | 1143 // We don't need a swap when going from view-source to a debug URL like |
| 941 // chrome://crash, however. | 1144 // chrome://crash, however. |
| 942 // TODO(creis): Refactor this method so this duplicated code isn't needed. | 1145 // TODO(creis): Refactor this method so this duplicated code isn't needed. |
| 943 // See http://crbug.com/123007. | 1146 // See http://crbug.com/123007. |
| 944 if (current_entry && | 1147 if (current_entry && |
| 945 current_entry->IsViewSourceMode() != dest_is_view_source_mode && | 1148 current_entry->IsViewSourceMode() != dest_is_view_source_mode && |
| 946 !IsRendererDebugURL(dest_url)) { | 1149 !IsRendererDebugURL(dest_url)) { |
| 947 return SiteInstance::CreateForURL(browser_context, dest_url); | 1150 return CreateSiteInstanceForURL(browser_context, dest_url, |
| 1151 create_unbounded_site_instance, | |
| 1152 current_site_instance); | |
| 948 } | 1153 } |
| 949 | 1154 |
| 950 // Use the current SiteInstance for same site navigations, as long as the | 1155 // Use the current SiteInstance for same site navigations, as long as the |
| 951 // process type is correct. (The URL may have been installed as an app since | 1156 // process type is correct. (The URL may have been installed as an app since |
| 952 // the last time we visited it.) | 1157 // the last time we visited it.) |
| 953 const GURL& current_url = | 1158 const GURL& current_url = |
| 954 GetCurrentURLForSiteInstance(current_instance, current_entry); | 1159 GetCurrentURLForSiteInstance(current_instance, current_entry); |
| 955 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && | 1160 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && |
| 956 !current_site_instance->HasWrongProcessForURL(dest_url)) { | 1161 !current_site_instance->HasWrongProcessForURL(dest_url)) { |
| 957 return current_instance; | 1162 return current_instance; |
| 958 } | 1163 } |
| 959 | 1164 |
| 960 // Start the new renderer in a new SiteInstance, but in the current | 1165 // Start the new renderer in a new SiteInstance, but in the current |
| 961 // BrowsingInstance. It is important to immediately give this new | 1166 // BrowsingInstance. It is important to immediately give this new |
| 962 // SiteInstance to a RenderViewHost (if it is different than our current | 1167 // SiteInstance to a RenderViewHost (if it is different than our current |
| 963 // SiteInstance), so that it is ref counted. This will happen in | 1168 // SiteInstance), so that it is ref counted. This will happen in |
| 964 // CreateRenderView. | 1169 // CreateRenderView. |
| 1170 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url, | |
| 1171 create_unbounded_site_instance); | |
| 1172 } | |
| 1173 | |
| 1174 SiteInstance* RenderFrameHostManager::CreateSiteInstanceForURL( | |
| 1175 BrowserContext* browser_context, | |
| 1176 const GURL& dest_url, | |
| 1177 bool create_unbounded_site_instance, | |
| 1178 SiteInstanceImpl* current_instance) { | |
| 1179 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1180 switches::kEnableBrowserSideNavigation)) { | |
| 1181 if (create_unbounded_site_instance) { | |
| 1182 return SiteInstance::Create(browser_context); | |
| 1183 } | |
| 1184 if (speculative_render_frame_host_) { | |
| 1185 SiteInstanceImpl* sii = speculative_render_frame_host_->GetSiteInstance(); | |
| 1186 if (!sii->HasSite() && !sii->IsRelatedSiteInstance(current_instance)) { | |
| 1187 return sii; | |
| 1188 } | |
| 1189 } | |
| 1190 } | |
| 1191 | |
| 1192 return SiteInstance::CreateForURL(browser_context, dest_url); | |
| 1193 } | |
| 1194 | |
| 1195 SiteInstance* RenderFrameHostManager::GetRelatedSiteInstanceForURL( | |
| 1196 SiteInstanceImpl* current_instance, | |
| 1197 const GURL& dest_url, | |
| 1198 bool create_unbounded_site_instance) { | |
| 1199 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1200 switches::kEnableBrowserSideNavigation)) { | |
| 1201 if (!current_instance->HasRelatedSiteInstance(dest_url)) { | |
| 1202 if (create_unbounded_site_instance) { | |
| 1203 return current_instance->GetRelatedEmptySiteInstance(); | |
| 1204 } | |
| 1205 if (speculative_render_frame_host_) { | |
| 1206 SiteInstanceImpl* sii = | |
| 1207 speculative_render_frame_host_->GetSiteInstance(); | |
| 1208 if (!sii->HasSite() && sii->IsRelatedSiteInstance(current_instance)) { | |
| 1209 return sii; | |
| 1210 } | |
| 1211 } | |
| 1212 } | |
| 1213 } | |
| 1214 | |
| 965 return current_instance->GetRelatedSiteInstance(dest_url); | 1215 return current_instance->GetRelatedSiteInstance(dest_url); |
| 966 } | 1216 } |
| 967 | 1217 |
| 968 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance( | 1218 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance( |
| 969 SiteInstance* current_instance, NavigationEntry* current_entry) { | 1219 SiteInstance* current_instance, NavigationEntry* current_entry) { |
| 970 // If this is a subframe that is potentially out of process from its parent, | 1220 // If this is a subframe that is potentially out of process from its parent, |
| 971 // don't consider using current_entry's url for SiteInstance selection, since | 1221 // don't consider using current_entry's url for SiteInstance selection, since |
| 972 // current_entry's url is for the main frame and may be in a different site | 1222 // current_entry's url is for the main frame and may be in a different site |
| 973 // than this frame. | 1223 // than this frame. |
| 974 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url. | 1224 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url. |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1190 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); | 1440 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); |
| 1191 } else { | 1441 } else { |
| 1192 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | 1442 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled |
| 1193 // process unless it's swapped out. | 1443 // process unless it's swapped out. |
| 1194 if (render_view_host->is_active()) { | 1444 if (render_view_host->is_active()) { |
| 1195 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 1445 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
| 1196 render_view_host->GetProcess()->GetID())); | 1446 render_view_host->GetProcess()->GetID())); |
| 1197 } | 1447 } |
| 1198 } | 1448 } |
| 1199 | 1449 |
| 1200 return delegate_->CreateRenderViewForRenderManager(render_view_host, | 1450 return delegate_->CreateRenderViewForRenderManager( |
| 1201 opener_route_id, | 1451 render_view_host, opener_route_id, proxy_routing_id, |
| 1202 proxy_routing_id, | 1452 for_main_frame_navigation); |
|
carlosk
2014/11/05 16:45:44
IDK why but git cl format decided that this should
| |
| 1203 for_main_frame_navigation); | |
| 1204 } | 1453 } |
| 1205 | 1454 |
| 1206 bool RenderFrameHostManager::InitRenderFrame( | 1455 bool RenderFrameHostManager::InitRenderFrame( |
| 1207 RenderFrameHostImpl* render_frame_host) { | 1456 RenderFrameHostImpl* render_frame_host) { |
| 1208 if (render_frame_host->IsRenderFrameLive()) | 1457 if (render_frame_host->IsRenderFrameLive()) |
| 1209 return true; | 1458 return true; |
| 1210 | 1459 |
| 1211 int parent_routing_id = MSG_ROUTING_NONE; | 1460 int parent_routing_id = MSG_ROUTING_NONE; |
| 1212 int proxy_routing_id = MSG_ROUTING_NONE; | 1461 int proxy_routing_id = MSG_ROUTING_NONE; |
| 1213 if (frame_tree_node_->parent()) { | 1462 if (frame_tree_node_->parent()) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1239 return render_frame_host_->GetRoutingID(); | 1488 return render_frame_host_->GetRoutingID(); |
| 1240 | 1489 |
| 1241 RenderFrameProxyHostMap::iterator iter = | 1490 RenderFrameProxyHostMap::iterator iter = |
| 1242 proxy_hosts_.find(site_instance->GetId()); | 1491 proxy_hosts_.find(site_instance->GetId()); |
| 1243 if (iter != proxy_hosts_.end()) | 1492 if (iter != proxy_hosts_.end()) |
| 1244 return iter->second->GetRoutingID(); | 1493 return iter->second->GetRoutingID(); |
| 1245 | 1494 |
| 1246 return MSG_ROUTING_NONE; | 1495 return MSG_ROUTING_NONE; |
| 1247 } | 1496 } |
| 1248 | 1497 |
| 1249 void RenderFrameHostManager::CommitPending() { | 1498 void RenderFrameHostManager::CommitPending(bool use_speculative_rfh) { |
| 1250 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 1499 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
| 1251 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 1500 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 1501 // If use_speculative_rfh then kEnableBrowserSideNavigation must be enabled. | |
| 1502 DCHECK(!use_speculative_rfh || | |
| 1503 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1504 switches::kEnableBrowserSideNavigation)); | |
| 1505 | |
| 1252 // First check whether we're going to want to focus the location bar after | 1506 // First check whether we're going to want to focus the location bar after |
| 1253 // this commit. We do this now because the navigation hasn't formally | 1507 // this commit. We do this now because the navigation hasn't formally |
| 1254 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1508 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
| 1255 // this triggers won't be able to figure out what's going on. | 1509 // this triggers won't be able to figure out what's going on. |
| 1256 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1510 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 1257 | 1511 |
| 1258 // Next commit the Web UI, if any. Either replace |web_ui_| with | 1512 if (!use_speculative_rfh) { |
| 1259 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or | 1513 DCHECK(!speculative_web_ui_); |
| 1260 // leave |web_ui_| as is if reusing it. | 1514 // Next commit the Web UI, if any. Either replace |web_ui_| with |
| 1261 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); | 1515 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or |
| 1262 if (pending_web_ui_) { | 1516 // leave |web_ui_| as is if reusing it. |
| 1263 web_ui_.reset(pending_web_ui_.release()); | 1517 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); |
| 1264 } else if (!pending_and_current_web_ui_.get()) { | 1518 if (pending_web_ui_) { |
| 1265 web_ui_.reset(); | 1519 web_ui_.reset(pending_web_ui_.release()); |
| 1520 } else if (!pending_and_current_web_ui_.get()) { | |
| 1521 web_ui_.reset(); | |
| 1522 } else { | |
| 1523 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | |
| 1524 pending_and_current_web_ui_.reset(); | |
| 1525 } | |
| 1266 } else { | 1526 } else { |
| 1267 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | 1527 web_ui_.reset(speculative_web_ui_.release()); |
| 1268 pending_and_current_web_ui_.reset(); | |
| 1269 } | 1528 } |
| 1270 | 1529 |
| 1271 // It's possible for the pending_render_frame_host_ to be NULL when we aren't | 1530 // It's possible for the pending_render_frame_host_ to be NULL when we aren't |
| 1272 // crossing process boundaries. If so, we just needed to handle the Web UI | 1531 // crossing process boundaries. If so, we just needed to handle the Web UI |
| 1273 // committing above and we're done. | 1532 // committing above and we're done. |
| 1274 if (!pending_render_frame_host_) { | 1533 if (!pending_render_frame_host_ && !use_speculative_rfh) { |
| 1275 if (will_focus_location_bar) | 1534 if (will_focus_location_bar) |
| 1276 delegate_->SetFocusToLocationBar(false); | 1535 delegate_->SetFocusToLocationBar(false); |
| 1277 return; | 1536 return; |
| 1278 } | 1537 } |
| 1279 | 1538 |
| 1280 // Remember if the page was focused so we can focus the new renderer in | 1539 // Remember if the page was focused so we can focus the new renderer in |
| 1281 // that case. | 1540 // that case. |
| 1282 bool focus_render_view = !will_focus_location_bar && | 1541 bool focus_render_view = !will_focus_location_bar && |
| 1283 render_frame_host_->render_view_host()->GetView() && | 1542 render_frame_host_->render_view_host()->GetView() && |
| 1284 render_frame_host_->render_view_host()->GetView()->HasFocus(); | 1543 render_frame_host_->render_view_host()->GetView()->HasFocus(); |
| 1285 | 1544 |
| 1286 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 1545 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 1287 | 1546 |
| 1288 // Swap in the pending frame and make it active. Also ensure the FrameTree | 1547 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
| 1289 // stays in sync. | 1548 if (!use_speculative_rfh) { |
| 1290 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 1549 DCHECK(!speculative_render_frame_host_); |
| 1291 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 1550 // Swap in the pending frame and make it active. Also ensure the FrameTree |
| 1551 // stays in sync. | |
| 1552 old_render_frame_host = | |
| 1553 SetRenderFrameHost(pending_render_frame_host_.Pass()); | |
| 1554 } else { | |
| 1555 DCHECK(speculative_render_frame_host_); | |
| 1556 old_render_frame_host = | |
| 1557 SetRenderFrameHost(speculative_render_frame_host_.Pass()); | |
| 1558 } | |
| 1559 | |
| 1292 if (is_main_frame) | 1560 if (is_main_frame) |
| 1293 render_frame_host_->render_view_host()->AttachToFrameTree(); | 1561 render_frame_host_->render_view_host()->AttachToFrameTree(); |
| 1294 | 1562 |
| 1295 // The process will no longer try to exit, so we can decrement the count. | 1563 // The process will no longer try to exit, so we can decrement the count. |
| 1296 render_frame_host_->GetProcess()->RemovePendingView(); | 1564 render_frame_host_->GetProcess()->RemovePendingView(); |
| 1297 | 1565 |
| 1298 // Show the new view (or a sad tab) if necessary. | 1566 // Show the new view (or a sad tab) if necessary. |
| 1299 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); | 1567 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); |
| 1300 if (!delegate_->IsHidden() && new_rfh_has_view) { | 1568 if (!delegate_->IsHidden() && new_rfh_has_view) { |
| 1301 // In most cases, we need to show the new view. | 1569 // In most cases, we need to show the new view. |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1408 // If we are currently navigating cross-process, we want to get back to normal | 1676 // If we are currently navigating cross-process, we want to get back to normal |
| 1409 // and then navigate as usual. | 1677 // and then navigate as usual. |
| 1410 if (cross_navigation_pending_) { | 1678 if (cross_navigation_pending_) { |
| 1411 if (pending_render_frame_host_) | 1679 if (pending_render_frame_host_) |
| 1412 CancelPending(); | 1680 CancelPending(); |
| 1413 cross_navigation_pending_ = false; | 1681 cross_navigation_pending_ = false; |
| 1414 } | 1682 } |
| 1415 | 1683 |
| 1416 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1684 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 1417 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( | 1685 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
| 1418 url, instance, transition, is_restore, is_view_source_mode); | 1686 url, instance, transition, is_restore, is_view_source_mode, false); |
| 1687 | |
| 1688 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1689 switches::kEnableBrowserSideNavigation) && | |
| 1690 speculative_render_frame_host_) { | |
| 1691 if (speculative_render_frame_host_->GetSiteInstance() == new_instance) { | |
| 1692 return speculative_render_frame_host_.get(); | |
| 1693 } | |
| 1694 CleanUpCurrentNavigation(); | |
| 1695 } | |
| 1419 | 1696 |
| 1420 const NavigationEntry* current_entry = | 1697 const NavigationEntry* current_entry = |
| 1421 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1698 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
| 1422 | 1699 |
| 1423 if (new_instance.get() != current_instance) { | 1700 if (new_instance.get() != current_instance) { |
| 1424 TRACE_EVENT_INSTANT2( | 1701 TRACE_EVENT_INSTANT2( |
| 1425 "navigation", | 1702 "navigation", |
| 1426 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 1703 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
| 1427 TRACE_EVENT_SCOPE_THREAD, | 1704 TRACE_EVENT_SCOPE_THREAD, |
| 1428 "current_instance id", current_instance->GetId(), | 1705 "current_instance id", current_instance->GetId(), |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1445 } | 1722 } |
| 1446 | 1723 |
| 1447 // Check if our current RFH is live before we set up a transition. | 1724 // Check if our current RFH is live before we set up a transition. |
| 1448 if (!render_frame_host_->IsRenderFrameLive()) { | 1725 if (!render_frame_host_->IsRenderFrameLive()) { |
| 1449 if (!cross_navigation_pending_) { | 1726 if (!cross_navigation_pending_) { |
| 1450 // The current RFH is not live. There's no reason to sit around with a | 1727 // The current RFH is not live. There's no reason to sit around with a |
| 1451 // sad tab or a newly created RFH while we wait for the pending RFH to | 1728 // sad tab or a newly created RFH while we wait for the pending RFH to |
| 1452 // navigate. Just switch to the pending RFH now and go back to non | 1729 // navigate. Just switch to the pending RFH now and go back to non |
| 1453 // cross-navigating (Note that we don't care about on{before}unload | 1730 // cross-navigating (Note that we don't care about on{before}unload |
| 1454 // handlers if the current RFH isn't live.) | 1731 // handlers if the current RFH isn't live.) |
| 1455 CommitPending(); | 1732 CommitPending(false); |
| 1456 return render_frame_host_.get(); | 1733 return render_frame_host_.get(); |
| 1457 } else { | 1734 } else { |
| 1458 NOTREACHED(); | 1735 NOTREACHED(); |
| 1459 return render_frame_host_.get(); | 1736 return render_frame_host_.get(); |
| 1460 } | 1737 } |
| 1461 } | 1738 } |
| 1462 // Otherwise, it's safe to treat this as a pending cross-site transition. | 1739 // Otherwise, it's safe to treat this as a pending cross-site transition. |
| 1463 | 1740 |
| 1464 // We now have a pending RFH. | 1741 // We now have a pending RFH. |
| 1465 DCHECK(!cross_navigation_pending_); | 1742 DCHECK(!cross_navigation_pending_); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1494 render_frame_host_->Send(new FrameMsg_Stop( | 1771 render_frame_host_->Send(new FrameMsg_Stop( |
| 1495 render_frame_host_->GetRoutingID())); | 1772 render_frame_host_->GetRoutingID())); |
| 1496 pending_render_frame_host_->SetNavigationsSuspended(true, | 1773 pending_render_frame_host_->SetNavigationsSuspended(true, |
| 1497 base::TimeTicks()); | 1774 base::TimeTicks()); |
| 1498 // Unless we are transferring an existing request, we should now tell the | 1775 // Unless we are transferring an existing request, we should now tell the |
| 1499 // old render view to run its beforeunload handler, since it doesn't | 1776 // old render view to run its beforeunload handler, since it doesn't |
| 1500 // otherwise know that the cross-site request is happening. This will | 1777 // otherwise know that the cross-site request is happening. This will |
| 1501 // trigger a call to OnBeforeUnloadACK with the reply. | 1778 // trigger a call to OnBeforeUnloadACK with the reply. |
| 1502 render_frame_host_->DispatchBeforeUnload(true); | 1779 render_frame_host_->DispatchBeforeUnload(true); |
| 1503 } | 1780 } |
| 1504 | |
|
carlosk
2014/11/05 16:45:44
I already added this back locally.
| |
| 1505 return pending_render_frame_host_.get(); | 1781 return pending_render_frame_host_.get(); |
| 1506 } | 1782 } |
| 1507 | 1783 |
| 1508 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. | 1784 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. |
| 1509 DCHECK(!cross_navigation_pending_); | 1785 DCHECK(!cross_navigation_pending_); |
| 1510 | 1786 |
| 1511 // It's possible to swap out the current RFH and then decide to navigate in it | 1787 // It's possible to swap out the current RFH and then decide to navigate in it |
| 1512 // anyway (e.g., a cross-process navigation that redirects back to the | 1788 // anyway (e.g., a cross-process navigation that redirects back to the |
| 1513 // original site). In that case, we have a proxy for the current RFH but | 1789 // original site). In that case, we have a proxy for the current RFH but |
| 1514 // haven't deleted it yet. The new navigation will swap it back in, so we can | 1790 // haven't deleted it yet. The new navigation will swap it back in, so we can |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1533 render_frame_host_->render_view_host()); | 1809 render_frame_host_->render_view_host()); |
| 1534 } | 1810 } |
| 1535 | 1811 |
| 1536 // The renderer can exit view source mode when any error or cancellation | 1812 // The renderer can exit view source mode when any error or cancellation |
| 1537 // happen. We must overwrite to recover the mode. | 1813 // happen. We must overwrite to recover the mode. |
| 1538 if (is_view_source_mode) { | 1814 if (is_view_source_mode) { |
| 1539 render_frame_host_->render_view_host()->Send( | 1815 render_frame_host_->render_view_host()->Send( |
| 1540 new ViewMsg_EnableViewSourceMode( | 1816 new ViewMsg_EnableViewSourceMode( |
| 1541 render_frame_host_->render_view_host()->GetRoutingID())); | 1817 render_frame_host_->render_view_host()->GetRoutingID())); |
| 1542 } | 1818 } |
| 1543 | |
|
carlosk
2014/11/05 16:45:44
I already added this back locally.
| |
| 1544 return render_frame_host_.get(); | 1819 return render_frame_host_.get(); |
| 1545 } | 1820 } |
| 1546 | 1821 |
| 1547 void RenderFrameHostManager::CancelPending() { | 1822 void RenderFrameHostManager::CancelPending() { |
| 1548 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", | 1823 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", |
| 1549 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 1824 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 1550 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = | 1825 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = |
| 1551 pending_render_frame_host_.Pass(); | 1826 pending_render_frame_host_.Pass(); |
| 1552 | 1827 |
| 1553 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( | 1828 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( |
| 1554 pending_render_frame_host->render_view_host(), | 1829 pending_render_frame_host->render_view_host(), |
| 1555 render_frame_host_->render_view_host()); | 1830 render_frame_host_->render_view_host()); |
| 1556 | 1831 |
| 1557 // We no longer need to prevent the process from exiting. | 1832 // We no longer need to prevent the process from exiting. |
| 1558 pending_render_frame_host->GetProcess()->RemovePendingView(); | 1833 pending_render_frame_host->GetProcess()->RemovePendingView(); |
| 1559 | 1834 |
| 1560 // If the SiteInstance for the pending RFH is being used by others, don't | 1835 RecycleRenderFrameHost(pending_render_frame_host.Pass()); |
| 1561 // delete the RFH, just swap it out and it can be reused at a later point. | |
| 1562 SiteInstanceImpl* site_instance = | |
| 1563 pending_render_frame_host->GetSiteInstance(); | |
| 1564 if (site_instance->active_frame_count() > 1) { | |
| 1565 // Any currently suspended navigations are no longer needed. | |
| 1566 pending_render_frame_host->CancelSuspendedNavigations(); | |
| 1567 | |
| 1568 RenderFrameProxyHost* proxy = | |
| 1569 new RenderFrameProxyHost(site_instance, frame_tree_node_); | |
| 1570 proxy_hosts_[site_instance->GetId()] = proxy; | |
| 1571 pending_render_frame_host->SwapOut(proxy); | |
| 1572 if (frame_tree_node_->IsMainFrame()) | |
| 1573 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); | |
| 1574 } else { | |
| 1575 // We won't be coming back, so delete this one. | |
| 1576 pending_render_frame_host.reset(); | |
| 1577 } | |
| 1578 | 1836 |
| 1579 pending_web_ui_.reset(); | 1837 pending_web_ui_.reset(); |
| 1580 pending_and_current_web_ui_.reset(); | 1838 pending_and_current_web_ui_.reset(); |
| 1581 } | 1839 } |
| 1582 | 1840 |
| 1841 void RenderFrameHostManager::CleanUpCurrentNavigation() { | |
| 1842 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1843 switches::kEnableBrowserSideNavigation)); | |
| 1844 if (speculative_render_frame_host_) { | |
| 1845 speculative_render_frame_host_->GetProcess()->RemovePendingView(); | |
| 1846 RecycleRenderFrameHost(speculative_render_frame_host_.Pass()); | |
| 1847 } | |
| 1848 if (speculative_web_ui_) { | |
| 1849 speculative_web_ui_.reset(); | |
| 1850 } | |
| 1851 } | |
| 1852 | |
| 1583 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 1853 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
| 1584 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 1854 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 1585 // Swap the two. | 1855 // Swap the two. |
| 1586 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 1856 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
| 1587 render_frame_host_.Pass(); | 1857 render_frame_host_.Pass(); |
| 1588 render_frame_host_ = render_frame_host.Pass(); | 1858 render_frame_host_ = render_frame_host.Pass(); |
| 1589 | 1859 |
| 1590 if (frame_tree_node_->IsMainFrame()) { | 1860 if (frame_tree_node_->IsMainFrame()) { |
| 1591 // Update the count of top-level frames using this SiteInstance. All | 1861 // Update the count of top-level frames using this SiteInstance. All |
| 1592 // subframes are in the same BrowsingInstance as the main frame, so we only | 1862 // subframes are in the same BrowsingInstance as the main frame, so we only |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1652 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1922 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
| 1653 SiteInstance* instance) { | 1923 SiteInstance* instance) { |
| 1654 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1924 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
| 1655 if (iter != proxy_hosts_.end()) { | 1925 if (iter != proxy_hosts_.end()) { |
| 1656 delete iter->second; | 1926 delete iter->second; |
| 1657 proxy_hosts_.erase(iter); | 1927 proxy_hosts_.erase(iter); |
| 1658 } | 1928 } |
| 1659 } | 1929 } |
| 1660 | 1930 |
| 1661 } // namespace content | 1931 } // namespace content |
| OLD | NEW |