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