OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |