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

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 and one more round of CR work. 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 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 (CommandLine::ForCurrentProcess()->HasSwitch(
74 switches::kEnableBrowserSideNavigation)) {
75 UnsetSpeculativeRenderFrameHost();
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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 285 }
280 } 286 }
281 return false; 287 return false;
282 } 288 }
283 289
284 void RenderFrameHostManager::OnBeforeUnloadACK( 290 void RenderFrameHostManager::OnBeforeUnloadACK(
285 bool for_cross_site_transition, 291 bool for_cross_site_transition,
286 bool proceed, 292 bool proceed,
287 const base::TimeTicks& proceed_time) { 293 const base::TimeTicks& proceed_time) {
288 if (for_cross_site_transition) { 294 if (for_cross_site_transition) {
295 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
296 switches::kEnableBrowserSideNavigation));
289 // Ignore if we're not in a cross-site navigation. 297 // Ignore if we're not in a cross-site navigation.
290 if (!cross_navigation_pending_) 298 if (!cross_navigation_pending_)
291 return; 299 return;
292 300
293 if (proceed) { 301 if (proceed) {
294 // Ok to unload the current page, so proceed with the cross-site 302 // Ok to unload the current page, so proceed with the cross-site
295 // navigation. Note that if navigations are not currently suspended, it 303 // navigation. Note that if navigations are not currently suspended, it
296 // might be because the renderer was deemed unresponsive and this call was 304 // might be because the renderer was deemed unresponsive and this call was
297 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it 305 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it
298 // is ok to do nothing here. 306 // is ok to do nothing here.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 412
405 response_started_id_.reset(); 413 response_started_id_.reset();
406 } 414 }
407 415
408 void RenderFrameHostManager::ClearNavigationTransitionData() { 416 void RenderFrameHostManager::ClearNavigationTransitionData() {
409 render_frame_host_->ClearPendingTransitionRequestData(); 417 render_frame_host_->ClearPendingTransitionRequestData();
410 } 418 }
411 419
412 void RenderFrameHostManager::DidNavigateFrame( 420 void RenderFrameHostManager::DidNavigateFrame(
413 RenderFrameHostImpl* render_frame_host, 421 RenderFrameHostImpl* render_frame_host,
414 bool was_caused_by_user_gesture) { 422 bool was_caused_by_user_gesture,
423 bool was_within_same_page) {
424 DCHECK(render_frame_host);
425 if (CommandLine::ForCurrentProcess()->HasSwitch(
426 switches::kEnableBrowserSideNavigation)) {
427 if (render_frame_host == speculative_render_frame_host_.get()) {
428 CommitPending();
429 } else if (render_frame_host == render_frame_host_.get()) {
nasko 2014/12/20 00:09:09 Can't we simplify this if/else to be if (spectulat
carlosk 2014/12/29 16:40:16 If I understood correctly what you meant I think i
430 if (!was_within_same_page) {
nasko 2014/12/20 00:09:09 If statement just for a DCHECK isn't worthwhile. F
carlosk 2014/12/29 16:40:16 Done.
431 // This is a same-site navigation driven by the browser. There should
432 // not be a speculative RenderFrameHost.
433 DCHECK(!speculative_render_frame_host_.get());
434 } else {
435 if (was_caused_by_user_gesture) {
nasko 2014/12/20 00:09:09 Let's skip adding the if statement, just add the c
carlosk 2014/12/29 16:40:16 Done.
436 // TODO(carlosk): properly cancel an ongoing navigation request.
437 }
438 }
439 } else {
440 // No one else should be sending us a DidNavigate in this state.
441 DCHECK(false);
442 }
443 DCHECK(!speculative_render_frame_host_.get());
444 return;
445 }
446
415 if (!cross_navigation_pending_) { 447 if (!cross_navigation_pending_) {
416 DCHECK(!pending_render_frame_host_); 448 DCHECK(!pending_render_frame_host_);
417 449
418 // We should only hear this from our current renderer. 450 // We should only hear this from our current renderer.
419 DCHECK_EQ(render_frame_host_, render_frame_host); 451 DCHECK_EQ(render_frame_host_, render_frame_host);
420 452
421 // Even when there is no pending RVH, there may be a pending Web UI. 453 // Even when there is no pending RVH, there may be a pending Web UI.
422 if (pending_web_ui()) 454 if (pending_web_ui())
423 CommitPending(); 455 CommitPending();
424 return; 456 return;
425 } 457 }
426 458
427 if (render_frame_host == pending_render_frame_host_) { 459 if (render_frame_host == pending_render_frame_host_) {
428 // The pending cross-site navigation completed, so show the renderer. 460 // The pending cross-site navigation completed, so show the renderer.
429 CommitPending(); 461 CommitPending();
430 cross_navigation_pending_ = false; 462 cross_navigation_pending_ = false;
431 } else if (render_frame_host == render_frame_host_) { 463 } else if (render_frame_host == render_frame_host_) {
432 if (was_caused_by_user_gesture) { 464 if (was_caused_by_user_gesture) {
433 // A navigation in the original page has taken place. Cancel the pending 465 // A navigation in the original page has taken place. Cancel the pending
434 // one. Only do it for user gesture originated navigations to prevent 466 // one. Only do it for user gesture originated navigations to prevent
435 // page doing any shenanigans to prevent user from navigating. 467 // page doing any shenanigans to prevent user from navigating.
436 // See https://code.google.com/p/chromium/issues/detail?id=75195 468 // See https://crbug.com/75195.
437 CancelPending(); 469 CancelPending();
438 cross_navigation_pending_ = false; 470 cross_navigation_pending_ = false;
439 } 471 }
440 } else { 472 } else {
441 // No one else should be sending us DidNavigate in this state. 473 // No one else should be sending us DidNavigate in this state.
442 DCHECK(false); 474 DCHECK(false);
443 } 475 }
444 } 476 }
445 477
446 void RenderFrameHostManager::DidDisownOpener( 478 void RenderFrameHostManager::DidDisownOpener(
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 // If the SiteInstance for the pending RFH is being used by others don't 596 // If the SiteInstance for the pending RFH is being used by others don't
565 // delete the RFH. Just swap it out and it can be reused at a later point. 597 // delete the RFH. Just swap it out and it can be reused at a later point.
566 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); 598 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
567 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { 599 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
568 // Any currently suspended navigations are no longer needed. 600 // Any currently suspended navigations are no longer needed.
569 render_frame_host->CancelSuspendedNavigations(); 601 render_frame_host->CancelSuspendedNavigations();
570 602
571 RenderFrameProxyHost* proxy = 603 RenderFrameProxyHost* proxy =
572 new RenderFrameProxyHost(site_instance, frame_tree_node_); 604 new RenderFrameProxyHost(site_instance, frame_tree_node_);
573 proxy_hosts_[site_instance->GetId()] = proxy; 605 proxy_hosts_[site_instance->GetId()] = proxy;
574 render_frame_host->SwapOut(proxy, false); 606
607 if (!render_frame_host->is_swapped_out())
608 render_frame_host->SwapOut(proxy, false);
609
575 if (frame_tree_node_->IsMainFrame()) 610 if (frame_tree_node_->IsMainFrame())
576 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); 611 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
577 } else { 612 } else {
578 // We won't be coming back, so delete this one. 613 // We won't be coming back, so delete this one.
579 render_frame_host.reset(); 614 render_frame_host.reset();
580 } 615 }
581 } 616 }
582 617
583 void RenderFrameHostManager::MoveToPendingDeleteHosts( 618 void RenderFrameHostManager::MoveToPendingDeleteHosts(
584 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 619 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
(...skipping 24 matching lines...) Expand all
609 } 644 }
610 } 645 }
611 return false; 646 return false;
612 } 647 }
613 648
614 void RenderFrameHostManager::ResetProxyHosts() { 649 void RenderFrameHostManager::ResetProxyHosts() {
615 STLDeleteValues(&proxy_hosts_); 650 STLDeleteValues(&proxy_hosts_);
616 } 651 }
617 652
618 // PlzNavigate 653 // PlzNavigate
654 void RenderFrameHostManager::BeginNavigation(
655 const FrameHostMsg_BeginNavigation_Params& params,
656 const CommonNavigationParams& common_params) {
657 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
658 switches::kEnableBrowserSideNavigation));
659 // Cleans up any state in case there's an ongoing navigation.
660 // TODO(carlosk): remove this cleanup here once we properly cancel ongoing
661 // navigations.
662 CleanUpNavigation();
663
664 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
nasko 2014/12/20 00:09:09 The block of code from here to 692 looks almost id
carlosk 2014/12/29 16:40:16 I replied to a very similar comment from creis@ in
clamy 2014/12/29 17:36:21 The thing is we should also make sure here that th
carlosk 2014/12/30 15:54:50 Yes, you are both right in fact! I was utterly con
665 // TODO(carlosk): Replace the default values with the right ones for
666 // source_instance, dest_instance, dest_is_restore, dest_is_view_source_mode.
667 scoped_refptr<SiteInstanceImpl> new_instance = static_cast<SiteInstanceImpl*>(
668 GetSiteInstanceForNavigation(common_params.url, nullptr, nullptr,
669 common_params.transition, false, false));
670
671 // Will keep the current RFH if its SiteInstance matches the new one from
672 // the navigation or if this is a subframe navigation. If --site-per-process
673 // is enabled the RFH is never kept when sites don't match.
674 // TODO(carlosk): do not swap processes for renderer initiated navigations
675 // (see crbug.com/440266).
676 if (current_instance == new_instance.get() ||
677 (!frame_tree_node_->IsMainFrame() &&
678 !CommandLine::ForCurrentProcess()->HasSwitch(
679 switches::kSitePerProcess))) {
680 // Make sure the current RFH is alive.
681 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) {
682 // Recreate the opener chain.
683 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
684 render_frame_host_->GetSiteInstance());
685 bool success = InitRenderView(render_frame_host_->render_view_host(),
686 opener_route_id, MSG_ROUTING_NONE,
687 frame_tree_node_->IsMainFrame());
688 DCHECK(success);
689 }
690 DCHECK(current_instance->GetProcess()->HasConnection());
691 return;
692 }
693
694 // Speculatively create a new RFH.
695 // TODO(carlosk): enable bindings check below.
696 bool success = CreateSpeculativeRenderFrameHost(
697 common_params.url, current_instance, new_instance.get(),
698 NavigationEntryImpl::kInvalidBindings);
699 DCHECK(success);
700 DCHECK(new_instance->GetProcess()->HasConnection());
701 }
702
703 // PlzNavigate
704 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
705 const GURL& url,
706 SiteInstance* old_instance,
707 SiteInstance* new_instance,
708 int bindings) {
709 CHECK(new_instance);
710 CHECK_NE(old_instance, new_instance);
711
712 const NavigationEntry* current_navigation_entry =
713 delegate_->GetLastCommittedNavigationEntryForRenderManager();
714 scoped_ptr<WebUIImpl> new_web_ui;
715 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, url);
716 if (!should_reuse_web_ui_)
717 new_web_ui = CreateWebUI(url, bindings);
718
719 int opener_route_id =
720 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance);
721
722 int create_render_frame_flags = 0;
723 if (frame_tree_node_->IsMainFrame())
724 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION;
725 if (delegate_->IsHidden())
726 create_render_frame_flags |= CREATE_RF_HIDDEN;
727 scoped_ptr<RenderFrameHostImpl> new_render_frame_host =
728 CreateRenderFrame(new_instance, new_web_ui.get(), opener_route_id,
729 create_render_frame_flags, nullptr);
730 if (!new_render_frame_host) {
731 return false;
732 }
733 speculative_render_frame_host_.reset(new_render_frame_host.release());
734 speculative_web_ui_.reset(new_web_ui.release());
735 return true;
736 }
737
738 // PlzNavigate
619 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( 739 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
620 const GURL& url, 740 const GURL& url,
621 ui::PageTransition transition) { 741 ui::PageTransition transition) {
622 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( 742 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
623 switches::kEnableBrowserSideNavigation)); 743 switches::kEnableBrowserSideNavigation));
624 // TODO(clamy): When we handle renderer initiated navigations, make sure not 744 // Pick the right RenderFrameHost to commit the navigation.
625 // to use a different process for subframes if --site-per-process is not 745 RenderFrameHostImpl* rfh_for_navigation = nullptr;
626 // enabled.
627 746
628 // Pick the right RenderFrameHost to commit the navigation. 747 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
629 // TODO(clamy): Replace the default values by the right ones. 748 // TODO(clamy): Replace the default values with the right ones for
630 RenderFrameHostImpl* render_frame_host = UpdateStateForNavigate( 749 // source_instance, dest_instance, dest_is_restore, dest_is_view_source_mode.
631 url, nullptr, nullptr, transition, false, false, GlobalRequestID(), 750 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
632 NavigationEntryImpl::kInvalidBindings); 751 url, nullptr, nullptr, transition, false, false);
633 752
634 // If the renderer that needs to navigate is not live (it was just created or 753 // Will keep the current RFH if its SiteInstance matches the new one from
635 // it crashed), initialize it. 754 // the navigation or if this is a subframe navigation. If --site-per-process
636 if (!render_frame_host->render_view_host()->IsRenderViewLive()) { 755 // is enabled the RFH is never kept when sites don't match.
756 // TODO(carlosk): do not swap processes for renderer initiated navigations
757 // (see crbug.com/440266).
758 if (current_instance == new_instance.get() ||
759 (!frame_tree_node_->IsMainFrame() &&
760 !CommandLine::ForCurrentProcess()->HasSwitch(
761 switches::kSitePerProcess))) {
762 CleanUpNavigation();
763 rfh_for_navigation = render_frame_host_.get();
764 } else {
765 // If the SiteInstance for the final URL doesn't match the one from the
766 // speculatively created RenderFrameHost, create a new one using the
767 // former.
nasko 2014/12/20 00:09:09 nit: former is what? SiteInstance, URL, or RFH?
carlosk 2014/12/29 16:40:16 I made the comment clearer.
768 if (!speculative_render_frame_host_ ||
769 speculative_render_frame_host_->GetSiteInstance() !=
770 new_instance.get()) {
771 CleanUpNavigation();
772 // TODO(clamy): Replace the binding value with the right one.
773 bool success = CreateSpeculativeRenderFrameHost(
774 url, current_instance, new_instance.get(),
775 NavigationEntryImpl::kInvalidBindings);
776 CHECK(success);
777 }
778 DCHECK(speculative_render_frame_host_);
779 rfh_for_navigation = speculative_render_frame_host_.get();
780 }
781 DCHECK(rfh_for_navigation);
782
783 // If the renderer that needs to navigate is not live (it was just created
784 // or it crashed), initialize it.
785 if (!rfh_for_navigation->render_view_host()->IsRenderViewLive()) {
637 // Recreate the opener chain. 786 // Recreate the opener chain.
638 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( 787 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
639 render_frame_host->GetSiteInstance()); 788 rfh_for_navigation->GetSiteInstance());
640 if (!InitRenderView(render_frame_host->render_view_host(), 789 if (!InitRenderView(rfh_for_navigation->render_view_host(), opener_route_id,
641 opener_route_id, 790 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame())) {
642 MSG_ROUTING_NONE,
643 frame_tree_node_->IsMainFrame())) {
644 return nullptr; 791 return nullptr;
645 } 792 }
646 } 793 }
647 return render_frame_host; 794
795 return rfh_for_navigation;
796 }
797
798 // PlzNavigate
799 void RenderFrameHostManager::CleanUpNavigation() {
800 scoped_ptr<RenderFrameHostImpl> rfh = UnsetSpeculativeRenderFrameHost();
801 if (rfh)
802 DiscardUnusedFrame(rfh.Pass());
803 }
804
805 // PlzNavigate
806 scoped_ptr<RenderFrameHostImpl>
807 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() {
808 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
809 switches::kEnableBrowserSideNavigation));
810 if (speculative_web_ui_)
811 speculative_web_ui_.reset();
812 should_reuse_web_ui_ = false;
813 if (speculative_render_frame_host_) {
814 speculative_render_frame_host_->GetProcess()->RemovePendingView();
815 return speculative_render_frame_host_.Pass();
816 }
817 return nullptr;
648 } 818 }
649 819
650 void RenderFrameHostManager::OnDidStartLoading() { 820 void RenderFrameHostManager::OnDidStartLoading() {
651 for (const auto& pair : proxy_hosts_) { 821 for (const auto& pair : proxy_hosts_) {
652 pair.second->Send( 822 pair.second->Send(
653 new FrameMsg_DidStartLoading(pair.second->GetRoutingID())); 823 new FrameMsg_DidStartLoading(pair.second->GetRoutingID()));
654 } 824 }
655 } 825 }
656 826
657 void RenderFrameHostManager::OnDidStopLoading() { 827 void RenderFrameHostManager::OnDidStopLoading() {
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 int frame_routing_id, 1248 int frame_routing_id,
1079 int flags) { 1249 int flags) {
1080 if (frame_routing_id == MSG_ROUTING_NONE) 1250 if (frame_routing_id == MSG_ROUTING_NONE)
1081 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); 1251 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
1082 1252
1083 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1253 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
1084 bool hidden = !!(flags & CREATE_RF_HIDDEN); 1254 bool hidden = !!(flags & CREATE_RF_HIDDEN);
1085 1255
1086 // Create a RVH for main frames, or find the existing one for subframes. 1256 // Create a RVH for main frames, or find the existing one for subframes.
1087 FrameTree* frame_tree = frame_tree_node_->frame_tree(); 1257 FrameTree* frame_tree = frame_tree_node_->frame_tree();
1088 RenderViewHostImpl* render_view_host = NULL; 1258 RenderViewHostImpl* render_view_host = nullptr;
1089 if (frame_tree_node_->IsMainFrame()) { 1259 if (frame_tree_node_->IsMainFrame()) {
1090 render_view_host = frame_tree->CreateRenderViewHost( 1260 render_view_host = frame_tree->CreateRenderViewHost(
1091 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); 1261 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden);
1092 } else { 1262 } else {
1093 render_view_host = frame_tree->GetRenderViewHost(site_instance); 1263 render_view_host = frame_tree->GetRenderViewHost(site_instance);
1094 1264
1095 CHECK(render_view_host); 1265 CHECK(render_view_host);
1096 } 1266 }
1097 1267
1098 // TODO(creis): Pass hidden to RFH. 1268 // TODO(creis): Pass hidden to RFH.
(...skipping 19 matching lines...) Expand all
1118 // longer relies on swapped out RFH for the top-level frame. 1288 // longer relies on swapped out RFH for the top-level frame.
1119 if (!frame_tree_node_->IsMainFrame()) { 1289 if (!frame_tree_node_->IsMainFrame()) {
1120 CHECK(!swapped_out); 1290 CHECK(!swapped_out);
1121 } 1291 }
1122 1292
1123 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; 1293 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
1124 bool success = true; 1294 bool success = true;
1125 if (view_routing_id_ptr) 1295 if (view_routing_id_ptr)
1126 *view_routing_id_ptr = MSG_ROUTING_NONE; 1296 *view_routing_id_ptr = MSG_ROUTING_NONE;
1127 1297
1128 // We are creating a pending or swapped out RFH here. We should never create 1298 // We are creating a pending, speculative or swapped out RFH here. We should
1129 // it in the same SiteInstance as our current RFH. 1299 // never create it in the same SiteInstance as our current RFH.
1130 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); 1300 CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
1131 1301
1132 // Check if we've already created an RFH for this SiteInstance. If so, try 1302 // Check if we've already created an RFH for this SiteInstance. If so, try
1133 // to re-use the existing one, which has already been initialized. We'll 1303 // to re-use the existing one, which has already been initialized. We'll
1134 // remove it from the list of proxy hosts below if it will be active. 1304 // remove it from the list of proxy hosts below if it will be active.
1135 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1305 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1136 if (proxy && proxy->render_frame_host()) { 1306 if (proxy && proxy->render_frame_host()) {
1137 if (view_routing_id_ptr) 1307 if (view_routing_id_ptr)
1138 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); 1308 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID();
1139 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. 1309 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 proxy_hosts_.find(site_instance->GetId()); 1466 proxy_hosts_.find(site_instance->GetId());
1297 if (iter != proxy_hosts_.end()) 1467 if (iter != proxy_hosts_.end())
1298 return iter->second->GetRoutingID(); 1468 return iter->second->GetRoutingID();
1299 1469
1300 return MSG_ROUTING_NONE; 1470 return MSG_ROUTING_NONE;
1301 } 1471 }
1302 1472
1303 void RenderFrameHostManager::CommitPending() { 1473 void RenderFrameHostManager::CommitPending() {
1304 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 1474 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
1305 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1475 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1476 bool browser_side_navigation = CommandLine::ForCurrentProcess()->HasSwitch(
1477 switches::kEnableBrowserSideNavigation);
1306 // First check whether we're going to want to focus the location bar after 1478 // First check whether we're going to want to focus the location bar after
1307 // this commit. We do this now because the navigation hasn't formally 1479 // this commit. We do this now because the navigation hasn't formally
1308 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 1480 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
1309 // this triggers won't be able to figure out what's going on. 1481 // this triggers won't be able to figure out what's going on.
1310 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1482 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1311 1483
1312 // Next commit the Web UI, if any. Either replace |web_ui_| with 1484 if (!browser_side_navigation) {
1313 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 1485 DCHECK(!speculative_web_ui_);
1314 // leave |web_ui_| as is if reusing it. 1486 // Next commit the Web UI, if any. Either replace |web_ui_| with
1315 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); 1487 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
1316 if (pending_web_ui_) { 1488 // leave |web_ui_| as is if reusing it.
1317 web_ui_.reset(pending_web_ui_.release()); 1489 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
1318 } else if (!pending_and_current_web_ui_.get()) { 1490 if (pending_web_ui_) {
1319 web_ui_.reset(); 1491 web_ui_.reset(pending_web_ui_.release());
1492 } else if (!pending_and_current_web_ui_.get()) {
1493 web_ui_.reset();
1494 } else {
1495 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
1496 pending_and_current_web_ui_.reset();
1497 }
1320 } else { 1498 } else {
1321 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); 1499 // PlzNavigate
1322 pending_and_current_web_ui_.reset(); 1500 if (!should_reuse_web_ui_)
1501 web_ui_.reset(speculative_web_ui_.release());
1502 DCHECK(!speculative_web_ui_);
1323 } 1503 }
1324 1504
1325 // It's possible for the pending_render_frame_host_ to be NULL when we aren't 1505 // It's possible for the pending_render_frame_host_ to be nullptr when we
1326 // crossing process boundaries. If so, we just needed to handle the Web UI 1506 // aren't crossing process boundaries. If so, we just needed to handle the Web
1327 // committing above and we're done. 1507 // UI committing above and we're done.
1328 if (!pending_render_frame_host_) { 1508 if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
1329 if (will_focus_location_bar) 1509 if (will_focus_location_bar)
1330 delegate_->SetFocusToLocationBar(false); 1510 delegate_->SetFocusToLocationBar(false);
1331 return; 1511 return;
1332 } 1512 }
1333 1513
1334 // Remember if the page was focused so we can focus the new renderer in 1514 // Remember if the page was focused so we can focus the new renderer in
1335 // that case. 1515 // that case.
1336 bool focus_render_view = !will_focus_location_bar && 1516 bool focus_render_view = !will_focus_location_bar &&
1337 render_frame_host_->render_view_host()->GetView() && 1517 render_frame_host_->render_view_host()->GetView() &&
1338 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1518 render_frame_host_->render_view_host()->GetView()->HasFocus();
1339 1519
1340 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1520 bool is_main_frame = frame_tree_node_->IsMainFrame();
1341 1521
1342 // Swap in the pending frame and make it active. Also ensure the FrameTree 1522 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
1343 // stays in sync. 1523 if (!browser_side_navigation) {
1344 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1524 DCHECK(!speculative_render_frame_host_);
1345 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1525 // Swap in the pending frame and make it active. Also ensure the FrameTree
nasko 2014/12/20 00:09:09 I think this comment can be updated and put above
carlosk 2014/12/29 16:40:16 Done.
1526 // stays in sync.
1527 old_render_frame_host =
1528 SetRenderFrameHost(pending_render_frame_host_.Pass());
1529 } else {
1530 // PlzNavigate
1531 DCHECK(speculative_render_frame_host_);
1532 old_render_frame_host =
1533 SetRenderFrameHost(speculative_render_frame_host_.Pass());
1534 }
1535
1346 if (is_main_frame) 1536 if (is_main_frame)
1347 render_frame_host_->render_view_host()->AttachToFrameTree(); 1537 render_frame_host_->render_view_host()->AttachToFrameTree();
1348 1538
1349 // The process will no longer try to exit, so we can decrement the count. 1539 // The process will no longer try to exit, so we can decrement the count.
1350 render_frame_host_->GetProcess()->RemovePendingView(); 1540 render_frame_host_->GetProcess()->RemovePendingView();
1351 1541
1352 // Show the new view (or a sad tab) if necessary. 1542 // Show the new view (or a sad tab) if necessary.
1353 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1543 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView();
1354 if (!delegate_->IsHidden() && new_rfh_has_view) { 1544 if (!delegate_->IsHidden() && new_rfh_has_view) {
1355 // In most cases, we need to show the new view. 1545 // In most cases, we need to show the new view.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 TRACE_EVENT_INSTANT2( 1670 TRACE_EVENT_INSTANT2(
1481 "navigation", 1671 "navigation",
1482 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 1672 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
1483 TRACE_EVENT_SCOPE_THREAD, 1673 TRACE_EVENT_SCOPE_THREAD,
1484 "current_instance id", current_instance->GetId(), 1674 "current_instance id", current_instance->GetId(),
1485 "new_instance id", new_instance->GetId()); 1675 "new_instance id", new_instance->GetId());
1486 1676
1487 // New SiteInstance: create a pending RFH to navigate. 1677 // New SiteInstance: create a pending RFH to navigate.
1488 DCHECK(!cross_navigation_pending_); 1678 DCHECK(!cross_navigation_pending_);
1489 1679
1490 // This will possibly create (set to NULL) a Web UI object for the pending 1680 // This will possibly create (set to nullptr) a Web UI object for the
1491 // page. We'll use this later to give the page special access. This must 1681 // pending page. We'll use this later to give the page special access. This
1492 // happen before the new renderer is created below so it will get bindings. 1682 // must happen before the new renderer is created below so it will get
1493 // It must also happen after the above conditional call to CancelPending(), 1683 // bindings. It must also happen after the above conditional call to
1494 // otherwise CancelPending may clear the pending_web_ui_ and the page will 1684 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_
1495 // not have its bindings set appropriately. 1685 // and the page will not have its bindings set appropriately.
1496 SetPendingWebUI(dest_url, bindings); 1686 SetPendingWebUI(dest_url, bindings);
1497 CreatePendingRenderFrameHost(current_instance, new_instance.get(), 1687 CreatePendingRenderFrameHost(current_instance, new_instance.get(),
1498 frame_tree_node_->IsMainFrame()); 1688 frame_tree_node_->IsMainFrame());
1499 if (!pending_render_frame_host_.get()) { 1689 if (!pending_render_frame_host_.get()) {
1500 return NULL; 1690 return nullptr;
1501 } 1691 }
1502 1692
1503 // Check if our current RFH is live before we set up a transition. 1693 // Check if our current RFH is live before we set up a transition.
1504 if (!render_frame_host_->IsRenderFrameLive()) { 1694 if (!render_frame_host_->IsRenderFrameLive()) {
1505 if (!cross_navigation_pending_) { 1695 if (!cross_navigation_pending_) {
1506 // The current RFH is not live. There's no reason to sit around with a 1696 // The current RFH is not live. There's no reason to sit around with a
1507 // sad tab or a newly created RFH while we wait for the pending RFH to 1697 // sad tab or a newly created RFH while we wait for the pending RFH to
1508 // navigate. Just switch to the pending RFH now and go back to non 1698 // navigate. Just switch to the pending RFH now and go back to non
1509 // cross-navigating (Note that we don't care about on{before}unload 1699 // cross-navigating (Note that we don't care about on{before}unload
1510 // handlers if the current RFH isn't live.) 1700 // handlers if the current RFH isn't live.)
1511 CommitPending(); 1701 CommitPending();
1512 return render_frame_host_.get(); 1702 return render_frame_host_.get();
1513 } else { 1703 } else {
1514 NOTREACHED(); 1704 NOTREACHED();
1515 return render_frame_host_.get(); 1705 return render_frame_host_.get();
1516 } 1706 }
1517 } 1707 }
1518 // Otherwise, it's safe to treat this as a pending cross-site transition. 1708 // Otherwise, it's safe to treat this as a pending cross-site transition.
1519 1709
1520 // We now have a pending RFH. 1710 // We now have a pending RFH.
1521 DCHECK(!cross_navigation_pending_); 1711 DCHECK(!cross_navigation_pending_);
1522 cross_navigation_pending_ = true; 1712 cross_navigation_pending_ = true;
1523 1713
1524 // PlzNavigate: There is no notion of transfer navigations, and the old
1525 // renderer before unload handler has already run at that point, so return
1526 // here.
1527 if (CommandLine::ForCurrentProcess()->HasSwitch(
1528 switches::kEnableBrowserSideNavigation)) {
1529 return pending_render_frame_host_.get();
1530 }
1531
carlosk 2014/12/19 04:27:15 UpdateStateForNavigate is not called by PlzNavigat
1532 // We need to wait until the beforeunload handler has run, unless we are 1714 // We need to wait until the beforeunload handler has run, unless we are
1533 // transferring an existing request (in which case it has already run). 1715 // transferring an existing request (in which case it has already run).
1534 // Suspend the new render view (i.e., don't let it send the cross-site 1716 // Suspend the new render view (i.e., don't let it send the cross-site
1535 // Navigate message) until we hear back from the old renderer's 1717 // Navigate message) until we hear back from the old renderer's
1536 // beforeunload handler. If the handler returns false, we'll have to 1718 // beforeunload handler. If the handler returns false, we'll have to
1537 // cancel the request. 1719 // cancel the request.
1538 // 1720 //
1539 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); 1721 DCHECK(!pending_render_frame_host_->are_navigations_suspended());
1540 bool is_transfer = transferred_request_id != GlobalRequestID(); 1722 bool is_transfer = transferred_request_id != GlobalRequestID();
1541 if (is_transfer) { 1723 if (is_transfer) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1696 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1878 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1697 SiteInstance* instance) { 1879 SiteInstance* instance) {
1698 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1880 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1699 if (iter != proxy_hosts_.end()) { 1881 if (iter != proxy_hosts_.end()) {
1700 delete iter->second; 1882 delete iter->second;
1701 proxy_hosts_.erase(iter); 1883 proxy_hosts_.erase(iter);
1702 } 1884 }
1703 } 1885 }
1704 1886
1705 } // namespace content 1887 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698