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

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: Addressed creis comments. 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 DCHECK(frame_tree_node_); 65 DCHECK(frame_tree_node_);
66 } 66 }
67 67
68 RenderFrameHostManager::~RenderFrameHostManager() { 68 RenderFrameHostManager::~RenderFrameHostManager() {
69 if (pending_render_frame_host_) 69 if (pending_render_frame_host_)
70 CancelPending(); 70 CancelPending();
71 71
72 if (CommandLine::ForCurrentProcess()->HasSwitch(
73 switches::kEnableBrowserSideNavigation)) {
74 CleanUpSpeculativeRenderFrameHost();
75 }
76
72 // We should always have a current RenderFrameHost except in some tests. 77 // We should always have a current RenderFrameHost except in some tests.
73 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); 78 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>());
74 79
75 // Delete any swapped out RenderFrameHosts. 80 // Delete any swapped out RenderFrameHosts.
76 STLDeleteValues(&proxy_hosts_); 81 STLDeleteValues(&proxy_hosts_);
77 } 82 }
78 83
79 void RenderFrameHostManager::Init(BrowserContext* browser_context, 84 void RenderFrameHostManager::Init(BrowserContext* browser_context,
80 SiteInstance* site_instance, 85 SiteInstance* site_instance,
81 int view_routing_id, 86 int view_routing_id,
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 // is ok to do nothing here. 305 // is ok to do nothing here.
301 if (pending_render_frame_host_ && 306 if (pending_render_frame_host_ &&
302 pending_render_frame_host_->are_navigations_suspended()) { 307 pending_render_frame_host_->are_navigations_suspended()) {
303 pending_render_frame_host_->SetNavigationsSuspended(false, 308 pending_render_frame_host_->SetNavigationsSuspended(false,
304 proceed_time); 309 proceed_time);
305 } 310 }
306 } else { 311 } else {
307 // Current page says to cancel. 312 // Current page says to cancel.
308 CancelPending(); 313 CancelPending();
309 cross_navigation_pending_ = false; 314 cross_navigation_pending_ = false;
315 if (CommandLine::ForCurrentProcess()->HasSwitch(
316 switches::kEnableBrowserSideNavigation)) {
317 CleanUpSpeculativeRenderFrameHost();
318 }
310 } 319 }
311 } else { 320 } else {
312 // Non-cross site transition means closing the entire tab. 321 // Non-cross site transition means closing the entire tab.
313 bool proceed_to_fire_unload; 322 bool proceed_to_fire_unload;
314 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time, 323 delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time,
315 &proceed_to_fire_unload); 324 &proceed_to_fire_unload);
316 325
317 if (proceed_to_fire_unload) { 326 if (proceed_to_fire_unload) {
318 // If we're about to close the tab and there's a pending RFH, cancel it. 327 // 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 328 // Otherwise, if the navigation in the pending RFH completes before the
320 // close in the current RFH, we'll lose the tab close. 329 // close in the current RFH, we'll lose the tab close.
321 if (pending_render_frame_host_) { 330 if (pending_render_frame_host_) {
322 CancelPending(); 331 CancelPending();
323 cross_navigation_pending_ = false; 332 cross_navigation_pending_ = false;
333 if (CommandLine::ForCurrentProcess()->HasSwitch(
334 switches::kEnableBrowserSideNavigation)) {
335 CleanUpSpeculativeRenderFrameHost();
336 }
324 } 337 }
325 338
326 // This is not a cross-site navigation, the tab is being closed. 339 // This is not a cross-site navigation, the tab is being closed.
327 render_frame_host_->render_view_host()->ClosePage(); 340 render_frame_host_->render_view_host()->ClosePage();
328 } 341 }
329 } 342 }
330 } 343 }
331 344
332 void RenderFrameHostManager::OnCrossSiteResponse( 345 void RenderFrameHostManager::OnCrossSiteResponse(
333 RenderFrameHostImpl* pending_render_frame_host, 346 RenderFrameHostImpl* pending_render_frame_host,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 425
413 response_started_id_.reset(); 426 response_started_id_.reset();
414 } 427 }
415 428
416 void RenderFrameHostManager::ClearNavigationTransitionData() { 429 void RenderFrameHostManager::ClearNavigationTransitionData() {
417 render_frame_host_->ClearPendingTransitionRequestData(); 430 render_frame_host_->ClearPendingTransitionRequestData();
418 } 431 }
419 432
420 void RenderFrameHostManager::DidNavigateFrame( 433 void RenderFrameHostManager::DidNavigateFrame(
421 RenderFrameHostImpl* render_frame_host) { 434 RenderFrameHostImpl* render_frame_host) {
435 DCHECK(render_frame_host);
436 if (CommandLine::ForCurrentProcess()->HasSwitch(
437 switches::kEnableBrowserSideNavigation)) {
438 if (speculative_render_frame_host_.get() == render_frame_host) {
439 CommitPending(true);
440 return;
441 }
442 CleanUpSpeculativeRenderFrameHost();
443 }
444
422 if (!cross_navigation_pending_) { 445 if (!cross_navigation_pending_) {
423 DCHECK(!pending_render_frame_host_); 446 DCHECK(!pending_render_frame_host_);
424 447
425 // We should only hear this from our current renderer. 448 // We should only hear this from our current renderer.
426 DCHECK_EQ(render_frame_host_, render_frame_host); 449 DCHECK_EQ(render_frame_host_, render_frame_host);
427 450
428 // Even when there is no pending RVH, there may be a pending Web UI. 451 // Even when there is no pending RVH, there may be a pending Web UI.
429 if (pending_web_ui()) 452 if (pending_web_ui())
430 CommitPending(); 453 CommitPending(false);
431 return; 454 return;
432 } 455 }
433 456
434 if (render_frame_host == pending_render_frame_host_) { 457 if (render_frame_host == pending_render_frame_host_) {
435 // The pending cross-site navigation completed, so show the renderer. 458 // The pending cross-site navigation completed, so show the renderer.
436 CommitPending(); 459 CommitPending(false);
437 cross_navigation_pending_ = false; 460 cross_navigation_pending_ = false;
438 } else if (render_frame_host == render_frame_host_) { 461 } else if (render_frame_host == render_frame_host_) {
439 // A navigation in the original page has taken place. Cancel the pending 462 // A navigation in the original page has taken place. Cancel the pending
440 // one. 463 // one.
441 CancelPending(); 464 CancelPending();
442 cross_navigation_pending_ = false; 465 cross_navigation_pending_ = false;
443 } else { 466 } else {
444 // No one else should be sending us DidNavigate in this state. 467 // No one else should be sending us DidNavigate in this state.
445 DCHECK(false); 468 DCHECK(false);
446 } 469 }
447 } 470 }
448 471
472 void RenderFrameHostManager::CancelNavigation() {
473 CleanUpSpeculativeRenderFrameHost();
474 }
475
449 void RenderFrameHostManager::DidDisownOpener( 476 void RenderFrameHostManager::DidDisownOpener(
450 RenderFrameHost* render_frame_host) { 477 RenderFrameHost* render_frame_host) {
451 // Notify all RenderFrameHosts but the one that notified us. This is necessary 478 // 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. 479 // in case a process swap has occurred while the message was in flight.
453 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin(); 480 for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
454 iter != proxy_hosts_.end(); 481 iter != proxy_hosts_.end();
455 ++iter) { 482 ++iter) {
456 DCHECK_NE(iter->second->GetSiteInstance(), 483 DCHECK_NE(iter->second->GetSiteInstance(),
457 current_frame_host()->GetSiteInstance()); 484 current_frame_host()->GetSiteInstance());
458 iter->second->DisownOpener(); 485 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 579 // We shouldn't get here for subframes, since we only swap subframes when
553 // --site-per-process is used. 580 // --site-per-process is used.
554 DCHECK(is_main_frame); 581 DCHECK(is_main_frame);
555 582
556 // The old RenderFrameHost will stay alive inside the proxy so that existing 583 // The old RenderFrameHost will stay alive inside the proxy so that existing
557 // JavaScript window references to it stay valid. 584 // JavaScript window references to it stay valid.
558 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); 585 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass());
559 } 586 }
560 } 587 }
561 588
589 void RenderFrameHostManager::RecycleRenderFrameHost(
590 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
591 // TODO(carlosk): this code is very similar to what can be found in
592 // SwapOutOldFrame and we should see that these are unified at some point.
593
594 // If the SiteInstance for the pending RFH is being used by others, don't
595 // delete the RFH, just swap it out and it can be reused at a later point.
596 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
597 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
598 // Any currently suspended navigations are no longer needed.
599 render_frame_host->CancelSuspendedNavigations();
600
601 RenderFrameProxyHost* proxy =
602 new RenderFrameProxyHost(site_instance, frame_tree_node_);
603 proxy_hosts_[site_instance->GetId()] = proxy;
604 render_frame_host->SwapOut(proxy);
605 if (frame_tree_node_->IsMainFrame())
606 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
607 } else {
608 // We won't be coming back, so delete this one.
609 render_frame_host.reset();
610 }
611 }
612
562 void RenderFrameHostManager::MoveToPendingDeleteHosts( 613 void RenderFrameHostManager::MoveToPendingDeleteHosts(
563 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 614 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
564 // |render_frame_host| will be deleted when its SwapOut ACK is received, or 615 // |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 616 // when the timer times out, or when the RFHM itself is deleted (whichever
566 // comes first). 617 // comes first).
567 pending_delete_hosts_.push_back( 618 pending_delete_hosts_.push_back(
568 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); 619 linked_ptr<RenderFrameHostImpl>(render_frame_host.release()));
569 } 620 }
570 621
571 bool RenderFrameHostManager::IsPendingDeletion( 622 bool RenderFrameHostManager::IsPendingDeletion(
(...skipping 15 matching lines...) Expand all
587 return true; 638 return true;
588 } 639 }
589 } 640 }
590 return false; 641 return false;
591 } 642 }
592 643
593 void RenderFrameHostManager::ResetProxyHosts() { 644 void RenderFrameHostManager::ResetProxyHosts() {
594 STLDeleteValues(&proxy_hosts_); 645 STLDeleteValues(&proxy_hosts_);
595 } 646 }
596 647
648 void RenderFrameHostManager::BeginNavigation(
649 const FrameHostMsg_BeginNavigation_Params& params,
650 const CommonNavigationParams& common_params) {
651 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
652 switches::kEnableBrowserSideNavigation));
653 // If there is an ongoing navigation, just clean it up.
nasko 2014/11/10 17:35:31 Semantically, we should be cancelling an existing
carlosk 2014/11/13 14:40:25 Done.
654 CleanUpSpeculativeRenderFrameHost();
655
656 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
657 // TODO(carlosk): Replace the default values by the right ones.
658 scoped_refptr<SiteInstanceImpl> new_instance =
659 static_cast<SiteInstanceImpl*>(GetSiteInstanceForNavigation(
660 common_params.url, NULL, common_params.transition, false, false,
661 true));
662
663 if (new_instance.get() != current_instance) {
664 // Navigating to a new SiteInstance -> speculatively create a new RFH
665
666 // TODO(carlosk): what the TRACE_EVENT_INSTANT2 for New SiteInstance found
667 // in UpdateStateForNavigate be copied here?
668
669 bool success = CreateSpeculativeRenderFrameHost(
670 common_params.url, current_instance, new_instance.get());
671 if (!success) {
nasko 2014/11/10 17:35:31 nit: no need for {} when you have one line if stat
carlosk 2014/11/13 14:40:25 Done.
672 return;
673 }
674 } else {
675 // Navigating to the same SiteInstance -> make sure the current RFH is alive
676
677 // TODO(carlosk): do I need to AddPendingView() in this case as well???
nasko 2014/11/10 17:35:31 You shouldn't need to. This accounts for browser-s
carlosk 2014/11/13 14:40:25 Acknowledged.
678 DCHECK(render_frame_host_->GetSiteInstance() == new_instance);
679 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) {
680 // Recreate the opener chain.
681 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
682 render_frame_host_->GetSiteInstance());
683 if (!InitRenderView(render_frame_host_->render_view_host(),
684 opener_route_id, MSG_ROUTING_NONE,
685 frame_tree_node_->IsMainFrame())) {
686 return;
687 }
688 }
689 }
690 DCHECK(new_instance->GetProcess()->HasConnection());
691 DCHECK(new_instance->GetProcess()->GetBrowserContext());
692 }
693
694 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
clamy 2014/11/12 13:01:13 As mentioned offline, it would be good if this was
carlosk 2014/11/13 14:40:25 I'll be working on this next.
695 const GURL& url, SiteInstance* old_instance, SiteInstance* new_instance) {
nasko 2014/11/10 17:35:31 nit: params each on its own line
carlosk 2014/11/13 14:40:25 Done.
696 CHECK(new_instance);
697 CHECK_NE(old_instance, new_instance);
698
699 // TODO(carlosk): should also try to reuse the current web_ui
700 // (ShouldReuseWebUI)?
701 scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url));
702 // TODO(carlosk): confirm this next section copied from SetPendingWebUI
703 // is in fact needed... I need access to the respective navigation entry
704 // though.
705 // If we have assigned (zero or more) bindings to this NavigationEntry in the
706 // past, make sure we're not granting it different bindings than it had
707 // before. If so, note it and don't give it any bindings, to avoid a
708 // potential privilege escalation.
709 // if (new_web_ui &&
710 // bindings != NavigationEntryImpl::kInvalidBindings &&
711 // new_web_ui->GetBindings() != bindings) {
712 // RecordAction(
713 // base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
714 // new_web_ui.reset();
715 // }
716
717 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
718
719 // Check if we've already created an RFH for this SiteInstance. If so, try
720 // to re-use the existing one, which has already been initialized. We'll
721 // remove it from the list of proxy hosts below if it will be active.
722 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(new_instance);
723 if (proxy && proxy->render_frame_host()) {
724 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
725 // Prevent the process from exiting while we're trying to use it.
726 new_render_frame_host = proxy->PassFrameHostOwnership();
727 new_render_frame_host->GetProcess()->AddPendingView();
728
729 proxy_hosts_.erase(new_instance->GetId());
730 delete proxy;
731
732 // When a new render view is created by the renderer, the new WebContents
733 // gets a RenderViewHost in the SiteInstance of its opener WebContents.
734 // If not used in the first navigation, this RVH is swapped out and is not
735 // granted bindings, so we may need to grant them when swapping it in.
736 if (new_web_ui && !new_render_frame_host->GetProcess()->IsIsolatedGuest()) {
737 int required_bindings = new_web_ui->GetBindings();
738 RenderViewHost* rvh = new_render_frame_host->render_view_host();
739 if ((rvh->GetEnabledBindings() & required_bindings) !=
740 required_bindings) {
741 rvh->AllowBindings(required_bindings);
742 }
743 }
744 } else {
745 // Create a new RenderFrameHost if we don't find an existing one.
746 new_render_frame_host =
747 CreateRenderFrameHost(new_instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
748 false, delegate_->IsHidden());
749 DCHECK(new_render_frame_host);
750 RenderViewHostImpl* rvh = new_render_frame_host->render_view_host();
751
752 // Prevent the process from exiting while we're trying to navigate in it.
753 // Otherwise, if the new RFH is swapped out already, store it.
754 new_render_frame_host->GetProcess()->AddPendingView();
755
756 // Ensure that we have created RFHs for the new RFH's opener chain if
757 // we are staying in the same BrowsingInstance. This allows the new RFH
758 // to send cross-process script calls to its opener(s).
759 int opener_route_id = MSG_ROUTING_NONE;
760 if (new_instance->IsRelatedSiteInstance(old_instance)) {
761 opener_route_id =
762 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
763 if (CommandLine::ForCurrentProcess()->HasSwitch(
764 switches::kSitePerProcess)) {
765 // Ensure that the frame tree has RenderFrameProxyHosts for the new
766 // SiteInstance in all nodes except the current one.
767 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance(
768 frame_tree_node_, new_instance);
769 }
770 }
771
772 bool success = InitRenderView(rvh, opener_route_id, MSG_ROUTING_NONE,
773 frame_tree_node_->IsMainFrame());
774 if (success) {
775 if (frame_tree_node_->IsMainFrame()) {
776 // Don't show the main frame's view until we know it will be used.
777 rvh->GetView()->Hide();
778 } else {
779 // Init the RFH, so a RenderFrame is created in the renderer.
780 success = InitRenderFrame(new_render_frame_host.get());
781 }
782 }
783 if (!success) {
784 return false;
785 }
786 // TODO(carlosk): Should this notification call be made this early on in the
787 // navigation or only later?
nasko 2014/11/10 17:35:31 This should probably be called here. Longer term i
carlosk 2014/11/13 14:40:25 Acknowledged.
788 render_frame_delegate_->RenderFrameCreated(new_render_frame_host.get());
789 }
790
791 DCHECK(new_render_frame_host->GetSiteInstance() == new_instance);
792 speculative_render_frame_host_.reset(new_render_frame_host.release());
793 speculative_web_ui_.reset(new_web_ui.release());
794 return true;
795 }
796
597 // PlzNavigate 797 // PlzNavigate
598 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( 798 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
599 const GURL& url, 799 const GURL& url,
600 ui::PageTransition transition) { 800 ui::PageTransition transition) {
601 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( 801 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
602 switches::kEnableBrowserSideNavigation)); 802 switches::kEnableBrowserSideNavigation));
603 // TODO(clamy): When we handle renderer initiated navigations, make sure not 803 // 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 804 // to use a different process for subframes if --site-per-process is not
605 // enabled. 805 // enabled.
606 806
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 controller.GetBrowserContext(), current_entry->GetURL()) == 950 controller.GetBrowserContext(), current_entry->GetURL()) ==
751 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 951 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
752 controller.GetBrowserContext(), new_url)); 952 controller.GetBrowserContext(), new_url));
753 } 953 }
754 954
755 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( 955 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
756 const GURL& dest_url, 956 const GURL& dest_url,
757 SiteInstance* dest_instance, 957 SiteInstance* dest_instance,
758 ui::PageTransition dest_transition, 958 ui::PageTransition dest_transition,
759 bool dest_is_restore, 959 bool dest_is_restore,
760 bool dest_is_view_source_mode) { 960 bool dest_is_view_source_mode,
961 bool create_unbounded_site_instance) {
761 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 962 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
762 SiteInstance* new_instance = current_instance; 963 SiteInstance* new_instance = current_instance;
763 964
764 // We do not currently swap processes for navigations in webview tag guests. 965 // We do not currently swap processes for navigations in webview tag guests.
765 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme)) 966 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme))
766 return current_instance; 967 return current_instance;
767 968
768 // Determine if we need a new BrowsingInstance for this entry. If true, this 969 // Determine if we need a new BrowsingInstance for this entry. If true, this
769 // implies that it will get a new SiteInstance (and likely process), and that 970 // implies that it will get a new SiteInstance (and likely process), and that
770 // other tabs in the current BrowsingInstance will be unable to script it. 971 // other tabs in the current BrowsingInstance will be unable to script it.
(...skipping 11 matching lines...) Expand all
782 bool current_is_view_source_mode = current_entry ? 983 bool current_is_view_source_mode = current_entry ?
783 current_entry->IsViewSourceMode() : dest_is_view_source_mode; 984 current_entry->IsViewSourceMode() : dest_is_view_source_mode;
784 bool force_swap = ShouldSwapBrowsingInstancesForNavigation( 985 bool force_swap = ShouldSwapBrowsingInstancesForNavigation(
785 current_effective_url, 986 current_effective_url,
786 current_is_view_source_mode, 987 current_is_view_source_mode,
787 dest_instance, 988 dest_instance,
788 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), 989 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
789 dest_is_view_source_mode); 990 dest_is_view_source_mode);
790 if (ShouldTransitionCrossSite() || force_swap) { 991 if (ShouldTransitionCrossSite() || force_swap) {
791 new_instance = GetSiteInstanceForURL( 992 new_instance = GetSiteInstanceForURL(
792 dest_url, 993 dest_url, dest_instance, dest_transition, dest_is_restore,
793 dest_instance, 994 dest_is_view_source_mode, current_instance, force_swap,
794 dest_transition, 995 create_unbounded_site_instance);
795 dest_is_restore,
796 dest_is_view_source_mode,
797 current_instance,
798 force_swap);
799 } 996 }
800 997
801 // If force_swap is true, we must use a different SiteInstance. If we didn't, 998 // 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 999 // we would have two RenderFrameHosts in the same SiteInstance and the same
803 // frame, resulting in page_id conflicts for their NavigationEntries. 1000 // frame, resulting in page_id conflicts for their NavigationEntries.
804 if (force_swap) 1001 if (force_swap)
805 CHECK_NE(new_instance, current_instance); 1002 CHECK_NE(new_instance, current_instance);
806 return new_instance; 1003 return new_instance;
807 } 1004 }
808 1005
809 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( 1006 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL(
810 const GURL& dest_url, 1007 const GURL& dest_url,
811 SiteInstance* dest_instance, 1008 SiteInstance* dest_instance,
812 ui::PageTransition dest_transition, 1009 ui::PageTransition dest_transition,
813 bool dest_is_restore, 1010 bool dest_is_restore,
814 bool dest_is_view_source_mode, 1011 bool dest_is_view_source_mode,
815 SiteInstance* current_instance, 1012 SiteInstance* current_instance,
816 bool force_browsing_instance_swap) { 1013 bool force_browsing_instance_swap,
1014 bool create_unbounded_site_instance) {
817 NavigationControllerImpl& controller = 1015 NavigationControllerImpl& controller =
818 delegate_->GetControllerForRenderManager(); 1016 delegate_->GetControllerForRenderManager();
819 BrowserContext* browser_context = controller.GetBrowserContext(); 1017 BrowserContext* browser_context = controller.GetBrowserContext();
820 1018
821 // If the entry has an instance already we should use it. 1019 // If the entry has an instance already we should use it.
822 if (dest_instance) { 1020 if (dest_instance) {
823 // If we are forcing a swap, this should be in a different BrowsingInstance. 1021 // If we are forcing a swap, this should be in a different BrowsingInstance.
824 if (force_browsing_instance_swap) { 1022 if (force_browsing_instance_swap) {
825 CHECK(!dest_instance->IsRelatedSiteInstance( 1023 CHECK(!dest_instance->IsRelatedSiteInstance(
826 render_frame_host_->GetSiteInstance())); 1024 render_frame_host_->GetSiteInstance()));
827 } 1025 }
828 return dest_instance; 1026 return dest_instance;
829 } 1027 }
830 1028
1029 SiteInstanceImpl* current_site_instance =
1030 static_cast<SiteInstanceImpl*>(current_instance);
1031
831 // If a swap is required, we need to force the SiteInstance AND 1032 // If a swap is required, we need to force the SiteInstance AND
832 // BrowsingInstance to be different ones, using CreateForURL. 1033 // BrowsingInstance to be different ones, using CreateForURL.
833 if (force_browsing_instance_swap) 1034 if (force_browsing_instance_swap) {
834 return SiteInstance::CreateForURL(browser_context, dest_url); 1035 return CreateSiteInstanceForURL(browser_context, dest_url,
1036 create_unbounded_site_instance,
1037 current_site_instance);
1038 }
835 1039
836 // (UGLY) HEURISTIC, process-per-site only: 1040 // (UGLY) HEURISTIC, process-per-site only:
837 // 1041 //
838 // If this navigation is generated, then it probably corresponds to a search 1042 // If this navigation is generated, then it probably corresponds to a search
839 // query. Given that search results typically lead to users navigating to 1043 // query. Given that search results typically lead to users navigating to
840 // other sites, we don't really want to use the search engine hostname to 1044 // other sites, we don't really want to use the search engine hostname to
841 // determine the site instance for this navigation. 1045 // determine the site instance for this navigation.
842 // 1046 //
843 // NOTE: This can be removed once we have a way to transition between 1047 // NOTE: This can be removed once we have a way to transition between
844 // RenderViews in response to a link click. 1048 // RenderViews in response to a link click.
845 // 1049 //
846 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && 1050 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) &&
847 ui::PageTransitionCoreTypeIs( 1051 ui::PageTransitionCoreTypeIs(
848 dest_transition, ui::PAGE_TRANSITION_GENERATED)) { 1052 dest_transition, ui::PAGE_TRANSITION_GENERATED)) {
849 return current_instance; 1053 return current_instance;
850 } 1054 }
851 1055
852 SiteInstanceImpl* current_site_instance =
853 static_cast<SiteInstanceImpl*>(current_instance);
854
855 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it 1056 // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
856 // for this entry. We won't commit the SiteInstance to this site until the 1057 // for this entry. We won't commit the SiteInstance to this site until the
857 // navigation commits (in DidNavigate), unless the navigation entry was 1058 // navigation commits (in DidNavigate), unless the navigation entry was
858 // restored or it's a Web UI as described below. 1059 // restored or it's a Web UI as described below.
859 if (!current_site_instance->HasSite()) { 1060 if (!current_site_instance->HasSite()) {
860 // If we've already created a SiteInstance for our destination, we don't 1061 // If we've already created a SiteInstance for our destination, we don't
861 // want to use this unused SiteInstance; use the existing one. (We don't 1062 // want to use this unused SiteInstance; use the existing one. (We don't
862 // do this check if the current_instance has a site, because for now, we 1063 // do this check if the current_instance has a site, because for now, we
863 // want to compare against the current URL and not the SiteInstance's site. 1064 // want to compare against the current URL and not the SiteInstance's site.
864 // In this case, there is no current URL, so comparing against the site is 1065 // In this case, there is no current URL, so comparing against the site is
865 // ok. See additional comments below.) 1066 // ok. See additional comments below.)
866 // 1067 //
867 // Also, if the URL should use process-per-site mode and there is an 1068 // Also, if the URL should use process-per-site mode and there is an
868 // existing process for the site, we should use it. We can call 1069 // existing process for the site, we should use it. We can call
869 // GetRelatedSiteInstance() for this, which will eagerly set the site and 1070 // GetRelatedSiteInstance() for this, which will eagerly set the site and
870 // thus use the correct process. 1071 // thus use the correct process.
871 bool use_process_per_site = 1072 bool use_process_per_site =
872 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) && 1073 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) &&
873 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url); 1074 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url);
874 if (current_site_instance->HasRelatedSiteInstance(dest_url) || 1075 if (current_site_instance->HasRelatedSiteInstance(dest_url) ||
875 use_process_per_site) { 1076 use_process_per_site) {
876 return current_site_instance->GetRelatedSiteInstance(dest_url); 1077 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url,
1078 create_unbounded_site_instance);
877 } 1079 }
878 1080
879 // For extensions, Web UI URLs (such as the new tab page), and apps we do 1081 // For extensions, Web UI URLs (such as the new tab page), and apps we do
880 // not want to use the current_instance if it has no site, since it will 1082 // not want to use the current_instance if it has no site, since it will
881 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for 1083 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for
882 // this URL instead (with the correct process type). 1084 // this URL instead (with the correct process type).
883 if (current_site_instance->HasWrongProcessForURL(dest_url)) 1085 if (current_site_instance->HasWrongProcessForURL(dest_url)) {
884 return current_site_instance->GetRelatedSiteInstance(dest_url); 1086 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url,
1087 create_unbounded_site_instance);
1088 }
885 1089
886 // View-source URLs must use a new SiteInstance and BrowsingInstance. 1090 // View-source URLs must use a new SiteInstance and BrowsingInstance.
887 // TODO(nasko): This is the same condition as later in the function. This 1091 // TODO(nasko): This is the same condition as later in the function. This
888 // should be taken into account when refactoring this method as part of 1092 // should be taken into account when refactoring this method as part of
889 // http://crbug.com/123007. 1093 // http://crbug.com/123007.
890 if (dest_is_view_source_mode) 1094 if (dest_is_view_source_mode) {
891 return SiteInstance::CreateForURL(browser_context, dest_url); 1095 return CreateSiteInstanceForURL(browser_context, dest_url,
1096 create_unbounded_site_instance,
1097 current_site_instance);
1098 }
892 1099
893 // If we are navigating from a blank SiteInstance to a WebUI, make sure we 1100 // If we are navigating from a blank SiteInstance to a WebUI, make sure we
894 // create a new SiteInstance. 1101 // create a new SiteInstance.
895 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 1102 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
896 browser_context, dest_url)) { 1103 browser_context, dest_url)) {
897 return SiteInstance::CreateForURL(browser_context, dest_url); 1104 return CreateSiteInstanceForURL(browser_context, dest_url,
1105 create_unbounded_site_instance,
1106 current_site_instance);
898 } 1107 }
899 1108
900 // Normally the "site" on the SiteInstance is set lazily when the load 1109 // Normally the "site" on the SiteInstance is set lazily when the load
901 // actually commits. This is to support better process sharing in case 1110 // actually commits. This is to support better process sharing in case
902 // the site redirects to some other site: we want to use the destination 1111 // the site redirects to some other site: we want to use the destination
903 // site in the site instance. 1112 // site in the site instance.
904 // 1113 //
905 // In the case of session restore, as it loads all the pages immediately 1114 // In the case of session restore, as it loads all the pages immediately
906 // we need to set the site first, otherwise after a restore none of the 1115 // we need to set the site first, otherwise after a restore none of the
907 // pages would share renderers in process-per-site. 1116 // pages would share renderers in process-per-site.
(...skipping 29 matching lines...) Expand all
937 } 1146 }
938 1147
939 // View-source URLs must use a new SiteInstance and BrowsingInstance. 1148 // View-source URLs must use a new SiteInstance and BrowsingInstance.
940 // We don't need a swap when going from view-source to a debug URL like 1149 // We don't need a swap when going from view-source to a debug URL like
941 // chrome://crash, however. 1150 // chrome://crash, however.
942 // TODO(creis): Refactor this method so this duplicated code isn't needed. 1151 // TODO(creis): Refactor this method so this duplicated code isn't needed.
943 // See http://crbug.com/123007. 1152 // See http://crbug.com/123007.
944 if (current_entry && 1153 if (current_entry &&
945 current_entry->IsViewSourceMode() != dest_is_view_source_mode && 1154 current_entry->IsViewSourceMode() != dest_is_view_source_mode &&
946 !IsRendererDebugURL(dest_url)) { 1155 !IsRendererDebugURL(dest_url)) {
947 return SiteInstance::CreateForURL(browser_context, dest_url); 1156 return CreateSiteInstanceForURL(browser_context, dest_url,
1157 create_unbounded_site_instance,
1158 current_site_instance);
948 } 1159 }
949 1160
950 // Use the current SiteInstance for same site navigations, as long as the 1161 // Use the current SiteInstance for same site navigations, as long as the
951 // process type is correct. (The URL may have been installed as an app since 1162 // process type is correct. (The URL may have been installed as an app since
952 // the last time we visited it.) 1163 // the last time we visited it.)
953 const GURL& current_url = 1164 const GURL& current_url =
954 GetCurrentURLForSiteInstance(current_instance, current_entry); 1165 GetCurrentURLForSiteInstance(current_instance, current_entry);
955 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && 1166 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
956 !current_site_instance->HasWrongProcessForURL(dest_url)) { 1167 !current_site_instance->HasWrongProcessForURL(dest_url)) {
957 return current_instance; 1168 return current_instance;
958 } 1169 }
959 1170
960 // Start the new renderer in a new SiteInstance, but in the current 1171 // Start the new renderer in a new SiteInstance, but in the current
961 // BrowsingInstance. It is important to immediately give this new 1172 // BrowsingInstance. It is important to immediately give this new
962 // SiteInstance to a RenderViewHost (if it is different than our current 1173 // SiteInstance to a RenderViewHost (if it is different than our current
963 // SiteInstance), so that it is ref counted. This will happen in 1174 // SiteInstance), so that it is ref counted. This will happen in
964 // CreateRenderView. 1175 // CreateRenderView.
1176 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url,
1177 create_unbounded_site_instance);
1178 }
1179
1180 SiteInstance* RenderFrameHostManager::CreateSiteInstanceForURL(
1181 BrowserContext* browser_context,
1182 const GURL& dest_url,
1183 bool create_unbounded_site_instance,
1184 SiteInstanceImpl* current_instance) {
1185 if (CommandLine::ForCurrentProcess()->HasSwitch(
1186 switches::kEnableBrowserSideNavigation)) {
1187 if (create_unbounded_site_instance) {
1188 return SiteInstance::Create(browser_context);
1189 }
1190 if (speculative_render_frame_host_) {
nasko 2014/11/10 17:35:31 Why would this condition be hit? If there is a spe
carlosk 2014/11/13 14:40:26 This method is called twice during a navigation wi
1191 SiteInstanceImpl* sii = speculative_render_frame_host_->GetSiteInstance();
1192 if (!sii->HasSite() && !sii->IsRelatedSiteInstance(current_instance)) {
1193 return sii;
1194 }
1195 }
1196 }
1197
1198 return SiteInstance::CreateForURL(browser_context, dest_url);
1199 }
1200
1201 SiteInstance* RenderFrameHostManager::GetRelatedSiteInstanceForURL(
1202 SiteInstanceImpl* current_instance,
1203 const GURL& dest_url,
1204 bool create_unbounded_site_instance) {
1205 if (CommandLine::ForCurrentProcess()->HasSwitch(
1206 switches::kEnableBrowserSideNavigation)) {
1207 if (!current_instance->HasRelatedSiteInstance(dest_url)) {
1208 if (create_unbounded_site_instance) {
1209 return current_instance->GetRelatedEmptySiteInstance();
1210 }
1211 if (speculative_render_frame_host_) {
1212 SiteInstanceImpl* sii =
1213 speculative_render_frame_host_->GetSiteInstance();
1214 if (!sii->HasSite() && sii->IsRelatedSiteInstance(current_instance)) {
1215 return sii;
1216 }
1217 }
1218 }
1219 }
1220
965 return current_instance->GetRelatedSiteInstance(dest_url); 1221 return current_instance->GetRelatedSiteInstance(dest_url);
966 } 1222 }
967 1223
968 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance( 1224 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance(
969 SiteInstance* current_instance, NavigationEntry* current_entry) { 1225 SiteInstance* current_instance, NavigationEntry* current_entry) {
970 // If this is a subframe that is potentially out of process from its parent, 1226 // If this is a subframe that is potentially out of process from its parent,
971 // don't consider using current_entry's url for SiteInstance selection, since 1227 // don't consider using current_entry's url for SiteInstance selection, since
972 // current_entry's url is for the main frame and may be in a different site 1228 // current_entry's url is for the main frame and may be in a different site
973 // than this frame. 1229 // than this frame.
974 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url. 1230 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url.
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); 1446 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
1191 } else { 1447 } else {
1192 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 1448 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
1193 // process unless it's swapped out. 1449 // process unless it's swapped out.
1194 if (render_view_host->is_active()) { 1450 if (render_view_host->is_active()) {
1195 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1451 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1196 render_view_host->GetProcess()->GetID())); 1452 render_view_host->GetProcess()->GetID()));
1197 } 1453 }
1198 } 1454 }
1199 1455
1200 return delegate_->CreateRenderViewForRenderManager(render_view_host, 1456 return delegate_->CreateRenderViewForRenderManager(
1201 opener_route_id, 1457 render_view_host, opener_route_id, proxy_routing_id,
1202 proxy_routing_id, 1458 for_main_frame_navigation);
1203 for_main_frame_navigation);
1204 } 1459 }
1205 1460
1206 bool RenderFrameHostManager::InitRenderFrame( 1461 bool RenderFrameHostManager::InitRenderFrame(
1207 RenderFrameHostImpl* render_frame_host) { 1462 RenderFrameHostImpl* render_frame_host) {
1208 if (render_frame_host->IsRenderFrameLive()) 1463 if (render_frame_host->IsRenderFrameLive())
1209 return true; 1464 return true;
1210 1465
1211 int parent_routing_id = MSG_ROUTING_NONE; 1466 int parent_routing_id = MSG_ROUTING_NONE;
1212 int proxy_routing_id = MSG_ROUTING_NONE; 1467 int proxy_routing_id = MSG_ROUTING_NONE;
1213 if (frame_tree_node_->parent()) { 1468 if (frame_tree_node_->parent()) {
(...skipping 25 matching lines...) Expand all
1239 return render_frame_host_->GetRoutingID(); 1494 return render_frame_host_->GetRoutingID();
1240 1495
1241 RenderFrameProxyHostMap::iterator iter = 1496 RenderFrameProxyHostMap::iterator iter =
1242 proxy_hosts_.find(site_instance->GetId()); 1497 proxy_hosts_.find(site_instance->GetId());
1243 if (iter != proxy_hosts_.end()) 1498 if (iter != proxy_hosts_.end())
1244 return iter->second->GetRoutingID(); 1499 return iter->second->GetRoutingID();
1245 1500
1246 return MSG_ROUTING_NONE; 1501 return MSG_ROUTING_NONE;
1247 } 1502 }
1248 1503
1249 void RenderFrameHostManager::CommitPending() { 1504 void RenderFrameHostManager::CommitPending(bool use_speculative_rfh) {
1250 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 1505 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
1251 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1506 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1507 // If use_speculative_rfh then kEnableBrowserSideNavigation must be enabled.
1508 DCHECK(!use_speculative_rfh ||
nasko 2014/11/10 17:35:31 nit: CHECK
carlosk 2014/11/13 14:40:26 Done.
1509 CommandLine::ForCurrentProcess()->HasSwitch(
1510 switches::kEnableBrowserSideNavigation));
1511
1252 // First check whether we're going to want to focus the location bar after 1512 // 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 1513 // 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 1514 // 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. 1515 // this triggers won't be able to figure out what's going on.
1256 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1516 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1257 1517
1258 // Next commit the Web UI, if any. Either replace |web_ui_| with 1518 if (!use_speculative_rfh) {
1259 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 1519 DCHECK(!speculative_web_ui_);
1260 // leave |web_ui_| as is if reusing it. 1520 // Next commit the Web UI, if any. Either replace |web_ui_| with
1261 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); 1521 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
1262 if (pending_web_ui_) { 1522 // leave |web_ui_| as is if reusing it.
1263 web_ui_.reset(pending_web_ui_.release()); 1523 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
1264 } else if (!pending_and_current_web_ui_.get()) { 1524 if (pending_web_ui_) {
1265 web_ui_.reset(); 1525 web_ui_.reset(pending_web_ui_.release());
1526 } else if (!pending_and_current_web_ui_.get()) {
1527 web_ui_.reset();
1528 } else {
1529 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
1530 pending_and_current_web_ui_.reset();
1531 }
1266 } else { 1532 } else {
1267 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); 1533 web_ui_.reset(speculative_web_ui_.release());
1268 pending_and_current_web_ui_.reset();
1269 } 1534 }
1270 1535
1271 // It's possible for the pending_render_frame_host_ to be NULL when we aren't 1536 // 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 1537 // crossing process boundaries. If so, we just needed to handle the Web UI
1273 // committing above and we're done. 1538 // committing above and we're done.
1274 if (!pending_render_frame_host_) { 1539 if (!pending_render_frame_host_ && !use_speculative_rfh) {
1275 if (will_focus_location_bar) 1540 if (will_focus_location_bar)
1276 delegate_->SetFocusToLocationBar(false); 1541 delegate_->SetFocusToLocationBar(false);
1277 return; 1542 return;
1278 } 1543 }
1279 1544
1280 // Remember if the page was focused so we can focus the new renderer in 1545 // Remember if the page was focused so we can focus the new renderer in
1281 // that case. 1546 // that case.
1282 bool focus_render_view = !will_focus_location_bar && 1547 bool focus_render_view = !will_focus_location_bar &&
1283 render_frame_host_->render_view_host()->GetView() && 1548 render_frame_host_->render_view_host()->GetView() &&
1284 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1549 render_frame_host_->render_view_host()->GetView()->HasFocus();
1285 1550
1286 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1551 bool is_main_frame = frame_tree_node_->IsMainFrame();
1287 1552
1288 // Swap in the pending frame and make it active. Also ensure the FrameTree 1553 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
1289 // stays in sync. 1554 if (!use_speculative_rfh) {
1290 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1555 DCHECK(!speculative_render_frame_host_);
1291 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1556 // Swap in the pending frame and make it active. Also ensure the FrameTree
1557 // stays in sync.
1558 old_render_frame_host =
1559 SetRenderFrameHost(pending_render_frame_host_.Pass());
1560 } else {
1561 DCHECK(speculative_render_frame_host_);
1562 old_render_frame_host =
1563 SetRenderFrameHost(speculative_render_frame_host_.Pass());
1564 }
1565
1292 if (is_main_frame) 1566 if (is_main_frame)
1293 render_frame_host_->render_view_host()->AttachToFrameTree(); 1567 render_frame_host_->render_view_host()->AttachToFrameTree();
1294 1568
1295 // The process will no longer try to exit, so we can decrement the count. 1569 // The process will no longer try to exit, so we can decrement the count.
1296 render_frame_host_->GetProcess()->RemovePendingView(); 1570 render_frame_host_->GetProcess()->RemovePendingView();
1297 1571
1298 // Show the new view (or a sad tab) if necessary. 1572 // Show the new view (or a sad tab) if necessary.
1299 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1573 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView();
1300 if (!delegate_->IsHidden() && new_rfh_has_view) { 1574 if (!delegate_->IsHidden() && new_rfh_has_view) {
1301 // In most cases, we need to show the new view. 1575 // In most cases, we need to show the new view.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 // If we are currently navigating cross-process, we want to get back to normal 1682 // If we are currently navigating cross-process, we want to get back to normal
1409 // and then navigate as usual. 1683 // and then navigate as usual.
1410 if (cross_navigation_pending_) { 1684 if (cross_navigation_pending_) {
1411 if (pending_render_frame_host_) 1685 if (pending_render_frame_host_)
1412 CancelPending(); 1686 CancelPending();
1413 cross_navigation_pending_ = false; 1687 cross_navigation_pending_ = false;
1414 } 1688 }
1415 1689
1416 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1690 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1417 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( 1691 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
1418 url, instance, transition, is_restore, is_view_source_mode); 1692 url, instance, transition, is_restore, is_view_source_mode, false);
1693
1694 if (CommandLine::ForCurrentProcess()->HasSwitch(
1695 switches::kEnableBrowserSideNavigation) &&
1696 speculative_render_frame_host_) {
1697 if (speculative_render_frame_host_->GetSiteInstance() == new_instance) {
clamy 2014/11/12 13:01:13 nit: no need for braces.
carlosk 2014/11/13 14:40:26 Done.
1698 return speculative_render_frame_host_.get();
1699 }
1700 CleanUpSpeculativeRenderFrameHost();
nasko 2014/11/10 17:35:31 All of the sprinkled calls for CleanUpSpeculativeR
carlosk 2014/11/13 14:40:25 In this case that's not true: if the SiteInstance
1701 }
1419 1702
1420 const NavigationEntry* current_entry = 1703 const NavigationEntry* current_entry =
1421 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 1704 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1422 1705
1423 if (new_instance.get() != current_instance) { 1706 if (new_instance.get() != current_instance) {
1424 TRACE_EVENT_INSTANT2( 1707 TRACE_EVENT_INSTANT2(
1425 "navigation", 1708 "navigation",
1426 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 1709 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
1427 TRACE_EVENT_SCOPE_THREAD, 1710 TRACE_EVENT_SCOPE_THREAD,
1428 "current_instance id", current_instance->GetId(), 1711 "current_instance id", current_instance->GetId(),
(...skipping 16 matching lines...) Expand all
1445 } 1728 }
1446 1729
1447 // Check if our current RFH is live before we set up a transition. 1730 // Check if our current RFH is live before we set up a transition.
1448 if (!render_frame_host_->IsRenderFrameLive()) { 1731 if (!render_frame_host_->IsRenderFrameLive()) {
1449 if (!cross_navigation_pending_) { 1732 if (!cross_navigation_pending_) {
1450 // The current RFH is not live. There's no reason to sit around with a 1733 // 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 1734 // 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 1735 // 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 1736 // cross-navigating (Note that we don't care about on{before}unload
1454 // handlers if the current RFH isn't live.) 1737 // handlers if the current RFH isn't live.)
1455 CommitPending(); 1738 CommitPending(false);
1456 return render_frame_host_.get(); 1739 return render_frame_host_.get();
1457 } else { 1740 } else {
1458 NOTREACHED(); 1741 NOTREACHED();
1459 return render_frame_host_.get(); 1742 return render_frame_host_.get();
1460 } 1743 }
1461 } 1744 }
1462 // Otherwise, it's safe to treat this as a pending cross-site transition. 1745 // Otherwise, it's safe to treat this as a pending cross-site transition.
1463 1746
1464 // We now have a pending RFH. 1747 // We now have a pending RFH.
1465 DCHECK(!cross_navigation_pending_); 1748 DCHECK(!cross_navigation_pending_);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = 1833 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
1551 pending_render_frame_host_.Pass(); 1834 pending_render_frame_host_.Pass();
1552 1835
1553 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( 1836 RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
1554 pending_render_frame_host->render_view_host(), 1837 pending_render_frame_host->render_view_host(),
1555 render_frame_host_->render_view_host()); 1838 render_frame_host_->render_view_host());
1556 1839
1557 // We no longer need to prevent the process from exiting. 1840 // We no longer need to prevent the process from exiting.
1558 pending_render_frame_host->GetProcess()->RemovePendingView(); 1841 pending_render_frame_host->GetProcess()->RemovePendingView();
1559 1842
1560 // If the SiteInstance for the pending RFH is being used by others, don't 1843 RecycleRenderFrameHost(pending_render_frame_host.Pass());
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 1844
1579 pending_web_ui_.reset(); 1845 pending_web_ui_.reset();
1580 pending_and_current_web_ui_.reset(); 1846 pending_and_current_web_ui_.reset();
1581 } 1847 }
1582 1848
1849 void RenderFrameHostManager::CleanUpSpeculativeRenderFrameHost() {
1850 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
1851 switches::kEnableBrowserSideNavigation));
1852 if (speculative_render_frame_host_) {
1853 speculative_render_frame_host_->GetProcess()->RemovePendingView();
1854 RecycleRenderFrameHost(speculative_render_frame_host_.Pass());
1855 }
1856 if (speculative_web_ui_) {
clamy 2014/11/12 13:01:13 nit: no need for braces.
carlosk 2014/11/13 14:40:26 Done.
1857 speculative_web_ui_.reset();
1858 }
1859 }
1860
1583 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( 1861 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
1584 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 1862 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
1585 // Swap the two. 1863 // Swap the two.
1586 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1864 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
1587 render_frame_host_.Pass(); 1865 render_frame_host_.Pass();
1588 render_frame_host_ = render_frame_host.Pass(); 1866 render_frame_host_ = render_frame_host.Pass();
1589 1867
1590 if (frame_tree_node_->IsMainFrame()) { 1868 if (frame_tree_node_->IsMainFrame()) {
1591 // Update the count of top-level frames using this SiteInstance. All 1869 // 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 1870 // 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( 1930 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1653 SiteInstance* instance) { 1931 SiteInstance* instance) {
1654 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1932 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1655 if (iter != proxy_hosts_.end()) { 1933 if (iter != proxy_hosts_.end()) {
1656 delete iter->second; 1934 delete iter->second;
1657 proxy_hosts_.erase(iter); 1935 proxy_hosts_.erase(iter);
1658 } 1936 }
1659 } 1937 }
1660 1938
1661 } // namespace content 1939 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698