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

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: Addressing latest comments from creis@. 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> navigation_site_instance =
679 GetSiteInstanceForNavigation(url, nullptr, nullptr, transition, false,
680 false);
681 // The appropriate RenderFrameHost to commit the navigation.
682 RenderFrameHostImpl* navigation_rfh = nullptr;
683
684 // TODO(carlosk): do not swap processes for renderer initiated navigations
685 // (see crbug.com/440266).
686 if (current_site_instance == navigation_site_instance.get() ||
687 (!frame_tree_node_->IsMainFrame() &&
688 !base::CommandLine::ForCurrentProcess()->HasSwitch(
689 switches::kSitePerProcess))) {
690 // Reuse the current RFH if its SiteInstance matches the the navigation's
691 // or if this is a subframe navigation. We only swap RFHs for subframes when
692 // --site-per-process is enabled.
693 CleanUpNavigation();
694 navigation_rfh = render_frame_host_.get();
695 } else {
696 // If the current render_frame_host_ isn't live, we should create it so
697 // that we don't show a sad tab while the navigation is ongoing.
698 // (Bug 1145340)
699 if (!render_frame_host_->IsRenderFrameLive()) {
700 // Note: we don't call InitRenderView here because we are navigating away
701 // soon anyway, and we don't have the NavigationEntry for this host.
702 delegate_->CreateRenderViewForRenderManager(
703 render_frame_host_->render_view_host(), MSG_ROUTING_NONE,
704 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame());
705 }
706
707 // If the SiteInstance for the final URL doesn't match the one from the
708 // speculatively created RenderFrameHost, create a new RenderFrameHost using
709 // this new SiteInstance.
710 if (!speculative_render_frame_host_ ||
711 speculative_render_frame_host_->GetSiteInstance() !=
712 navigation_site_instance.get()) {
713 CleanUpNavigation();
714 // TODO(carlosk): Replace the binding value with the right one.
715 bool success = CreateSpeculativeRenderFrameHost(
716 url, current_site_instance, navigation_site_instance.get(),
717 NavigationEntryImpl::kInvalidBindings);
718 DCHECK(success);
719 }
720 DCHECK(speculative_render_frame_host_);
721 navigation_rfh = speculative_render_frame_host_.get();
722 }
723 DCHECK(navigation_rfh &&
724 (navigation_rfh == render_frame_host_.get() ||
725 navigation_rfh == speculative_render_frame_host_.get()));
726
727 // If the renderer that needs to navigate is not live (it was just created
728 // or it crashed), initialize it.
729 if (!navigation_rfh->IsRenderFrameLive()) {
644 // Recreate the opener chain. 730 // Recreate the opener chain.
645 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( 731 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
646 render_frame_host->GetSiteInstance()); 732 navigation_rfh->GetSiteInstance());
647 if (!InitRenderView(render_frame_host->render_view_host(), 733 if (!InitRenderView(navigation_rfh->render_view_host(), opener_route_id,
648 opener_route_id, 734 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame())) {
649 MSG_ROUTING_NONE,
650 frame_tree_node_->IsMainFrame())) {
651 return nullptr; 735 return nullptr;
652 } 736 }
653 } 737 }
654 return render_frame_host; 738
739 return navigation_rfh;
740 }
741
742 // PlzNavigate
743 void RenderFrameHostManager::CleanUpNavigation() {
744 if (speculative_render_frame_host_)
745 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
746 }
747
748 // PlzNavigate
749 scoped_ptr<RenderFrameHostImpl>
750 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() {
751 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
752 switches::kEnableBrowserSideNavigation));
753 if (speculative_web_ui_)
754 speculative_web_ui_.reset();
755 should_reuse_web_ui_ = false;
756 if (speculative_render_frame_host_) {
757 speculative_render_frame_host_->GetProcess()->RemovePendingView();
758 return speculative_render_frame_host_.Pass();
759 }
760 return nullptr;
655 } 761 }
656 762
657 void RenderFrameHostManager::OnDidStartLoading() { 763 void RenderFrameHostManager::OnDidStartLoading() {
658 for (const auto& pair : proxy_hosts_) { 764 for (const auto& pair : proxy_hosts_) {
659 pair.second->Send( 765 pair.second->Send(
660 new FrameMsg_DidStartLoading(pair.second->GetRoutingID())); 766 new FrameMsg_DidStartLoading(pair.second->GetRoutingID()));
661 } 767 }
662 } 768 }
663 769
664 void RenderFrameHostManager::OnDidStopLoading() { 770 void RenderFrameHostManager::OnDidStopLoading() {
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 int frame_routing_id, 1193 int frame_routing_id,
1088 int flags) { 1194 int flags) {
1089 if (frame_routing_id == MSG_ROUTING_NONE) 1195 if (frame_routing_id == MSG_ROUTING_NONE)
1090 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); 1196 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
1091 1197
1092 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1198 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
1093 bool hidden = !!(flags & CREATE_RF_HIDDEN); 1199 bool hidden = !!(flags & CREATE_RF_HIDDEN);
1094 1200
1095 // Create a RVH for main frames, or find the existing one for subframes. 1201 // Create a RVH for main frames, or find the existing one for subframes.
1096 FrameTree* frame_tree = frame_tree_node_->frame_tree(); 1202 FrameTree* frame_tree = frame_tree_node_->frame_tree();
1097 RenderViewHostImpl* render_view_host = NULL; 1203 RenderViewHostImpl* render_view_host = nullptr;
1098 if (frame_tree_node_->IsMainFrame()) { 1204 if (frame_tree_node_->IsMainFrame()) {
1099 render_view_host = frame_tree->CreateRenderViewHost( 1205 render_view_host = frame_tree->CreateRenderViewHost(
1100 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); 1206 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden);
1101 } else { 1207 } else {
1102 render_view_host = frame_tree->GetRenderViewHost(site_instance); 1208 render_view_host = frame_tree->GetRenderViewHost(site_instance);
1103 1209
1104 CHECK(render_view_host); 1210 CHECK(render_view_host);
1105 } 1211 }
1106 1212
1107 // TODO(creis): Pass hidden to RFH. 1213 // TODO(creis): Pass hidden to RFH.
1108 scoped_ptr<RenderFrameHostImpl> render_frame_host = 1214 scoped_ptr<RenderFrameHostImpl> render_frame_host =
1109 make_scoped_ptr(RenderFrameHostFactory::Create( 1215 make_scoped_ptr(RenderFrameHostFactory::Create(
1110 render_view_host, render_frame_delegate_, frame_tree, 1216 render_view_host, render_frame_delegate_, frame_tree,
1111 frame_tree_node_, frame_routing_id, flags).release()); 1217 frame_tree_node_, frame_routing_id, flags).release());
1112 return render_frame_host.Pass(); 1218 return render_frame_host.Pass();
1113 } 1219 }
1114 1220
1221 // PlzNavigate
1222 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
1223 const GURL& url,
1224 SiteInstance* old_instance,
1225 SiteInstance* new_instance,
1226 int bindings) {
1227 CHECK(new_instance);
1228 CHECK_NE(old_instance, new_instance);
1229
1230 const NavigationEntry* current_navigation_entry =
1231 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1232 scoped_ptr<WebUIImpl> new_web_ui;
1233 bool should_reuse_web_ui = ShouldReuseWebUI(current_navigation_entry, url);
1234 if (!should_reuse_web_ui)
1235 new_web_ui = CreateWebUI(url, bindings);
1236
1237 int opener_route_id =
1238 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance);
1239
1240 int create_render_frame_flags = 0;
1241 if (frame_tree_node_->IsMainFrame())
1242 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION;
1243 if (delegate_->IsHidden())
1244 create_render_frame_flags |= CREATE_RF_HIDDEN;
1245 scoped_ptr<RenderFrameHostImpl> new_render_frame_host =
1246 CreateRenderFrame(new_instance, new_web_ui.get(), opener_route_id,
1247 create_render_frame_flags, nullptr);
1248
1249 if (!new_render_frame_host)
1250 return false;
1251
1252 speculative_render_frame_host_ = new_render_frame_host.Pass();
1253 speculative_web_ui_ = new_web_ui.Pass();
1254 should_reuse_web_ui_ = should_reuse_web_ui;
1255 return true;
1256 }
1257
1115 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( 1258 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
1116 SiteInstance* instance, 1259 SiteInstance* instance,
1117 WebUIImpl* web_ui, 1260 WebUIImpl* web_ui,
1118 int opener_route_id, 1261 int opener_route_id,
1119 int flags, 1262 int flags,
1120 int* view_routing_id_ptr) { 1263 int* view_routing_id_ptr) {
1121 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1264 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
1122 CHECK(instance); 1265 CHECK(instance);
1123 // Swapped out views should always be hidden. 1266 // Swapped out views should always be hidden.
1124 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN)); 1267 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN));
1125 1268
1126 // TODO(nasko): Remove the following CHECK once cross-site navigation no 1269 // TODO(nasko): Remove the following CHECK once cross-site navigation no
1127 // longer relies on swapped out RFH for the top-level frame. 1270 // longer relies on swapped out RFH for the top-level frame.
1128 if (!frame_tree_node_->IsMainFrame()) 1271 if (!frame_tree_node_->IsMainFrame())
1129 CHECK(!swapped_out); 1272 CHECK(!swapped_out);
1130 1273
1131 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; 1274 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
1132 bool success = true; 1275 bool success = true;
1133 if (view_routing_id_ptr) 1276 if (view_routing_id_ptr)
1134 *view_routing_id_ptr = MSG_ROUTING_NONE; 1277 *view_routing_id_ptr = MSG_ROUTING_NONE;
1135 1278
1136 // We are creating a pending or swapped out RFH here. We should never create 1279 // We are creating a pending, speculative or swapped out RFH here. We should
1137 // it in the same SiteInstance as our current RFH. 1280 // never create it in the same SiteInstance as our current RFH.
1138 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); 1281 CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
1139 1282
1140 // Check if we've already created an RFH for this SiteInstance. If so, try 1283 // 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 1284 // 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. 1285 // remove it from the list of proxy hosts below if it will be active.
1143 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1286 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1144 if (proxy && proxy->render_frame_host()) { 1287 if (proxy && proxy->render_frame_host()) {
1145 if (view_routing_id_ptr) 1288 if (view_routing_id_ptr)
1146 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); 1289 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID();
1147 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. 1290 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 1383
1241 bool RenderFrameHostManager::InitRenderView( 1384 bool RenderFrameHostManager::InitRenderView(
1242 RenderViewHostImpl* render_view_host, 1385 RenderViewHostImpl* render_view_host,
1243 int opener_route_id, 1386 int opener_route_id,
1244 int proxy_routing_id, 1387 int proxy_routing_id,
1245 bool for_main_frame_navigation) { 1388 bool for_main_frame_navigation) {
1246 // We may have initialized this RenderViewHost for another RenderFrameHost. 1389 // We may have initialized this RenderViewHost for another RenderFrameHost.
1247 if (render_view_host->IsRenderViewLive()) 1390 if (render_view_host->IsRenderViewLive())
1248 return true; 1391 return true;
1249 1392
1250 // If the pending navigation is to a WebUI and the RenderView is not in a 1393 // 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 1394 // guest process, tell the RenderViewHost about any bindings it will need
1252 // enabled. 1395 // enabled.
1253 if (pending_web_ui() && !render_view_host->GetProcess()->IsIsolatedGuest()) { 1396 WebUIImpl* dest_web_ui = nullptr;
1254 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 1397 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1398 switches::kEnableBrowserSideNavigation)) {
1399 dest_web_ui =
1400 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
1401 } else {
1402 dest_web_ui = pending_web_ui();
1403 }
1404 if (dest_web_ui && !render_view_host->GetProcess()->IsIsolatedGuest()) {
1405 render_view_host->AllowBindings(dest_web_ui->GetBindings());
1255 } else { 1406 } else {
1256 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 1407 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
1257 // process unless it's swapped out. 1408 // process unless it's swapped out.
1258 if (render_view_host->is_active()) { 1409 if (render_view_host->is_active()) {
1259 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1410 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1260 render_view_host->GetProcess()->GetID())); 1411 render_view_host->GetProcess()->GetID()));
1261 } 1412 }
1262 } 1413 }
1263 1414
1264 return delegate_->CreateRenderViewForRenderManager(render_view_host, 1415 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()); 1457 proxy_hosts_.find(site_instance->GetId());
1307 if (iter != proxy_hosts_.end()) 1458 if (iter != proxy_hosts_.end())
1308 return iter->second->GetRoutingID(); 1459 return iter->second->GetRoutingID();
1309 1460
1310 return MSG_ROUTING_NONE; 1461 return MSG_ROUTING_NONE;
1311 } 1462 }
1312 1463
1313 void RenderFrameHostManager::CommitPending() { 1464 void RenderFrameHostManager::CommitPending() {
1314 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 1465 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
1315 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1466 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1467 bool browser_side_navigation =
1468 base::CommandLine::ForCurrentProcess()->HasSwitch(
1469 switches::kEnableBrowserSideNavigation);
1316 // First check whether we're going to want to focus the location bar after 1470 // 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 1471 // 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 1472 // 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. 1473 // this triggers won't be able to figure out what's going on.
1320 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1474 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1321 1475
1322 // Next commit the Web UI, if any. Either replace |web_ui_| with 1476 if (!browser_side_navigation) {
1323 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 1477 DCHECK(!speculative_web_ui_);
1324 // leave |web_ui_| as is if reusing it. 1478 // Next commit the Web UI, if any. Either replace |web_ui_| with
1325 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); 1479 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
1326 if (pending_web_ui_) { 1480 // leave |web_ui_| as is if reusing it.
1327 web_ui_.reset(pending_web_ui_.release()); 1481 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
1328 } else if (!pending_and_current_web_ui_.get()) { 1482 if (pending_web_ui_) {
1329 web_ui_.reset(); 1483 web_ui_.reset(pending_web_ui_.release());
1484 } else if (!pending_and_current_web_ui_.get()) {
1485 web_ui_.reset();
1486 } else {
1487 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
1488 pending_and_current_web_ui_.reset();
1489 }
1330 } else { 1490 } else {
1331 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); 1491 // PlzNavigate
1332 pending_and_current_web_ui_.reset(); 1492 if (!should_reuse_web_ui_)
1493 web_ui_.reset(speculative_web_ui_.release());
1494 DCHECK(!speculative_web_ui_);
1333 } 1495 }
1334 1496
1335 // It's possible for the pending_render_frame_host_ to be NULL when we aren't 1497 // 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 1498 // aren't crossing process boundaries. If so, we just needed to handle the Web
1337 // committing above and we're done. 1499 // UI committing above and we're done.
1338 if (!pending_render_frame_host_) { 1500 if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
1339 if (will_focus_location_bar) 1501 if (will_focus_location_bar)
1340 delegate_->SetFocusToLocationBar(false); 1502 delegate_->SetFocusToLocationBar(false);
1341 return; 1503 return;
1342 } 1504 }
1343 1505
1344 // Remember if the page was focused so we can focus the new renderer in 1506 // Remember if the page was focused so we can focus the new renderer in
1345 // that case. 1507 // that case.
1346 bool focus_render_view = !will_focus_location_bar && 1508 bool focus_render_view = !will_focus_location_bar &&
1347 render_frame_host_->render_view_host()->GetView() && 1509 render_frame_host_->render_view_host()->GetView() &&
1348 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1510 render_frame_host_->render_view_host()->GetView()->HasFocus();
1349 1511
1350 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1512 bool is_main_frame = frame_tree_node_->IsMainFrame();
1351 1513
1352 // Swap in the pending frame and make it active. Also ensure the FrameTree 1514 // Swap in the pending or speculative frame and make it active. Also ensure
1353 // stays in sync. 1515 // the FrameTree stays in sync.
1354 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1516 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
1355 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1517 if (!browser_side_navigation) {
1518 DCHECK(!speculative_render_frame_host_);
1519 old_render_frame_host =
1520 SetRenderFrameHost(pending_render_frame_host_.Pass());
1521 } else {
1522 // PlzNavigate
1523 DCHECK(speculative_render_frame_host_);
1524 old_render_frame_host =
1525 SetRenderFrameHost(speculative_render_frame_host_.Pass());
1526 }
1527
1356 if (is_main_frame) 1528 if (is_main_frame)
1357 render_frame_host_->render_view_host()->AttachToFrameTree(); 1529 render_frame_host_->render_view_host()->AttachToFrameTree();
1358 1530
1359 // The process will no longer try to exit, so we can decrement the count. 1531 // The process will no longer try to exit, so we can decrement the count.
1360 render_frame_host_->GetProcess()->RemovePendingView(); 1532 render_frame_host_->GetProcess()->RemovePendingView();
1361 1533
1362 // Show the new view (or a sad tab) if necessary. 1534 // Show the new view (or a sad tab) if necessary.
1363 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1535 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView();
1364 if (!delegate_->IsHidden() && new_rfh_has_view) { 1536 if (!delegate_->IsHidden() && new_rfh_has_view) {
1365 // In most cases, we need to show the new view. 1537 // 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( 1663 TRACE_EVENT_INSTANT2(
1492 "navigation", 1664 "navigation",
1493 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 1665 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
1494 TRACE_EVENT_SCOPE_THREAD, 1666 TRACE_EVENT_SCOPE_THREAD,
1495 "current_instance id", current_instance->GetId(), 1667 "current_instance id", current_instance->GetId(),
1496 "new_instance id", new_instance->GetId()); 1668 "new_instance id", new_instance->GetId());
1497 1669
1498 // New SiteInstance: create a pending RFH to navigate. 1670 // New SiteInstance: create a pending RFH to navigate.
1499 DCHECK(!cross_navigation_pending_); 1671 DCHECK(!cross_navigation_pending_);
1500 1672
1501 // This will possibly create (set to NULL) a Web UI object for the pending 1673 // 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 1674 // 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. 1675 // 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(), 1676 // bindings. It must also happen after the above conditional call to
1505 // otherwise CancelPending may clear the pending_web_ui_ and the page will 1677 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_
1506 // not have its bindings set appropriately. 1678 // and the page will not have its bindings set appropriately.
1507 SetPendingWebUI(dest_url, bindings); 1679 SetPendingWebUI(dest_url, bindings);
1508 CreatePendingRenderFrameHost(current_instance, new_instance.get(), 1680 CreatePendingRenderFrameHost(current_instance, new_instance.get(),
1509 frame_tree_node_->IsMainFrame()); 1681 frame_tree_node_->IsMainFrame());
1510 if (!pending_render_frame_host_.get()) { 1682 if (!pending_render_frame_host_.get()) {
1511 return NULL; 1683 return nullptr;
1512 } 1684 }
1513 1685
1514 // Check if our current RFH is live before we set up a transition. 1686 // Check if our current RFH is live before we set up a transition.
1515 if (!render_frame_host_->IsRenderFrameLive()) { 1687 if (!render_frame_host_->IsRenderFrameLive()) {
1516 if (!cross_navigation_pending_) { 1688 if (!cross_navigation_pending_) {
1517 // The current RFH is not live. There's no reason to sit around with a 1689 // 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 1690 // 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 1691 // 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 1692 // cross-navigating (Note that we don't care about on{before}unload
1521 // handlers if the current RFH isn't live.) 1693 // handlers if the current RFH isn't live.)
1522 CommitPending(); 1694 CommitPending();
1523 return render_frame_host_.get(); 1695 return render_frame_host_.get();
1524 } else { 1696 } else {
1525 NOTREACHED(); 1697 NOTREACHED();
1526 return render_frame_host_.get(); 1698 return render_frame_host_.get();
1527 } 1699 }
1528 } 1700 }
1529 // Otherwise, it's safe to treat this as a pending cross-site transition. 1701 // Otherwise, it's safe to treat this as a pending cross-site transition.
1530 1702
1531 // We now have a pending RFH. 1703 // We now have a pending RFH.
1532 DCHECK(!cross_navigation_pending_); 1704 DCHECK(!cross_navigation_pending_);
1533 cross_navigation_pending_ = true; 1705 cross_navigation_pending_ = true;
1534 1706
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 1707 // 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). 1708 // 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 1709 // 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 1710 // Navigate message) until we hear back from the old renderer's
1547 // beforeunload handler. If the handler returns false, we'll have to 1711 // beforeunload handler. If the handler returns false, we'll have to
1548 // cancel the request. 1712 // cancel the request.
1549 // 1713 //
1550 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); 1714 DCHECK(!pending_render_frame_host_->are_navigations_suspended());
1551 bool is_transfer = transferred_request_id != GlobalRequestID(); 1715 bool is_transfer = transferred_request_id != GlobalRequestID();
1552 if (is_transfer) { 1716 if (is_transfer) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1871 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1708 SiteInstance* instance) { 1872 SiteInstance* instance) {
1709 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1873 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1710 if (iter != proxy_hosts_.end()) { 1874 if (iter != proxy_hosts_.end()) {
1711 delete iter->second; 1875 delete iter->second;
1712 proxy_hosts_.erase(iter); 1876 proxy_hosts_.erase(iter);
1713 } 1877 }
1714 } 1878 }
1715 1879
1716 } // namespace content 1880 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698