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

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: Updated tests and refactored code based on CR comments. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/frame_host/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 RenderViewHostDelegate* render_view_delegate, 54 RenderViewHostDelegate* render_view_delegate,
55 RenderWidgetHostDelegate* render_widget_delegate, 55 RenderWidgetHostDelegate* render_widget_delegate,
56 Delegate* delegate) 56 Delegate* delegate)
57 : frame_tree_node_(frame_tree_node), 57 : frame_tree_node_(frame_tree_node),
58 delegate_(delegate), 58 delegate_(delegate),
59 cross_navigation_pending_(false), 59 cross_navigation_pending_(false),
60 render_frame_delegate_(render_frame_delegate), 60 render_frame_delegate_(render_frame_delegate),
61 render_view_delegate_(render_view_delegate), 61 render_view_delegate_(render_view_delegate),
62 render_widget_delegate_(render_widget_delegate), 62 render_widget_delegate_(render_widget_delegate),
63 interstitial_page_(NULL), 63 interstitial_page_(NULL),
64 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 CancelPending(); 71 CancelPending();
71 72
73 if (CommandLine::ForCurrentProcess()->HasSwitch(
74 switches::kEnableBrowserSideNavigation)) {
75 CleanUpNavigation();
ncarter (slow) 2014/12/12 22:37:54 A CL I'm working on -- https://codereview.chromium
carlosk 2014/12/16 01:53:48 Thanks for pointing this out! I refactored the cod
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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 } 287 }
282 } 288 }
283 return false; 289 return false;
284 } 290 }
285 291
286 void RenderFrameHostManager::OnBeforeUnloadACK( 292 void RenderFrameHostManager::OnBeforeUnloadACK(
287 bool for_cross_site_transition, 293 bool for_cross_site_transition,
288 bool proceed, 294 bool proceed,
289 const base::TimeTicks& proceed_time) { 295 const base::TimeTicks& proceed_time) {
290 if (for_cross_site_transition) { 296 if (for_cross_site_transition) {
297 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
298 switches::kEnableBrowserSideNavigation));
291 // Ignore if we're not in a cross-site navigation. 299 // Ignore if we're not in a cross-site navigation.
292 if (!cross_navigation_pending_) 300 if (!cross_navigation_pending_)
293 return; 301 return;
294 302
295 if (proceed) { 303 if (proceed) {
296 // Ok to unload the current page, so proceed with the cross-site 304 // Ok to unload the current page, so proceed with the cross-site
297 // navigation. Note that if navigations are not currently suspended, it 305 // navigation. Note that if navigations are not currently suspended, it
298 // might be because the renderer was deemed unresponsive and this call was 306 // might be because the renderer was deemed unresponsive and this call was
299 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it 307 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it
300 // is ok to do nothing here. 308 // is ok to do nothing here.
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 420
413 response_started_id_.reset(); 421 response_started_id_.reset();
414 } 422 }
415 423
416 void RenderFrameHostManager::ClearNavigationTransitionData() { 424 void RenderFrameHostManager::ClearNavigationTransitionData() {
417 render_frame_host_->ClearPendingTransitionRequestData(); 425 render_frame_host_->ClearPendingTransitionRequestData();
418 } 426 }
419 427
420 void RenderFrameHostManager::DidNavigateFrame( 428 void RenderFrameHostManager::DidNavigateFrame(
421 RenderFrameHostImpl* render_frame_host) { 429 RenderFrameHostImpl* render_frame_host) {
430 DCHECK(render_frame_host);
431 if (CommandLine::ForCurrentProcess()->HasSwitch(
432 switches::kEnableBrowserSideNavigation)) {
433 return;
434 }
435
422 if (!cross_navigation_pending_) { 436 if (!cross_navigation_pending_) {
423 DCHECK(!pending_render_frame_host_); 437 DCHECK(!pending_render_frame_host_);
424 438
425 // We should only hear this from our current renderer. 439 // We should only hear this from our current renderer.
426 DCHECK_EQ(render_frame_host_, render_frame_host); 440 DCHECK_EQ(render_frame_host_, render_frame_host);
427 441
428 // Even when there is no pending RVH, there may be a pending Web UI. 442 // Even when there is no pending RVH, there may be a pending Web UI.
429 if (pending_web_ui()) 443 if (pending_web_ui())
430 CommitPending(); 444 CommitPending();
431 return; 445 return;
432 } 446 }
433 447
434 if (render_frame_host == pending_render_frame_host_) { 448 if (render_frame_host == pending_render_frame_host_) {
clamy 2014/12/09 15:09:52 We probably want to something a bit similar, only
carlosk 2014/12/16 01:53:48 This makes me think that even after committing a s
clamy 2014/12/16 15:22:48 No we can only get the pending RFH or current RFH
carlosk 2014/12/19 04:27:14 Now that I read all of your other comments I reali
435 // The pending cross-site navigation completed, so show the renderer. 449 // The pending cross-site navigation completed, so show the renderer.
436 CommitPending(); 450 CommitPending();
437 cross_navigation_pending_ = false; 451 cross_navigation_pending_ = false;
438 } else if (render_frame_host == render_frame_host_) { 452 } else if (render_frame_host == render_frame_host_) {
clamy 2014/12/09 15:09:52 Note that in the PlzNavigate case, we only want to
carlosk 2014/12/16 01:53:48 Let me try to understand what you are saying. You
clamy 2014/12/16 15:22:48 I've written what I meant in code version in the c
carlosk 2014/12/19 04:27:14 Acknowledged. Note: Your reference to the "code a
439 // A navigation in the original page has taken place. Cancel the pending 453 // A navigation in the original page has taken place. Cancel the pending
440 // one. 454 // one.
441 CancelPending(); 455 CancelPending();
442 cross_navigation_pending_ = false; 456 cross_navigation_pending_ = false;
443 } else { 457 } else {
444 // No one else should be sending us DidNavigate in this state. 458 // No one else should be sending us DidNavigate in this state.
445 DCHECK(false); 459 DCHECK(false);
446 } 460 }
447 } 461 }
448 462
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 // If the SiteInstance for the pending RFH is being used by others don't 581 // If the SiteInstance for the pending RFH is being used by others don't
568 // delete the RFH. Just swap it out and it can be reused at a later point. 582 // delete the RFH. Just swap it out and it can be reused at a later point.
569 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); 583 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
570 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { 584 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
571 // Any currently suspended navigations are no longer needed. 585 // Any currently suspended navigations are no longer needed.
572 render_frame_host->CancelSuspendedNavigations(); 586 render_frame_host->CancelSuspendedNavigations();
573 587
574 RenderFrameProxyHost* proxy = 588 RenderFrameProxyHost* proxy =
575 new RenderFrameProxyHost(site_instance, frame_tree_node_); 589 new RenderFrameProxyHost(site_instance, frame_tree_node_);
576 proxy_hosts_[site_instance->GetId()] = proxy; 590 proxy_hosts_[site_instance->GetId()] = proxy;
577 render_frame_host->SwapOut(proxy); 591
592 if (!render_frame_host->is_swapped_out())
593 render_frame_host->SwapOut(proxy);
594
578 if (frame_tree_node_->IsMainFrame()) 595 if (frame_tree_node_->IsMainFrame())
579 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); 596 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
580 } else { 597 } else {
581 // We won't be coming back, so delete this one. 598 // We won't be coming back, so delete this one.
582 render_frame_host.reset(); 599 render_frame_host.reset();
583 } 600 }
584 } 601 }
585 602
586 void RenderFrameHostManager::MoveToPendingDeleteHosts( 603 void RenderFrameHostManager::MoveToPendingDeleteHosts(
587 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 604 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
(...skipping 24 matching lines...) Expand all
612 } 629 }
613 } 630 }
614 return false; 631 return false;
615 } 632 }
616 633
617 void RenderFrameHostManager::ResetProxyHosts() { 634 void RenderFrameHostManager::ResetProxyHosts() {
618 STLDeleteValues(&proxy_hosts_); 635 STLDeleteValues(&proxy_hosts_);
619 } 636 }
620 637
621 // PlzNavigate 638 // PlzNavigate
639 void RenderFrameHostManager::BeginNavigation(
640 const FrameHostMsg_BeginNavigation_Params& params,
641 const CommonNavigationParams& common_params) {
642 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
643 switches::kEnableBrowserSideNavigation));
644 // Cleans up any state in case there's an ongoing navigation.
645 CleanUpNavigation();
646
647 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
648 // TODO(carlosk): Replace the default values with the right ones for
649 // dest_instance, dest_is_restore, dest_is_view_source_mode.
650 scoped_refptr<SiteInstanceImpl> new_instance =
651 static_cast<SiteInstanceImpl*>(GetSiteInstanceForNavigation(
652 common_params.url, nullptr, common_params.transition, false, false));
653
654 // Will keep the current RFH if its SiteInstance matches the new one from
655 // the navigation or if this is a subframe navigation. If --site-per-process
656 // is enabled the RFH is never kept when sites don't match.
657 // TODO(carlosk): do not swap processes for renderer initiated navigations
658 // (see crbug.com/440266).
659 if (current_instance == new_instance.get() ||
660 (!frame_tree_node_->IsMainFrame() &&
661 !CommandLine::ForCurrentProcess()->HasSwitch(
662 switches::kSitePerProcess))) {
663 // Make sure the current RFH is alive.
664 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) {
665 // Recreate the opener chain.
666 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
667 render_frame_host_->GetSiteInstance());
668 if (!InitRenderView(render_frame_host_->render_view_host(),
669 opener_route_id, MSG_ROUTING_NONE,
670 frame_tree_node_->IsMainFrame())) {
671 return;
carlosk 2014/12/09 07:55:43 These are the returns I'd like to eliminate but I'
clamy 2014/12/09 15:09:52 While it is fine in general to have an if-block wi
Charlie Reis 2014/12/10 22:37:45 +1 to both. (DCHECKs inside a conditional mostly
carlosk 2014/12/16 01:53:48 Finally I didn't need the if's. I simply DCHECK th
clamy 2014/12/16 15:22:48 That is not equivalent to the previous condition.
carlosk 2014/12/19 04:27:14 You are right, it is not equivalent for the Debug
672 }
673 }
674 DCHECK(current_instance->GetProcess()->HasConnection());
675 return;
676 }
677 // Speculatively create a new RFH.
clamy 2014/12/09 15:09:52 Please add a line before that comment and remove t
carlosk 2014/12/16 01:53:48 Done.
678
679 // TODO(carlosk): enable bindings check below.
680 bool success = CreateSpeculativeRenderFrameHost(
681 common_params.url, current_instance, new_instance.get(),
682 NavigationEntryImpl::kInvalidBindings);
683 if (!success)
684 return;
685 DCHECK(new_instance->GetProcess()->HasConnection());
686 }
687
688 // PlzNavigate
689 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
690 const GURL& url,
691 SiteInstance* old_instance,
692 SiteInstance* new_instance,
693 int bindings) {
694 CHECK(new_instance);
695 CHECK_NE(old_instance, new_instance);
696
697 const NavigationEntry* current_navigation_entry =
698 delegate_->GetLastCommittedNavigationEntryForRenderManager();
699 scoped_ptr<WebUIImpl> new_web_ui;
700 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, url);
701 if (!should_reuse_web_ui_)
702 new_web_ui = CreateWebUI(url, bindings);
703
704 int opener_route_id =
705 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance);
706
707 int create_render_frame_flags = 0;
708 if (frame_tree_node_->IsMainFrame())
709 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION;
710 if (delegate_->IsHidden())
711 create_render_frame_flags |= CREATE_RF_HIDDEN;
712 scoped_ptr<RenderFrameHostImpl> new_render_frame_host =
713 CreateRenderFrame(new_instance, new_web_ui.get(), opener_route_id,
714 create_render_frame_flags, nullptr);
715 if (!new_render_frame_host) {
716 return false;
717 }
718 speculative_render_frame_host_.reset(new_render_frame_host.release());
719 speculative_web_ui_.reset(new_web_ui.release());
720 return true;
721 }
722
723 // PlzNavigate
622 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( 724 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
clamy 2014/12/09 15:09:52 Please modify this function so that it does not co
carlosk 2014/12/16 01:53:48 Done.
623 const GURL& url, 725 const GURL& url,
624 ui::PageTransition transition) { 726 ui::PageTransition transition) {
625 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( 727 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
626 switches::kEnableBrowserSideNavigation)); 728 switches::kEnableBrowserSideNavigation));
627 // TODO(clamy): When we handle renderer initiated navigations, make sure not 729 // Pick the right RenderFrameHost to commit the navigation.
628 // to use a different process for subframes if --site-per-process is not
629 // enabled.
carlosk 2014/12/09 07:55:43 I removed this TODO in favor of the new ones I'm a
630 730
631 // Pick the right RenderFrameHost to commit the navigation. 731 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
632 // TODO(clamy): Replace the default values by the right ones. 732 // TODO(clamy): Replace the default values with the right ones for
633 RenderFrameHostImpl* render_frame_host = UpdateStateForNavigate( 733 // dest_instance, dest_is_restore, dest_is_view_source_mode.
634 url, NULL, transition, false, false, GlobalRequestID(), 734 scoped_refptr<SiteInstance> new_instance =
635 NavigationEntryImpl::kInvalidBindings); 735 GetSiteInstanceForNavigation(url, NULL, transition, false, false);
736
737 // Will keep the current RFH if its SiteInstance matches the new one from
738 // the navigation or if this is a subframe navigation. If --site-per-process
739 // is enabled the RFH is never kept when sites don't match.
740 // TODO(carlosk): do not swap processes for renderer initiated navigations
741 // (see crbug.com/440266).
742 if (current_instance == new_instance.get() ||
743 (!frame_tree_node_->IsMainFrame() &&
744 !CommandLine::ForCurrentProcess()->HasSwitch(
745 switches::kSitePerProcess))) {
746 CleanUpNavigation();
747 } else {
748 // If the SiteInstance for the final URL doesn't match the one from the
749 // speculatively created RenderFrameHost, create a new one using the
750 // former.
751 if (!speculative_render_frame_host_ ||
752 speculative_render_frame_host_->GetSiteInstance() !=
753 new_instance.get()) {
754 CleanUpNavigation();
755 // TODO(clamy): Replace the binding value with the right one.
756 bool success = CreateSpeculativeRenderFrameHost(
757 url, current_instance, new_instance.get(),
758 NavigationEntryImpl::kInvalidBindings);
759 CHECK(success);
760 }
761 DCHECK(speculative_render_frame_host_);
762 CommitPending();
nasko 2014/12/10 23:11:34 Why is this method calling CommitPending?
carlosk 2014/12/16 01:53:48 Because it was here that we would switch the activ
763 DCHECK(!speculative_render_frame_host_);
764 }
636 765
637 // If the renderer that needs to navigate is not live (it was just created or 766 // If the renderer that needs to navigate is not live (it was just created or
clamy 2014/12/16 15:22:48 As mentionned above this _must_ absolutely stay th
carlosk 2014/12/19 04:27:14 Acknowledged and moved it back here from DidNaviga
638 // it crashed), initialize it. 767 // it crashed), initialize it.
639 if (!render_frame_host->render_view_host()->IsRenderViewLive()) { 768 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) {
640 // Recreate the opener chain. 769 // Recreate the opener chain.
641 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( 770 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
642 render_frame_host->GetSiteInstance()); 771 render_frame_host_->GetSiteInstance());
643 if (!InitRenderView(render_frame_host->render_view_host(), 772 if (!InitRenderView(render_frame_host_->render_view_host(), opener_route_id,
644 opener_route_id, 773 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame())) {
645 MSG_ROUTING_NONE,
646 frame_tree_node_->IsMainFrame())) {
647 return NULL; 774 return NULL;
648 } 775 }
649 } 776 }
650 return render_frame_host; 777 return render_frame_host_.get();
778 }
779
780 // PlzNavigate
781 void RenderFrameHostManager::CleanUpNavigation() {
782 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
783 switches::kEnableBrowserSideNavigation));
784 if (speculative_render_frame_host_) {
785 speculative_render_frame_host_->GetProcess()->RemovePendingView();
786 DiscardUnusedFrame(speculative_render_frame_host_.Pass());
787 }
788 if (speculative_web_ui_)
789 speculative_web_ui_.reset();
790 should_reuse_web_ui_ = false;
651 } 791 }
652 792
653 void RenderFrameHostManager::Observe( 793 void RenderFrameHostManager::Observe(
654 int type, 794 int type,
655 const NotificationSource& source, 795 const NotificationSource& source,
656 const NotificationDetails& details) { 796 const NotificationDetails& details) {
657 switch (type) { 797 switch (type) {
658 case NOTIFICATION_RENDERER_PROCESS_CLOSED: 798 case NOTIFICATION_RENDERER_PROCESS_CLOSED:
659 case NOTIFICATION_RENDERER_PROCESS_CLOSING: 799 case NOTIFICATION_RENDERER_PROCESS_CLOSING:
660 RendererProcessClosing( 800 RendererProcessClosing(
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 // longer relies on swapped out RFH for the top-level frame. 1243 // longer relies on swapped out RFH for the top-level frame.
1104 if (!frame_tree_node_->IsMainFrame()) { 1244 if (!frame_tree_node_->IsMainFrame()) {
1105 CHECK(!swapped_out); 1245 CHECK(!swapped_out);
1106 } 1246 }
1107 1247
1108 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; 1248 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
1109 bool success = true; 1249 bool success = true;
1110 if (view_routing_id_ptr) 1250 if (view_routing_id_ptr)
1111 *view_routing_id_ptr = MSG_ROUTING_NONE; 1251 *view_routing_id_ptr = MSG_ROUTING_NONE;
1112 1252
1113 // We are creating a pending or swapped out RFH here. We should never create 1253 // We are creating a pending, speculative or swapped out RFH here. We should
1114 // it in the same SiteInstance as our current RFH. 1254 // never create it in the same SiteInstance as our current RFH.
1115 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); 1255 CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
1116 1256
1117 // Check if we've already created an RFH for this SiteInstance. If so, try 1257 // Check if we've already created an RFH for this SiteInstance. If so, try
1118 // to re-use the existing one, which has already been initialized. We'll 1258 // to re-use the existing one, which has already been initialized. We'll
1119 // remove it from the list of proxy hosts below if it will be active. 1259 // remove it from the list of proxy hosts below if it will be active.
1120 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1260 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1121 if (proxy && proxy->render_frame_host()) { 1261 if (proxy && proxy->render_frame_host()) {
1122 if (view_routing_id_ptr) 1262 if (view_routing_id_ptr)
1123 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); 1263 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID();
1124 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. 1264 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 proxy_hosts_.find(site_instance->GetId()); 1421 proxy_hosts_.find(site_instance->GetId());
1282 if (iter != proxy_hosts_.end()) 1422 if (iter != proxy_hosts_.end())
1283 return iter->second->GetRoutingID(); 1423 return iter->second->GetRoutingID();
1284 1424
1285 return MSG_ROUTING_NONE; 1425 return MSG_ROUTING_NONE;
1286 } 1426 }
1287 1427
1288 void RenderFrameHostManager::CommitPending() { 1428 void RenderFrameHostManager::CommitPending() {
1289 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 1429 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
1290 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1430 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1431 bool browser_side_navigation = CommandLine::ForCurrentProcess()->HasSwitch(
1432 switches::kEnableBrowserSideNavigation);
1291 // First check whether we're going to want to focus the location bar after 1433 // First check whether we're going to want to focus the location bar after
1292 // this commit. We do this now because the navigation hasn't formally 1434 // this commit. We do this now because the navigation hasn't formally
1293 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 1435 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
1294 // this triggers won't be able to figure out what's going on. 1436 // this triggers won't be able to figure out what's going on.
1295 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1437 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1296 1438
1297 // Next commit the Web UI, if any. Either replace |web_ui_| with 1439 if (!browser_side_navigation) {
1298 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 1440 DCHECK(!speculative_web_ui_);
1299 // leave |web_ui_| as is if reusing it. 1441 // Next commit the Web UI, if any. Either replace |web_ui_| with
1300 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); 1442 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
1301 if (pending_web_ui_) { 1443 // leave |web_ui_| as is if reusing it.
1302 web_ui_.reset(pending_web_ui_.release()); 1444 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
1303 } else if (!pending_and_current_web_ui_.get()) { 1445 if (pending_web_ui_) {
1304 web_ui_.reset(); 1446 web_ui_.reset(pending_web_ui_.release());
1447 } else if (!pending_and_current_web_ui_.get()) {
1448 web_ui_.reset();
1449 } else {
1450 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
1451 pending_and_current_web_ui_.reset();
1452 }
1305 } else { 1453 } else {
1306 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); 1454 // PlzNavigate
1307 pending_and_current_web_ui_.reset(); 1455 if (!should_reuse_web_ui_)
1456 web_ui_.reset(speculative_web_ui_.release());
1457 DCHECK(!speculative_web_ui_);
1308 } 1458 }
1309 1459
1310 // It's possible for the pending_render_frame_host_ to be NULL when we aren't 1460 // It's possible for the pending_render_frame_host_ to be NULL when we aren't
1311 // crossing process boundaries. If so, we just needed to handle the Web UI 1461 // crossing process boundaries. If so, we just needed to handle the Web UI
1312 // committing above and we're done. 1462 // committing above and we're done.
1313 if (!pending_render_frame_host_) { 1463 if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
1314 if (will_focus_location_bar) 1464 if (will_focus_location_bar)
1315 delegate_->SetFocusToLocationBar(false); 1465 delegate_->SetFocusToLocationBar(false);
1316 return; 1466 return;
1317 } 1467 }
1318 1468
1319 // Remember if the page was focused so we can focus the new renderer in 1469 // Remember if the page was focused so we can focus the new renderer in
1320 // that case. 1470 // that case.
1321 bool focus_render_view = !will_focus_location_bar && 1471 bool focus_render_view = !will_focus_location_bar &&
1322 render_frame_host_->render_view_host()->GetView() && 1472 render_frame_host_->render_view_host()->GetView() &&
1323 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1473 render_frame_host_->render_view_host()->GetView()->HasFocus();
1324 1474
1325 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1475 bool is_main_frame = frame_tree_node_->IsMainFrame();
1326 1476
1327 // Swap in the pending frame and make it active. Also ensure the FrameTree 1477 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
1328 // stays in sync. 1478 if (!browser_side_navigation) {
1329 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1479 DCHECK(!speculative_render_frame_host_);
1330 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1480 // Swap in the pending frame and make it active. Also ensure the FrameTree
1481 // stays in sync.
1482 old_render_frame_host =
1483 SetRenderFrameHost(pending_render_frame_host_.Pass());
1484 } else {
1485 // PlzNavigate
1486 DCHECK(speculative_render_frame_host_);
1487 old_render_frame_host =
1488 SetRenderFrameHost(speculative_render_frame_host_.Pass());
1489 }
1490
1331 if (is_main_frame) 1491 if (is_main_frame)
1332 render_frame_host_->render_view_host()->AttachToFrameTree(); 1492 render_frame_host_->render_view_host()->AttachToFrameTree();
1333 1493
1334 // The process will no longer try to exit, so we can decrement the count. 1494 // The process will no longer try to exit, so we can decrement the count.
1335 render_frame_host_->GetProcess()->RemovePendingView(); 1495 render_frame_host_->GetProcess()->RemovePendingView();
1336 1496
1337 // Show the new view (or a sad tab) if necessary. 1497 // Show the new view (or a sad tab) if necessary.
1338 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1498 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView();
1339 if (!delegate_->IsHidden() && new_rfh_has_view) { 1499 if (!delegate_->IsHidden() && new_rfh_has_view) {
1340 // In most cases, we need to show the new view. 1500 // In most cases, we need to show the new view.
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1834 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1675 SiteInstance* instance) { 1835 SiteInstance* instance) {
1676 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1836 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1677 if (iter != proxy_hosts_.end()) { 1837 if (iter != proxy_hosts_.end()) {
1678 delete iter->second; 1838 delete iter->second;
1679 proxy_hosts_.erase(iter); 1839 proxy_hosts_.erase(iter);
1680 } 1840 }
1681 } 1841 }
1682 1842
1683 } // namespace content 1843 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698