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 |