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

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: When navigating checks if the current WebUI can be reused. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/frame_host/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 RenderViewHostDelegate* render_view_delegate, 54 RenderViewHostDelegate* render_view_delegate,
55 RenderWidgetHostDelegate* render_widget_delegate, 55 RenderWidgetHostDelegate* render_widget_delegate,
56 Delegate* delegate) 56 Delegate* delegate)
57 : frame_tree_node_(frame_tree_node), 57 : frame_tree_node_(frame_tree_node),
58 delegate_(delegate), 58 delegate_(delegate),
59 cross_navigation_pending_(false), 59 cross_navigation_pending_(false),
60 render_frame_delegate_(render_frame_delegate), 60 render_frame_delegate_(render_frame_delegate),
61 render_view_delegate_(render_view_delegate), 61 render_view_delegate_(render_view_delegate),
62 render_widget_delegate_(render_widget_delegate), 62 render_widget_delegate_(render_widget_delegate),
63 interstitial_page_(NULL), 63 interstitial_page_(NULL),
64 weak_factory_(this) { 64 weak_factory_(this),
65 should_reuse_web_ui_(false) {
65 DCHECK(frame_tree_node_); 66 DCHECK(frame_tree_node_);
66 } 67 }
67 68
68 RenderFrameHostManager::~RenderFrameHostManager() { 69 RenderFrameHostManager::~RenderFrameHostManager() {
69 if (pending_render_frame_host_) 70 if (pending_render_frame_host_)
70 CancelPending(); 71 CancelPending();
71 72
73 if (CommandLine::ForCurrentProcess()->HasSwitch(
74 switches::kEnableBrowserSideNavigation)) {
75 CleanUpSpeculativeRenderFrameHost();
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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 ->render_manager() 135 ->render_manager()
130 ->current_frame_host() 136 ->current_frame_host()
131 ->GetSiteInstance() 137 ->GetSiteInstance()
132 ->GetId()); 138 ->GetId());
133 if (iter == proxy_hosts_.end()) 139 if (iter == proxy_hosts_.end())
134 return NULL; 140 return NULL;
135 141
136 return iter->second; 142 return iter->second;
137 } 143 }
138 144
139 void RenderFrameHostManager::SetPendingWebUI(const GURL& url, 145 void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) {
140 int bindings) { 146 pending_web_ui_.reset(CreateWebUI(url, bindings));
141 pending_web_ui_.reset(
142 delegate_->CreateWebUIForRenderManager(url));
143 pending_and_current_web_ui_.reset(); 147 pending_and_current_web_ui_.reset();
148 }
149
150 WebUIImpl* RenderFrameHostManager::CreateWebUI(const GURL& url, int bindings) {
151 WebUIImpl* new_web_ui = delegate_->CreateWebUIForRenderManager(url);
144 152
145 // If we have assigned (zero or more) bindings to this NavigationEntry in the 153 // If we have assigned (zero or more) bindings to this NavigationEntry in the
146 // past, make sure we're not granting it different bindings than it had 154 // past, make sure we're not granting it different bindings than it had
147 // before. If so, note it and don't give it any bindings, to avoid a 155 // before. If so, note it and don't give it any bindings, to avoid a
148 // potential privilege escalation. 156 // potential privilege escalation.
149 if (pending_web_ui_.get() && 157 if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings &&
150 bindings != NavigationEntryImpl::kInvalidBindings && 158 new_web_ui->GetBindings() != bindings) {
151 pending_web_ui_->GetBindings() != bindings) { 159 RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
152 RecordAction( 160 delete new_web_ui;
153 base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); 161 return NULL;
nasko 2014/11/19 01:00:23 nit: nullptr
carlosk 2014/11/19 17:24:29 I was in doubt about this as I understood we are c
nasko 2014/11/19 19:01:29 New code should be using current(new) conventions,
carlosk 2014/11/21 14:36:34 Acknowledged and done.
154 pending_web_ui_.reset();
155 } 162 }
163 return new_web_ui;
156 } 164 }
157 165
158 RenderFrameHostImpl* RenderFrameHostManager::Navigate( 166 RenderFrameHostImpl* RenderFrameHostManager::Navigate(
159 const NavigationEntryImpl& entry) { 167 const NavigationEntryImpl& entry) {
160 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", 168 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate",
161 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 169 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
162 // Create a pending RenderFrameHost to use for the navigation. 170 // Create a pending RenderFrameHost to use for the navigation.
163 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( 171 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate(
164 entry.GetURL(), 172 entry.GetURL(),
165 entry.site_instance(), 173 entry.site_instance(),
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 // is ok to do nothing here. 308 // is ok to do nothing here.
301 if (pending_render_frame_host_ && 309 if (pending_render_frame_host_ &&
302 pending_render_frame_host_->are_navigations_suspended()) { 310 pending_render_frame_host_->are_navigations_suspended()) {
303 pending_render_frame_host_->SetNavigationsSuspended(false, 311 pending_render_frame_host_->SetNavigationsSuspended(false,
304 proceed_time); 312 proceed_time);
305 } 313 }
306 } else { 314 } else {
307 // Current page says to cancel. 315 // Current page says to cancel.
308 CancelPending(); 316 CancelPending();
309 cross_navigation_pending_ = false; 317 cross_navigation_pending_ = false;
318 if (CommandLine::ForCurrentProcess()->HasSwitch(
clamy 2014/11/19 15:03:29 We should not receive a beforeunload ack in the ca
carlosk 2014/11/19 17:24:29 Done for the 1st one. I didn't understood what yo
carlosk 2014/11/21 14:36:33 Removed second block as discussed in person.
319 switches::kEnableBrowserSideNavigation)) {
320 CleanUpSpeculativeRenderFrameHost();
321 }
310 } 322 }
311 } else { 323 } else {
312 // Non-cross site transition means closing the entire tab. 324 // Non-cross site transition means closing the entire tab.
313 bool proceed_to_fire_unload; 325 bool proceed_to_fire_unload;
314 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time, 326 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time,
315 &proceed_to_fire_unload); 327 &proceed_to_fire_unload);
316 328
317 if (proceed_to_fire_unload) { 329 if (proceed_to_fire_unload) {
318 // If we're about to close the tab and there's a pending RFH, cancel it. 330 // If we're about to close the tab and there's a pending RFH, cancel it.
319 // Otherwise, if the navigation in the pending RFH completes before the 331 // Otherwise, if the navigation in the pending RFH completes before the
320 // close in the current RFH, we'll lose the tab close. 332 // close in the current RFH, we'll lose the tab close.
321 if (pending_render_frame_host_) { 333 if (pending_render_frame_host_) {
322 CancelPending(); 334 CancelPending();
323 cross_navigation_pending_ = false; 335 cross_navigation_pending_ = false;
336 if (CommandLine::ForCurrentProcess()->HasSwitch(
337 switches::kEnableBrowserSideNavigation)) {
338 CleanUpSpeculativeRenderFrameHost();
339 }
324 } 340 }
325 341
326 // This is not a cross-site navigation, the tab is being closed. 342 // This is not a cross-site navigation, the tab is being closed.
327 render_frame_host_->render_view_host()->ClosePage(); 343 render_frame_host_->render_view_host()->ClosePage();
328 } 344 }
329 } 345 }
330 } 346 }
331 347
332 void RenderFrameHostManager::OnCrossSiteResponse( 348 void RenderFrameHostManager::OnCrossSiteResponse(
333 RenderFrameHostImpl* pending_render_frame_host, 349 RenderFrameHostImpl* pending_render_frame_host,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 428
413 response_started_id_.reset(); 429 response_started_id_.reset();
414 } 430 }
415 431
416 void RenderFrameHostManager::ClearNavigationTransitionData() { 432 void RenderFrameHostManager::ClearNavigationTransitionData() {
417 render_frame_host_->ClearPendingTransitionRequestData(); 433 render_frame_host_->ClearPendingTransitionRequestData();
418 } 434 }
419 435
420 void RenderFrameHostManager::DidNavigateFrame( 436 void RenderFrameHostManager::DidNavigateFrame(
421 RenderFrameHostImpl* render_frame_host) { 437 RenderFrameHostImpl* render_frame_host) {
438 DCHECK(render_frame_host);
439 if (CommandLine::ForCurrentProcess()->HasSwitch(
440 switches::kEnableBrowserSideNavigation)) {
441 return;
442 }
443
422 if (!cross_navigation_pending_) { 444 if (!cross_navigation_pending_) {
423 DCHECK(!pending_render_frame_host_); 445 DCHECK(!pending_render_frame_host_);
424 446
425 // We should only hear this from our current renderer. 447 // We should only hear this from our current renderer.
426 DCHECK_EQ(render_frame_host_, render_frame_host); 448 DCHECK_EQ(render_frame_host_, render_frame_host);
427 449
428 // Even when there is no pending RVH, there may be a pending Web UI. 450 // Even when there is no pending RVH, there may be a pending Web UI.
429 if (pending_web_ui()) 451 if (pending_web_ui())
430 CommitPending(); 452 CommitPending(false);
431 return; 453 return;
432 } 454 }
433 455
434 if (render_frame_host == pending_render_frame_host_) { 456 if (render_frame_host == pending_render_frame_host_) {
435 // The pending cross-site navigation completed, so show the renderer. 457 // The pending cross-site navigation completed, so show the renderer.
436 CommitPending(); 458 CommitPending(false);
437 cross_navigation_pending_ = false; 459 cross_navigation_pending_ = false;
438 } else if (render_frame_host == render_frame_host_) { 460 } else if (render_frame_host == render_frame_host_) {
439 // A navigation in the original page has taken place. Cancel the pending 461 // A navigation in the original page has taken place. Cancel the pending
440 // one. 462 // one.
441 CancelPending(); 463 CancelPending();
442 cross_navigation_pending_ = false; 464 cross_navigation_pending_ = false;
443 } else { 465 } else {
444 // No one else should be sending us DidNavigate in this state. 466 // No one else should be sending us DidNavigate in this state.
445 DCHECK(false); 467 DCHECK(false);
446 } 468 }
447 } 469 }
448 470
471 void RenderFrameHostManager::CancelNavigation() {
472 CleanUpSpeculativeRenderFrameHost();
clamy 2014/11/19 15:03:29 Considering that CancelNavigation is now just a ca
carlosk 2014/11/19 17:24:29 My reasoning is: - From a public perspective, one
nasko 2014/11/19 19:01:29 We shouldn't be speculating about the future. Let'
carlosk 2014/11/21 14:36:34 Done. After discussing with clamy@ I left a single
473 }
474
449 void RenderFrameHostManager::DidDisownOpener( 475 void RenderFrameHostManager::DidDisownOpener(
450 RenderFrameHost* render_frame_host) { 476 RenderFrameHost* render_frame_host) {
451 // Notify all RenderFrameHosts but the one that notified us. This is necessary 477 // Notify all RenderFrameHosts but the one that notified us. This is necessary
452 // in case a process swap has occurred while the message was in flight. 478 // in case a process swap has occurred while the message was in flight.
453 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); 479 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
454 iter != proxy_hosts_.end(); 480 iter != proxy_hosts_.end();
455 ++iter) { 481 ++iter) {
456 DCHECK_NE(iter->second->GetSiteInstance(), 482 DCHECK_NE(iter->second->GetSiteInstance(),
457 current_frame_host()->GetSiteInstance()); 483 current_frame_host()->GetSiteInstance());
458 iter->second->DisownOpener(); 484 iter->second->DisownOpener();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 // We shouldn't get here for subframes, since we only swap subframes when 578 // We shouldn't get here for subframes, since we only swap subframes when
553 // --site-per-process is used. 579 // --site-per-process is used.
554 DCHECK(is_main_frame); 580 DCHECK(is_main_frame);
555 581
556 // The old RenderFrameHost will stay alive inside the proxy so that existing 582 // The old RenderFrameHost will stay alive inside the proxy so that existing
557 // JavaScript window references to it stay valid. 583 // JavaScript window references to it stay valid.
558 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); 584 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass());
559 } 585 }
560 } 586 }
561 587
588 void RenderFrameHostManager::RecycleRenderFrameHost(
589 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
590 // TODO(carlosk): this code is very similar to what can be found in
591 // SwapOutOldFrame and we should see that these are unified at some point.
592
593 // If the SiteInstance for the pending RFH is being used by others, don't
594 // delete the RFH, just swap it out and it can be reused at a later point.
595 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
596 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
597 // Any currently suspended navigations are no longer needed.
598 render_frame_host->CancelSuspendedNavigations();
599
600 RenderFrameProxyHost* proxy =
601 new RenderFrameProxyHost(site_instance, frame_tree_node_);
602 proxy_hosts_[site_instance->GetId()] = proxy;
603 render_frame_host->SwapOut(proxy);
604 if (frame_tree_node_->IsMainFrame())
605 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
606 } else {
607 // We won't be coming back, so delete this one.
608 render_frame_host.reset();
609 }
610 }
611
562 void RenderFrameHostManager::MoveToPendingDeleteHosts( 612 void RenderFrameHostManager::MoveToPendingDeleteHosts(
563 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 613 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
564 // |render_frame_host| will be deleted when its SwapOut ACK is received, or 614 // |render_frame_host| will be deleted when its SwapOut ACK is received, or
565 // when the timer times out, or when the RFHM itself is deleted (whichever 615 // when the timer times out, or when the RFHM itself is deleted (whichever
566 // comes first). 616 // comes first).
567 pending_delete_hosts_.push_back( 617 pending_delete_hosts_.push_back(
568 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); 618 linked_ptr<RenderFrameHostImpl>(render_frame_host.release()));
569 } 619 }
570 620
571 bool RenderFrameHostManager::IsPendingDeletion( 621 bool RenderFrameHostManager::IsPendingDeletion(
(...skipping 15 matching lines...) Expand all
587 return true; 637 return true;
588 } 638 }
589 } 639 }
590 return false; 640 return false;
591 } 641 }
592 642
593 void RenderFrameHostManager::ResetProxyHosts() { 643 void RenderFrameHostManager::ResetProxyHosts() {
594 STLDeleteValues(&proxy_hosts_); 644 STLDeleteValues(&proxy_hosts_);
595 } 645 }
596 646
647 void RenderFrameHostManager::BeginNavigation(
clamy 2014/11/19 15:03:29 nit: Add above // PlzNavigate
carlosk 2014/11/19 17:24:29 Done.
carlosk 2014/11/21 14:36:33 Done.
648 const FrameHostMsg_BeginNavigation_Params& params,
649 const CommonNavigationParams& common_params) {
650 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
651 switches::kEnableBrowserSideNavigation));
652 // If there is an ongoing navigation, cancel it.
653 CancelNavigation();
654
655 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
656 // TODO(carlosk): Replace the default values by the right ones.
657 scoped_refptr<SiteInstanceImpl> new_instance =
658 static_cast<SiteInstanceImpl*>(GetSiteInstanceForNavigation(
659 common_params.url, NULL, common_params.transition, false, false));
660
661 if (new_instance.get() != current_instance) {
662 // Navigating to a new SiteInstance -> speculatively create a new RFH
clamy 2014/11/19 15:03:29 nit: add a . at the end of the sentence.
carlosk 2014/11/19 17:24:29 Done.
carlosk 2014/11/21 14:36:34 Done.
663
664 // TODO(carlosk): what the TRACE_EVENT_INSTANT2 for New SiteInstance found
665 // in UpdateStateForNavigate be copied here?
nasko 2014/11/19 01:00:23 I think we discussed this in the sync-up meeting.
carlosk 2014/11/19 17:24:29 Yes, and I will. :) I rephrased the TODO to make
carlosk 2014/11/21 14:36:33 It was indeed a "bad" TODO so I removed it for now
666
667 // TODO(carlosk): enable bindings check below
clamy 2014/11/19 15:03:29 nit: add a . at the end of the comment.
carlosk 2014/11/19 17:24:29 Done.
carlosk 2014/11/21 14:36:33 Done.
668 bool success = CreateSpeculativeRenderFrameHost(
669 common_params.url, current_instance, new_instance.get(),
670 NavigationEntryImpl::kInvalidBindings);
671 if (!success)
672 return;
673 } else {
674 // Navigating to the same SiteInstance -> make sure the current RFH is alive
clamy 2014/11/19 15:03:29 nit: add a . at the end of the comment.
carlosk 2014/11/19 17:24:29 Done.
carlosk 2014/11/21 14:36:34 Done.
675 DCHECK(render_frame_host_->GetSiteInstance() == new_instance);
676 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) {
677 // Recreate the opener chain.
678 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
679 render_frame_host_->GetSiteInstance());
680 if (!InitRenderView(render_frame_host_->render_view_host(),
681 opener_route_id, MSG_ROUTING_NONE,
682 frame_tree_node_->IsMainFrame())) {
683 return;
684 }
685 }
686 }
687 DCHECK(new_instance->GetProcess()->HasConnection());
688 DCHECK(new_instance->GetProcess()->GetBrowserContext());
689 }
690
691 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
clamy 2014/11/19 15:03:29 nit: add above // PlzNavigate
carlosk 2014/11/19 17:24:29 Done.
carlosk 2014/11/21 14:36:34 Done.
692 const GURL& url,
693 SiteInstance* old_instance,
694 SiteInstance* new_instance,
695 int bindings) {
696 CHECK(new_instance);
697 CHECK_NE(old_instance, new_instance);
698
699 const NavigationEntry* current_navigation_entry =
700 delegate_->GetLastCommittedNavigationEntryForRenderManager();
701 scoped_ptr<WebUIImpl> new_web_ui;
702 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, url);
703 if (!should_reuse_web_ui_)
704 new_web_ui.reset(CreateWebUI(url, bindings));
705
706 int opener_route_id =
707 GetOpenerRouteIDForNewRenderView(old_instance, new_instance);
708
709 scoped_ptr<RenderFrameHostImpl> new_render_frame_host =
710 CreateRenderFrameInternal(new_instance, opener_route_id, false,
711 frame_tree_node_->IsMainFrame(),
712 delegate_->IsHidden(), new_web_ui.get(), NULL);
713 if (!new_render_frame_host) {
714 return false;
715 }
716 speculative_render_frame_host_.reset(new_render_frame_host.release());
717 speculative_web_ui_.reset(new_web_ui.release());
718 return true;
719 }
720
597 // PlzNavigate 721 // PlzNavigate
598 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( 722 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
599 const GURL& url, 723 const GURL& url,
600 ui::PageTransition transition) { 724 ui::PageTransition transition) {
601 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( 725 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
602 switches::kEnableBrowserSideNavigation)); 726 switches::kEnableBrowserSideNavigation));
603 // TODO(clamy): When we handle renderer initiated navigations, make sure not 727 // TODO(clamy): When we handle renderer initiated navigations, make sure not
604 // to use a different process for subframes if --site-per-process is not 728 // to use a different process for subframes if --site-per-process is not
605 // enabled. 729 // enabled.
606 730
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 bool current_is_view_source_mode = current_entry ? 906 bool current_is_view_source_mode = current_entry ?
783 current_entry->IsViewSourceMode() : dest_is_view_source_mode; 907 current_entry->IsViewSourceMode() : dest_is_view_source_mode;
784 bool force_swap = ShouldSwapBrowsingInstancesForNavigation( 908 bool force_swap = ShouldSwapBrowsingInstancesForNavigation(
785 current_effective_url, 909 current_effective_url,
786 current_is_view_source_mode, 910 current_is_view_source_mode,
787 dest_instance, 911 dest_instance,
788 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), 912 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
789 dest_is_view_source_mode); 913 dest_is_view_source_mode);
790 if (ShouldTransitionCrossSite() || force_swap) { 914 if (ShouldTransitionCrossSite() || force_swap) {
791 new_instance = GetSiteInstanceForURL( 915 new_instance = GetSiteInstanceForURL(
792 dest_url, 916 dest_url, dest_instance, dest_transition, dest_is_restore,
nasko 2014/11/19 01:00:23 No need to change format of code you aren't modify
carlosk 2014/11/19 17:24:29 Reverted. This was a consequence of my previous c
carlosk 2014/11/21 14:36:33 Done.
793 dest_instance, 917 dest_is_view_source_mode, current_instance, force_swap);
794 dest_transition,
795 dest_is_restore,
796 dest_is_view_source_mode,
797 current_instance,
798 force_swap);
799 } 918 }
800 919
801 // If force_swap is true, we must use a different SiteInstance. If we didn't, 920 // If force_swap is true, we must use a different SiteInstance. If we didn't,
802 // we would have two RenderFrameHosts in the same SiteInstance and the same 921 // we would have two RenderFrameHosts in the same SiteInstance and the same
803 // frame, resulting in page_id conflicts for their NavigationEntries. 922 // frame, resulting in page_id conflicts for their NavigationEntries.
804 if (force_swap) 923 if (force_swap)
805 CHECK_NE(new_instance, current_instance); 924 CHECK_NE(new_instance, current_instance);
806 return new_instance; 925 return new_instance;
807 } 926 }
808 927
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 // practice.) 1108 // practice.)
990 if (current_entry) 1109 if (current_entry)
991 return current_entry->GetURL(); 1110 return current_entry->GetURL();
992 return current_instance->GetSiteURL(); 1111 return current_instance->GetSiteURL();
993 } 1112 }
994 1113
995 void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance( 1114 void RenderFrameHostManager::CreateRenderFrameHostForNewSiteInstance(
996 SiteInstance* old_instance, 1115 SiteInstance* old_instance,
997 SiteInstance* new_instance, 1116 SiteInstance* new_instance,
998 bool is_main_frame) { 1117 bool is_main_frame) {
999 // Ensure that we have created RFHs for the new RFH's opener chain if 1118 int opener_route_id =
1000 // we are staying in the same BrowsingInstance. This allows the new RFH 1119 GetOpenerRouteIDForNewRenderView(old_instance, new_instance);
1001 // to send cross-process script calls to its opener(s). 1120 // TODO(carlosk): does this "earlier" call for CancelPending affects anything?
1121 // It used to happen inside the creation method iff the new RFH was
clamy 2014/11/19 15:03:29 nit: s/iff/if
carlosk 2014/11/19 17:24:29 This is not a typo: iff == if and only if (http://
1122 // successfully created.
1123 if (pending_render_frame_host_)
1124 CancelPending();
nasko 2014/11/19 01:00:23 Why is this needed?
carlosk 2014/11/19 17:24:29 See lines 1143-1144 from the previous version: thi
1125 // Create a non-swapped-out RFH with the given opener.
1126 pending_render_frame_host_ = CreateRenderFrameInternal(
1127 new_instance, opener_route_id, false, is_main_frame,
1128 delegate_->IsHidden(), pending_web_ui(), NULL);
1129 }
1130
1131 int RenderFrameHostManager::GetOpenerRouteIDForNewRenderView(
nasko 2014/11/19 01:00:23 This method does a lot more than GetOpenerRouteID.
carlosk 2014/11/19 17:24:29 Agreed. I extracted the behavior I wanted to share
nasko 2014/11/19 19:01:29 For one, you lost a very important comment that wa
carlosk 2014/11/21 14:36:33 I didn't lose it. As that comment seemed to descri
1132 SiteInstance* old_instance,
1133 SiteInstance* new_instance) {
1002 int opener_route_id = MSG_ROUTING_NONE; 1134 int opener_route_id = MSG_ROUTING_NONE;
1003 if (new_instance->IsRelatedSiteInstance(old_instance)) { 1135 if (new_instance->IsRelatedSiteInstance(old_instance)) {
1004 opener_route_id = 1136 opener_route_id =
1005 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance); 1137 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
1006 if (CommandLine::ForCurrentProcess()->HasSwitch( 1138 if (CommandLine::ForCurrentProcess()->HasSwitch(
1007 switches::kSitePerProcess)) { 1139 switches::kSitePerProcess)) {
1008 // Ensure that the frame tree has RenderFrameProxyHosts for the new 1140 // Ensure that the frame tree has RenderFrameProxyHosts for the new
1009 // SiteInstance in all nodes except the current one. 1141 // SiteInstance in all nodes except the current one.
1010 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance( 1142 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance(
1011 frame_tree_node_, new_instance); 1143 frame_tree_node_, new_instance);
1012 } 1144 }
1013 } 1145 }
1014 1146 return opener_route_id;
1015 // Create a non-swapped-out RFH with the given opener.
1016 int route_id = CreateRenderFrame(
1017 new_instance, opener_route_id, false, is_main_frame,
1018 delegate_->IsHidden());
1019 if (route_id == MSG_ROUTING_NONE) {
1020 pending_render_frame_host_.reset();
1021 return;
1022 }
1023 } 1147 }
1024 1148
1025 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( 1149 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
1026 SiteInstance* site_instance, 1150 SiteInstance* site_instance,
1027 int view_routing_id, 1151 int view_routing_id,
1028 int frame_routing_id, 1152 int frame_routing_id,
1029 bool swapped_out, 1153 bool swapped_out,
1030 bool hidden) { 1154 bool hidden) {
1031 if (frame_routing_id == MSG_ROUTING_NONE) 1155 if (frame_routing_id == MSG_ROUTING_NONE)
1032 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); 1156 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
(...skipping 14 matching lines...) Expand all
1047 scoped_ptr<RenderFrameHostImpl> render_frame_host = 1171 scoped_ptr<RenderFrameHostImpl> render_frame_host =
1048 make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host, 1172 make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host,
1049 render_frame_delegate_, 1173 render_frame_delegate_,
1050 frame_tree, 1174 frame_tree,
1051 frame_tree_node_, 1175 frame_tree_node_,
1052 frame_routing_id, 1176 frame_routing_id,
1053 swapped_out).release()); 1177 swapped_out).release());
1054 return render_frame_host.Pass(); 1178 return render_frame_host.Pass();
1055 } 1179 }
1056 1180
1057 int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, 1181 int RenderFrameHostManager::CreateSwappedOutHiddenRenderFrame(
nasko 2014/11/19 01:00:24 I don't see a clear advantage to having this wrapp
carlosk 2014/11/19 17:24:29 Calls made outside of RFHM are all swapped-out and
nasko 2014/11/19 19:01:29 While I agree this is in general a very good goal
carlosk 2014/11/21 14:36:33 OK, I reverted to having one single public method.
1058 int opener_route_id, 1182 SiteInstance* instance,
1059 bool swapped_out, 1183 int opener_route_id,
1060 bool for_main_frame_navigation, 1184 bool for_main_frame_navigation) {
1061 bool hidden) { 1185 int routing_id = MSG_ROUTING_NONE;
1186 CreateRenderFrameInternal(instance, opener_route_id, true,
1187 for_main_frame_navigation, true, NULL, &routing_id);
1188 return routing_id;
1189 }
1190
1191 scoped_ptr<RenderFrameHostImpl>
1192 RenderFrameHostManager::CreateRenderFrameInternal(
clamy 2014/11/19 15:03:29 Note: In theory, methods in the .cc file should ha
carlosk 2014/11/19 17:24:28 Acknowledged and done. From now on I will follow t
nasko 2014/11/19 19:01:29 You can still keep them together, just reorder the
carlosk 2014/11/21 14:36:33 I couldn't really as one method was public and the
1193 SiteInstance* instance,
1194 int opener_route_id,
1195 bool swapped_out,
1196 bool for_main_frame_navigation,
1197 bool hidden,
1198 const WebUIImpl* web_ui,
1199 int* routing_id_ptr) {
1062 CHECK(instance); 1200 CHECK(instance);
1063 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden. 1201 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden.
1064 1202
1065 // TODO(nasko): Remove the following CHECK once cross-site navigation no 1203 // TODO(nasko): Remove the following CHECK once cross-site navigation no
1066 // longer relies on swapped out RFH for the top-level frame. 1204 // longer relies on swapped out RFH for the top-level frame.
1067 if (!frame_tree_node_->IsMainFrame()) { 1205 if (!frame_tree_node_->IsMainFrame()) {
1068 CHECK(!swapped_out); 1206 CHECK(!swapped_out);
1069 } 1207 }
1070 1208
1071 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; 1209 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
1072 RenderFrameHostImpl* frame_to_announce = NULL; 1210 bool success = true;
1073 int routing_id = MSG_ROUTING_NONE; 1211 if (routing_id_ptr)
1212 *routing_id_ptr = MSG_ROUTING_NONE;
1074 1213
1075 // We are creating a pending or swapped out RFH here. We should never create 1214 // We are creating a pending, speculative or swapped out RFH here. We should
1076 // it in the same SiteInstance as our current RFH. 1215 // never create it in the same SiteInstance as our current RFH.
1077 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); 1216 CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
1078 1217
1079 // Check if we've already created an RFH for this SiteInstance. If so, try 1218 // Check if we've already created an RFH for this SiteInstance. If so, try
1080 // to re-use the existing one, which has already been initialized. We'll 1219 // to re-use the existing one, which has already been initialized. We'll
1081 // remove it from the list of proxy hosts below if it will be active. 1220 // remove it from the list of proxy hosts below if it will be active.
1082 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1221 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1083
1084 if (proxy && proxy->render_frame_host()) { 1222 if (proxy && proxy->render_frame_host()) {
1085 routing_id = proxy->GetRenderViewHost()->GetRoutingID(); 1223 if (routing_id_ptr)
1224 *routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID();
1086 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. 1225 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
1087 // Prevent the process from exiting while we're trying to use it. 1226 // Prevent the process from exiting while we're trying to use it.
1088 if (!swapped_out) { 1227 if (!swapped_out) {
1089 new_render_frame_host = proxy->PassFrameHostOwnership(); 1228 new_render_frame_host = proxy->PassFrameHostOwnership();
1090 new_render_frame_host->GetProcess()->AddPendingView(); 1229 new_render_frame_host->GetProcess()->AddPendingView();
1091 1230
1092 proxy_hosts_.erase(instance->GetId()); 1231 proxy_hosts_.erase(instance->GetId());
1093 delete proxy; 1232 delete proxy;
1094 1233
1095 // When a new render view is created by the renderer, the new WebContents 1234 // When a new render view is created by the renderer, the new WebContents
1096 // gets a RenderViewHost in the SiteInstance of its opener WebContents. 1235 // gets a RenderViewHost in the SiteInstance of its opener WebContents.
1097 // If not used in the first navigation, this RVH is swapped out and is not 1236 // If not used in the first navigation, this RVH is swapped out and is not
1098 // granted bindings, so we may need to grant them when swapping it in. 1237 // granted bindings, so we may need to grant them when swapping it in.
1099 if (pending_web_ui() && 1238 if (web_ui && !new_render_frame_host->GetProcess()->IsIsolatedGuest()) {
1100 !new_render_frame_host->GetProcess()->IsIsolatedGuest()) { 1239 int required_bindings = web_ui->GetBindings();
1101 int required_bindings = pending_web_ui()->GetBindings(); 1240 RenderViewHost* render_view_host =
1102 RenderViewHost* rvh = new_render_frame_host->render_view_host(); 1241 new_render_frame_host->render_view_host();
1103 if ((rvh->GetEnabledBindings() & required_bindings) != 1242 if ((render_view_host->GetEnabledBindings() & required_bindings) !=
1104 required_bindings) { 1243 required_bindings) {
1105 rvh->AllowBindings(required_bindings); 1244 render_view_host->AllowBindings(required_bindings);
1106 } 1245 }
1107 } 1246 }
1108 } 1247 }
1109 } else { 1248 } else {
1110 // Create a new RenderFrameHost if we don't find an existing one. 1249 // Create a new RenderFrameHost if we don't find an existing one.
1111 new_render_frame_host = CreateRenderFrameHost( 1250 new_render_frame_host = CreateRenderFrameHost(
1112 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden); 1251 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden);
1113 RenderViewHostImpl* render_view_host = 1252 RenderViewHostImpl* render_view_host =
1114 new_render_frame_host->render_view_host(); 1253 new_render_frame_host->render_view_host();
1115 int proxy_routing_id = MSG_ROUTING_NONE; 1254 int proxy_routing_id = MSG_ROUTING_NONE;
1116 1255
1117 // Prevent the process from exiting while we're trying to navigate in it. 1256 // Prevent the process from exiting while we're trying to navigate in it.
1118 // Otherwise, if the new RFH is swapped out already, store it. 1257 // Otherwise, if the new RFH is swapped out already, store it.
1119 if (!swapped_out) { 1258 if (!swapped_out) {
1120 new_render_frame_host->GetProcess()->AddPendingView(); 1259 new_render_frame_host->GetProcess()->AddPendingView();
1121 } else { 1260 } else {
1122 proxy = new RenderFrameProxyHost( 1261 proxy = new RenderFrameProxyHost(
1123 new_render_frame_host->GetSiteInstance(), frame_tree_node_); 1262 new_render_frame_host->GetSiteInstance(), frame_tree_node_);
1124 proxy_hosts_[instance->GetId()] = proxy; 1263 proxy_hosts_[instance->GetId()] = proxy;
1125 proxy_routing_id = proxy->GetRoutingID(); 1264 proxy_routing_id = proxy->GetRoutingID();
1126 if (frame_tree_node_->IsMainFrame()) 1265 if (frame_tree_node_->IsMainFrame())
1127 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); 1266 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass());
1128 } 1267 }
1129 1268
1130 bool success = InitRenderView(render_view_host, 1269 success = InitRenderView(render_view_host, opener_route_id,
1131 opener_route_id, 1270 proxy_routing_id, for_main_frame_navigation);
1132 proxy_routing_id,
1133 for_main_frame_navigation);
1134 if (success) { 1271 if (success) {
1135 if (frame_tree_node_->IsMainFrame()) { 1272 if (frame_tree_node_->IsMainFrame()) {
1136 // Don't show the main frame's view until we get a DidNavigate from it. 1273 // Don't show the main frame's view until we get a DidNavigate from it.
1137 render_view_host->GetView()->Hide(); 1274 render_view_host->GetView()->Hide();
1138 } else if (!swapped_out) { 1275 } else if (!swapped_out) {
1139 // Init the RFH, so a RenderFrame is created in the renderer. 1276 // Init the RFH, so a RenderFrame is created in the renderer.
1140 DCHECK(new_render_frame_host.get()); 1277 DCHECK(new_render_frame_host.get());
1141 success = InitRenderFrame(new_render_frame_host.get()); 1278 success = InitRenderFrame(new_render_frame_host.get());
1142 } 1279 }
1143 } else if (!swapped_out && pending_render_frame_host_) { 1280 if (success) {
1144 CancelPending(); 1281 if (routing_id_ptr)
1282 *routing_id_ptr = render_view_host->GetRoutingID();
1283 // If a brand new RFH was created, announce it to observers.
1284 // TODO(carlosk): verify there's no problem that now this RFH will only
1285 // be set as the pending one *after* this delegate call (used to be
1286 // before).
1287 if (new_render_frame_host) {
1288 render_frame_delegate_->RenderFrameCreated(
1289 new_render_frame_host.get());
1290 }
1291 }
1145 } 1292 }
1146 routing_id = render_view_host->GetRoutingID();
1147 frame_to_announce = new_render_frame_host.get();
1148 } 1293 }
1149 1294
1150 // Use this as our new pending RFH if it isn't swapped out. 1295 // Returns the new RFH if it isn't swapped out.
1151 if (!swapped_out) 1296 if (success && !swapped_out) {
1152 pending_render_frame_host_ = new_render_frame_host.Pass(); 1297 DCHECK(new_render_frame_host->GetSiteInstance() == instance);
1153 1298 return new_render_frame_host.Pass();
1154 // If a brand new RFH was created, announce it to observers. 1299 }
1155 if (frame_to_announce) 1300 return NULL;
1156 render_frame_delegate_->RenderFrameCreated(frame_to_announce);
1157
1158 return routing_id;
1159 } 1301 }
1160 1302
1161 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { 1303 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
1162 // A RenderFrameProxyHost should never be created in the same SiteInstance as 1304 // A RenderFrameProxyHost should never be created in the same SiteInstance as
1163 // the current RFH. 1305 // the current RFH.
1164 CHECK(instance); 1306 CHECK(instance);
1165 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); 1307 CHECK_NE(instance, render_frame_host_->GetSiteInstance());
1166 1308
1167 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1309 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1168 if (proxy) 1310 if (proxy)
(...skipping 21 matching lines...) Expand all
1190 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 1332 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
1191 } else { 1333 } else {
1192 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 1334 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
1193 // process unless it's swapped out. 1335 // process unless it's swapped out.
1194 if (render_view_host->is_active()) { 1336 if (render_view_host->is_active()) {
1195 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1337 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1196 render_view_host->GetProcess()->GetID())); 1338 render_view_host->GetProcess()->GetID()));
1197 } 1339 }
1198 } 1340 }
1199 1341
1200 return delegate_->CreateRenderViewForRenderManager(render_view_host, 1342 return delegate_->CreateRenderViewForRenderManager(
clamy 2014/11/19 15:03:29 You don't need to change formating for code that i
carlosk 2014/11/19 17:24:29 Reverted. Same reason as before...
carlosk 2014/11/21 14:36:33 Done.
1201 opener_route_id, 1343 render_view_host, opener_route_id, proxy_routing_id,
1202 proxy_routing_id, 1344 for_main_frame_navigation);
1203 for_main_frame_navigation);
1204 } 1345 }
1205 1346
1206 bool RenderFrameHostManager::InitRenderFrame( 1347 bool RenderFrameHostManager::InitRenderFrame(
1207 RenderFrameHostImpl* render_frame_host) { 1348 RenderFrameHostImpl* render_frame_host) {
1208 if (render_frame_host->IsRenderFrameLive()) 1349 if (render_frame_host->IsRenderFrameLive())
1209 return true; 1350 return true;
1210 1351
1211 int parent_routing_id = MSG_ROUTING_NONE; 1352 int parent_routing_id = MSG_ROUTING_NONE;
1212 int proxy_routing_id = MSG_ROUTING_NONE; 1353 int proxy_routing_id = MSG_ROUTING_NONE;
1213 if (frame_tree_node_->parent()) { 1354 if (frame_tree_node_->parent()) {
(...skipping 25 matching lines...) Expand all
1239 return render_frame_host_->GetRoutingID(); 1380 return render_frame_host_->GetRoutingID();
1240 1381
1241 RenderFrameProxyHostMap::iterator iter = 1382 RenderFrameProxyHostMap::iterator iter =
1242 proxy_hosts_.find(site_instance->GetId()); 1383 proxy_hosts_.find(site_instance->GetId());
1243 if (iter != proxy_hosts_.end()) 1384 if (iter != proxy_hosts_.end())
1244 return iter->second->GetRoutingID(); 1385 return iter->second->GetRoutingID();
1245 1386
1246 return MSG_ROUTING_NONE; 1387 return MSG_ROUTING_NONE;
1247 } 1388 }
1248 1389
1249 void RenderFrameHostManager::CommitPending() { 1390 void RenderFrameHostManager::CommitPending(bool use_speculative_rfh) {
1250 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 1391 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
1251 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1392 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1393 // If use_speculative_rfh then kEnableBrowserSideNavigation must be enabled.
1394 CHECK(!use_speculative_rfh ||
1395 CommandLine::ForCurrentProcess()->HasSwitch(
1396 switches::kEnableBrowserSideNavigation));
1397
1252 // First check whether we're going to want to focus the location bar after 1398 // First check whether we're going to want to focus the location bar after
1253 // this commit. We do this now because the navigation hasn't formally 1399 // this commit. We do this now because the navigation hasn't formally
1254 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 1400 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
1255 // this triggers won't be able to figure out what's going on. 1401 // this triggers won't be able to figure out what's going on.
1256 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1402 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1257 1403
1258 // Next commit the Web UI, if any. Either replace |web_ui_| with 1404 if (!use_speculative_rfh) {
1259 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 1405 DCHECK(!speculative_web_ui_);
1260 // leave |web_ui_| as is if reusing it. 1406 // Next commit the Web UI, if any. Either replace |web_ui_| with
1261 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); 1407 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
1262 if (pending_web_ui_) { 1408 // leave |web_ui_| as is if reusing it.
1263 web_ui_.reset(pending_web_ui_.release()); 1409 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
1264 } else if (!pending_and_current_web_ui_.get()) { 1410 if (pending_web_ui_) {
1265 web_ui_.reset(); 1411 web_ui_.reset(pending_web_ui_.release());
1412 } else if (!pending_and_current_web_ui_.get()) {
1413 web_ui_.reset();
1414 } else {
1415 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
1416 pending_and_current_web_ui_.reset();
1417 }
1266 } else { 1418 } else {
1267 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); 1419 if (!should_reuse_web_ui_)
1268 pending_and_current_web_ui_.reset(); 1420 web_ui_.reset(speculative_web_ui_.release());
1269 } 1421 }
1270 1422
1271 // It's possible for the pending_render_frame_host_ to be NULL when we aren't 1423 // It's possible for the pending_render_frame_host_ to be NULL when we aren't
1272 // crossing process boundaries. If so, we just needed to handle the Web UI 1424 // crossing process boundaries. If so, we just needed to handle the Web UI
1273 // committing above and we're done. 1425 // committing above and we're done.
1274 if (!pending_render_frame_host_) { 1426 if (!pending_render_frame_host_ && !use_speculative_rfh) {
1275 if (will_focus_location_bar) 1427 if (will_focus_location_bar)
1276 delegate_->SetFocusToLocationBar(false); 1428 delegate_->SetFocusToLocationBar(false);
1277 return; 1429 return;
1278 } 1430 }
1279 1431
1280 // Remember if the page was focused so we can focus the new renderer in 1432 // Remember if the page was focused so we can focus the new renderer in
1281 // that case. 1433 // that case.
1282 bool focus_render_view = !will_focus_location_bar && 1434 bool focus_render_view = !will_focus_location_bar &&
1283 render_frame_host_->render_view_host()->GetView() && 1435 render_frame_host_->render_view_host()->GetView() &&
1284 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1436 render_frame_host_->render_view_host()->GetView()->HasFocus();
1285 1437
1286 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1438 bool is_main_frame = frame_tree_node_->IsMainFrame();
1287 1439
1288 // Swap in the pending frame and make it active. Also ensure the FrameTree 1440 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
1289 // stays in sync. 1441 if (!use_speculative_rfh) {
1290 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1442 DCHECK(!speculative_render_frame_host_);
1291 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1443 // Swap in the pending frame and make it active. Also ensure the FrameTree
1444 // stays in sync.
1445 old_render_frame_host =
1446 SetRenderFrameHost(pending_render_frame_host_.Pass());
1447 } else {
1448 DCHECK(speculative_render_frame_host_);
1449 old_render_frame_host =
1450 SetRenderFrameHost(speculative_render_frame_host_.Pass());
1451 }
1452
1292 if (is_main_frame) 1453 if (is_main_frame)
1293 render_frame_host_->render_view_host()->AttachToFrameTree(); 1454 render_frame_host_->render_view_host()->AttachToFrameTree();
1294 1455
1295 // The process will no longer try to exit, so we can decrement the count. 1456 // The process will no longer try to exit, so we can decrement the count.
1296 render_frame_host_->GetProcess()->RemovePendingView(); 1457 render_frame_host_->GetProcess()->RemovePendingView();
1297 1458
1298 // Show the new view (or a sad tab) if necessary. 1459 // Show the new view (or a sad tab) if necessary.
1299 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1460 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView();
1300 if (!delegate_->IsHidden() && new_rfh_has_view) { 1461 if (!delegate_->IsHidden() && new_rfh_has_view) {
1301 // In most cases, we need to show the new view. 1462 // In most cases, we need to show the new view.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 if (cross_navigation_pending_) { 1571 if (cross_navigation_pending_) {
1411 if (pending_render_frame_host_) 1572 if (pending_render_frame_host_)
1412 CancelPending(); 1573 CancelPending();
1413 cross_navigation_pending_ = false; 1574 cross_navigation_pending_ = false;
1414 } 1575 }
1415 1576
1416 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1577 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1417 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( 1578 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
1418 url, instance, transition, is_restore, is_view_source_mode); 1579 url, instance, transition, is_restore, is_view_source_mode);
1419 1580
1581 if (CommandLine::ForCurrentProcess()->HasSwitch(
1582 switches::kEnableBrowserSideNavigation)) {
1583 if (current_instance == new_instance.get()) {
1584 CleanUpSpeculativeRenderFrameHost();
1585 } else {
1586 // If the SiteInstance for the final URL doesn't match the one form the
1587 // speculatively created RenderFrameHost, create a new one using the
1588 // former.
1589 if (!speculative_render_frame_host_ ||
1590 speculative_render_frame_host_->GetSiteInstance() !=
1591 new_instance.get()) {
1592 CleanUpSpeculativeRenderFrameHost();
1593 // TODO(carlosk): Should rename this method and the speculative members
1594 // because in this case they are not speculative. Suggestions are
1595 // very welcome!
1596 bool success = CreateSpeculativeRenderFrameHost(
1597 url, current_instance, new_instance.get(), bindings);
1598 if (!success)
1599 return NULL;
1600 }
1601 DCHECK(speculative_render_frame_host_);
1602 CommitPending(true);
1603 DCHECK(!speculative_render_frame_host_);
1604 }
1605 return render_frame_host_.get();
1606 }
1607
1420 const NavigationEntry* current_entry = 1608 const NavigationEntry* current_entry =
1421 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 1609 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1422 1610
1423 if (new_instance.get() != current_instance) { 1611 if (new_instance.get() != current_instance) {
1424 TRACE_EVENT_INSTANT2( 1612 TRACE_EVENT_INSTANT2(
1425 "navigation", 1613 "navigation",
1426 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 1614 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
1427 TRACE_EVENT_SCOPE_THREAD, 1615 TRACE_EVENT_SCOPE_THREAD,
1428 "current_instance id", current_instance->GetId(), 1616 "current_instance id", current_instance->GetId(),
1429 "new_instance id", new_instance->GetId()); 1617 "new_instance id", new_instance->GetId());
(...skipping 15 matching lines...) Expand all
1445 } 1633 }
1446 1634
1447 // Check if our current RFH is live before we set up a transition. 1635 // Check if our current RFH is live before we set up a transition.
1448 if (!render_frame_host_->IsRenderFrameLive()) { 1636 if (!render_frame_host_->IsRenderFrameLive()) {
1449 if (!cross_navigation_pending_) { 1637 if (!cross_navigation_pending_) {
1450 // The current RFH is not live. There's no reason to sit around with a 1638 // The current RFH is not live. There's no reason to sit around with a
1451 // sad tab or a newly created RFH while we wait for the pending RFH to 1639 // sad tab or a newly created RFH while we wait for the pending RFH to
1452 // navigate. Just switch to the pending RFH now and go back to non 1640 // navigate. Just switch to the pending RFH now and go back to non
1453 // cross-navigating (Note that we don't care about on{before}unload 1641 // cross-navigating (Note that we don't care about on{before}unload
1454 // handlers if the current RFH isn't live.) 1642 // handlers if the current RFH isn't live.)
1455 CommitPending(); 1643 CommitPending(false);
1456 return render_frame_host_.get(); 1644 return render_frame_host_.get();
1457 } else { 1645 } else {
1458 NOTREACHED(); 1646 NOTREACHED();
1459 return render_frame_host_.get(); 1647 return render_frame_host_.get();
1460 } 1648 }
1461 } 1649 }
1462 // Otherwise, it's safe to treat this as a pending cross-site transition. 1650 // Otherwise, it's safe to treat this as a pending cross-site transition.
1463 1651
1464 // We now have a pending RFH. 1652 // We now have a pending RFH.
1465 DCHECK(!cross_navigation_pending_); 1653 DCHECK(!cross_navigation_pending_);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = 1738 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
1551 pending_render_frame_host_.Pass(); 1739 pending_render_frame_host_.Pass();
1552 1740
1553 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( 1741 RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
1554 pending_render_frame_host->render_view_host(), 1742 pending_render_frame_host->render_view_host(),
1555 render_frame_host_->render_view_host()); 1743 render_frame_host_->render_view_host());
1556 1744
1557 // We no longer need to prevent the process from exiting. 1745 // We no longer need to prevent the process from exiting.
1558 pending_render_frame_host->GetProcess()->RemovePendingView(); 1746 pending_render_frame_host->GetProcess()->RemovePendingView();
1559 1747
1560 // If the SiteInstance for the pending RFH is being used by others, don't 1748 RecycleRenderFrameHost(pending_render_frame_host.Pass());
nasko 2014/11/19 19:01:29 Recycle sounds like we will like to use it again a
carlosk 2014/11/21 14:36:34 Done. Renamed to DiscardRenderFrameHost. WDYT?
1561 // delete the RFH, just swap it out and it can be reused at a later point.
1562 SiteInstanceImpl* site_instance =
1563 pending_render_frame_host->GetSiteInstance();
1564 if (site_instance->active_frame_count() > 1) {
1565 // Any currently suspended navigations are no longer needed.
1566 pending_render_frame_host->CancelSuspendedNavigations();
1567
1568 RenderFrameProxyHost* proxy =
1569 new RenderFrameProxyHost(site_instance, frame_tree_node_);
1570 proxy_hosts_[site_instance->GetId()] = proxy;
1571 pending_render_frame_host->SwapOut(proxy);
1572 if (frame_tree_node_->IsMainFrame())
1573 proxy->TakeFrameHostOwnership(pending_render_frame_host.Pass());
1574 } else {
1575 // We won't be coming back, so delete this one.
1576 pending_render_frame_host.reset();
1577 }
1578 1749
1579 pending_web_ui_.reset(); 1750 pending_web_ui_.reset();
1580 pending_and_current_web_ui_.reset(); 1751 pending_and_current_web_ui_.reset();
1581 } 1752 }
1582 1753
1754 void RenderFrameHostManager::CleanUpSpeculativeRenderFrameHost() {
1755 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
1756 switches::kEnableBrowserSideNavigation));
1757 if (speculative_render_frame_host_) {
1758 speculative_render_frame_host_->GetProcess()->RemovePendingView();
1759 RecycleRenderFrameHost(speculative_render_frame_host_.Pass());
1760 }
1761 if (speculative_web_ui_)
1762 speculative_web_ui_.reset();
1763 }
1764
1583 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( 1765 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
1584 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 1766 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
1585 // Swap the two. 1767 // Swap the two.
1586 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1768 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
1587 render_frame_host_.Pass(); 1769 render_frame_host_.Pass();
1588 render_frame_host_ = render_frame_host.Pass(); 1770 render_frame_host_ = render_frame_host.Pass();
1589 1771
1590 if (frame_tree_node_->IsMainFrame()) { 1772 if (frame_tree_node_->IsMainFrame()) {
1591 // Update the count of top-level frames using this SiteInstance. All 1773 // Update the count of top-level frames using this SiteInstance. All
1592 // subframes are in the same BrowsingInstance as the main frame, so we only 1774 // subframes are in the same BrowsingInstance as the main frame, so we only
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 void RenderFrameHostManager::DeleteRenderFrameProxyHost( 1834 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1653 SiteInstance* instance) { 1835 SiteInstance* instance) {
1654 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1836 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1655 if (iter != proxy_hosts_.end()) { 1837 if (iter != proxy_hosts_.end()) {
1656 delete iter->second; 1838 delete iter->second;
1657 proxy_hosts_.erase(iter); 1839 proxy_hosts_.erase(iter);
1658 } 1840 }
1659 } 1841 }
1660 1842
1661 } // namespace content 1843 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698