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

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: 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 CleanUpCurrentNavigation();
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 CleanUpCurrentNavigation();
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 CleanUpCurrentNavigation();
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 CleanUpCurrentNavigation();
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 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 // We shouldn't get here for subframes, since we only swap subframes when 575 // We shouldn't get here for subframes, since we only swap subframes when
553 // --site-per-process is used. 576 // --site-per-process is used.
554 DCHECK(is_main_frame); 577 DCHECK(is_main_frame);
555 578
556 // The old RenderFrameHost will stay alive inside the proxy so that existing 579 // The old RenderFrameHost will stay alive inside the proxy so that existing
557 // JavaScript window references to it stay valid. 580 // JavaScript window references to it stay valid.
558 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass()); 581 proxy->TakeFrameHostOwnership(old_render_frame_host.Pass());
559 } 582 }
560 } 583 }
561 584
585 void RenderFrameHostManager::RecycleRenderFrameHost(
586 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
587 // TODO(carlosk): this code is very similar to what can be found in
588 // SwapOutOldFrame and we should see that these are unified at some point.
carlosk 2014/11/05 16:45:44 SwapOutOldFrame does all of this (extracted from C
Charlie Reis 2014/11/05 17:50:01 I would also like to see this code unified. We ca
carlosk 2014/11/05 20:28:58 Acknowledged.
589
590 // If the SiteInstance for the pending RFH is being used by others, don't
591 // delete the RFH, just swap it out and it can be reused at a later point.
592 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
593 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
594 // Any currently suspended navigations are no longer needed.
595 render_frame_host->CancelSuspendedNavigations();
596
597 RenderFrameProxyHost* proxy =
598 new RenderFrameProxyHost(site_instance, frame_tree_node_);
599 proxy_hosts_[site_instance->GetId()] = proxy;
600 render_frame_host->SwapOut(proxy);
601 if (frame_tree_node_->IsMainFrame())
602 proxy->TakeFrameHostOwnership(render_frame_host.Pass());
603 } else {
604 // We won't be coming back, so delete this one.
605 render_frame_host.reset();
606 }
607 }
608
562 void RenderFrameHostManager::MoveToPendingDeleteHosts( 609 void RenderFrameHostManager::MoveToPendingDeleteHosts(
563 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 610 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
564 // |render_frame_host| will be deleted when its SwapOut ACK is received, or 611 // |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 612 // when the timer times out, or when the RFHM itself is deleted (whichever
566 // comes first). 613 // comes first).
567 pending_delete_hosts_.push_back( 614 pending_delete_hosts_.push_back(
568 linked_ptr<RenderFrameHostImpl>(render_frame_host.release())); 615 linked_ptr<RenderFrameHostImpl>(render_frame_host.release()));
569 } 616 }
570 617
571 bool RenderFrameHostManager::IsPendingDeletion( 618 bool RenderFrameHostManager::IsPendingDeletion(
(...skipping 15 matching lines...) Expand all
587 return true; 634 return true;
588 } 635 }
589 } 636 }
590 return false; 637 return false;
591 } 638 }
592 639
593 void RenderFrameHostManager::ResetProxyHosts() { 640 void RenderFrameHostManager::ResetProxyHosts() {
594 STLDeleteValues(&proxy_hosts_); 641 STLDeleteValues(&proxy_hosts_);
595 } 642 }
596 643
644 void RenderFrameHostManager::WillBeginNavigating(
645 const FrameHostMsg_BeginNavigation_Params& params,
646 const CommonNavigationParams& common_params) {
647 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
648 switches::kEnableBrowserSideNavigation));
649 // If there is an ongoing navigation, just clean it up.
650 CleanUpCurrentNavigation();
651
652 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
653 // TODO(carlosk): Replace the default values by the right ones.
654 scoped_refptr<SiteInstanceImpl> new_instance =
655 static_cast<SiteInstanceImpl*>(GetSiteInstanceForNavigation(
656 common_params.url, NULL, common_params.transition, false, false,
657 true));
658
659 if (new_instance.get() != current_instance) {
660 // Navigating to a new SiteInstance -> speculatively create a new RFH
661
662 // TODO(carlosk): what the TRACE_EVENT_INSTANT2 for New SiteInstance found
663 // in UpdateStateForNavigate be copied here?
664
665 bool success = CreateSpeculativeRenderFrameHost(
666 common_params.url, current_instance, new_instance.get());
667 if (!success) {
668 return;
669 }
670 } else {
671 // Navigating to the same SiteInstance -> make sure the current RFH is alive
672
673 // TODO(carlosk): do I need to AddPendingView() in this case as well???
674 DCHECK(render_frame_host_->GetSiteInstance() == new_instance);
675 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) {
676 // Recreate the opener chain.
677 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
678 render_frame_host_->GetSiteInstance());
679 if (!InitRenderView(render_frame_host_->render_view_host(),
680 opener_route_id, MSG_ROUTING_NONE,
681 frame_tree_node_->IsMainFrame())) {
682 return;
683 }
684 }
685 }
686 DCHECK(new_instance->GetProcess()->HasConnection());
687 DCHECK(new_instance->GetProcess()->GetBrowserContext());
688 }
689
690 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
691 const GURL& url, SiteInstance* old_instance, SiteInstance* new_instance) {
692 CHECK(new_instance);
693 CHECK_NE(old_instance, new_instance);
694
695 // TODO(carlosk): should also try to reuse the current web_ui
696 // (ShouldReuseWebUI)?
697 scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url));
698 // TODO(carlosk): confirm this next section copied from SetPendingWebUI
699 // is in fact needed... I need access to the respective navigation entry
700 // though.
701 // If we have assigned (zero or more) bindings to this NavigationEntry in the
702 // past, make sure we're not granting it different bindings than it had
703 // before. If so, note it and don't give it any bindings, to avoid a
704 // potential privilege escalation.
705 // if (new_web_ui &&
706 // bindings != NavigationEntryImpl::kInvalidBindings &&
707 // new_web_ui->GetBindings() != bindings) {
708 // RecordAction(
709 // base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
710 // new_web_ui.reset();
711 // }
712
713 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
714
715 // Check if we've already created an RFH for this SiteInstance. If so, try
716 // to re-use the existing one, which has already been initialized. We'll
717 // remove it from the list of proxy hosts below if it will be active.
718 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(new_instance);
719 if (proxy && proxy->render_frame_host()) {
720 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
721 // Prevent the process from exiting while we're trying to use it.
722 new_render_frame_host = proxy->PassFrameHostOwnership();
723 new_render_frame_host->GetProcess()->AddPendingView();
724
725 proxy_hosts_.erase(new_instance->GetId());
726 delete proxy;
727
728 // When a new render view is created by the renderer, the new WebContents
729 // gets a RenderViewHost in the SiteInstance of its opener WebContents.
730 // If not used in the first navigation, this RVH is swapped out and is not
731 // granted bindings, so we may need to grant them when swapping it in.
732 if (new_web_ui && !new_render_frame_host->GetProcess()->IsIsolatedGuest()) {
733 int required_bindings = new_web_ui->GetBindings();
734 RenderViewHost* rvh = new_render_frame_host->render_view_host();
735 if ((rvh->GetEnabledBindings() & required_bindings) !=
736 required_bindings) {
737 rvh->AllowBindings(required_bindings);
738 }
739 }
740 } else {
741 // Create a new RenderFrameHost if we don't find an existing one.
742 new_render_frame_host =
743 CreateRenderFrameHost(new_instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
744 false, delegate_->IsHidden());
745 DCHECK(new_render_frame_host);
746 RenderViewHostImpl* rvh = new_render_frame_host->render_view_host();
747
748 // Prevent the process from exiting while we're trying to navigate in it.
749 // Otherwise, if the new RFH is swapped out already, store it.
750 new_render_frame_host->GetProcess()->AddPendingView();
751
752 // Ensure that we have created RFHs for the new RFH's opener chain if
753 // we are staying in the same BrowsingInstance. This allows the new RFH
754 // to send cross-process script calls to its opener(s).
755 int opener_route_id = MSG_ROUTING_NONE;
756 if (new_instance->IsRelatedSiteInstance(old_instance)) {
757 opener_route_id =
758 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
759 if (CommandLine::ForCurrentProcess()->HasSwitch(
760 switches::kSitePerProcess)) {
761 // Ensure that the frame tree has RenderFrameProxyHosts for the new
762 // SiteInstance in all nodes except the current one.
763 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance(
764 frame_tree_node_, new_instance);
765 }
766 }
767
768 bool success = InitRenderView(rvh, opener_route_id, MSG_ROUTING_NONE,
769 frame_tree_node_->IsMainFrame());
770 if (success) {
771 if (frame_tree_node_->IsMainFrame()) {
772 // Don't show the main frame's view until we know it will be used.
773 rvh->GetView()->Hide();
774 } else {
775 // Init the RFH, so a RenderFrame is created in the renderer.
776 success = InitRenderFrame(new_render_frame_host.get());
777 }
778 }
779 if (!success) {
780 return false;
781 }
782 // TODO(carlosk): find out if this should be called here or only later on.
carlosk 2014/11/05 16:45:45 This is also a question to reviewers...
783 render_frame_delegate_->RenderFrameCreated(new_render_frame_host.get());
784 }
785
786 DCHECK(new_render_frame_host->GetSiteInstance() == new_instance);
787 speculative_render_frame_host_.reset(new_render_frame_host.release());
788 speculative_web_ui_.reset(new_web_ui.release());
789 return true;
790 }
791
597 // PlzNavigate 792 // PlzNavigate
598 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( 793 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
599 const GURL& url, 794 const GURL& url,
600 ui::PageTransition transition) { 795 ui::PageTransition transition) {
601 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( 796 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
602 switches::kEnableBrowserSideNavigation)); 797 switches::kEnableBrowserSideNavigation));
603 // TODO(clamy): When we handle renderer initiated navigations, make sure not 798 // 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 799 // to use a different process for subframes if --site-per-process is not
605 // enabled. 800 // enabled.
606 801
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 controller.GetBrowserContext(), current_entry->GetURL()) == 945 controller.GetBrowserContext(), current_entry->GetURL()) ==
751 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 946 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
752 controller.GetBrowserContext(), new_url)); 947 controller.GetBrowserContext(), new_url));
753 } 948 }
754 949
755 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( 950 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
756 const GURL& dest_url, 951 const GURL& dest_url,
757 SiteInstance* dest_instance, 952 SiteInstance* dest_instance,
758 ui::PageTransition dest_transition, 953 ui::PageTransition dest_transition,
759 bool dest_is_restore, 954 bool dest_is_restore,
760 bool dest_is_view_source_mode) { 955 bool dest_is_view_source_mode,
956 bool create_unbounded_site_instance) {
761 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 957 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
762 SiteInstance* new_instance = current_instance; 958 SiteInstance* new_instance = current_instance;
763 959
764 // We do not currently swap processes for navigations in webview tag guests. 960 // We do not currently swap processes for navigations in webview tag guests.
765 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme)) 961 if (current_instance->GetSiteURL().SchemeIs(kGuestScheme))
766 return current_instance; 962 return current_instance;
767 963
768 // Determine if we need a new BrowsingInstance for this entry. If true, this 964 // 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 965 // 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. 966 // 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 ? 978 bool current_is_view_source_mode = current_entry ?
783 current_entry->IsViewSourceMode() : dest_is_view_source_mode; 979 current_entry->IsViewSourceMode() : dest_is_view_source_mode;
784 bool force_swap = ShouldSwapBrowsingInstancesForNavigation( 980 bool force_swap = ShouldSwapBrowsingInstancesForNavigation(
785 current_effective_url, 981 current_effective_url,
786 current_is_view_source_mode, 982 current_is_view_source_mode,
787 dest_instance, 983 dest_instance,
788 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url), 984 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
789 dest_is_view_source_mode); 985 dest_is_view_source_mode);
790 if (ShouldTransitionCrossSite() || force_swap) { 986 if (ShouldTransitionCrossSite() || force_swap) {
791 new_instance = GetSiteInstanceForURL( 987 new_instance = GetSiteInstanceForURL(
792 dest_url, 988 dest_url, dest_instance, dest_transition, dest_is_restore,
793 dest_instance, 989 dest_is_view_source_mode, current_instance, force_swap,
794 dest_transition, 990 create_unbounded_site_instance);
795 dest_is_restore,
796 dest_is_view_source_mode,
797 current_instance,
798 force_swap);
799 } 991 }
800 992
801 // If force_swap is true, we must use a different SiteInstance. If we didn't, 993 // 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 994 // we would have two RenderFrameHosts in the same SiteInstance and the same
803 // frame, resulting in page_id conflicts for their NavigationEntries. 995 // frame, resulting in page_id conflicts for their NavigationEntries.
804 if (force_swap) 996 if (force_swap)
805 CHECK_NE(new_instance, current_instance); 997 CHECK_NE(new_instance, current_instance);
806 return new_instance; 998 return new_instance;
807 } 999 }
808 1000
809 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL( 1001 SiteInstance* RenderFrameHostManager::GetSiteInstanceForURL(
810 const GURL& dest_url, 1002 const GURL& dest_url,
811 SiteInstance* dest_instance, 1003 SiteInstance* dest_instance,
812 ui::PageTransition dest_transition, 1004 ui::PageTransition dest_transition,
813 bool dest_is_restore, 1005 bool dest_is_restore,
814 bool dest_is_view_source_mode, 1006 bool dest_is_view_source_mode,
815 SiteInstance* current_instance, 1007 SiteInstance* current_instance,
816 bool force_browsing_instance_swap) { 1008 bool force_browsing_instance_swap,
1009 bool create_unbounded_site_instance) {
817 NavigationControllerImpl& controller = 1010 NavigationControllerImpl& controller =
818 delegate_->GetControllerForRenderManager(); 1011 delegate_->GetControllerForRenderManager();
819 BrowserContext* browser_context = controller.GetBrowserContext(); 1012 BrowserContext* browser_context = controller.GetBrowserContext();
820 1013
821 // If the entry has an instance already we should use it. 1014 // If the entry has an instance already we should use it.
822 if (dest_instance) { 1015 if (dest_instance) {
823 // If we are forcing a swap, this should be in a different BrowsingInstance. 1016 // If we are forcing a swap, this should be in a different BrowsingInstance.
824 if (force_browsing_instance_swap) { 1017 if (force_browsing_instance_swap) {
825 CHECK(!dest_instance->IsRelatedSiteInstance( 1018 CHECK(!dest_instance->IsRelatedSiteInstance(
826 render_frame_host_->GetSiteInstance())); 1019 render_frame_host_->GetSiteInstance()));
827 } 1020 }
828 return dest_instance; 1021 return dest_instance;
829 } 1022 }
830 1023
1024 SiteInstanceImpl* current_site_instance =
1025 static_cast<SiteInstanceImpl*>(current_instance);
1026
831 // If a swap is required, we need to force the SiteInstance AND 1027 // If a swap is required, we need to force the SiteInstance AND
832 // BrowsingInstance to be different ones, using CreateForURL. 1028 // BrowsingInstance to be different ones, using CreateForURL.
833 if (force_browsing_instance_swap) 1029 if (force_browsing_instance_swap) {
834 return SiteInstance::CreateForURL(browser_context, dest_url); 1030 return CreateSiteInstanceForURL(browser_context, dest_url,
1031 create_unbounded_site_instance,
1032 current_site_instance);
1033 }
835 1034
836 // (UGLY) HEURISTIC, process-per-site only: 1035 // (UGLY) HEURISTIC, process-per-site only:
837 // 1036 //
838 // If this navigation is generated, then it probably corresponds to a search 1037 // If this navigation is generated, then it probably corresponds to a search
839 // query. Given that search results typically lead to users navigating to 1038 // 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 1039 // other sites, we don't really want to use the search engine hostname to
841 // determine the site instance for this navigation. 1040 // determine the site instance for this navigation.
842 // 1041 //
843 // NOTE: This can be removed once we have a way to transition between 1042 // NOTE: This can be removed once we have a way to transition between
844 // RenderViews in response to a link click. 1043 // RenderViews in response to a link click.
845 // 1044 //
846 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) && 1045 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) &&
847 ui::PageTransitionCoreTypeIs( 1046 ui::PageTransitionCoreTypeIs(
848 dest_transition, ui::PAGE_TRANSITION_GENERATED)) { 1047 dest_transition, ui::PAGE_TRANSITION_GENERATED)) {
849 return current_instance; 1048 return current_instance;
850 } 1049 }
851 1050
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 1051 // 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 1052 // for this entry. We won't commit the SiteInstance to this site until the
857 // navigation commits (in DidNavigate), unless the navigation entry was 1053 // navigation commits (in DidNavigate), unless the navigation entry was
858 // restored or it's a Web UI as described below. 1054 // restored or it's a Web UI as described below.
859 if (!current_site_instance->HasSite()) { 1055 if (!current_site_instance->HasSite()) {
860 // If we've already created a SiteInstance for our destination, we don't 1056 // 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 1057 // 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 1058 // 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. 1059 // 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 1060 // In this case, there is no current URL, so comparing against the site is
865 // ok. See additional comments below.) 1061 // ok. See additional comments below.)
866 // 1062 //
867 // Also, if the URL should use process-per-site mode and there is an 1063 // 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 1064 // existing process for the site, we should use it. We can call
869 // GetRelatedSiteInstance() for this, which will eagerly set the site and 1065 // GetRelatedSiteInstance() for this, which will eagerly set the site and
870 // thus use the correct process. 1066 // thus use the correct process.
871 bool use_process_per_site = 1067 bool use_process_per_site =
872 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) && 1068 RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) &&
873 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url); 1069 RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url);
874 if (current_site_instance->HasRelatedSiteInstance(dest_url) || 1070 if (current_site_instance->HasRelatedSiteInstance(dest_url) ||
875 use_process_per_site) { 1071 use_process_per_site) {
876 return current_site_instance->GetRelatedSiteInstance(dest_url); 1072 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url,
1073 create_unbounded_site_instance);
877 } 1074 }
878 1075
879 // For extensions, Web UI URLs (such as the new tab page), and apps we do 1076 // 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 1077 // 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 1078 // have a RenderProcessHost of PRIV_NORMAL. Create a new SiteInstance for
882 // this URL instead (with the correct process type). 1079 // this URL instead (with the correct process type).
883 if (current_site_instance->HasWrongProcessForURL(dest_url)) 1080 if (current_site_instance->HasWrongProcessForURL(dest_url)) {
884 return current_site_instance->GetRelatedSiteInstance(dest_url); 1081 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url,
1082 create_unbounded_site_instance);
1083 }
885 1084
886 // View-source URLs must use a new SiteInstance and BrowsingInstance. 1085 // View-source URLs must use a new SiteInstance and BrowsingInstance.
887 // TODO(nasko): This is the same condition as later in the function. This 1086 // 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 1087 // should be taken into account when refactoring this method as part of
889 // http://crbug.com/123007. 1088 // http://crbug.com/123007.
890 if (dest_is_view_source_mode) 1089 if (dest_is_view_source_mode) {
891 return SiteInstance::CreateForURL(browser_context, dest_url); 1090 return CreateSiteInstanceForURL(browser_context, dest_url,
1091 create_unbounded_site_instance,
1092 current_site_instance);
1093 }
892 1094
893 // If we are navigating from a blank SiteInstance to a WebUI, make sure we 1095 // If we are navigating from a blank SiteInstance to a WebUI, make sure we
894 // create a new SiteInstance. 1096 // create a new SiteInstance.
895 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 1097 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
896 browser_context, dest_url)) { 1098 browser_context, dest_url)) {
897 return SiteInstance::CreateForURL(browser_context, dest_url); 1099 return CreateSiteInstanceForURL(browser_context, dest_url,
1100 create_unbounded_site_instance,
1101 current_site_instance);
898 } 1102 }
899 1103
900 // Normally the "site" on the SiteInstance is set lazily when the load 1104 // Normally the "site" on the SiteInstance is set lazily when the load
901 // actually commits. This is to support better process sharing in case 1105 // 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 1106 // the site redirects to some other site: we want to use the destination
903 // site in the site instance. 1107 // site in the site instance.
904 // 1108 //
905 // In the case of session restore, as it loads all the pages immediately 1109 // 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 1110 // we need to set the site first, otherwise after a restore none of the
907 // pages would share renderers in process-per-site. 1111 // pages would share renderers in process-per-site.
908 // 1112 //
909 // The embedder can request some urls never to be assigned to SiteInstance 1113 // The embedder can request some urls never to be assigned to SiteInstance
910 // through the ShouldAssignSiteForURL() content client method, so that 1114 // through the ShouldAssignSiteForURL() content client method, so that
911 // renderers created for particular chrome urls (e.g. the chrome-native:// 1115 // renderers created for particular chrome urls (e.g. the chrome-native://
912 // scheme) can be reused for subsequent navigations in the same WebContents. 1116 // scheme) can be reused for subsequent navigations in the same WebContents.
913 // See http://crbug.com/386542. 1117 // See http://crbug.com/386542.
914 if (dest_is_restore && 1118 if (dest_is_restore &&
915 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) { 1119 GetContentClient()->browser()->ShouldAssignSiteForURL(dest_url)) {
916 current_site_instance->SetSite(dest_url); 1120 current_site_instance->SetSite(dest_url);
917 } 1121 }
918
carlosk 2014/11/05 16:45:44 I already added this back locally.
919 return current_site_instance; 1122 return current_site_instance;
920 } 1123 }
921 1124
922 // Otherwise, only create a new SiteInstance for a cross-site navigation. 1125 // Otherwise, only create a new SiteInstance for a cross-site navigation.
923 1126
924 // TODO(creis): Once we intercept links and script-based navigations, we 1127 // TODO(creis): Once we intercept links and script-based navigations, we
925 // will be able to enforce that all entries in a SiteInstance actually have 1128 // will be able to enforce that all entries in a SiteInstance actually have
926 // the same site, and it will be safe to compare the URL against the 1129 // the same site, and it will be safe to compare the URL against the
927 // SiteInstance's site, as follows: 1130 // SiteInstance's site, as follows:
928 // const GURL& current_url = current_instance->site(); 1131 // const GURL& current_url = current_instance->site();
929 // For now, though, we're in a hybrid model where you only switch 1132 // For now, though, we're in a hybrid model where you only switch
930 // SiteInstances if you type in a cross-site URL. This means we have to 1133 // SiteInstances if you type in a cross-site URL. This means we have to
931 // compare the entry's URL to the last committed entry's URL. 1134 // compare the entry's URL to the last committed entry's URL.
932 NavigationEntry* current_entry = controller.GetLastCommittedEntry(); 1135 NavigationEntry* current_entry = controller.GetLastCommittedEntry();
933 if (interstitial_page_) { 1136 if (interstitial_page_) {
934 // The interstitial is currently the last committed entry, but we want to 1137 // The interstitial is currently the last committed entry, but we want to
935 // compare against the last non-interstitial entry. 1138 // compare against the last non-interstitial entry.
936 current_entry = controller.GetEntryAtOffset(-1); 1139 current_entry = controller.GetEntryAtOffset(-1);
937 } 1140 }
938 1141
939 // View-source URLs must use a new SiteInstance and BrowsingInstance. 1142 // 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 1143 // We don't need a swap when going from view-source to a debug URL like
941 // chrome://crash, however. 1144 // chrome://crash, however.
942 // TODO(creis): Refactor this method so this duplicated code isn't needed. 1145 // TODO(creis): Refactor this method so this duplicated code isn't needed.
943 // See http://crbug.com/123007. 1146 // See http://crbug.com/123007.
944 if (current_entry && 1147 if (current_entry &&
945 current_entry->IsViewSourceMode() != dest_is_view_source_mode && 1148 current_entry->IsViewSourceMode() != dest_is_view_source_mode &&
946 !IsRendererDebugURL(dest_url)) { 1149 !IsRendererDebugURL(dest_url)) {
947 return SiteInstance::CreateForURL(browser_context, dest_url); 1150 return CreateSiteInstanceForURL(browser_context, dest_url,
1151 create_unbounded_site_instance,
1152 current_site_instance);
948 } 1153 }
949 1154
950 // Use the current SiteInstance for same site navigations, as long as the 1155 // 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 1156 // process type is correct. (The URL may have been installed as an app since
952 // the last time we visited it.) 1157 // the last time we visited it.)
953 const GURL& current_url = 1158 const GURL& current_url =
954 GetCurrentURLForSiteInstance(current_instance, current_entry); 1159 GetCurrentURLForSiteInstance(current_instance, current_entry);
955 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) && 1160 if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
956 !current_site_instance->HasWrongProcessForURL(dest_url)) { 1161 !current_site_instance->HasWrongProcessForURL(dest_url)) {
957 return current_instance; 1162 return current_instance;
958 } 1163 }
959 1164
960 // Start the new renderer in a new SiteInstance, but in the current 1165 // Start the new renderer in a new SiteInstance, but in the current
961 // BrowsingInstance. It is important to immediately give this new 1166 // BrowsingInstance. It is important to immediately give this new
962 // SiteInstance to a RenderViewHost (if it is different than our current 1167 // SiteInstance to a RenderViewHost (if it is different than our current
963 // SiteInstance), so that it is ref counted. This will happen in 1168 // SiteInstance), so that it is ref counted. This will happen in
964 // CreateRenderView. 1169 // CreateRenderView.
1170 return GetRelatedSiteInstanceForURL(current_site_instance, dest_url,
1171 create_unbounded_site_instance);
1172 }
1173
1174 SiteInstance* RenderFrameHostManager::CreateSiteInstanceForURL(
1175 BrowserContext* browser_context,
1176 const GURL& dest_url,
1177 bool create_unbounded_site_instance,
1178 SiteInstanceImpl* current_instance) {
1179 if (CommandLine::ForCurrentProcess()->HasSwitch(
1180 switches::kEnableBrowserSideNavigation)) {
1181 if (create_unbounded_site_instance) {
1182 return SiteInstance::Create(browser_context);
1183 }
1184 if (speculative_render_frame_host_) {
1185 SiteInstanceImpl* sii = speculative_render_frame_host_->GetSiteInstance();
1186 if (!sii->HasSite() && !sii->IsRelatedSiteInstance(current_instance)) {
1187 return sii;
1188 }
1189 }
1190 }
1191
1192 return SiteInstance::CreateForURL(browser_context, dest_url);
1193 }
1194
1195 SiteInstance* RenderFrameHostManager::GetRelatedSiteInstanceForURL(
1196 SiteInstanceImpl* current_instance,
1197 const GURL& dest_url,
1198 bool create_unbounded_site_instance) {
1199 if (CommandLine::ForCurrentProcess()->HasSwitch(
1200 switches::kEnableBrowserSideNavigation)) {
1201 if (!current_instance->HasRelatedSiteInstance(dest_url)) {
1202 if (create_unbounded_site_instance) {
1203 return current_instance->GetRelatedEmptySiteInstance();
1204 }
1205 if (speculative_render_frame_host_) {
1206 SiteInstanceImpl* sii =
1207 speculative_render_frame_host_->GetSiteInstance();
1208 if (!sii->HasSite() && sii->IsRelatedSiteInstance(current_instance)) {
1209 return sii;
1210 }
1211 }
1212 }
1213 }
1214
965 return current_instance->GetRelatedSiteInstance(dest_url); 1215 return current_instance->GetRelatedSiteInstance(dest_url);
966 } 1216 }
967 1217
968 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance( 1218 const GURL& RenderFrameHostManager::GetCurrentURLForSiteInstance(
969 SiteInstance* current_instance, NavigationEntry* current_entry) { 1219 SiteInstance* current_instance, NavigationEntry* current_entry) {
970 // If this is a subframe that is potentially out of process from its parent, 1220 // 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 1221 // 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 1222 // current_entry's url is for the main frame and may be in a different site
973 // than this frame. 1223 // than this frame.
974 // TODO(creis): Remove this when we can check the FrameNavigationEntry's url. 1224 // 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()); 1440 render_view_host->AllowBindings(pending_web_ui()->GetBindings());
1191 } else { 1441 } else {
1192 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled 1442 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
1193 // process unless it's swapped out. 1443 // process unless it's swapped out.
1194 if (render_view_host->is_active()) { 1444 if (render_view_host->is_active()) {
1195 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1445 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1196 render_view_host->GetProcess()->GetID())); 1446 render_view_host->GetProcess()->GetID()));
1197 } 1447 }
1198 } 1448 }
1199 1449
1200 return delegate_->CreateRenderViewForRenderManager(render_view_host, 1450 return delegate_->CreateRenderViewForRenderManager(
1201 opener_route_id, 1451 render_view_host, opener_route_id, proxy_routing_id,
1202 proxy_routing_id, 1452 for_main_frame_navigation);
carlosk 2014/11/05 16:45:44 IDK why but git cl format decided that this should
1203 for_main_frame_navigation);
1204 } 1453 }
1205 1454
1206 bool RenderFrameHostManager::InitRenderFrame( 1455 bool RenderFrameHostManager::InitRenderFrame(
1207 RenderFrameHostImpl* render_frame_host) { 1456 RenderFrameHostImpl* render_frame_host) {
1208 if (render_frame_host->IsRenderFrameLive()) 1457 if (render_frame_host->IsRenderFrameLive())
1209 return true; 1458 return true;
1210 1459
1211 int parent_routing_id = MSG_ROUTING_NONE; 1460 int parent_routing_id = MSG_ROUTING_NONE;
1212 int proxy_routing_id = MSG_ROUTING_NONE; 1461 int proxy_routing_id = MSG_ROUTING_NONE;
1213 if (frame_tree_node_->parent()) { 1462 if (frame_tree_node_->parent()) {
(...skipping 25 matching lines...) Expand all
1239 return render_frame_host_->GetRoutingID(); 1488 return render_frame_host_->GetRoutingID();
1240 1489
1241 RenderFrameProxyHostMap::iterator iter = 1490 RenderFrameProxyHostMap::iterator iter =
1242 proxy_hosts_.find(site_instance->GetId()); 1491 proxy_hosts_.find(site_instance->GetId());
1243 if (iter != proxy_hosts_.end()) 1492 if (iter != proxy_hosts_.end())
1244 return iter->second->GetRoutingID(); 1493 return iter->second->GetRoutingID();
1245 1494
1246 return MSG_ROUTING_NONE; 1495 return MSG_ROUTING_NONE;
1247 } 1496 }
1248 1497
1249 void RenderFrameHostManager::CommitPending() { 1498 void RenderFrameHostManager::CommitPending(bool use_speculative_rfh) {
1250 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 1499 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
1251 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1500 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1501 // If use_speculative_rfh then kEnableBrowserSideNavigation must be enabled.
1502 DCHECK(!use_speculative_rfh ||
1503 CommandLine::ForCurrentProcess()->HasSwitch(
1504 switches::kEnableBrowserSideNavigation));
1505
1252 // First check whether we're going to want to focus the location bar after 1506 // 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 1507 // 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 1508 // 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. 1509 // this triggers won't be able to figure out what's going on.
1256 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1510 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1257 1511
1258 // Next commit the Web UI, if any. Either replace |web_ui_| with 1512 if (!use_speculative_rfh) {
1259 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 1513 DCHECK(!speculative_web_ui_);
1260 // leave |web_ui_| as is if reusing it. 1514 // Next commit the Web UI, if any. Either replace |web_ui_| with
1261 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); 1515 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
1262 if (pending_web_ui_) { 1516 // leave |web_ui_| as is if reusing it.
1263 web_ui_.reset(pending_web_ui_.release()); 1517 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
1264 } else if (!pending_and_current_web_ui_.get()) { 1518 if (pending_web_ui_) {
1265 web_ui_.reset(); 1519 web_ui_.reset(pending_web_ui_.release());
1520 } else if (!pending_and_current_web_ui_.get()) {
1521 web_ui_.reset();
1522 } else {
1523 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
1524 pending_and_current_web_ui_.reset();
1525 }
1266 } else { 1526 } else {
1267 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); 1527 web_ui_.reset(speculative_web_ui_.release());
1268 pending_and_current_web_ui_.reset();
1269 } 1528 }
1270 1529
1271 // It's possible for the pending_render_frame_host_ to be NULL when we aren't 1530 // 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 1531 // crossing process boundaries. If so, we just needed to handle the Web UI
1273 // committing above and we're done. 1532 // committing above and we're done.
1274 if (!pending_render_frame_host_) { 1533 if (!pending_render_frame_host_ && !use_speculative_rfh) {
1275 if (will_focus_location_bar) 1534 if (will_focus_location_bar)
1276 delegate_->SetFocusToLocationBar(false); 1535 delegate_->SetFocusToLocationBar(false);
1277 return; 1536 return;
1278 } 1537 }
1279 1538
1280 // Remember if the page was focused so we can focus the new renderer in 1539 // Remember if the page was focused so we can focus the new renderer in
1281 // that case. 1540 // that case.
1282 bool focus_render_view = !will_focus_location_bar && 1541 bool focus_render_view = !will_focus_location_bar &&
1283 render_frame_host_->render_view_host()->GetView() && 1542 render_frame_host_->render_view_host()->GetView() &&
1284 render_frame_host_->render_view_host()->GetView()->HasFocus(); 1543 render_frame_host_->render_view_host()->GetView()->HasFocus();
1285 1544
1286 bool is_main_frame = frame_tree_node_->IsMainFrame(); 1545 bool is_main_frame = frame_tree_node_->IsMainFrame();
1287 1546
1288 // Swap in the pending frame and make it active. Also ensure the FrameTree 1547 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
1289 // stays in sync. 1548 if (!use_speculative_rfh) {
1290 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1549 DCHECK(!speculative_render_frame_host_);
1291 SetRenderFrameHost(pending_render_frame_host_.Pass()); 1550 // Swap in the pending frame and make it active. Also ensure the FrameTree
1551 // stays in sync.
1552 old_render_frame_host =
1553 SetRenderFrameHost(pending_render_frame_host_.Pass());
1554 } else {
1555 DCHECK(speculative_render_frame_host_);
1556 old_render_frame_host =
1557 SetRenderFrameHost(speculative_render_frame_host_.Pass());
1558 }
1559
1292 if (is_main_frame) 1560 if (is_main_frame)
1293 render_frame_host_->render_view_host()->AttachToFrameTree(); 1561 render_frame_host_->render_view_host()->AttachToFrameTree();
1294 1562
1295 // The process will no longer try to exit, so we can decrement the count. 1563 // The process will no longer try to exit, so we can decrement the count.
1296 render_frame_host_->GetProcess()->RemovePendingView(); 1564 render_frame_host_->GetProcess()->RemovePendingView();
1297 1565
1298 // Show the new view (or a sad tab) if necessary. 1566 // Show the new view (or a sad tab) if necessary.
1299 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); 1567 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView();
1300 if (!delegate_->IsHidden() && new_rfh_has_view) { 1568 if (!delegate_->IsHidden() && new_rfh_has_view) {
1301 // In most cases, we need to show the new view. 1569 // 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 1676 // If we are currently navigating cross-process, we want to get back to normal
1409 // and then navigate as usual. 1677 // and then navigate as usual.
1410 if (cross_navigation_pending_) { 1678 if (cross_navigation_pending_) {
1411 if (pending_render_frame_host_) 1679 if (pending_render_frame_host_)
1412 CancelPending(); 1680 CancelPending();
1413 cross_navigation_pending_ = false; 1681 cross_navigation_pending_ = false;
1414 } 1682 }
1415 1683
1416 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1684 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1417 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( 1685 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
1418 url, instance, transition, is_restore, is_view_source_mode); 1686 url, instance, transition, is_restore, is_view_source_mode, false);
1687
1688 if (CommandLine::ForCurrentProcess()->HasSwitch(
1689 switches::kEnableBrowserSideNavigation) &&
1690 speculative_render_frame_host_) {
1691 if (speculative_render_frame_host_->GetSiteInstance() == new_instance) {
1692 return speculative_render_frame_host_.get();
1693 }
1694 CleanUpCurrentNavigation();
1695 }
1419 1696
1420 const NavigationEntry* current_entry = 1697 const NavigationEntry* current_entry =
1421 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 1698 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1422 1699
1423 if (new_instance.get() != current_instance) { 1700 if (new_instance.get() != current_instance) {
1424 TRACE_EVENT_INSTANT2( 1701 TRACE_EVENT_INSTANT2(
1425 "navigation", 1702 "navigation",
1426 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 1703 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
1427 TRACE_EVENT_SCOPE_THREAD, 1704 TRACE_EVENT_SCOPE_THREAD,
1428 "current_instance id", current_instance->GetId(), 1705 "current_instance id", current_instance->GetId(),
(...skipping 16 matching lines...) Expand all
1445 } 1722 }
1446 1723
1447 // Check if our current RFH is live before we set up a transition. 1724 // Check if our current RFH is live before we set up a transition.
1448 if (!render_frame_host_->IsRenderFrameLive()) { 1725 if (!render_frame_host_->IsRenderFrameLive()) {
1449 if (!cross_navigation_pending_) { 1726 if (!cross_navigation_pending_) {
1450 // The current RFH is not live. There's no reason to sit around with a 1727 // 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 1728 // 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 1729 // 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 1730 // cross-navigating (Note that we don't care about on{before}unload
1454 // handlers if the current RFH isn't live.) 1731 // handlers if the current RFH isn't live.)
1455 CommitPending(); 1732 CommitPending(false);
1456 return render_frame_host_.get(); 1733 return render_frame_host_.get();
1457 } else { 1734 } else {
1458 NOTREACHED(); 1735 NOTREACHED();
1459 return render_frame_host_.get(); 1736 return render_frame_host_.get();
1460 } 1737 }
1461 } 1738 }
1462 // Otherwise, it's safe to treat this as a pending cross-site transition. 1739 // Otherwise, it's safe to treat this as a pending cross-site transition.
1463 1740
1464 // We now have a pending RFH. 1741 // We now have a pending RFH.
1465 DCHECK(!cross_navigation_pending_); 1742 DCHECK(!cross_navigation_pending_);
(...skipping 28 matching lines...) Expand all
1494 render_frame_host_->Send(new FrameMsg_Stop( 1771 render_frame_host_->Send(new FrameMsg_Stop(
1495 render_frame_host_->GetRoutingID())); 1772 render_frame_host_->GetRoutingID()));
1496 pending_render_frame_host_->SetNavigationsSuspended(true, 1773 pending_render_frame_host_->SetNavigationsSuspended(true,
1497 base::TimeTicks()); 1774 base::TimeTicks());
1498 // Unless we are transferring an existing request, we should now tell the 1775 // Unless we are transferring an existing request, we should now tell the
1499 // old render view to run its beforeunload handler, since it doesn't 1776 // old render view to run its beforeunload handler, since it doesn't
1500 // otherwise know that the cross-site request is happening. This will 1777 // otherwise know that the cross-site request is happening. This will
1501 // trigger a call to OnBeforeUnloadACK with the reply. 1778 // trigger a call to OnBeforeUnloadACK with the reply.
1502 render_frame_host_->DispatchBeforeUnload(true); 1779 render_frame_host_->DispatchBeforeUnload(true);
1503 } 1780 }
1504
carlosk 2014/11/05 16:45:44 I already added this back locally.
1505 return pending_render_frame_host_.get(); 1781 return pending_render_frame_host_.get();
1506 } 1782 }
1507 1783
1508 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. 1784 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_.
1509 DCHECK(!cross_navigation_pending_); 1785 DCHECK(!cross_navigation_pending_);
1510 1786
1511 // It's possible to swap out the current RFH and then decide to navigate in it 1787 // It's possible to swap out the current RFH and then decide to navigate in it
1512 // anyway (e.g., a cross-process navigation that redirects back to the 1788 // anyway (e.g., a cross-process navigation that redirects back to the
1513 // original site). In that case, we have a proxy for the current RFH but 1789 // original site). In that case, we have a proxy for the current RFH but
1514 // haven't deleted it yet. The new navigation will swap it back in, so we can 1790 // haven't deleted it yet. The new navigation will swap it back in, so we can
(...skipping 18 matching lines...) Expand all
1533 render_frame_host_->render_view_host()); 1809 render_frame_host_->render_view_host());
1534 } 1810 }
1535 1811
1536 // The renderer can exit view source mode when any error or cancellation 1812 // The renderer can exit view source mode when any error or cancellation
1537 // happen. We must overwrite to recover the mode. 1813 // happen. We must overwrite to recover the mode.
1538 if (is_view_source_mode) { 1814 if (is_view_source_mode) {
1539 render_frame_host_->render_view_host()->Send( 1815 render_frame_host_->render_view_host()->Send(
1540 new ViewMsg_EnableViewSourceMode( 1816 new ViewMsg_EnableViewSourceMode(
1541 render_frame_host_->render_view_host()->GetRoutingID())); 1817 render_frame_host_->render_view_host()->GetRoutingID()));
1542 } 1818 }
1543
carlosk 2014/11/05 16:45:44 I already added this back locally.
1544 return render_frame_host_.get(); 1819 return render_frame_host_.get();
1545 } 1820 }
1546 1821
1547 void RenderFrameHostManager::CancelPending() { 1822 void RenderFrameHostManager::CancelPending() {
1548 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", 1823 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
1549 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 1824 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
1550 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = 1825 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
1551 pending_render_frame_host_.Pass(); 1826 pending_render_frame_host_.Pass();
1552 1827
1553 RenderViewDevToolsAgentHost::OnCancelPendingNavigation( 1828 RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
1554 pending_render_frame_host->render_view_host(), 1829 pending_render_frame_host->render_view_host(),
1555 render_frame_host_->render_view_host()); 1830 render_frame_host_->render_view_host());
1556 1831
1557 // We no longer need to prevent the process from exiting. 1832 // We no longer need to prevent the process from exiting.
1558 pending_render_frame_host->GetProcess()->RemovePendingView(); 1833 pending_render_frame_host->GetProcess()->RemovePendingView();
1559 1834
1560 // If the SiteInstance for the pending RFH is being used by others, don't 1835 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 1836
1579 pending_web_ui_.reset(); 1837 pending_web_ui_.reset();
1580 pending_and_current_web_ui_.reset(); 1838 pending_and_current_web_ui_.reset();
1581 } 1839 }
1582 1840
1841 void RenderFrameHostManager::CleanUpCurrentNavigation() {
1842 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
1843 switches::kEnableBrowserSideNavigation));
1844 if (speculative_render_frame_host_) {
1845 speculative_render_frame_host_->GetProcess()->RemovePendingView();
1846 RecycleRenderFrameHost(speculative_render_frame_host_.Pass());
1847 }
1848 if (speculative_web_ui_) {
1849 speculative_web_ui_.reset();
1850 }
1851 }
1852
1583 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( 1853 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
1584 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 1854 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
1585 // Swap the two. 1855 // Swap the two.
1586 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 1856 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
1587 render_frame_host_.Pass(); 1857 render_frame_host_.Pass();
1588 render_frame_host_ = render_frame_host.Pass(); 1858 render_frame_host_ = render_frame_host.Pass();
1589 1859
1590 if (frame_tree_node_->IsMainFrame()) { 1860 if (frame_tree_node_->IsMainFrame()) {
1591 // Update the count of top-level frames using this SiteInstance. All 1861 // 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 1862 // 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( 1922 void RenderFrameHostManager::DeleteRenderFrameProxyHost(
1653 SiteInstance* instance) { 1923 SiteInstance* instance) {
1654 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); 1924 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId());
1655 if (iter != proxy_hosts_.end()) { 1925 if (iter != proxy_hosts_.end()) {
1656 delete iter->second; 1926 delete iter->second;
1657 proxy_hosts_.erase(iter); 1927 proxy_hosts_.erase(iter);
1658 } 1928 }
1659 } 1929 }
1660 1930
1661 } // namespace content 1931 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698