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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 RenderFrameHostDelegate* render_frame_delegate, | 53 RenderFrameHostDelegate* render_frame_delegate, |
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_(nullptr), |
| 64 should_reuse_web_ui_(false), |
64 weak_factory_(this) { | 65 weak_factory_(this) { |
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 UnsetPendingRenderFrameHost(); | 71 UnsetPendingRenderFrameHost(); |
71 | 72 |
| 73 if (speculative_render_frame_host_) |
| 74 UnsetSpeculativeRenderFrameHost(); |
| 75 |
72 if (render_frame_host_ && | 76 if (render_frame_host_ && |
73 render_frame_host_->GetSiteInstance()->active_frame_count() <= 1U) { | 77 render_frame_host_->GetSiteInstance()->active_frame_count() <= 1U) { |
74 ShutdownRenderFrameProxyHostsInSiteInstance( | 78 ShutdownRenderFrameProxyHostsInSiteInstance( |
75 render_frame_host_->GetSiteInstance()->GetId()); | 79 render_frame_host_->GetSiteInstance()->GetId()); |
76 } | 80 } |
77 | 81 |
78 // We should always have a current RenderFrameHost except in some tests. | 82 // We should always have a current RenderFrameHost except in some tests. |
79 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); | 83 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); |
80 | 84 |
81 // Delete any swapped out RenderFrameHosts. | 85 // Delete any swapped out RenderFrameHosts. |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 } | 289 } |
286 } | 290 } |
287 return false; | 291 return false; |
288 } | 292 } |
289 | 293 |
290 void RenderFrameHostManager::OnBeforeUnloadACK( | 294 void RenderFrameHostManager::OnBeforeUnloadACK( |
291 bool for_cross_site_transition, | 295 bool for_cross_site_transition, |
292 bool proceed, | 296 bool proceed, |
293 const base::TimeTicks& proceed_time) { | 297 const base::TimeTicks& proceed_time) { |
294 if (for_cross_site_transition) { | 298 if (for_cross_site_transition) { |
| 299 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 300 switches::kEnableBrowserSideNavigation)); |
295 // Ignore if we're not in a cross-site navigation. | 301 // Ignore if we're not in a cross-site navigation. |
296 if (!cross_navigation_pending_) | 302 if (!cross_navigation_pending_) |
297 return; | 303 return; |
298 | 304 |
299 if (proceed) { | 305 if (proceed) { |
300 // Ok to unload the current page, so proceed with the cross-site | 306 // Ok to unload the current page, so proceed with the cross-site |
301 // navigation. Note that if navigations are not currently suspended, it | 307 // navigation. Note that if navigations are not currently suspended, it |
302 // might be because the renderer was deemed unresponsive and this call was | 308 // might be because the renderer was deemed unresponsive and this call was |
303 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it | 309 // already made by ShouldCloseTabOnUnresponsiveRenderer. In that case, it |
304 // is ok to do nothing here. | 310 // is ok to do nothing here. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 response_started_id_.reset(); | 417 response_started_id_.reset(); |
412 } | 418 } |
413 | 419 |
414 void RenderFrameHostManager::ClearNavigationTransitionData() { | 420 void RenderFrameHostManager::ClearNavigationTransitionData() { |
415 render_frame_host_->ClearPendingTransitionRequestData(); | 421 render_frame_host_->ClearPendingTransitionRequestData(); |
416 } | 422 } |
417 | 423 |
418 void RenderFrameHostManager::DidNavigateFrame( | 424 void RenderFrameHostManager::DidNavigateFrame( |
419 RenderFrameHostImpl* render_frame_host, | 425 RenderFrameHostImpl* render_frame_host, |
420 bool was_caused_by_user_gesture) { | 426 bool was_caused_by_user_gesture) { |
| 427 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 428 switches::kEnableBrowserSideNavigation)) { |
| 429 if (render_frame_host == speculative_render_frame_host_.get()) { |
| 430 CommitPending(); |
| 431 } else if (render_frame_host == render_frame_host_.get()) { |
| 432 // TODO(carlosk): this code doesn't properly handle in-page navigation or |
| 433 // interwoven navigation requests. |
| 434 DCHECK(!speculative_render_frame_host_); |
| 435 } else { |
| 436 // No one else should be sending us a DidNavigate in this state. |
| 437 DCHECK(false); |
| 438 } |
| 439 DCHECK(!speculative_render_frame_host_); |
| 440 return; |
| 441 } |
| 442 |
421 if (!cross_navigation_pending_) { | 443 if (!cross_navigation_pending_) { |
422 DCHECK(!pending_render_frame_host_); | 444 DCHECK(!pending_render_frame_host_); |
423 | 445 |
424 // We should only hear this from our current renderer. | 446 // We should only hear this from our current renderer. |
425 DCHECK_EQ(render_frame_host_, render_frame_host); | 447 DCHECK_EQ(render_frame_host_, render_frame_host); |
426 | 448 |
427 // Even when there is no pending RVH, there may be a pending Web UI. | 449 // Even when there is no pending RVH, there may be a pending Web UI. |
428 if (pending_web_ui()) | 450 if (pending_web_ui()) |
429 CommitPending(); | 451 CommitPending(); |
430 return; | 452 return; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 // If the SiteInstance for the pending RFH is being used by others don't | 593 // If the SiteInstance for the pending RFH is being used by others don't |
572 // delete the RFH. Just swap it out and it can be reused at a later point. | 594 // delete the RFH. Just swap it out and it can be reused at a later point. |
573 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); | 595 SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance(); |
574 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { | 596 if (site_instance->HasSite() && site_instance->active_frame_count() > 1) { |
575 // Any currently suspended navigations are no longer needed. | 597 // Any currently suspended navigations are no longer needed. |
576 render_frame_host->CancelSuspendedNavigations(); | 598 render_frame_host->CancelSuspendedNavigations(); |
577 | 599 |
578 RenderFrameProxyHost* proxy = | 600 RenderFrameProxyHost* proxy = |
579 new RenderFrameProxyHost(site_instance, frame_tree_node_); | 601 new RenderFrameProxyHost(site_instance, frame_tree_node_); |
580 proxy_hosts_[site_instance->GetId()] = proxy; | 602 proxy_hosts_[site_instance->GetId()] = proxy; |
581 render_frame_host->SwapOut(proxy, false); | 603 |
| 604 // Check if the RenderFrameHost is already swapped out, to avoid swapping it |
| 605 // out again. |
| 606 if (!render_frame_host->is_swapped_out()) |
| 607 render_frame_host->SwapOut(proxy, false); |
| 608 |
582 if (frame_tree_node_->IsMainFrame()) | 609 if (frame_tree_node_->IsMainFrame()) |
583 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); | 610 proxy->TakeFrameHostOwnership(render_frame_host.Pass()); |
584 } else { | 611 } else { |
585 // We won't be coming back, so delete this one. | 612 // We won't be coming back, so delete this one. |
586 render_frame_host.reset(); | 613 render_frame_host.reset(); |
587 } | 614 } |
588 } | 615 } |
589 | 616 |
590 void RenderFrameHostManager::MoveToPendingDeleteHosts( | 617 void RenderFrameHostManager::MoveToPendingDeleteHosts( |
591 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 618 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
(...skipping 24 matching lines...) Expand all Loading... |
616 } | 643 } |
617 } | 644 } |
618 return false; | 645 return false; |
619 } | 646 } |
620 | 647 |
621 void RenderFrameHostManager::ResetProxyHosts() { | 648 void RenderFrameHostManager::ResetProxyHosts() { |
622 STLDeleteValues(&proxy_hosts_); | 649 STLDeleteValues(&proxy_hosts_); |
623 } | 650 } |
624 | 651 |
625 // PlzNavigate | 652 // PlzNavigate |
| 653 void RenderFrameHostManager::BeginNavigation( |
| 654 const CommonNavigationParams& common_params) { |
| 655 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 656 switches::kEnableBrowserSideNavigation)); |
| 657 // Clean up any state in case there's an ongoing navigation. |
| 658 // TODO(carlosk): remove this cleanup here once we properly cancel ongoing |
| 659 // navigations. |
| 660 CleanUpNavigation(); |
| 661 |
| 662 RenderFrameHostImpl* dest_rfh = |
| 663 GetFrameHostForNavigation(common_params.url, common_params.transition); |
| 664 DCHECK(dest_rfh); |
| 665 } |
| 666 |
| 667 // PlzNavigate |
626 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( | 668 RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation( |
627 const GURL& url, | 669 const GURL& url, |
628 ui::PageTransition transition) { | 670 ui::PageTransition transition) { |
629 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 671 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
630 switches::kEnableBrowserSideNavigation)); | 672 switches::kEnableBrowserSideNavigation)); |
631 // TODO(clamy): When we handle renderer initiated navigations, make sure not | |
632 // to use a different process for subframes if --site-per-process is not | |
633 // enabled. | |
634 | 673 |
635 // Pick the right RenderFrameHost to commit the navigation. | 674 SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance(); |
636 // TODO(clamy): Replace the default values by the right ones. | |
637 RenderFrameHostImpl* render_frame_host = UpdateStateForNavigate( | |
638 url, nullptr, nullptr, transition, false, false, GlobalRequestID(), | |
639 NavigationEntryImpl::kInvalidBindings); | |
640 | 675 |
641 // If the renderer that needs to navigate is not live (it was just created or | 676 // TODO(carlosk): Replace the default values with the right ones for |
642 // it crashed), initialize it. | 677 // source_instance, dest_instance, dest_is_restore, dest_is_view_source_mode. |
643 if (!render_frame_host->render_view_host()->IsRenderViewLive()) { | 678 scoped_refptr<SiteInstance> navigation_site_instance = |
| 679 GetSiteInstanceForNavigation(url, nullptr, nullptr, transition, false, |
| 680 false); |
| 681 // The appropriate RenderFrameHost to commit the navigation. |
| 682 RenderFrameHostImpl* navigation_rfh = nullptr; |
| 683 |
| 684 // TODO(carlosk): do not swap processes for renderer initiated navigations |
| 685 // (see crbug.com/440266). |
| 686 if (current_site_instance == navigation_site_instance.get() || |
| 687 (!frame_tree_node_->IsMainFrame() && |
| 688 !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 689 switches::kSitePerProcess))) { |
| 690 // Reuse the current RFH if its SiteInstance matches the the navigation's |
| 691 // or if this is a subframe navigation. We only swap RFHs for subframes when |
| 692 // --site-per-process is enabled. |
| 693 CleanUpNavigation(); |
| 694 navigation_rfh = render_frame_host_.get(); |
| 695 } else { |
| 696 // If the current render_frame_host_ isn't live, we should create it so |
| 697 // that we don't show a sad tab while the navigation is ongoing. |
| 698 // (Bug 1145340) |
| 699 if (!render_frame_host_->IsRenderFrameLive()) { |
| 700 // Note: we don't call InitRenderView here because we are navigating away |
| 701 // soon anyway, and we don't have the NavigationEntry for this host. |
| 702 delegate_->CreateRenderViewForRenderManager( |
| 703 render_frame_host_->render_view_host(), MSG_ROUTING_NONE, |
| 704 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame()); |
| 705 } |
| 706 |
| 707 // If the SiteInstance for the final URL doesn't match the one from the |
| 708 // speculatively created RenderFrameHost, create a new RenderFrameHost using |
| 709 // this new SiteInstance. |
| 710 if (!speculative_render_frame_host_ || |
| 711 speculative_render_frame_host_->GetSiteInstance() != |
| 712 navigation_site_instance.get()) { |
| 713 CleanUpNavigation(); |
| 714 // TODO(carlosk): Replace the binding value with the right one. |
| 715 bool success = CreateSpeculativeRenderFrameHost( |
| 716 url, current_site_instance, navigation_site_instance.get(), |
| 717 NavigationEntryImpl::kInvalidBindings); |
| 718 DCHECK(success); |
| 719 } |
| 720 DCHECK(speculative_render_frame_host_); |
| 721 navigation_rfh = speculative_render_frame_host_.get(); |
| 722 } |
| 723 DCHECK(navigation_rfh && |
| 724 (navigation_rfh == render_frame_host_.get() || |
| 725 navigation_rfh == speculative_render_frame_host_.get())); |
| 726 |
| 727 // If the renderer that needs to navigate is not live (it was just created |
| 728 // or it crashed), initialize it. |
| 729 if (!navigation_rfh->IsRenderFrameLive()) { |
644 // Recreate the opener chain. | 730 // Recreate the opener chain. |
645 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( | 731 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager( |
646 render_frame_host->GetSiteInstance()); | 732 navigation_rfh->GetSiteInstance()); |
647 if (!InitRenderView(render_frame_host->render_view_host(), | 733 if (!InitRenderView(navigation_rfh->render_view_host(), opener_route_id, |
648 opener_route_id, | 734 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame())) { |
649 MSG_ROUTING_NONE, | |
650 frame_tree_node_->IsMainFrame())) { | |
651 return nullptr; | 735 return nullptr; |
652 } | 736 } |
653 } | 737 } |
654 return render_frame_host; | 738 |
| 739 return navigation_rfh; |
| 740 } |
| 741 |
| 742 // PlzNavigate |
| 743 void RenderFrameHostManager::CleanUpNavigation() { |
| 744 if (speculative_render_frame_host_) |
| 745 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
| 746 } |
| 747 |
| 748 // PlzNavigate |
| 749 scoped_ptr<RenderFrameHostImpl> |
| 750 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { |
| 751 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 752 switches::kEnableBrowserSideNavigation)); |
| 753 if (speculative_web_ui_) |
| 754 speculative_web_ui_.reset(); |
| 755 should_reuse_web_ui_ = false; |
| 756 if (speculative_render_frame_host_) { |
| 757 speculative_render_frame_host_->GetProcess()->RemovePendingView(); |
| 758 return speculative_render_frame_host_.Pass(); |
| 759 } |
| 760 return nullptr; |
655 } | 761 } |
656 | 762 |
657 void RenderFrameHostManager::OnDidStartLoading() { | 763 void RenderFrameHostManager::OnDidStartLoading() { |
658 for (const auto& pair : proxy_hosts_) { | 764 for (const auto& pair : proxy_hosts_) { |
659 pair.second->Send( | 765 pair.second->Send( |
660 new FrameMsg_DidStartLoading(pair.second->GetRoutingID())); | 766 new FrameMsg_DidStartLoading(pair.second->GetRoutingID())); |
661 } | 767 } |
662 } | 768 } |
663 | 769 |
664 void RenderFrameHostManager::OnDidStopLoading() { | 770 void RenderFrameHostManager::OnDidStopLoading() { |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 int frame_routing_id, | 1193 int frame_routing_id, |
1088 int flags) { | 1194 int flags) { |
1089 if (frame_routing_id == MSG_ROUTING_NONE) | 1195 if (frame_routing_id == MSG_ROUTING_NONE) |
1090 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); | 1196 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); |
1091 | 1197 |
1092 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1198 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
1093 bool hidden = !!(flags & CREATE_RF_HIDDEN); | 1199 bool hidden = !!(flags & CREATE_RF_HIDDEN); |
1094 | 1200 |
1095 // Create a RVH for main frames, or find the existing one for subframes. | 1201 // Create a RVH for main frames, or find the existing one for subframes. |
1096 FrameTree* frame_tree = frame_tree_node_->frame_tree(); | 1202 FrameTree* frame_tree = frame_tree_node_->frame_tree(); |
1097 RenderViewHostImpl* render_view_host = NULL; | 1203 RenderViewHostImpl* render_view_host = nullptr; |
1098 if (frame_tree_node_->IsMainFrame()) { | 1204 if (frame_tree_node_->IsMainFrame()) { |
1099 render_view_host = frame_tree->CreateRenderViewHost( | 1205 render_view_host = frame_tree->CreateRenderViewHost( |
1100 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); | 1206 site_instance, view_routing_id, frame_routing_id, swapped_out, hidden); |
1101 } else { | 1207 } else { |
1102 render_view_host = frame_tree->GetRenderViewHost(site_instance); | 1208 render_view_host = frame_tree->GetRenderViewHost(site_instance); |
1103 | 1209 |
1104 CHECK(render_view_host); | 1210 CHECK(render_view_host); |
1105 } | 1211 } |
1106 | 1212 |
1107 // TODO(creis): Pass hidden to RFH. | 1213 // TODO(creis): Pass hidden to RFH. |
1108 scoped_ptr<RenderFrameHostImpl> render_frame_host = | 1214 scoped_ptr<RenderFrameHostImpl> render_frame_host = |
1109 make_scoped_ptr(RenderFrameHostFactory::Create( | 1215 make_scoped_ptr(RenderFrameHostFactory::Create( |
1110 render_view_host, render_frame_delegate_, frame_tree, | 1216 render_view_host, render_frame_delegate_, frame_tree, |
1111 frame_tree_node_, frame_routing_id, flags).release()); | 1217 frame_tree_node_, frame_routing_id, flags).release()); |
1112 return render_frame_host.Pass(); | 1218 return render_frame_host.Pass(); |
1113 } | 1219 } |
1114 | 1220 |
| 1221 // PlzNavigate |
| 1222 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( |
| 1223 const GURL& url, |
| 1224 SiteInstance* old_instance, |
| 1225 SiteInstance* new_instance, |
| 1226 int bindings) { |
| 1227 CHECK(new_instance); |
| 1228 CHECK_NE(old_instance, new_instance); |
| 1229 |
| 1230 const NavigationEntry* current_navigation_entry = |
| 1231 delegate_->GetLastCommittedNavigationEntryForRenderManager(); |
| 1232 scoped_ptr<WebUIImpl> new_web_ui; |
| 1233 bool should_reuse_web_ui = ShouldReuseWebUI(current_navigation_entry, url); |
| 1234 if (!should_reuse_web_ui) |
| 1235 new_web_ui = CreateWebUI(url, bindings); |
| 1236 |
| 1237 int opener_route_id = |
| 1238 CreateOpenerRenderViewsIfNeeded(old_instance, new_instance); |
| 1239 |
| 1240 int create_render_frame_flags = 0; |
| 1241 if (frame_tree_node_->IsMainFrame()) |
| 1242 create_render_frame_flags |= CREATE_RF_FOR_MAIN_FRAME_NAVIGATION; |
| 1243 if (delegate_->IsHidden()) |
| 1244 create_render_frame_flags |= CREATE_RF_HIDDEN; |
| 1245 scoped_ptr<RenderFrameHostImpl> new_render_frame_host = |
| 1246 CreateRenderFrame(new_instance, new_web_ui.get(), opener_route_id, |
| 1247 create_render_frame_flags, nullptr); |
| 1248 |
| 1249 if (!new_render_frame_host) |
| 1250 return false; |
| 1251 |
| 1252 speculative_render_frame_host_ = new_render_frame_host.Pass(); |
| 1253 speculative_web_ui_ = new_web_ui.Pass(); |
| 1254 should_reuse_web_ui_ = should_reuse_web_ui; |
| 1255 return true; |
| 1256 } |
| 1257 |
1115 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( | 1258 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( |
1116 SiteInstance* instance, | 1259 SiteInstance* instance, |
1117 WebUIImpl* web_ui, | 1260 WebUIImpl* web_ui, |
1118 int opener_route_id, | 1261 int opener_route_id, |
1119 int flags, | 1262 int flags, |
1120 int* view_routing_id_ptr) { | 1263 int* view_routing_id_ptr) { |
1121 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1264 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
1122 CHECK(instance); | 1265 CHECK(instance); |
1123 // Swapped out views should always be hidden. | 1266 // Swapped out views should always be hidden. |
1124 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN)); | 1267 DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN)); |
1125 | 1268 |
1126 // TODO(nasko): Remove the following CHECK once cross-site navigation no | 1269 // TODO(nasko): Remove the following CHECK once cross-site navigation no |
1127 // longer relies on swapped out RFH for the top-level frame. | 1270 // longer relies on swapped out RFH for the top-level frame. |
1128 if (!frame_tree_node_->IsMainFrame()) | 1271 if (!frame_tree_node_->IsMainFrame()) |
1129 CHECK(!swapped_out); | 1272 CHECK(!swapped_out); |
1130 | 1273 |
1131 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; | 1274 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; |
1132 bool success = true; | 1275 bool success = true; |
1133 if (view_routing_id_ptr) | 1276 if (view_routing_id_ptr) |
1134 *view_routing_id_ptr = MSG_ROUTING_NONE; | 1277 *view_routing_id_ptr = MSG_ROUTING_NONE; |
1135 | 1278 |
1136 // We are creating a pending or swapped out RFH here. We should never create | 1279 // We are creating a pending, speculative or swapped out RFH here. We should |
1137 // it in the same SiteInstance as our current RFH. | 1280 // never create it in the same SiteInstance as our current RFH. |
1138 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); | 1281 CHECK_NE(render_frame_host_->GetSiteInstance(), instance); |
1139 | 1282 |
1140 // Check if we've already created an RFH for this SiteInstance. If so, try | 1283 // Check if we've already created an RFH for this SiteInstance. If so, try |
1141 // to re-use the existing one, which has already been initialized. We'll | 1284 // to re-use the existing one, which has already been initialized. We'll |
1142 // remove it from the list of proxy hosts below if it will be active. | 1285 // remove it from the list of proxy hosts below if it will be active. |
1143 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); | 1286 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); |
1144 if (proxy && proxy->render_frame_host()) { | 1287 if (proxy && proxy->render_frame_host()) { |
1145 if (view_routing_id_ptr) | 1288 if (view_routing_id_ptr) |
1146 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); | 1289 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); |
1147 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. | 1290 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 | 1383 |
1241 bool RenderFrameHostManager::InitRenderView( | 1384 bool RenderFrameHostManager::InitRenderView( |
1242 RenderViewHostImpl* render_view_host, | 1385 RenderViewHostImpl* render_view_host, |
1243 int opener_route_id, | 1386 int opener_route_id, |
1244 int proxy_routing_id, | 1387 int proxy_routing_id, |
1245 bool for_main_frame_navigation) { | 1388 bool for_main_frame_navigation) { |
1246 // We may have initialized this RenderViewHost for another RenderFrameHost. | 1389 // We may have initialized this RenderViewHost for another RenderFrameHost. |
1247 if (render_view_host->IsRenderViewLive()) | 1390 if (render_view_host->IsRenderViewLive()) |
1248 return true; | 1391 return true; |
1249 | 1392 |
1250 // If the pending navigation is to a WebUI and the RenderView is not in a | 1393 // If the ongoing navigation is to a WebUI and the RenderView is not in a |
1251 // guest process, tell the RenderViewHost about any bindings it will need | 1394 // guest process, tell the RenderViewHost about any bindings it will need |
1252 // enabled. | 1395 // enabled. |
1253 if (pending_web_ui() && !render_view_host->GetProcess()->IsIsolatedGuest()) { | 1396 WebUIImpl* dest_web_ui = nullptr; |
1254 render_view_host->AllowBindings(pending_web_ui()->GetBindings()); | 1397 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1398 switches::kEnableBrowserSideNavigation)) { |
| 1399 dest_web_ui = |
| 1400 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get(); |
| 1401 } else { |
| 1402 dest_web_ui = pending_web_ui(); |
| 1403 } |
| 1404 if (dest_web_ui && !render_view_host->GetProcess()->IsIsolatedGuest()) { |
| 1405 render_view_host->AllowBindings(dest_web_ui->GetBindings()); |
1255 } else { | 1406 } else { |
1256 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | 1407 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled |
1257 // process unless it's swapped out. | 1408 // process unless it's swapped out. |
1258 if (render_view_host->is_active()) { | 1409 if (render_view_host->is_active()) { |
1259 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | 1410 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( |
1260 render_view_host->GetProcess()->GetID())); | 1411 render_view_host->GetProcess()->GetID())); |
1261 } | 1412 } |
1262 } | 1413 } |
1263 | 1414 |
1264 return delegate_->CreateRenderViewForRenderManager(render_view_host, | 1415 return delegate_->CreateRenderViewForRenderManager(render_view_host, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1306 proxy_hosts_.find(site_instance->GetId()); | 1457 proxy_hosts_.find(site_instance->GetId()); |
1307 if (iter != proxy_hosts_.end()) | 1458 if (iter != proxy_hosts_.end()) |
1308 return iter->second->GetRoutingID(); | 1459 return iter->second->GetRoutingID(); |
1309 | 1460 |
1310 return MSG_ROUTING_NONE; | 1461 return MSG_ROUTING_NONE; |
1311 } | 1462 } |
1312 | 1463 |
1313 void RenderFrameHostManager::CommitPending() { | 1464 void RenderFrameHostManager::CommitPending() { |
1314 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 1465 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
1315 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 1466 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 1467 bool browser_side_navigation = |
| 1468 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1469 switches::kEnableBrowserSideNavigation); |
1316 // First check whether we're going to want to focus the location bar after | 1470 // First check whether we're going to want to focus the location bar after |
1317 // this commit. We do this now because the navigation hasn't formally | 1471 // this commit. We do this now because the navigation hasn't formally |
1318 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 1472 // committed yet, so if we've already cleared |pending_web_ui_| the call chain |
1319 // this triggers won't be able to figure out what's going on. | 1473 // this triggers won't be able to figure out what's going on. |
1320 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 1474 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
1321 | 1475 |
1322 // Next commit the Web UI, if any. Either replace |web_ui_| with | 1476 if (!browser_side_navigation) { |
1323 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or | 1477 DCHECK(!speculative_web_ui_); |
1324 // leave |web_ui_| as is if reusing it. | 1478 // Next commit the Web UI, if any. Either replace |web_ui_| with |
1325 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); | 1479 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or |
1326 if (pending_web_ui_) { | 1480 // leave |web_ui_| as is if reusing it. |
1327 web_ui_.reset(pending_web_ui_.release()); | 1481 DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get())); |
1328 } else if (!pending_and_current_web_ui_.get()) { | 1482 if (pending_web_ui_) { |
1329 web_ui_.reset(); | 1483 web_ui_.reset(pending_web_ui_.release()); |
| 1484 } else if (!pending_and_current_web_ui_.get()) { |
| 1485 web_ui_.reset(); |
| 1486 } else { |
| 1487 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); |
| 1488 pending_and_current_web_ui_.reset(); |
| 1489 } |
1330 } else { | 1490 } else { |
1331 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | 1491 // PlzNavigate |
1332 pending_and_current_web_ui_.reset(); | 1492 if (!should_reuse_web_ui_) |
| 1493 web_ui_.reset(speculative_web_ui_.release()); |
| 1494 DCHECK(!speculative_web_ui_); |
1333 } | 1495 } |
1334 | 1496 |
1335 // It's possible for the pending_render_frame_host_ to be NULL when we aren't | 1497 // It's possible for the pending_render_frame_host_ to be nullptr when we |
1336 // crossing process boundaries. If so, we just needed to handle the Web UI | 1498 // aren't crossing process boundaries. If so, we just needed to handle the Web |
1337 // committing above and we're done. | 1499 // UI committing above and we're done. |
1338 if (!pending_render_frame_host_) { | 1500 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { |
1339 if (will_focus_location_bar) | 1501 if (will_focus_location_bar) |
1340 delegate_->SetFocusToLocationBar(false); | 1502 delegate_->SetFocusToLocationBar(false); |
1341 return; | 1503 return; |
1342 } | 1504 } |
1343 | 1505 |
1344 // Remember if the page was focused so we can focus the new renderer in | 1506 // Remember if the page was focused so we can focus the new renderer in |
1345 // that case. | 1507 // that case. |
1346 bool focus_render_view = !will_focus_location_bar && | 1508 bool focus_render_view = !will_focus_location_bar && |
1347 render_frame_host_->render_view_host()->GetView() && | 1509 render_frame_host_->render_view_host()->GetView() && |
1348 render_frame_host_->render_view_host()->GetView()->HasFocus(); | 1510 render_frame_host_->render_view_host()->GetView()->HasFocus(); |
1349 | 1511 |
1350 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 1512 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
1351 | 1513 |
1352 // Swap in the pending frame and make it active. Also ensure the FrameTree | 1514 // Swap in the pending or speculative frame and make it active. Also ensure |
1353 // stays in sync. | 1515 // the FrameTree stays in sync. |
1354 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 1516 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
1355 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 1517 if (!browser_side_navigation) { |
| 1518 DCHECK(!speculative_render_frame_host_); |
| 1519 old_render_frame_host = |
| 1520 SetRenderFrameHost(pending_render_frame_host_.Pass()); |
| 1521 } else { |
| 1522 // PlzNavigate |
| 1523 DCHECK(speculative_render_frame_host_); |
| 1524 old_render_frame_host = |
| 1525 SetRenderFrameHost(speculative_render_frame_host_.Pass()); |
| 1526 } |
| 1527 |
1356 if (is_main_frame) | 1528 if (is_main_frame) |
1357 render_frame_host_->render_view_host()->AttachToFrameTree(); | 1529 render_frame_host_->render_view_host()->AttachToFrameTree(); |
1358 | 1530 |
1359 // The process will no longer try to exit, so we can decrement the count. | 1531 // The process will no longer try to exit, so we can decrement the count. |
1360 render_frame_host_->GetProcess()->RemovePendingView(); | 1532 render_frame_host_->GetProcess()->RemovePendingView(); |
1361 | 1533 |
1362 // Show the new view (or a sad tab) if necessary. | 1534 // Show the new view (or a sad tab) if necessary. |
1363 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); | 1535 bool new_rfh_has_view = !!render_frame_host_->render_view_host()->GetView(); |
1364 if (!delegate_->IsHidden() && new_rfh_has_view) { | 1536 if (!delegate_->IsHidden() && new_rfh_has_view) { |
1365 // In most cases, we need to show the new view. | 1537 // In most cases, we need to show the new view. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 TRACE_EVENT_INSTANT2( | 1663 TRACE_EVENT_INSTANT2( |
1492 "navigation", | 1664 "navigation", |
1493 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 1665 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
1494 TRACE_EVENT_SCOPE_THREAD, | 1666 TRACE_EVENT_SCOPE_THREAD, |
1495 "current_instance id", current_instance->GetId(), | 1667 "current_instance id", current_instance->GetId(), |
1496 "new_instance id", new_instance->GetId()); | 1668 "new_instance id", new_instance->GetId()); |
1497 | 1669 |
1498 // New SiteInstance: create a pending RFH to navigate. | 1670 // New SiteInstance: create a pending RFH to navigate. |
1499 DCHECK(!cross_navigation_pending_); | 1671 DCHECK(!cross_navigation_pending_); |
1500 | 1672 |
1501 // This will possibly create (set to NULL) a Web UI object for the pending | 1673 // This will possibly create (set to nullptr) a Web UI object for the |
1502 // page. We'll use this later to give the page special access. This must | 1674 // pending page. We'll use this later to give the page special access. This |
1503 // happen before the new renderer is created below so it will get bindings. | 1675 // must happen before the new renderer is created below so it will get |
1504 // It must also happen after the above conditional call to CancelPending(), | 1676 // bindings. It must also happen after the above conditional call to |
1505 // otherwise CancelPending may clear the pending_web_ui_ and the page will | 1677 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_ |
1506 // not have its bindings set appropriately. | 1678 // and the page will not have its bindings set appropriately. |
1507 SetPendingWebUI(dest_url, bindings); | 1679 SetPendingWebUI(dest_url, bindings); |
1508 CreatePendingRenderFrameHost(current_instance, new_instance.get(), | 1680 CreatePendingRenderFrameHost(current_instance, new_instance.get(), |
1509 frame_tree_node_->IsMainFrame()); | 1681 frame_tree_node_->IsMainFrame()); |
1510 if (!pending_render_frame_host_.get()) { | 1682 if (!pending_render_frame_host_.get()) { |
1511 return NULL; | 1683 return nullptr; |
1512 } | 1684 } |
1513 | 1685 |
1514 // Check if our current RFH is live before we set up a transition. | 1686 // Check if our current RFH is live before we set up a transition. |
1515 if (!render_frame_host_->IsRenderFrameLive()) { | 1687 if (!render_frame_host_->IsRenderFrameLive()) { |
1516 if (!cross_navigation_pending_) { | 1688 if (!cross_navigation_pending_) { |
1517 // The current RFH is not live. There's no reason to sit around with a | 1689 // The current RFH is not live. There's no reason to sit around with a |
1518 // sad tab or a newly created RFH while we wait for the pending RFH to | 1690 // sad tab or a newly created RFH while we wait for the pending RFH to |
1519 // navigate. Just switch to the pending RFH now and go back to non | 1691 // navigate. Just switch to the pending RFH now and go back to non |
1520 // cross-navigating (Note that we don't care about on{before}unload | 1692 // cross-navigating (Note that we don't care about on{before}unload |
1521 // handlers if the current RFH isn't live.) | 1693 // handlers if the current RFH isn't live.) |
1522 CommitPending(); | 1694 CommitPending(); |
1523 return render_frame_host_.get(); | 1695 return render_frame_host_.get(); |
1524 } else { | 1696 } else { |
1525 NOTREACHED(); | 1697 NOTREACHED(); |
1526 return render_frame_host_.get(); | 1698 return render_frame_host_.get(); |
1527 } | 1699 } |
1528 } | 1700 } |
1529 // Otherwise, it's safe to treat this as a pending cross-site transition. | 1701 // Otherwise, it's safe to treat this as a pending cross-site transition. |
1530 | 1702 |
1531 // We now have a pending RFH. | 1703 // We now have a pending RFH. |
1532 DCHECK(!cross_navigation_pending_); | 1704 DCHECK(!cross_navigation_pending_); |
1533 cross_navigation_pending_ = true; | 1705 cross_navigation_pending_ = true; |
1534 | 1706 |
1535 // PlzNavigate: There is no notion of transfer navigations, and the old | |
1536 // renderer before unload handler has already run at that point, so return | |
1537 // here. | |
1538 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
1539 switches::kEnableBrowserSideNavigation)) { | |
1540 return pending_render_frame_host_.get(); | |
1541 } | |
1542 | |
1543 // We need to wait until the beforeunload handler has run, unless we are | 1707 // We need to wait until the beforeunload handler has run, unless we are |
1544 // transferring an existing request (in which case it has already run). | 1708 // transferring an existing request (in which case it has already run). |
1545 // Suspend the new render view (i.e., don't let it send the cross-site | 1709 // Suspend the new render view (i.e., don't let it send the cross-site |
1546 // Navigate message) until we hear back from the old renderer's | 1710 // Navigate message) until we hear back from the old renderer's |
1547 // beforeunload handler. If the handler returns false, we'll have to | 1711 // beforeunload handler. If the handler returns false, we'll have to |
1548 // cancel the request. | 1712 // cancel the request. |
1549 // | 1713 // |
1550 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); | 1714 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); |
1551 bool is_transfer = transferred_request_id != GlobalRequestID(); | 1715 bool is_transfer = transferred_request_id != GlobalRequestID(); |
1552 if (is_transfer) { | 1716 if (is_transfer) { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1707 void RenderFrameHostManager::DeleteRenderFrameProxyHost( | 1871 void RenderFrameHostManager::DeleteRenderFrameProxyHost( |
1708 SiteInstance* instance) { | 1872 SiteInstance* instance) { |
1709 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); | 1873 RenderFrameProxyHostMap::iterator iter = proxy_hosts_.find(instance->GetId()); |
1710 if (iter != proxy_hosts_.end()) { | 1874 if (iter != proxy_hosts_.end()) { |
1711 delete iter->second; | 1875 delete iter->second; |
1712 proxy_hosts_.erase(iter); | 1876 proxy_hosts_.erase(iter); |
1713 } | 1877 } |
1714 } | 1878 } |
1715 | 1879 |
1716 } // namespace content | 1880 } // namespace content |
OLD | NEW |