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

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: Rebase Created 5 years, 11 months 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 RenderFrameHostDelegate* render_frame_delegate, 53 RenderFrameHostDelegate* render_frame_delegate,
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_(nullptr),
64 should_reuse_web_ui_(false),
64 weak_factory_(this) { 65 weak_factory_(this) {
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 UnsetPendingRenderFrameHost(); 71 UnsetPendingRenderFrameHost();
71 72
73 if (speculative_render_frame_host_)
74 UnsetSpeculativeRenderFrameHost();
75
72 if (render_frame_host_ && 76 if (render_frame_host_ &&
73 render_frame_host_->GetSiteInstance()->active_frame_count() <= 1U) { 77 render_frame_host_->GetSiteInstance()->active_frame_count() <= 1U) {
74 ShutdownRenderFrameProxyHostsInSiteInstance( 78 ShutdownRenderFrameProxyHostsInSiteInstance(
75 render_frame_host_->GetSiteInstance()->GetId()); 79 render_frame_host_->GetSiteInstance()->GetId());
76 } 80 }
77 81
78 // We should always have a current RenderFrameHost except in some tests. 82 // We should always have a current RenderFrameHost except in some tests.
79 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); 83 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>());
80 84
81 // Delete any swapped out RenderFrameHosts. 85 // Delete any swapped out RenderFrameHosts.
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 } 289 }
286 } 290 }
287 return false; 291 return false;
288 } 292 }
289 293
290 void RenderFrameHostManager::OnBeforeUnloadACK( 294 void RenderFrameHostManager::OnBeforeUnloadACK(
291 bool for_cross_site_transition, 295 bool for_cross_site_transition,
292 bool proceed, 296 bool proceed,
293 const base::TimeTicks& proceed_time) { 297 const base::TimeTicks& proceed_time) {
294 if (for_cross_site_transition) { 298 if (for_cross_site_transition) {
299 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
300 switches::kEnableBrowserSideNavigation));
295 // Ignore if we're not in a cross-site navigation. 301 // Ignore if we're not in a cross-site navigation.
296 if (!cross_navigation_pending_) 302 if (!cross_navigation_pending_)
297 return; 303 return;
298 304
299 if (proceed) { 305 if (proceed) {
300 // Ok to unload the current page, so proceed with the cross-site 306 // Ok to unload the current page, so proceed with the cross-site
301 // navigation. Note that if navigations are not currently suspended, it 307 // navigation. Note that if navigations are not currently suspended, it
302 // might be because the renderer was deemed unresponsive and this call was 308 // might be because the renderer was deemed unresponsive and this call was
303 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it 309 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it
304 // is ok to do nothing here. 310 // is ok to do nothing here.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 response_started_id_.reset(); 417 response_started_id_.reset();
412 } 418 }
413 419
414 void RenderFrameHostManager::ClearNavigationTransitionData() { 420 void RenderFrameHostManager::ClearNavigationTransitionData() {
415 render_frame_host_->ClearPendingTransitionRequestData(); 421 render_frame_host_->ClearPendingTransitionRequestData();
416 } 422 }
417 423
418 void RenderFrameHostManager::DidNavigateFrame( 424 void RenderFrameHostManager::DidNavigateFrame(
419 RenderFrameHostImpl* render_frame_host, 425 RenderFrameHostImpl* render_frame_host,
420 bool was_caused_by_user_gesture) { 426 bool was_caused_by_user_gesture) {
427 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
428 switches::kEnableBrowserSideNavigation)) {
429 if (render_frame_host == speculative_render_frame_host_.get()) {
430 CommitPending();
431 } else if (render_frame_host == render_frame_host_.get()) {
432 // TODO(carlosk): this code doesn't properly handle in-page navigation or
433 // interwoven navigation requests.
434 DCHECK(!speculative_render_frame_host_);
435 } else {
436 // No one else should be sending us a DidNavigate in this state.
437 DCHECK(false);
438 }
439 DCHECK(!speculative_render_frame_host_);
440 return;
441 }
442
421 if (!cross_navigation_pending_) { 443 if (!cross_navigation_pending_) {
422 DCHECK(!pending_render_frame_host_); 444 DCHECK(!pending_render_frame_host_);
423 445
424 // We should only hear this from our current renderer. 446 // We should only hear this from our current renderer.
425 DCHECK_EQ(render_frame_host_, render_frame_host); 447 DCHECK_EQ(render_frame_host_, render_frame_host);
426 448
427 // Even when there is no pending RVH, there may be a pending Web UI. 449 // Even when there is no pending RVH, there may be a pending Web UI.
428 if (pending_web_ui()) 450 if (pending_web_ui())
429 CommitPending(); 451 CommitPending();
430 return; 452 return;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 // If the SiteInstance for the pending RFH is being used by others don't 593 // If the SiteInstance for the pending RFH is being used by others don't
572 // delete the RFH. Just swap it out and it can be reused at a later point. 594 // delete the RFH. Just swap it out and it can be reused at a later point.
573 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); 595 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
574 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { 596 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
575 // Any currently suspended navigations are no longer needed. 597 // Any currently suspended navigations are no longer needed.
576 render_frame_host->CancelSuspendedNavigations(); 598 render_frame_host->CancelSuspendedNavigations();
577 599
578 RenderFrameProxyHost* proxy = 600 RenderFrameProxyHost* proxy =
579 new RenderFrameProxyHost(site_instance, frame_tree_node_); 601 new RenderFrameProxyHost(site_instance, frame_tree_node_);
580 proxy_hosts_[site_instance->GetId()] = proxy; 602 proxy_hosts_[site_instance->GetId()] = proxy;
581 render_frame_host->SwapOut(proxy, false); 603
604 // Check if the RenderFrameHost is already swapped out, to avoid swapping it
605 // out again.
606 if (!render_frame_host->is_swapped_out())
607 render_frame_host->SwapOut(proxy, false);
608
582 if (frame_tree_node_->IsMainFrame()) 609 if (frame_tree_node_->IsMainFrame())
583 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); 610 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
584 } else { 611 } else {
585 // We won't be coming back, so delete this one. 612 // We won't be coming back, so delete this one.
586 render_frame_host.reset(); 613 render_frame_host.reset();
587 } 614 }
588 } 615 }
589 616
590 void RenderFrameHostManager::MoveToPendingDeleteHosts( 617 void RenderFrameHostManager::MoveToPendingDeleteHosts(
591 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 618 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
(...skipping 24 matching lines...) Expand all
616 } 643 }
617 } 644 }
618 return false; 645 return false;
619 } 646 }
620 647
621 void RenderFrameHostManager::ResetProxyHosts() { 648 void RenderFrameHostManager::ResetProxyHosts() {
622 STLDeleteValues(&proxy_hosts_); 649 STLDeleteValues(&proxy_hosts_);
623 } 650 }
624 651
625 // PlzNavigate 652 // PlzNavigate
653 void RenderFrameHostManager::BeginNavigation(
654 const CommonNavigationParams& common_params) {
655 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
656 switches::kEnableBrowserSideNavigation));
657 // Clean up any state in case there's an ongoing navigation.
658 // TODO(carlosk): remove this cleanup here once we properly cancel ongoing
659 // navigations.
660 CleanUpNavigation();
661
662 RenderFrameHostImpl* dest_rfh =
663 GetFrameHostForNavigation(common_params.url, common_params.transition);
664 DCHECK(dest_rfh);
665 }
666
667 // PlzNavigate
626 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( 668 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
627 const GURL& url, 669 const GURL& url,
628 ui::PageTransition transition) { 670 ui::PageTransition transition) {
629 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 671 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
630 switches::kEnableBrowserSideNavigation)); 672 switches::kEnableBrowserSideNavigation));
631 // TODO(clamy): When we handle renderer initiated navigations, make sure not
632 // to use a different process for subframes if --site-per-process is not
633 // enabled.
634 673
635 // Pick the right RenderFrameHost to commit the navigation. 674 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
636 // TODO(clamy): Replace the default values by the right ones.
637 RenderFrameHostImpl* render_frame_host = UpdateStateForNavigate(
638 url, nullptr, nullptr, transition, false, false, GlobalRequestID(),
639 NavigationEntryImpl::kInvalidBindings);
640 675
641 // If the renderer that needs to navigate is not live (it was just created or 676 // TODO(carlosk): Replace the default values with the right ones for
642 // it crashed), initialize it. 677 // source_instance, dest_instance, dest_is_restore, dest_is_view_source_mode.
643 if (!render_frame_host->render_view_host()->IsRenderViewLive()) { 678 scoped_refptr<SiteInstance> dest_site_instance = GetSiteInstanceForNavigation(
679 url, nullptr, nullptr, transition, false, false);
680 // The appropriate RenderFrameHost to commit the navigation.
681 RenderFrameHostImpl* navigation_rfh = nullptr;
682
683 // TODO(carlosk): do not swap processes for renderer initiated navigations
684 // (see crbug.com/440266).
685 if (current_site_instance == dest_site_instance.get() ||
686 (!frame_tree_node_->IsMainFrame() &&
687 !base::CommandLine::ForCurrentProcess()->HasSwitch(
688 switches::kSitePerProcess))) {
689 // Reuse the current RFH if its SiteInstance matches the the navigation's
690 // or if this is a subframe navigation. We only swap RFHs for subframes when
691 // --site-per-process is enabled.
692 CleanUpNavigation();
693 navigation_rfh = render_frame_host_.get();
694 } else {
695 // If the current render_frame_host_ isn't live, we should create it so
696 // that we don't show a sad tab while the navigation is ongoing.
697 // (Bug 1145340)
698 if (!render_frame_host_->IsRenderFrameLive()) {
699 // Note: we don't call InitRenderView here because we are navigating away
700 // soon anyway, and we don't have the NavigationEntry for this host.
701 delegate_->CreateRenderViewForRenderManager(
702 render_frame_host_->render_view_host(), MSG_ROUTING_NONE,
703 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame());
704 }
705
706 // If the SiteInstance for the final URL doesn't match the one from the
707 // speculatively created RenderFrameHost, create a new RenderFrameHost using
708 // this new SiteInstance.
709 if (!speculative_render_frame_host_ ||
710 speculative_render_frame_host_->GetSiteInstance() !=
711 dest_site_instance.get()) {
712 CleanUpNavigation();
713 // TODO(carlosk): Replace the binding value with the right one.
714 bool success = CreateSpeculativeRenderFrameHost(
715 url, current_site_instance, dest_site_instance.get(),
716 NavigationEntryImpl::kInvalidBindings);
717 DCHECK(success);
718 }
719 DCHECK(speculative_render_frame_host_);
720 navigation_rfh = speculative_render_frame_host_.get();
721 }
722 DCHECK(navigation_rfh &&
723 (navigation_rfh == render_frame_host_.get() ||
724 navigation_rfh == speculative_render_frame_host_.get()));
725
726 // If the renderer that needs to navigate is not live (it was just created
727 // or it crashed), initialize it.
728 if (!navigation_rfh->IsRenderFrameLive()) {
644 // Recreate the opener chain. 729 // Recreate the opener chain.
645 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( 730 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
646 render_frame_host->GetSiteInstance()); 731 navigation_rfh->GetSiteInstance());
647 if (!InitRenderView(render_frame_host->render_view_host(), 732 if (!InitRenderView(navigation_rfh->render_view_host(), opener_route_id,
648 opener_route_id, 733 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame())) {
649 MSG_ROUTING_NONE,
650 frame_tree_node_->IsMainFrame())) {
651 return nullptr; 734 return nullptr;
652 } 735 }
653 } 736 }
654 return render_frame_host; 737
738 return navigation_rfh;
739 }
740
741 // PlzNavigate
742 void RenderFrameHostManager::CleanUpNavigation() {
743 if (speculative_render_frame_host_)
744 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
745 }
746
747 // PlzNavigate
748 scoped_ptr<RenderFrameHostImpl>
749 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() {
750 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
751 switches::kEnableBrowserSideNavigation));
752 speculative_web_ui_.reset();
753 should_reuse_web_ui_ = false;
754 speculative_render_frame_host_->GetProcess()->RemovePendingView();
755 return speculative_render_frame_host_.Pass();
655 } 756 }
656 757
657 void RenderFrameHostManager::OnDidStartLoading() { 758 void RenderFrameHostManager::OnDidStartLoading() {
658 for (const auto& pair : proxy_hosts_) { 759 for (const auto& pair : proxy_hosts_) {
659 pair.second->Send( 760 pair.second->Send(
660 new FrameMsg_DidStartLoading(pair.second->GetRoutingID())); 761 new FrameMsg_DidStartLoading(pair.second->GetRoutingID()));
661 } 762 }
662 } 763 }
663 764
664 void RenderFrameHostManager::OnDidStopLoading() { 765 void RenderFrameHostManager::OnDidStopLoading() {
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 int frame_routing_id, 1188 int frame_routing_id,
1088 int flags) { 1189 int flags) {
1089 if (frame_routing_id == MSG_ROUTING_NONE) 1190 if (frame_routing_id == MSG_ROUTING_NONE)
1090 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); 1191 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
1091 1192
1092 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1193 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
1093 bool hidden = !!(flags & CREATE_RF_HIDDEN); 1194 bool hidden = !!(flags & CREATE_RF_HIDDEN);
1094 1195
1095 // Create a RVH for main frames, or find the existing one for subframes. 1196 // Create a RVH for main frames, or find the existing one for subframes.
1096 FrameTree* frame_tree = frame_tree_node_->frame_tree(); 1197 FrameTree* frame_tree = frame_tree_node_->frame_tree();
1097 RenderViewHostImpl* render_view_host = NULL; 1198 RenderViewHostImpl* render_view_host = nullptr;
1098 if (frame_tree_node_->IsMainFrame()) { 1199 if (frame_tree_node_->IsMainFrame()) {
1099 render_view_host = frame_tree->CreateRenderViewHost( 1200 render_view_host = frame_tree->CreateRenderViewHost(
1100 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); 1201 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden);
1101 } else { 1202 } else {
1102 render_view_host = frame_tree->GetRenderViewHost(site_instance); 1203 render_view_host = frame_tree->GetRenderViewHost(site_instance);
1103 1204
1104 CHECK(render_view_host); 1205 CHECK(render_view_host);
1105 } 1206 }
1106 1207
1107 // TODO(creis): Pass hidden to RFH. 1208 // TODO(creis): Pass hidden to RFH.
1108 scoped_ptr<RenderFrameHostImpl> render_frame_host = 1209 scoped_ptr<RenderFrameHostImpl> render_frame_host =
1109 make_scoped_ptr(RenderFrameHostFactory::Create( 1210 make_scoped_ptr(RenderFrameHostFactory::Create(
1110 render_view_host, render_frame_delegate_, frame_tree, 1211 render_view_host, render_frame_delegate_, frame_tree,
1111 frame_tree_node_, frame_routing_id, flags).release()); 1212 frame_tree_node_, frame_routing_id, flags).release());
1112 return render_frame_host.Pass(); 1213 return render_frame_host.Pass();
1113 } 1214 }
1114 1215
1216 // PlzNavigate
1217 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
1218 const GURL& url,
1219 SiteInstance* old_instance,
1220 SiteInstance* new_instance,
1221 int bindings) {
1222 CHECK(new_instance);
1223 CHECK_NE(old_instance, new_instance);
1224
1225 const NavigationEntry* current_navigation_entry =
1226 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1227 scoped_ptr<WebUIImpl> new_web_ui;
1228 bool should_reuse_web_ui = ShouldReuseWebUI(current_navigation_entry, url);
1229 if (!should_reuse_web_ui)
1230 new_web_ui = CreateWebUI(url, bindings);
1231
1232 int opener_route_id =
1233 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance);
1234
1235 int create_render_frame_flags = 0;
1236 if (frame_tree_node_->IsMainFrame())
1237 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION;
1238 if (delegate_->IsHidden())
1239 create_render_frame_flags |= CREATE_RF_HIDDEN;
1240 scoped_ptr<RenderFrameHostImpl> new_render_frame_host =
1241 CreateRenderFrame(new_instance, new_web_ui.get(), opener_route_id,
1242 create_render_frame_flags, nullptr);
1243
1244 if (!new_render_frame_host)
1245 return false;
1246
1247 speculative_render_frame_host_ = new_render_frame_host.Pass();
1248 speculative_web_ui_ = new_web_ui.Pass();
1249 should_reuse_web_ui_ = should_reuse_web_ui;
1250 return true;
1251 }
1252
1115 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( 1253 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
1116 SiteInstance* instance, 1254 SiteInstance* instance,
1117 WebUIImpl* web_ui, 1255 WebUIImpl* web_ui,
1118 int opener_route_id, 1256 int opener_route_id,
1119 int flags, 1257 int flags,
1120 int* view_routing_id_ptr) { 1258 int* view_routing_id_ptr) {
1121 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1259 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
1122 CHECK(instance); 1260 CHECK(instance);
1123 // Swapped out views should always be hidden. 1261 // Swapped out views should always be hidden.
1124 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN)); 1262 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN));
1125 1263
1126 // TODO(nasko): Remove the following CHECK once cross-site navigation no 1264 // TODO(nasko): Remove the following CHECK once cross-site navigation no
1127 // longer relies on swapped out RFH for the top-level frame. 1265 // longer relies on swapped out RFH for the top-level frame.
1128 if (!frame_tree_node_->IsMainFrame()) 1266 if (!frame_tree_node_->IsMainFrame())
1129 CHECK(!swapped_out); 1267 CHECK(!swapped_out);
1130 1268
1131 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; 1269 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
1132 bool success = true; 1270 bool success = true;
1133 if (view_routing_id_ptr) 1271 if (view_routing_id_ptr)
1134 *view_routing_id_ptr = MSG_ROUTING_NONE; 1272 *view_routing_id_ptr = MSG_ROUTING_NONE;
1135 1273
1136 // We are creating a pending or swapped out RFH here. We should never create 1274 // We are creating a pending, speculative or swapped out RFH here. We should
1137 // it in the same SiteInstance as our current RFH. 1275 // never create it in the same SiteInstance as our current RFH.
1138 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); 1276 CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
1139 1277
1140 // Check if we've already created an RFH for this SiteInstance. If so, try 1278 // Check if we've already created an RFH for this SiteInstance. If so, try
1141 // to re-use the existing one, which has already been initialized. We'll 1279 // to re-use the existing one, which has already been initialized. We'll
1142 // remove it from the list of proxy hosts below if it will be active. 1280 // remove it from the list of proxy hosts below if it will be active.
1143 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1281 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1144 if (proxy && proxy->render_frame_host()) { 1282 if (proxy && proxy->render_frame_host()) {
1145 if (view_routing_id_ptr) 1283 if (view_routing_id_ptr)
1146 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); 1284 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID();
1147 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. 1285 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 1378
1241 bool RenderFrameHostManager::InitRenderView( 1379 bool RenderFrameHostManager::InitRenderView(
1242 RenderViewHostImpl* render_view_host, 1380 RenderViewHostImpl* render_view_host,
1243 int opener_route_id, 1381 int opener_route_id,
1244 int proxy_routing_id, 1382 int proxy_routing_id,
1245 bool for_main_frame_navigation) { 1383 bool for_main_frame_navigation) {
1246 // We may have initialized this RenderViewHost for another RenderFrameHost. 1384 // We may have initialized this RenderViewHost for another RenderFrameHost.
1247 if (render_view_host->IsRenderViewLive()) 1385 if (render_view_host->IsRenderViewLive())
1248 return true; 1386 return true;
1249 1387
1250 // If the pending navigation is to a WebUI and the RenderView is not in a 1388 // If the ongoing navigation is to a WebUI and the RenderView is not in a
1251 // guest process, tell the RenderViewHost about any bindings it will need 1389 // guest process, tell the RenderViewHost about any bindings it will need
1252 // enabled. 1390 // enabled.
1253 if (pending_web_ui() && !render_view_host->GetProcess()->IsIsolatedGuest()) { 1391 WebUIImpl* dest_web_ui = nullptr;
1254 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 1392 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1393 switches::kEnableBrowserSideNavigation)) {
1394 dest_web_ui =
1395 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
1396 } else {
1397 dest_web_ui = pending_web_ui();
1398 }
1399 if (dest_web_ui && !render_view_host->GetProcess()->IsIsolatedGuest()) {
1400 render_view_host->AllowBindings(dest_web_ui->GetBindings());
1255 } else { 1401 } else {
1256 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 1402 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
1257 // process unless it's swapped out. 1403 // process unless it's swapped out.
1258 if (render_view_host->is_active()) { 1404 if (render_view_host->is_active()) {
1259 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1405 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1260 render_view_host->GetProcess()->GetID())); 1406 render_view_host->GetProcess()->GetID()));
1261 } 1407 }
1262 } 1408 }
1263 1409
1264 return delegate_->CreateRenderViewForRenderManager(render_view_host, 1410 return delegate_->CreateRenderViewForRenderManager(render_view_host,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 proxy_hosts_.find(site_instance->GetId()); 1452 proxy_hosts_.find(site_instance->GetId());
1307 if (iter != proxy_hosts_.end()) 1453 if (iter != proxy_hosts_.end())
1308 return iter->second->GetRoutingID(); 1454 return iter->second->GetRoutingID();
1309 1455
1310 return MSG_ROUTING_NONE; 1456 return MSG_ROUTING_NONE;
1311 } 1457 }
1312 1458
1313 void RenderFrameHostManager::CommitPending() { 1459 void RenderFrameHostManager::CommitPending() {
1314 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 1460 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
1315 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1461 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1462 bool browser_side_navigation =
1463 base::CommandLine::ForCurrentProcess()->HasSwitch(
1464 switches::kEnableBrowserSideNavigation);
1316 // First check whether we're going to want to focus the location bar after 1465 // First check whether we're going to want to focus the location bar after
1317 // this commit. We do this now because the navigation hasn't formally 1466 // this commit. We do this now because the navigation hasn't formally
1318 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 1467 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
1319 // this triggers won't be able to figure out what's going on. 1468 // this triggers won't be able to figure out what's going on.
1320 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1469 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1321 1470
1322 // Next commit the Web UI, if any. Either replace |web_ui_| with 1471 if (!browser_side_navigation) {
1323 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 1472 DCHECK(!speculative_web_ui_);
1324 // leave |web_ui_| as is if reusing it. 1473 // Next commit the Web UI, if any. Either replace |web_ui_| with
1325 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); 1474 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
1326 if (pending_web_ui_) { 1475 // leave |web_ui_| as is if reusing it.
1327 web_ui_.reset(pending_web_ui_.release()); 1476 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
1328 } else if (!pending_and_current_web_ui_.get()) { 1477 if (pending_web_ui_) {
1329 web_ui_.reset(); 1478 web_ui_.reset(pending_web_ui_.release());
1479 } else if (!pending_and_current_web_ui_.get()) {
1480 web_ui_.reset();
1481 } else {
1482 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
1483 pending_and_current_web_ui_.reset();
1484 }
1330 } else { 1485 } else {
1331 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); 1486 // PlzNavigate
1332 pending_and_current_web_ui_.reset(); 1487 if (!should_reuse_web_ui_)
1488 web_ui_.reset(speculative_web_ui_.release());
1489 DCHECK(!speculative_web_ui_);
1333 } 1490 }
1334 1491
1335 // It's possible for the pending_render_frame_host_ to be NULL when we aren't 1492 // It's possible for the pending_render_frame_host_ to be nullptr when we
1336 // crossing process boundaries. If so, we just needed to handle the Web UI 1493 // aren't crossing process boundaries. If so, we just needed to handle the Web
1337 // committing above and we're done. 1494 // UI committing above and we're done.
1338 if (!pending_render_frame_host_) { 1495 if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
1339 if (will_focus_location_bar) 1496 if (will_focus_location_bar)
1340 delegate_->SetFocusToLocationBar(false); 1497 delegate_->SetFocusToLocationBar(false);
1341 return; 1498 return;
1342 } 1499 }
1343 1500
1344 // Remember if the page was focused so we can focus the new renderer in 1501 // Remember if the page was focused so we can focus the new renderer in
1345 // that case. 1502 // that case.
1346 bool focus_render_view = !will_focus_location_bar && 1503 bool focus_render_view = !will_focus_location_bar &&
1347 render_frame_host_->render_view_host()->GetView() && 1504 render_frame_host_->render_view_host()->GetView() &&
1348 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1505 render_frame_host_->render_view_host()->GetView()->HasFocus();
1349 1506
1350 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1507 bool is_main_frame = frame_tree_node_->IsMainFrame();
1351 1508
1352 // Swap in the pending frame and make it active. Also ensure the FrameTree 1509 // Swap in the pending or speculative frame and make it active. Also ensure
1353 // stays in sync. 1510 // the FrameTree stays in sync.
1354 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1511 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
1355 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1512 if (!browser_side_navigation) {
1513 DCHECK(!speculative_render_frame_host_);
1514 old_render_frame_host =
1515 SetRenderFrameHost(pending_render_frame_host_.Pass());
1516 } else {
1517 // PlzNavigate
1518 DCHECK(speculative_render_frame_host_);
1519 old_render_frame_host =
1520 SetRenderFrameHost(speculative_render_frame_host_.Pass());
1521 }
1522
1356 if (is_main_frame) 1523 if (is_main_frame)
1357 render_frame_host_->render_view_host()->AttachToFrameTree(); 1524 render_frame_host_->render_view_host()->AttachToFrameTree();
1358 1525
1359 // The process will no longer try to exit, so we can decrement the count. 1526 // The process will no longer try to exit, so we can decrement the count.
1360 render_frame_host_->GetProcess()->RemovePendingView(); 1527 render_frame_host_->GetProcess()->RemovePendingView();
1361 1528
1362 // Show the new view (or a sad tab) if necessary. 1529 // Show the new view (or a sad tab) if necessary.
1363 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1530 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView();
1364 if (!delegate_->IsHidden() && new_rfh_has_view) { 1531 if (!delegate_->IsHidden() && new_rfh_has_view) {
1365 // In most cases, we need to show the new view. 1532 // In most cases, we need to show the new view.
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 TRACE_EVENT_INSTANT2( 1658 TRACE_EVENT_INSTANT2(
1492 "navigation", 1659 "navigation",
1493 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 1660 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
1494 TRACE_EVENT_SCOPE_THREAD, 1661 TRACE_EVENT_SCOPE_THREAD,
1495 "current_instance id", current_instance->GetId(), 1662 "current_instance id", current_instance->GetId(),
1496 "new_instance id", new_instance->GetId()); 1663 "new_instance id", new_instance->GetId());
1497 1664
1498 // New SiteInstance: create a pending RFH to navigate. 1665 // New SiteInstance: create a pending RFH to navigate.
1499 DCHECK(!cross_navigation_pending_); 1666 DCHECK(!cross_navigation_pending_);
1500 1667
1501 // This will possibly create (set to NULL) a Web UI object for the pending 1668 // This will possibly create (set to nullptr) a Web UI object for the
1502 // page. We'll use this later to give the page special access. This must 1669 // pending page. We'll use this later to give the page special access. This
1503 // happen before the new renderer is created below so it will get bindings. 1670 // must happen before the new renderer is created below so it will get
1504 // It must also happen after the above conditional call to CancelPending(), 1671 // bindings. It must also happen after the above conditional call to
1505 // otherwise CancelPending may clear the pending_web_ui_ and the page will 1672 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_
1506 // not have its bindings set appropriately. 1673 // and the page will not have its bindings set appropriately.
1507 SetPendingWebUI(dest_url, bindings); 1674 SetPendingWebUI(dest_url, bindings);
1508 CreatePendingRenderFrameHost(current_instance, new_instance.get(), 1675 CreatePendingRenderFrameHost(current_instance, new_instance.get(),
1509 frame_tree_node_->IsMainFrame()); 1676 frame_tree_node_->IsMainFrame());
1510 if (!pending_render_frame_host_.get()) { 1677 if (!pending_render_frame_host_.get()) {
1511 return NULL; 1678 return nullptr;
1512 } 1679 }
1513 1680
1514 // Check if our current RFH is live before we set up a transition. 1681 // Check if our current RFH is live before we set up a transition.
1515 if (!render_frame_host_->IsRenderFrameLive()) { 1682 if (!render_frame_host_->IsRenderFrameLive()) {
1516 if (!cross_navigation_pending_) { 1683 if (!cross_navigation_pending_) {
1517 // The current RFH is not live. There's no reason to sit around with a 1684 // The current RFH is not live. There's no reason to sit around with a
1518 // sad tab or a newly created RFH while we wait for the pending RFH to 1685 // sad tab or a newly created RFH while we wait for the pending RFH to
1519 // navigate. Just switch to the pending RFH now and go back to non 1686 // navigate. Just switch to the pending RFH now and go back to non
1520 // cross-navigating (Note that we don't care about on{before}unload 1687 // cross-navigating (Note that we don't care about on{before}unload
1521 // handlers if the current RFH isn't live.) 1688 // handlers if the current RFH isn't live.)
1522 CommitPending(); 1689 CommitPending();
1523 return render_frame_host_.get(); 1690 return render_frame_host_.get();
1524 } else { 1691 } else {
1525 NOTREACHED(); 1692 NOTREACHED();
1526 return render_frame_host_.get(); 1693 return render_frame_host_.get();
1527 } 1694 }
1528 } 1695 }
1529 // Otherwise, it's safe to treat this as a pending cross-site transition. 1696 // Otherwise, it's safe to treat this as a pending cross-site transition.
1530 1697
1531 // We now have a pending RFH. 1698 // We now have a pending RFH.
1532 DCHECK(!cross_navigation_pending_); 1699 DCHECK(!cross_navigation_pending_);
1533 cross_navigation_pending_ = true; 1700 cross_navigation_pending_ = true;
1534 1701
1535 // PlzNavigate: There is no notion of transfer navigations, and the old
1536 // renderer before unload handler has already run at that point, so return
1537 // here.
1538 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1539 switches::kEnableBrowserSideNavigation)) {
1540 return pending_render_frame_host_.get();
1541 }
1542
1543 // We need to wait until the beforeunload handler has run, unless we are 1702 // We need to wait until the beforeunload handler has run, unless we are
1544 // transferring an existing request (in which case it has already run). 1703 // transferring an existing request (in which case it has already run).
1545 // Suspend the new render view (i.e., don't let it send the cross-site 1704 // Suspend the new render view (i.e., don't let it send the cross-site
1546 // Navigate message) until we hear back from the old renderer's 1705 // Navigate message) until we hear back from the old renderer's
1547 // beforeunload handler. If the handler returns false, we'll have to 1706 // beforeunload handler. If the handler returns false, we'll have to
1548 // cancel the request. 1707 // cancel the request.
1549 // 1708 //
1550 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); 1709 DCHECK(!pending_render_frame_host_->are_navigations_suspended());
1551 bool is_transfer = transferred_request_id != GlobalRequestID(); 1710 bool is_transfer = transferred_request_id != GlobalRequestID();
1552 if (is_transfer) { 1711 if (is_transfer) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1866 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1708 SiteInstance* instance) { 1867 SiteInstance* instance) {
1709 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1868 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1710 if (iter != proxy_hosts_.end()) { 1869 if (iter != proxy_hosts_.end()) {
1711 delete iter->second; 1870 delete iter->second;
1712 proxy_hosts_.erase(iter); 1871 proxy_hosts_.erase(iter);
1713 } 1872 }
1714 } 1873 }
1715 1874
1716 } // namespace content 1875 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698