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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 RenderViewHostDelegate* render_view_delegate, | 54 RenderViewHostDelegate* render_view_delegate, |
| 55 RenderWidgetHostDelegate* render_widget_delegate, | 55 RenderWidgetHostDelegate* render_widget_delegate, |
| 56 Delegate* delegate) | 56 Delegate* delegate) |
| 57 : frame_tree_node_(frame_tree_node), | 57 : frame_tree_node_(frame_tree_node), |
| 58 delegate_(delegate), | 58 delegate_(delegate), |
| 59 cross_navigation_pending_(false), | 59 cross_navigation_pending_(false), |
| 60 render_frame_delegate_(render_frame_delegate), | 60 render_frame_delegate_(render_frame_delegate), |
| 61 render_view_delegate_(render_view_delegate), | 61 render_view_delegate_(render_view_delegate), |
| 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 should_reuse_web_ui_(false) { | |
| 65 DCHECK(frame_tree_node_); | 66 DCHECK(frame_tree_node_); |
| 66 } | 67 } |
| 67 | 68 |
| 68 RenderFrameHostManager::~RenderFrameHostManager() { | 69 RenderFrameHostManager::~RenderFrameHostManager() { |
| 69 if (pending_render_frame_host_) | 70 if (pending_render_frame_host_) |
| 70 CancelPending(); | 71 CancelPending(); |
| 71 | 72 |
| 73 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 74 switches::kEnableBrowserSideNavigation)) { | |
| 75 CleanUpNavigation(); | |
| 76 } | |
| 77 | |
| 72 // We should always have a current RenderFrameHost except in some tests. | 78 // We should always have a current RenderFrameHost except in some tests. |
| 73 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); | 79 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); |
| 74 | 80 |
| 75 // Delete any swapped out RenderFrameHosts. | 81 // Delete any swapped out RenderFrameHosts. |
| 76 STLDeleteValues(&proxy_hosts_); | 82 STLDeleteValues(&proxy_hosts_); |
| 77 } | 83 } |
| 78 | 84 |
| 79 void RenderFrameHostManager::Init(BrowserContext* browser_context, | 85 void RenderFrameHostManager::Init(BrowserContext* browser_context, |
| 80 SiteInstance* site_instance, | 86 SiteInstance* site_instance, |
| 81 int view_routing_id, | 87 int view_routing_id, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 ->render_manager() | 133 ->render_manager() |
| 128 ->current_frame_host() | 134 ->current_frame_host() |
| 129 ->GetSiteInstance() | 135 ->GetSiteInstance() |
| 130 ->GetId()); | 136 ->GetId()); |
| 131 if (iter == proxy_hosts_.end()) | 137 if (iter == proxy_hosts_.end()) |
| 132 return NULL; | 138 return NULL; |
| 133 | 139 |
| 134 return iter->second; | 140 return iter->second; |
| 135 } | 141 } |
| 136 | 142 |
| 137 void RenderFrameHostManager::SetPendingWebUI(const GURL& url, | 143 void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) { |
| 138 int bindings) { | 144 pending_web_ui_.reset(CreateWebUI(url, bindings)); |
| 139 pending_web_ui_.reset( | |
| 140 delegate_->CreateWebUIForRenderManager(url)); | |
| 141 pending_and_current_web_ui_.reset(); | 145 pending_and_current_web_ui_.reset(); |
| 146 } | |
| 147 | |
| 148 WebUIImpl* RenderFrameHostManager::CreateWebUI(const GURL& url, int bindings) { | |
| 149 WebUIImpl* new_web_ui = delegate_->CreateWebUIForRenderManager(url); | |
| 142 | 150 |
| 143 // If we have assigned (zero or more) bindings to this NavigationEntry in the | 151 // If we have assigned (zero or more) bindings to this NavigationEntry in the |
| 144 // past, make sure we're not granting it different bindings than it had | 152 // past, make sure we're not granting it different bindings than it had |
| 145 // before. If so, note it and don't give it any bindings, to avoid a | 153 // before. If so, note it and don't give it any bindings, to avoid a |
| 146 // potential privilege escalation. | 154 // potential privilege escalation. |
| 147 if (pending_web_ui_.get() && | 155 if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings && |
| 148 bindings != NavigationEntryImpl::kInvalidBindings && | 156 new_web_ui->GetBindings() != bindings) { |
| 149 pending_web_ui_->GetBindings() != bindings) { | 157 RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); |
| 150 RecordAction( | 158 delete new_web_ui; |
| 151 base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); | 159 return nullptr; |
| 152 pending_web_ui_.reset(); | |
| 153 } | 160 } |
| 161 return new_web_ui; | |
| 154 } | 162 } |
| 155 | 163 |
| 156 RenderFrameHostImpl* RenderFrameHostManager::Navigate( | 164 RenderFrameHostImpl* RenderFrameHostManager::Navigate( |
| 157 const NavigationEntryImpl& entry) { | 165 const NavigationEntryImpl& entry) { |
| 158 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", | 166 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", |
| 159 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 167 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 160 // Create a pending RenderFrameHost to use for the navigation. | 168 // Create a pending RenderFrameHost to use for the navigation. |
| 161 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( | 169 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( |
| 162 entry.GetURL(), | 170 entry.GetURL(), |
| 163 entry.site_instance(), | 171 entry.site_instance(), |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 } | 287 } |
| 280 } | 288 } |
| 281 return false; | 289 return false; |
| 282 } | 290 } |
| 283 | 291 |
| 284 void RenderFrameHostManager::OnBeforeUnloadACK( | 292 void RenderFrameHostManager::OnBeforeUnloadACK( |
| 285 bool for_cross_site_transition, | 293 bool for_cross_site_transition, |
| 286 bool proceed, | 294 bool proceed, |
| 287 const base::TimeTicks& proceed_time) { | 295 const base::TimeTicks& proceed_time) { |
| 288 if (for_cross_site_transition) { | 296 if (for_cross_site_transition) { |
| 297 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 298 switches::kEnableBrowserSideNavigation)); | |
| 289 // Ignore if we're not in a cross-site navigation. | 299 // Ignore if we're not in a cross-site navigation. |
| 290 if (!cross_navigation_pending_) | 300 if (!cross_navigation_pending_) |
| 291 return; | 301 return; |
| 292 | 302 |
| 293 if (proceed) { | 303 if (proceed) { |
| 294 // Ok to unload the current page, so proceed with the cross-site | 304 // Ok to unload the current page, so proceed with the cross-site |
| 295 // navigation. Note that if navigations are not currently suspended, it | 305 // navigation. Note that if navigations are not currently suspended, it |
| 296 // might be because the renderer was deemed unresponsive and this call was | 306 // might be because the renderer was deemed unresponsive and this call was |
| 297 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it | 307 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it |
| 298 // is ok to do nothing here. | 308 // is ok to do nothing here. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 | 420 |
| 411 response_started_id_.reset(); | 421 response_started_id_.reset(); |
| 412 } | 422 } |
| 413 | 423 |
| 414 void RenderFrameHostManager::ClearNavigationTransitionData() { | 424 void RenderFrameHostManager::ClearNavigationTransitionData() { |
| 415 render_frame_host_->ClearPendingTransitionRequestData(); | 425 render_frame_host_->ClearPendingTransitionRequestData(); |
| 416 } | 426 } |
| 417 | 427 |
| 418 void RenderFrameHostManager::DidNavigateFrame( | 428 void RenderFrameHostManager::DidNavigateFrame( |
| 419 RenderFrameHostImpl* render_frame_host) { | 429 RenderFrameHostImpl* render_frame_host) { |
| 430 DCHECK(render_frame_host); | |
| 431 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 432 switches::kEnableBrowserSideNavigation)) { | |
| 433 return; | |
| 434 } | |
| 435 | |
| 420 if (!cross_navigation_pending_) { | 436 if (!cross_navigation_pending_) { |
| 421 DCHECK(!pending_render_frame_host_); | 437 DCHECK(!pending_render_frame_host_); |
| 422 | 438 |
| 423 // We should only hear this from our current renderer. | 439 // We should only hear this from our current renderer. |
| 424 DCHECK_EQ(render_frame_host_, render_frame_host); | 440 DCHECK_EQ(render_frame_host_, render_frame_host); |
| 425 | 441 |
| 426 // Even when there is no pending RVH, there may be a pending Web UI. | 442 // Even when there is no pending RVH, there may be a pending Web UI. |
| 427 if (pending_web_ui()) | 443 if (pending_web_ui()) |
| 428 CommitPending(); | 444 CommitPending(false); |
| 429 return; | 445 return; |
| 430 } | 446 } |
| 431 | 447 |
| 432 if (render_frame_host == pending_render_frame_host_) { | 448 if (render_frame_host == pending_render_frame_host_) { |
| 433 // The pending cross-site navigation completed, so show the renderer. | 449 // The pending cross-site navigation completed, so show the renderer. |
| 434 CommitPending(); | 450 CommitPending(false); |
| 435 cross_navigation_pending_ = false; | 451 cross_navigation_pending_ = false; |
| 436 } else if (render_frame_host == render_frame_host_) { | 452 } else if (render_frame_host == render_frame_host_) { |
| 437 // A navigation in the original page has taken place. Cancel the pending | 453 // A navigation in the original page has taken place. Cancel the pending |
| 438 // one. | 454 // one. |
| 439 CancelPending(); | 455 CancelPending(); |
| 440 cross_navigation_pending_ = false; | 456 cross_navigation_pending_ = false; |
| 441 } else { | 457 } else { |
| 442 // No one else should be sending us DidNavigate in this state. | 458 // No one else should be sending us DidNavigate in this state. |
| 443 DCHECK(false); | 459 DCHECK(false); |
| 444 } | 460 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 // We shouldn't get here for subframes, since we only swap subframes when | 566 // We shouldn't get here for subframes, since we only swap subframes when |
| 551 // --site-per-process is used. | 567 // --site-per-process is used. |
| 552 DCHECK(is_main_frame); | 568 DCHECK(is_main_frame); |
| 553 | 569 |
| 554 // The old RenderFrameHost will stay alive inside the proxy so that existing | 570 // The old RenderFrameHost will stay alive inside the proxy so that existing |
| 555 // JavaScript window references to it stay valid. | 571 // JavaScript window references to it stay valid. |
| 556 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); | 572 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); |
| 557 } | 573 } |
| 558 } | 574 } |
| 559 | 575 |
| 576 void RenderFrameHostManager::DiscardRenderFrameHost( | |
| 577 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | |
| 578 // TODO(carlosk): this code is very similar to what can be found in | |
| 579 // SwapOutOldFrame and we should see that these are unified at some point. | |
| 580 | |
| 581 // If the SiteInstance for the pending RFH is being used by others, don't | |
| 582 // delete the RFH, just swap it out and it can be reused at a later point. | |
| 583 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); | |
| 584 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { | |
| 585 // Any currently suspended navigations are no longer needed. | |
| 586 render_frame_host->CancelSuspendedNavigations(); | |
| 587 | |
| 588 RenderFrameProxyHost* proxy = | |
| 589 new RenderFrameProxyHost(site_instance, frame_tree_node_); | |
| 590 proxy_hosts_[site_instance->GetId()] = proxy; | |
| 591 render_frame_host->SwapOut(proxy); | |
| 592 if (frame_tree_node_->IsMainFrame()) | |
| 593 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); | |
| 594 } else { | |
| 595 // We won't be coming back, so delete this one. | |
| 596 render_frame_host.reset(); | |
| 597 } | |
| 598 } | |
| 599 | |
| 560 void RenderFrameHostManager::MoveToPendingDeleteHosts( | 600 void RenderFrameHostManager::MoveToPendingDeleteHosts( |
| 561 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 601 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 562 // |render_frame_host| will be deleted when its SwapOut ACK is received, or | 602 // |render_frame_host| will be deleted when its SwapOut ACK is received, or |
| 563 // when the timer times out, or when the RFHM itself is deleted (whichever | 603 // when the timer times out, or when the RFHM itself is deleted (whichever |
| 564 // comes first). | 604 // comes first). |
| 565 pending_delete_hosts_.push_back( | 605 pending_delete_hosts_.push_back( |
| 566 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); | 606 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); |
| 567 } | 607 } |
| 568 | 608 |
| 569 bool RenderFrameHostManager::IsPendingDeletion( | 609 bool RenderFrameHostManager::IsPendingDeletion( |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 586 } | 626 } |
| 587 } | 627 } |
| 588 return false; | 628 return false; |
| 589 } | 629 } |
| 590 | 630 |
| 591 void RenderFrameHostManager::ResetProxyHosts() { | 631 void RenderFrameHostManager::ResetProxyHosts() { |
| 592 STLDeleteValues(&proxy_hosts_); | 632 STLDeleteValues(&proxy_hosts_); |
| 593 } | 633 } |
| 594 | 634 |
| 595 // PlzNavigate | 635 // PlzNavigate |
| 636 void RenderFrameHostManager::BeginNavigation( | |
| 637 const FrameHostMsg_BeginNavigation_Params& params, | |
| 638 const CommonNavigationParams& common_params) { | |
| 639 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
| 640 switches::kEnableBrowserSideNavigation)); | |
| 641 // If there is an ongoing navigation, cancel it. | |
| 642 CleanUpNavigation(); | |
| 643 | |
| 644 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | |
| 645 // TODO(carlosk): Replace the default values by the right ones. | |
| 646 scoped_refptr<SiteInstanceImpl> new_instance = | |
| 647 static_cast<SiteInstanceImpl*>(GetSiteInstanceForNavigation( | |
| 648 common_params.url, nullptr, common_params.transition, false, false)); | |
| 649 | |
| 650 if (new_instance.get() != current_instance) { | |
| 651 // Navigating to a new SiteInstance -> speculatively create a new RFH. | |
| 652 | |
| 653 // TODO(carlosk): enable bindings check below. | |
| 654 bool success = CreateSpeculativeRenderFrameHost( | |
| 655 common_params.url, current_instance, new_instance.get(), | |
| 656 NavigationEntryImpl::kInvalidBindings); | |
| 657 if (!success) | |
| 658 return; | |
| 659 } else { | |
| 660 // Navigating to the same SiteInstance -> make sure the current RFH is | |
| 661 // alive. | |
| 662 DCHECK(render_frame_host_->GetSiteInstance() == new_instance); | |
| 663 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { | |
| 664 // Recreate the opener chain. | |
| 665 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | |
| 666 render_frame_host_->GetSiteInstance()); | |
| 667 if (!InitRenderView(render_frame_host_->render_view_host(), | |
| 668 opener_route_id, MSG_ROUTING_NONE, | |
| 669 frame_tree_node_->IsMainFrame())) { | |
| 670 return; | |
| 671 } | |
| 672 } | |
| 673 } | |
| 674 DCHECK(new_instance->GetProcess()->HasConnection()); | |
| 675 DCHECK(new_instance->GetProcess()->GetBrowserContext()); | |
| 676 } | |
| 677 | |
| 678 // PlzNavigate | |
| 679 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( | |
| 680 const GURL& url, | |
| 681 SiteInstance* old_instance, | |
| 682 SiteInstance* new_instance, | |
| 683 int bindings) { | |
| 684 CHECK(new_instance); | |
| 685 CHECK_NE(old_instance, new_instance); | |
| 686 | |
| 687 const NavigationEntry* current_navigation_entry = | |
| 688 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
| 689 scoped_ptr<WebUIImpl> new_web_ui; | |
| 690 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, url); | |
| 691 if (!should_reuse_web_ui_) | |
| 692 new_web_ui.reset(CreateWebUI(url, bindings)); | |
| 693 | |
| 694 int opener_route_id = | |
| 695 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance); | |
| 696 | |
| 697 int create_render_frame_flags = 0; | |
| 698 if (frame_tree_node_->IsMainFrame()) | |
| 699 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION; | |
| 700 if (delegate_->IsHidden()) | |
| 701 create_render_frame_flags |= CREATE_RF_HIDDEN; | |
| 702 scoped_ptr<RenderFrameHostImpl> new_render_frame_host = | |
| 703 CreateRenderFrame(new_instance, opener_route_id, | |
| 704 create_render_frame_flags, new_web_ui.get(), nullptr); | |
| 705 if (!new_render_frame_host) { | |
| 706 return false; | |
| 707 } | |
| 708 speculative_render_frame_host_.reset(new_render_frame_host.release()); | |
| 709 speculative_web_ui_.reset(new_web_ui.release()); | |
| 710 return true; | |
| 711 } | |
| 712 | |
| 713 // PlzNavigate | |
| 596 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( | 714 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( |
| 597 const GURL& url, | 715 const GURL& url, |
| 598 ui::PageTransition transition) { | 716 ui::PageTransition transition) { |
| 599 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | 717 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 600 switches::kEnableBrowserSideNavigation)); | 718 switches::kEnableBrowserSideNavigation)); |
| 601 // TODO(clamy): When we handle renderer initiated navigations, make sure not | 719 // TODO(clamy): When we handle renderer initiated navigations, make sure not |
| 602 // to use a different process for subframes if --site-per-process is not | 720 // to use a different process for subframes if --site-per-process is not |
| 603 // enabled. | 721 // enabled. |
| 604 | 722 |
| 605 // Pick the right RenderFrameHost to commit the navigation. | 723 // Pick the right RenderFrameHost to commit the navigation. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 617 if (!InitRenderView(render_frame_host->render_view_host(), | 735 if (!InitRenderView(render_frame_host->render_view_host(), |
| 618 opener_route_id, | 736 opener_route_id, |
| 619 MSG_ROUTING_NONE, | 737 MSG_ROUTING_NONE, |
| 620 frame_tree_node_->IsMainFrame())) { | 738 frame_tree_node_->IsMainFrame())) { |
| 621 return NULL; | 739 return NULL; |
| 622 } | 740 } |
| 623 } | 741 } |
| 624 return render_frame_host; | 742 return render_frame_host; |
| 625 } | 743 } |
| 626 | 744 |
| 745 // PlzNavigate | |
| 746 void RenderFrameHostManager::CleanUpNavigation() { | |
| 747 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | |
| 748 switches::kEnableBrowserSideNavigation)); | |
| 749 if (speculative_render_frame_host_) { | |
| 750 speculative_render_frame_host_->GetProcess()->RemovePendingView(); | |
| 751 DiscardRenderFrameHost(speculative_render_frame_host_.Pass()); | |
| 752 } | |
| 753 if (speculative_web_ui_) | |
| 754 speculative_web_ui_.reset(); | |
| 755 } | |
| 756 | |
| 627 void RenderFrameHostManager::Observe( | 757 void RenderFrameHostManager::Observe( |
| 628 int type, | 758 int type, |
| 629 const NotificationSource& source, | 759 const NotificationSource& source, |
| 630 const NotificationDetails& details) { | 760 const NotificationDetails& details) { |
| 631 switch (type) { | 761 switch (type) { |
| 632 case NOTIFICATION_RENDERER_PROCESS_CLOSED: | 762 case NOTIFICATION_RENDERER_PROCESS_CLOSED: |
| 633 case NOTIFICATION_RENDERER_PROCESS_CLOSING: | 763 case NOTIFICATION_RENDERER_PROCESS_CLOSING: |
| 634 RendererProcessClosing( | 764 RendererProcessClosing( |
| 635 Source<RenderProcessHost>(source).ptr()); | 765 Source<RenderProcessHost>(source).ptr()); |
| 636 break; | 766 break; |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 990 return current_instance->GetSiteURL(); | 1120 return current_instance->GetSiteURL(); |
| 991 } | 1121 } |
| 992 | 1122 |
| 993 void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance( | 1123 void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance( |
| 994 SiteInstance* old_instance, | 1124 SiteInstance* old_instance, |
| 995 SiteInstance* new_instance, | 1125 SiteInstance* new_instance, |
| 996 bool is_main_frame) { | 1126 bool is_main_frame) { |
| 997 int create_render_frame_flags = 0; | 1127 int create_render_frame_flags = 0; |
| 998 if (is_main_frame) | 1128 if (is_main_frame) |
| 999 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION; | 1129 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION; |
| 1000 // Ensure that we have created RFHs for the new RFH's opener chain if | 1130 if (delegate_->IsHidden()) |
| 1001 // we are staying in the same BrowsingInstance. This allows the new RFH | 1131 create_render_frame_flags |= CREATE_RF_HIDDEN; |
| 1002 // to send cross-process script calls to its opener(s). | 1132 int opener_route_id = |
| 1133 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance); | |
| 1134 // TODO(carlosk): does this "earlier" call for CancelPending affects anything? | |
| 1135 // It used to happen inside the creation method iff the new RFH was | |
| 1136 // successfully created. | |
| 1137 if (pending_render_frame_host_) | |
| 1138 CancelPending(); | |
| 1139 // Create a non-swapped-out RFH with the given opener. | |
| 1140 pending_render_frame_host_ = | |
| 1141 CreateRenderFrame(new_instance, opener_route_id, | |
| 1142 create_render_frame_flags, pending_web_ui(), nullptr); | |
| 1143 } | |
| 1144 | |
| 1145 int RenderFrameHostManager::CreateOpenerRenderViewsIfNeeded( | |
| 1146 SiteInstance* old_instance, | |
| 1147 SiteInstance* new_instance) { | |
| 1003 int opener_route_id = MSG_ROUTING_NONE; | 1148 int opener_route_id = MSG_ROUTING_NONE; |
| 1004 if (new_instance->IsRelatedSiteInstance(old_instance)) { | 1149 if (new_instance->IsRelatedSiteInstance(old_instance)) { |
| 1005 opener_route_id = | 1150 opener_route_id = |
| 1006 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); | 1151 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); |
| 1007 if (CommandLine::ForCurrentProcess()->HasSwitch( | 1152 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 1008 switches::kSitePerProcess)) { | 1153 switches::kSitePerProcess)) { |
| 1009 // Ensure that the frame tree has RenderFrameProxyHosts for the new | 1154 // Ensure that the frame tree has RenderFrameProxyHosts for the new |
| 1010 // SiteInstance in all nodes except the current one. | 1155 // SiteInstance in all nodes except the current one. |
| 1011 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( | 1156 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( |
| 1012 frame_tree_node_, new_instance); | 1157 frame_tree_node_, new_instance); |
| 1013 } | 1158 } |
| 1014 } | 1159 } |
| 1015 | 1160 return opener_route_id; |
| 1016 if (delegate_->IsHidden()) | |
| 1017 create_render_frame_flags |= CREATE_RF_HIDDEN; | |
| 1018 | |
| 1019 // Create a non-swapped-out RFH with the given opener. | |
| 1020 int route_id = CreateRenderFrame(new_instance, opener_route_id, | |
| 1021 create_render_frame_flags); | |
| 1022 if (route_id == MSG_ROUTING_NONE) { | |
| 1023 pending_render_frame_host_.reset(); | |
| 1024 return; | |
| 1025 } | |
| 1026 } | 1161 } |
| 1027 | 1162 |
| 1028 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( | 1163 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( |
| 1029 SiteInstance* site_instance, | 1164 SiteInstance* site_instance, |
| 1030 int view_routing_id, | 1165 int view_routing_id, |
| 1031 int frame_routing_id, | 1166 int frame_routing_id, |
| 1032 int flags) { | 1167 int flags) { |
| 1033 if (frame_routing_id == MSG_ROUTING_NONE) | 1168 if (frame_routing_id == MSG_ROUTING_NONE) |
| 1034 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); | 1169 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); |
| 1035 | 1170 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1049 } | 1184 } |
| 1050 | 1185 |
| 1051 // TODO(creis): Pass hidden to RFH. | 1186 // TODO(creis): Pass hidden to RFH. |
| 1052 scoped_ptr<RenderFrameHostImpl> render_frame_host = | 1187 scoped_ptr<RenderFrameHostImpl> render_frame_host = |
| 1053 make_scoped_ptr(RenderFrameHostFactory::Create( | 1188 make_scoped_ptr(RenderFrameHostFactory::Create( |
| 1054 render_view_host, render_frame_delegate_, frame_tree, | 1189 render_view_host, render_frame_delegate_, frame_tree, |
| 1055 frame_tree_node_, frame_routing_id, flags).release()); | 1190 frame_tree_node_, frame_routing_id, flags).release()); |
| 1056 return render_frame_host.Pass(); | 1191 return render_frame_host.Pass(); |
| 1057 } | 1192 } |
| 1058 | 1193 |
| 1059 int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, | 1194 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( |
| 1060 int opener_route_id, | 1195 SiteInstance* instance, |
| 1061 int flags) { | 1196 int opener_route_id, |
| 1197 int flags, | |
| 1198 const WebUIImpl* web_ui, | |
| 1199 int* routing_id_ptr) { | |
| 1062 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1200 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
| 1063 CHECK(instance); | 1201 CHECK(instance); |
| 1064 // Swapped out views should always be hidden. | 1202 // Swapped out views should always be hidden. |
| 1065 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN)); | 1203 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN)); |
| 1066 | 1204 |
| 1067 // TODO(nasko): Remove the following CHECK once cross-site navigation no | 1205 // TODO(nasko): Remove the following CHECK once cross-site navigation no |
| 1068 // longer relies on swapped out RFH for the top-level frame. | 1206 // longer relies on swapped out RFH for the top-level frame. |
| 1069 if (!frame_tree_node_->IsMainFrame()) { | 1207 if (!frame_tree_node_->IsMainFrame()) { |
| 1070 CHECK(!swapped_out); | 1208 CHECK(!swapped_out); |
| 1071 } | 1209 } |
| 1072 | 1210 |
| 1073 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; | 1211 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; |
| 1074 RenderFrameHostImpl* frame_to_announce = NULL; | 1212 bool success = true; |
| 1075 int routing_id = MSG_ROUTING_NONE; | 1213 if (routing_id_ptr) |
| 1214 *routing_id_ptr = MSG_ROUTING_NONE; | |
| 1076 | 1215 |
| 1077 // We are creating a pending or swapped out RFH here. We should never create | 1216 // We are creating a pending, speculative or swapped out RFH here. We should |
| 1078 // it in the same SiteInstance as our current RFH. | 1217 // never create it in the same SiteInstance as our current RFH. |
| 1079 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 1218 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
| 1080 | 1219 |
| 1081 // Check if we've already created an RFH for this SiteInstance. If so, try | 1220 // Check if we've already created an RFH for this SiteInstance. If so, try |
| 1082 // to re-use the existing one, which has already been initialized. We'll | 1221 // to re-use the existing one, which has already been initialized. We'll |
| 1083 // remove it from the list of proxy hosts below if it will be active. | 1222 // remove it from the list of proxy hosts below if it will be active. |
| 1084 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 1223 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 1085 | |
| 1086 if (proxy && proxy->render_frame_host()) { | 1224 if (proxy && proxy->render_frame_host()) { |
| 1087 routing_id = proxy->GetRenderViewHost()->GetRoutingID(); | 1225 if (routing_id_ptr) |
| 1226 *routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); | |
| 1088 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 1227 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. |
| 1089 // Prevent the process from exiting while we're trying to use it. | 1228 // Prevent the process from exiting while we're trying to use it. |
| 1090 if (!swapped_out) { | 1229 if (!swapped_out) { |
| 1091 new_render_frame_host = proxy->PassFrameHostOwnership(); | 1230 new_render_frame_host = proxy->PassFrameHostOwnership(); |
| 1092 new_render_frame_host->GetProcess()->AddPendingView(); | 1231 new_render_frame_host->GetProcess()->AddPendingView(); |
| 1093 | 1232 |
| 1094 proxy_hosts_.erase(instance->GetId()); | 1233 proxy_hosts_.erase(instance->GetId()); |
| 1095 delete proxy; | 1234 delete proxy; |
| 1096 | 1235 |
| 1097 // When a new render view is created by the renderer, the new WebContents | 1236 // When a new render view is created by the renderer, the new WebContents |
| 1098 // gets a RenderViewHost in the SiteInstance of its opener WebContents. | 1237 // gets a RenderViewHost in the SiteInstance of its opener WebContents. |
| 1099 // If not used in the first navigation, this RVH is swapped out and is not | 1238 // If not used in the first navigation, this RVH is swapped out and is not |
| 1100 // granted bindings, so we may need to grant them when swapping it in. | 1239 // granted bindings, so we may need to grant them when swapping it in. |
| 1101 if (pending_web_ui() && | 1240 if (web_ui && !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { |
| 1102 !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { | 1241 int required_bindings = web_ui->GetBindings(); |
| 1103 int required_bindings = pending_web_ui()->GetBindings(); | 1242 RenderViewHost* render_view_host = |
| 1104 RenderViewHost* rvh = new_render_frame_host->render_view_host(); | 1243 new_render_frame_host->render_view_host(); |
| 1105 if ((rvh->GetEnabledBindings() & required_bindings) != | 1244 if ((render_view_host->GetEnabledBindings() & required_bindings) != |
| 1106 required_bindings) { | 1245 required_bindings) { |
| 1107 rvh->AllowBindings(required_bindings); | 1246 render_view_host->AllowBindings(required_bindings); |
| 1108 } | 1247 } |
| 1109 } | 1248 } |
| 1110 } | 1249 } |
| 1111 } else { | 1250 } else { |
| 1112 // Create a new RenderFrameHost if we don't find an existing one. | 1251 // Create a new RenderFrameHost if we don't find an existing one. |
| 1113 new_render_frame_host = CreateRenderFrameHost(instance, MSG_ROUTING_NONE, | 1252 new_render_frame_host = CreateRenderFrameHost(instance, MSG_ROUTING_NONE, |
| 1114 MSG_ROUTING_NONE, flags); | 1253 MSG_ROUTING_NONE, flags); |
| 1115 RenderViewHostImpl* render_view_host = | 1254 RenderViewHostImpl* render_view_host = |
| 1116 new_render_frame_host->render_view_host(); | 1255 new_render_frame_host->render_view_host(); |
| 1117 int proxy_routing_id = MSG_ROUTING_NONE; | 1256 int proxy_routing_id = MSG_ROUTING_NONE; |
| 1118 | 1257 |
| 1119 // Prevent the process from exiting while we're trying to navigate in it. | 1258 // Prevent the process from exiting while we're trying to navigate in it. |
| 1120 // Otherwise, if the new RFH is swapped out already, store it. | 1259 // Otherwise, if the new RFH is swapped out already, store it. |
| 1121 if (!swapped_out) { | 1260 if (!swapped_out) { |
| 1122 new_render_frame_host->GetProcess()->AddPendingView(); | 1261 new_render_frame_host->GetProcess()->AddPendingView(); |
| 1123 } else { | 1262 } else { |
| 1124 proxy = new RenderFrameProxyHost( | 1263 proxy = new RenderFrameProxyHost( |
| 1125 new_render_frame_host->GetSiteInstance(), frame_tree_node_); | 1264 new_render_frame_host->GetSiteInstance(), frame_tree_node_); |
| 1126 proxy_hosts_[instance->GetId()] = proxy; | 1265 proxy_hosts_[instance->GetId()] = proxy; |
| 1127 proxy_routing_id = proxy->GetRoutingID(); | 1266 proxy_routing_id = proxy->GetRoutingID(); |
| 1128 if (frame_tree_node_->IsMainFrame()) | 1267 if (frame_tree_node_->IsMainFrame()) |
| 1129 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); | 1268 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); |
| 1130 } | 1269 } |
| 1131 | 1270 |
| 1132 bool success = | 1271 success = |
| 1133 InitRenderView(render_view_host, opener_route_id, proxy_routing_id, | 1272 InitRenderView(render_view_host, opener_route_id, proxy_routing_id, |
| 1134 !!(flags & CREATE_RF_FOR_MAIN_FRAME_NAVIGATION)); | 1273 !!(flags & CREATE_RF_FOR_MAIN_FRAME_NAVIGATION)); |
| 1135 if (success) { | 1274 if (success) { |
| 1136 if (frame_tree_node_->IsMainFrame()) { | 1275 if (frame_tree_node_->IsMainFrame()) { |
| 1137 // Don't show the main frame's view until we get a DidNavigate from it. | 1276 // Don't show the main frame's view until we get a DidNavigate from it. |
| 1138 render_view_host->GetView()->Hide(); | 1277 render_view_host->GetView()->Hide(); |
| 1139 } else if (!swapped_out) { | 1278 } else if (!swapped_out) { |
| 1140 // Init the RFH, so a RenderFrame is created in the renderer. | 1279 // Init the RFH, so a RenderFrame is created in the renderer. |
| 1141 DCHECK(new_render_frame_host.get()); | 1280 DCHECK(new_render_frame_host.get()); |
| 1142 success = InitRenderFrame(new_render_frame_host.get()); | 1281 success = InitRenderFrame(new_render_frame_host.get()); |
| 1143 } | 1282 } |
| 1144 } else if (!swapped_out && pending_render_frame_host_) { | 1283 if (success) { |
| 1145 CancelPending(); | 1284 if (routing_id_ptr) |
| 1285 *routing_id_ptr = render_view_host->GetRoutingID(); | |
| 1286 // If a brand new RFH was created, announce it to observers. | |
| 1287 // TODO(carlosk): verify there's no problem that now this RFH will only | |
| 1288 // be set as the pending one *after* this delegate call (used to be | |
| 1289 // before). | |
| 1290 if (new_render_frame_host) { | |
| 1291 render_frame_delegate_->RenderFrameCreated( | |
| 1292 new_render_frame_host.get()); | |
| 1293 } | |
| 1294 } | |
| 1146 } | 1295 } |
| 1147 routing_id = render_view_host->GetRoutingID(); | |
| 1148 frame_to_announce = new_render_frame_host.get(); | |
| 1149 } | 1296 } |
| 1150 | 1297 |
| 1151 // Use this as our new pending RFH if it isn't swapped out. | 1298 // Returns the new RFH if it isn't swapped out. |
| 1152 if (!swapped_out) | 1299 if (success && !swapped_out) { |
| 1153 pending_render_frame_host_ = new_render_frame_host.Pass(); | 1300 DCHECK(new_render_frame_host->GetSiteInstance() == instance); |
| 1154 | 1301 return new_render_frame_host.Pass(); |
| 1155 // If a brand new RFH was created, announce it to observers. | 1302 } |
| 1156 if (frame_to_announce) | 1303 return nullptr; |
| 1157 render_frame_delegate_->RenderFrameCreated(frame_to_announce); | |
| 1158 | |
| 1159 return routing_id; | |
| 1160 } | 1304 } |
| 1161 | 1305 |
| 1162 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { | 1306 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { |
| 1163 // A RenderFrameProxyHost should never be created in the same SiteInstance as | 1307 // A RenderFrameProxyHost should never be created in the same SiteInstance as |
| 1164 // the current RFH. | 1308 // the current RFH. |
| 1165 CHECK(instance); | 1309 CHECK(instance); |
| 1166 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); | 1310 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); |
| 1167 | 1311 |
| 1168 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 1312 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
| 1169 if (proxy) | 1313 if (proxy) |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1240 return render_frame_host_->GetRoutingID(); | 1384 return render_frame_host_->GetRoutingID(); |
| 1241 | 1385 |
| 1242 RenderFrameProxyHostMap::iterator iter = | 1386 RenderFrameProxyHostMap::iterator iter = |
| 1243 proxy_hosts_.find(site_instance->GetId()); | 1387 proxy_hosts_.find(site_instance->GetId()); |
| 1244 if (iter != proxy_hosts_.end()) | 1388 if (iter != proxy_hosts_.end()) |
| 1245 return iter->second->GetRoutingID(); | 1389 return iter->second->GetRoutingID(); |
| 1246 | 1390 |
| 1247 return MSG_ROUTING_NONE; | 1391 return MSG_ROUTING_NONE; |
| 1248 } | 1392 } |
| 1249 | 1393 |
| 1250 void RenderFrameHostManager::CommitPending() { | 1394 void RenderFrameHostManager::CommitPending(bool use_speculative_rfh) { |
| 1251 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 1395 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
| 1252 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 1396 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 1397 // If use_speculative_rfh then kEnableBrowserSideNavigation must be enabled. | |
| 1398 CHECK(!use_speculative_rfh || | |
| 1399 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1400 switches::kEnableBrowserSideNavigation)); | |
| 1401 | |
| 1253 // First check whether we're going to want to focus the location bar after | 1402 // First check whether we're going to want to focus the location bar after |
| 1254 // this commit. We do this now because the navigation hasn't formally | 1403 // this commit. We do this now because the navigation hasn't formally |
| 1255 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1404 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
| 1256 // this triggers won't be able to figure out what's going on. | 1405 // this triggers won't be able to figure out what's going on. |
| 1257 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1406 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 1258 | 1407 |
| 1259 // Next commit the Web UI, if any. Either replace |web_ui_| with | 1408 if (!use_speculative_rfh) { |
|
nasko
2014/11/25 00:19:10
Can't this be just a check for browser-site-naviga
carlosk
2014/11/28 13:08:17
Indeed, now it can! Great catch! :)
| |
| 1260 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or | 1409 DCHECK(!speculative_web_ui_); |
| 1261 // leave |web_ui_| as is if reusing it. | 1410 // Next commit the Web UI, if any. Either replace |web_ui_| with |
| 1262 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); | 1411 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or |
| 1263 if (pending_web_ui_) { | 1412 // leave |web_ui_| as is if reusing it. |
| 1264 web_ui_.reset(pending_web_ui_.release()); | 1413 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); |
| 1265 } else if (!pending_and_current_web_ui_.get()) { | 1414 if (pending_web_ui_) { |
| 1266 web_ui_.reset(); | 1415 web_ui_.reset(pending_web_ui_.release()); |
| 1416 } else if (!pending_and_current_web_ui_.get()) { | |
| 1417 web_ui_.reset(); | |
| 1418 } else { | |
| 1419 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | |
| 1420 pending_and_current_web_ui_.reset(); | |
| 1421 } | |
| 1267 } else { | 1422 } else { |
| 1268 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | 1423 if (!should_reuse_web_ui_) |
| 1269 pending_and_current_web_ui_.reset(); | 1424 web_ui_.reset(speculative_web_ui_.release()); |
| 1270 } | 1425 } |
| 1271 | 1426 |
| 1272 // It's possible for the pending_render_frame_host_ to be NULL when we aren't | 1427 // It's possible for the pending_render_frame_host_ to be NULL when we aren't |
| 1273 // crossing process boundaries. If so, we just needed to handle the Web UI | 1428 // crossing process boundaries. If so, we just needed to handle the Web UI |
| 1274 // committing above and we're done. | 1429 // committing above and we're done. |
| 1275 if (!pending_render_frame_host_) { | 1430 if (!pending_render_frame_host_ && !use_speculative_rfh) { |
| 1276 if (will_focus_location_bar) | 1431 if (will_focus_location_bar) |
| 1277 delegate_->SetFocusToLocationBar(false); | 1432 delegate_->SetFocusToLocationBar(false); |
| 1278 return; | 1433 return; |
| 1279 } | 1434 } |
| 1280 | 1435 |
| 1281 // Remember if the page was focused so we can focus the new renderer in | 1436 // Remember if the page was focused so we can focus the new renderer in |
| 1282 // that case. | 1437 // that case. |
| 1283 bool focus_render_view = !will_focus_location_bar && | 1438 bool focus_render_view = !will_focus_location_bar && |
| 1284 render_frame_host_->render_view_host()->GetView() && | 1439 render_frame_host_->render_view_host()->GetView() && |
| 1285 render_frame_host_->render_view_host()->GetView()->HasFocus(); | 1440 render_frame_host_->render_view_host()->GetView()->HasFocus(); |
| 1286 | 1441 |
| 1287 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 1442 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 1288 | 1443 |
| 1289 // Swap in the pending frame and make it active. Also ensure the FrameTree | 1444 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
| 1290 // stays in sync. | 1445 if (!use_speculative_rfh) { |
| 1291 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 1446 DCHECK(!speculative_render_frame_host_); |
| 1292 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 1447 // Swap in the pending frame and make it active. Also ensure the FrameTree |
| 1448 // stays in sync. | |
| 1449 old_render_frame_host = | |
| 1450 SetRenderFrameHost(pending_render_frame_host_.Pass()); | |
| 1451 } else { | |
| 1452 DCHECK(speculative_render_frame_host_); | |
| 1453 old_render_frame_host = | |
| 1454 SetRenderFrameHost(speculative_render_frame_host_.Pass()); | |
| 1455 } | |
| 1456 | |
| 1293 if (is_main_frame) | 1457 if (is_main_frame) |
| 1294 render_frame_host_->render_view_host()->AttachToFrameTree(); | 1458 render_frame_host_->render_view_host()->AttachToFrameTree(); |
| 1295 | 1459 |
| 1296 // The process will no longer try to exit, so we can decrement the count. | 1460 // The process will no longer try to exit, so we can decrement the count. |
| 1297 render_frame_host_->GetProcess()->RemovePendingView(); | 1461 render_frame_host_->GetProcess()->RemovePendingView(); |
| 1298 | 1462 |
| 1299 // Show the new view (or a sad tab) if necessary. | 1463 // Show the new view (or a sad tab) if necessary. |
| 1300 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); | 1464 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); |
| 1301 if (!delegate_->IsHidden() && new_rfh_has_view) { | 1465 if (!delegate_->IsHidden() && new_rfh_has_view) { |
| 1302 // In most cases, we need to show the new view. | 1466 // In most cases, we need to show the new view. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1411 if (cross_navigation_pending_) { | 1575 if (cross_navigation_pending_) { |
| 1412 if (pending_render_frame_host_) | 1576 if (pending_render_frame_host_) |
| 1413 CancelPending(); | 1577 CancelPending(); |
| 1414 cross_navigation_pending_ = false; | 1578 cross_navigation_pending_ = false; |
| 1415 } | 1579 } |
| 1416 | 1580 |
| 1417 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1581 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 1418 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( | 1582 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
| 1419 url, instance, transition, is_restore, is_view_source_mode); | 1583 url, instance, transition, is_restore, is_view_source_mode); |
| 1420 | 1584 |
| 1585 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1586 switches::kEnableBrowserSideNavigation)) { | |
| 1587 if (current_instance == new_instance.get()) { | |
| 1588 CleanUpNavigation(); | |
| 1589 } else { | |
| 1590 // If the SiteInstance for the final URL doesn't match the one form the | |
| 1591 // speculatively created RenderFrameHost, create a new one using the | |
| 1592 // former. | |
| 1593 if (!speculative_render_frame_host_ || | |
| 1594 speculative_render_frame_host_->GetSiteInstance() != | |
| 1595 new_instance.get()) { | |
| 1596 CleanUpNavigation(); | |
| 1597 // TODO(carlosk): Should rename this method and the speculative members | |
| 1598 // because in this case they are not speculative. Suggestions are | |
| 1599 // very welcome! | |
| 1600 bool success = CreateSpeculativeRenderFrameHost( | |
| 1601 url, current_instance, new_instance.get(), bindings); | |
| 1602 if (!success) | |
| 1603 return nullptr; | |
| 1604 } | |
| 1605 DCHECK(speculative_render_frame_host_); | |
| 1606 CommitPending(true); | |
| 1607 DCHECK(!speculative_render_frame_host_); | |
| 1608 } | |
| 1609 return render_frame_host_.get(); | |
| 1610 } | |
| 1611 | |
| 1421 const NavigationEntry* current_entry = | 1612 const NavigationEntry* current_entry = |
| 1422 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1613 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
| 1423 | 1614 |
| 1424 if (new_instance.get() != current_instance) { | 1615 if (new_instance.get() != current_instance) { |
| 1425 TRACE_EVENT_INSTANT2( | 1616 TRACE_EVENT_INSTANT2( |
| 1426 "navigation", | 1617 "navigation", |
| 1427 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 1618 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
| 1428 TRACE_EVENT_SCOPE_THREAD, | 1619 TRACE_EVENT_SCOPE_THREAD, |
| 1429 "current_instance id", current_instance->GetId(), | 1620 "current_instance id", current_instance->GetId(), |
| 1430 "new_instance id", new_instance->GetId()); | 1621 "new_instance id", new_instance->GetId()); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1446 } | 1637 } |
| 1447 | 1638 |
| 1448 // Check if our current RFH is live before we set up a transition. | 1639 // Check if our current RFH is live before we set up a transition. |
| 1449 if (!render_frame_host_->IsRenderFrameLive()) { | 1640 if (!render_frame_host_->IsRenderFrameLive()) { |
| 1450 if (!cross_navigation_pending_) { | 1641 if (!cross_navigation_pending_) { |
| 1451 // The current RFH is not live. There's no reason to sit around with a | 1642 // The current RFH is not live. There's no reason to sit around with a |
| 1452 // sad tab or a newly created RFH while we wait for the pending RFH to | 1643 // sad tab or a newly created RFH while we wait for the pending RFH to |
| 1453 // navigate. Just switch to the pending RFH now and go back to non | 1644 // navigate. Just switch to the pending RFH now and go back to non |
| 1454 // cross-navigating (Note that we don't care about on{before}unload | 1645 // cross-navigating (Note that we don't care about on{before}unload |
| 1455 // handlers if the current RFH isn't live.) | 1646 // handlers if the current RFH isn't live.) |
| 1456 CommitPending(); | 1647 CommitPending(false); |
| 1457 return render_frame_host_.get(); | 1648 return render_frame_host_.get(); |
| 1458 } else { | 1649 } else { |
| 1459 NOTREACHED(); | 1650 NOTREACHED(); |
| 1460 return render_frame_host_.get(); | 1651 return render_frame_host_.get(); |
| 1461 } | 1652 } |
| 1462 } | 1653 } |
| 1463 // Otherwise, it's safe to treat this as a pending cross-site transition. | 1654 // Otherwise, it's safe to treat this as a pending cross-site transition. |
| 1464 | 1655 |
| 1465 // We now have a pending RFH. | 1656 // We now have a pending RFH. |
| 1466 DCHECK(!cross_navigation_pending_); | 1657 DCHECK(!cross_navigation_pending_); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1551 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = | 1742 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = |
| 1552 pending_render_frame_host_.Pass(); | 1743 pending_render_frame_host_.Pass(); |
| 1553 | 1744 |
| 1554 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( | 1745 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( |
| 1555 pending_render_frame_host->render_view_host(), | 1746 pending_render_frame_host->render_view_host(), |
| 1556 render_frame_host_->render_view_host()); | 1747 render_frame_host_->render_view_host()); |
| 1557 | 1748 |
| 1558 // We no longer need to prevent the process from exiting. | 1749 // We no longer need to prevent the process from exiting. |
| 1559 pending_render_frame_host->GetProcess()->RemovePendingView(); | 1750 pending_render_frame_host->GetProcess()->RemovePendingView(); |
| 1560 | 1751 |
| 1561 // If the SiteInstance for the pending RFH is being used by others, don't | 1752 DiscardRenderFrameHost(pending_render_frame_host.Pass()); |
| 1562 // delete the RFH, just swap it out and it can be reused at a later point. | |
| 1563 SiteInstanceImpl* site_instance = | |
| 1564 pending_render_frame_host->GetSiteInstance(); | |
| 1565 if (site_instance->active_frame_count() > 1) { | |
| 1566 // Any currently suspended navigations are no longer needed. | |
| 1567 pending_render_frame_host->CancelSuspendedNavigations(); | |
| 1568 | |
| 1569 RenderFrameProxyHost* proxy = | |
| 1570 new RenderFrameProxyHost(site_instance, frame_tree_node_); | |
| 1571 proxy_hosts_[site_instance->GetId()] = proxy; | |
| 1572 pending_render_frame_host->SwapOut(proxy); | |
| 1573 if (frame_tree_node_->IsMainFrame()) | |
| 1574 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass()); | |
| 1575 } else { | |
| 1576 // We won't be coming back, so delete this one. | |
| 1577 pending_render_frame_host.reset(); | |
| 1578 } | |
| 1579 | 1753 |
| 1580 pending_web_ui_.reset(); | 1754 pending_web_ui_.reset(); |
| 1581 pending_and_current_web_ui_.reset(); | 1755 pending_and_current_web_ui_.reset(); |
| 1582 } | 1756 } |
| 1583 | 1757 |
| 1584 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 1758 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
| 1585 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 1759 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 1586 // Swap the two. | 1760 // Swap the two. |
| 1587 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 1761 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
| 1588 render_frame_host_.Pass(); | 1762 render_frame_host_.Pass(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1653 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1827 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
| 1654 SiteInstance* instance) { | 1828 SiteInstance* instance) { |
| 1655 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1829 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
| 1656 if (iter != proxy_hosts_.end()) { | 1830 if (iter != proxy_hosts_.end()) { |
| 1657 delete iter->second; | 1831 delete iter->second; |
| 1658 proxy_hosts_.erase(iter); | 1832 proxy_hosts_.erase(iter); |
| 1659 } | 1833 } |
| 1660 } | 1834 } |
| 1661 | 1835 |
| 1662 } // namespace content | 1836 } // namespace content |
| OLD | NEW |