Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 701953006: PlzNavigate: Speculatively spawns a renderer process for navigations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Re-applying previous changes over. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698