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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 379143002: PlzNavigate: implement RequestNavigation in the no live renderer case (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed speculative rfh + no pending_navigation_entry dependency Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/frame_host/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "content/browser/child_process_security_policy_impl.h" 13 #include "content/browser/child_process_security_policy_impl.h"
14 #include "content/browser/devtools/render_view_devtools_agent_host.h" 14 #include "content/browser/devtools/render_view_devtools_agent_host.h"
15 #include "content/browser/frame_host/cross_site_transferring_request.h" 15 #include "content/browser/frame_host/cross_site_transferring_request.h"
16 #include "content/browser/frame_host/debug_urls.h" 16 #include "content/browser/frame_host/debug_urls.h"
17 #include "content/browser/frame_host/interstitial_page_impl.h" 17 #include "content/browser/frame_host/interstitial_page_impl.h"
18 #include "content/browser/frame_host/navigation_before_commit_info.h"
18 #include "content/browser/frame_host/navigation_controller_impl.h" 19 #include "content/browser/frame_host/navigation_controller_impl.h"
19 #include "content/browser/frame_host/navigation_entry_impl.h" 20 #include "content/browser/frame_host/navigation_entry_impl.h"
20 #include "content/browser/frame_host/navigation_request.h" 21 #include "content/browser/frame_host/navigation_request.h"
21 #include "content/browser/frame_host/navigation_request_info.h" 22 #include "content/browser/frame_host/navigation_request_info.h"
22 #include "content/browser/frame_host/navigator.h" 23 #include "content/browser/frame_host/navigator.h"
23 #include "content/browser/frame_host/render_frame_host_factory.h" 24 #include "content/browser/frame_host/render_frame_host_factory.h"
24 #include "content/browser/frame_host/render_frame_host_impl.h" 25 #include "content/browser/frame_host/render_frame_host_impl.h"
25 #include "content/browser/frame_host/render_frame_proxy_host.h" 26 #include "content/browser/frame_host/render_frame_proxy_host.h"
26 #include "content/browser/renderer_host/render_process_host_impl.h" 27 #include "content/browser/renderer_host/render_process_host_impl.h"
27 #include "content/browser/renderer_host/render_view_host_factory.h" 28 #include "content/browser/renderer_host/render_view_host_factory.h"
28 #include "content/browser/renderer_host/render_view_host_impl.h" 29 #include "content/browser/renderer_host/render_view_host_impl.h"
29 #include "content/browser/site_instance_impl.h" 30 #include "content/browser/site_instance_impl.h"
30 #include "content/browser/webui/web_ui_controller_factory_registry.h" 31 #include "content/browser/webui/web_ui_controller_factory_registry.h"
31 #include "content/browser/webui/web_ui_impl.h" 32 #include "content/browser/webui/web_ui_impl.h"
32 #include "content/common/view_messages.h" 33 #include "content/common/view_messages.h"
33 #include "content/public/browser/content_browser_client.h" 34 #include "content/public/browser/content_browser_client.h"
34 #include "content/public/browser/notification_service.h" 35 #include "content/public/browser/notification_service.h"
35 #include "content/public/browser/notification_types.h" 36 #include "content/public/browser/notification_types.h"
36 #include "content/public/browser/render_widget_host_iterator.h" 37 #include "content/public/browser/render_widget_host_iterator.h"
37 #include "content/public/browser/render_widget_host_view.h" 38 #include "content/public/browser/render_widget_host_view.h"
38 #include "content/public/browser/user_metrics.h" 39 #include "content/public/browser/user_metrics.h"
39 #include "content/public/browser/web_ui_controller.h" 40 #include "content/public/browser/web_ui_controller.h"
40 #include "content/public/common/content_switches.h" 41 #include "content/public/common/content_switches.h"
42 #include "content/public/common/referrer.h"
41 #include "content/public/common/url_constants.h" 43 #include "content/public/common/url_constants.h"
44 #include "net/base/load_flags.h"
42 45
43 namespace content { 46 namespace content {
44 47
48 namespace {
49
50 // PlzNavigate
51 FrameHostMsg_BeginNavigation_Params BeginNavigationFromNavigate(
Charlie Reis 2014/08/08 20:25:28 Let's add a comment here, since it's confusing to
clamy 2014/08/12 12:13:16 Done.
52 const FrameMsg_Navigate_Params& navigate_params) {
53 FrameHostMsg_BeginNavigation_Params begin_navigation_params;
54 begin_navigation_params.method = navigate_params.is_post ?
55 "POST" : "GET";
56 begin_navigation_params.url = navigate_params.url;
57 begin_navigation_params.referrer =
58 Referrer(navigate_params.referrer.url, navigate_params.referrer.policy);
59
60 // TODO(clamy): This should be modified to take into account caching policy
61 // requirements (eg for POST reloads).
62 begin_navigation_params.load_flags =
63 net::LOAD_NORMAL | net::LOAD_ENABLE_LOAD_TIMING;
64
65 // TODO(clamy): Post data from the browser should be put in the request body.
66
67 begin_navigation_params.has_user_gesture = false;
68 begin_navigation_params.transition_type = navigate_params.transition;
69 begin_navigation_params.should_replace_current_entry =
70 navigate_params.should_replace_current_entry;
71 begin_navigation_params.allow_download =
72 navigate_params.allow_download;
73 return begin_navigation_params;
74 }
75
76 } // namespace
77
45 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams( 78 RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams(
46 const GlobalRequestID& global_request_id, 79 const GlobalRequestID& global_request_id,
47 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request, 80 scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request,
48 const std::vector<GURL>& transfer_url_chain, 81 const std::vector<GURL>& transfer_url_chain,
49 Referrer referrer, 82 Referrer referrer,
50 PageTransition page_transition, 83 PageTransition page_transition,
51 int render_frame_id, 84 int render_frame_id,
52 bool should_replace_current_entry) 85 bool should_replace_current_entry)
53 : global_request_id(global_request_id), 86 : global_request_id(global_request_id),
54 cross_site_transferring_request(cross_site_transferring_request.Pass()), 87 cross_site_transferring_request(cross_site_transferring_request.Pass()),
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 } 206 }
174 207
175 RenderFrameHostImpl* RenderFrameHostManager::Navigate( 208 RenderFrameHostImpl* RenderFrameHostManager::Navigate(
176 const NavigationEntryImpl& entry) { 209 const NavigationEntryImpl& entry) {
177 TRACE_EVENT0("browser", "RenderFrameHostManager:Navigate"); 210 TRACE_EVENT0("browser", "RenderFrameHostManager:Navigate");
178 // Create a pending RenderFrameHost to use for the navigation. 211 // Create a pending RenderFrameHost to use for the navigation.
179 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate(entry); 212 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate(entry);
180 if (!dest_render_frame_host) 213 if (!dest_render_frame_host)
181 return NULL; // We weren't able to create a pending render frame host. 214 return NULL; // We weren't able to create a pending render frame host.
182 215
183 // If the current render_frame_host_ isn't live, we should create it so 216 // Initialize the destination RFH and the current RFH if they are not live.
184 // that we don't show a sad tab while the dest_render_frame_host fetches 217 if (!InitRenderFrameHostsBeforeNavigation(dest_render_frame_host))
185 // its first page. (Bug 1145340) 218 return NULL;
186 if (dest_render_frame_host != render_frame_host_ &&
187 !render_frame_host_->render_view_host()->IsRenderViewLive()) {
188 // Note: we don't call InitRenderView here because we are navigating away
189 // soon anyway, and we don't have the NavigationEntry for this host.
190 delegate_->CreateRenderViewForRenderManager(
191 render_frame_host_->render_view_host(), MSG_ROUTING_NONE,
192 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame());
193 }
194
195 // If the renderer crashed, then try to create a new one to satisfy this
196 // navigation request.
197 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) {
198 // Recreate the opener chain.
199 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
200 dest_render_frame_host->GetSiteInstance());
201 if (!InitRenderView(dest_render_frame_host->render_view_host(),
202 opener_route_id,
203 MSG_ROUTING_NONE,
204 frame_tree_node_->IsMainFrame()))
205 return NULL;
206
207 // Now that we've created a new renderer, be sure to hide it if it isn't
208 // our primary one. Otherwise, we might crash if we try to call Show()
209 // on it later.
210 if (dest_render_frame_host != render_frame_host_ &&
211 dest_render_frame_host->render_view_host()->GetView()) {
212 dest_render_frame_host->render_view_host()->GetView()->Hide();
213 } else {
214 // Notify here as we won't be calling CommitPending (which does the
215 // notify).
216 delegate_->NotifySwappedFromRenderManager(
217 NULL, render_frame_host_.get(), frame_tree_node_->IsMainFrame());
218 }
219 }
220 219
221 // If entry includes the request ID of a request that is being transferred, 220 // If entry includes the request ID of a request that is being transferred,
222 // the destination render frame will take ownership, so release ownership of 221 // the destination render frame will take ownership, so release ownership of
223 // the request. 222 // the request.
224 if (pending_nav_params_ && 223 if (pending_nav_params_ &&
225 pending_nav_params_->global_request_id == 224 pending_nav_params_->global_request_id ==
226 entry.transferred_global_request_id()) { 225 entry.transferred_global_request_id()) {
227 pending_nav_params_->cross_site_transferring_request->ReleaseRequest(); 226 pending_nav_params_->cross_site_transferring_request->ReleaseRequest();
228 } 227 }
229 228
230 return dest_render_frame_host; 229 return dest_render_frame_host;
231 } 230 }
232 231
232 // PlzNavigate
233 bool RenderFrameHostManager::RequestNavigation(
234 const NavigationEntryImpl& entry,
235 const FrameMsg_Navigate_Params& navigate_params) {
236 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
237 switches::kEnableBrowserSideNavigation));
238 // TODO(clamy): replace RenderViewHost::IsRenderViewLive by
239 // RenderFrameHost::IsLive.
240 if (render_frame_host_->render_view_host()->IsRenderViewLive())
241 // TODO(clamy): send a RequestNavigation IPC.
242 return true;
243
244 InitRenderFrameHostsBeforeNavigation(render_frame_host_.get());
Charlie Reis 2014/08/08 20:25:29 I don't see why we're making this call in RequestN
clamy 2014/08/12 12:13:16 Done.
245 // The navigation request is sent directly to the IO thread.
246 OnBeginNavigation(BeginNavigationFromNavigate(navigate_params),
247 entry);
248 return true;
249 }
250
233 void RenderFrameHostManager::Stop() { 251 void RenderFrameHostManager::Stop() {
234 render_frame_host_->render_view_host()->Stop(); 252 render_frame_host_->render_view_host()->Stop();
235 253
236 // If we are cross-navigating, we should stop the pending renderers. This 254 // If we are cross-navigating, we should stop the pending renderers. This
237 // will lead to a DidFailProvisionalLoad, which will properly destroy them. 255 // will lead to a DidFailProvisionalLoad, which will properly destroy them.
238 if (cross_navigation_pending_) { 256 if (cross_navigation_pending_) {
239 pending_render_frame_host_->render_view_host()->Send(new ViewMsg_Stop( 257 pending_render_frame_host_->render_view_host()->Send(new ViewMsg_Stop(
240 pending_render_frame_host_->render_view_host()->GetRoutingID())); 258 pending_render_frame_host_->render_view_host()->GetRoutingID()));
241 } 259 }
242 } 260 }
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 RFHPendingDeleteMap::iterator iter = 583 RFHPendingDeleteMap::iterator iter =
566 pending_delete_hosts_.find(site_instance_id); 584 pending_delete_hosts_.find(site_instance_id);
567 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh) 585 if (iter != pending_delete_hosts_.end() && iter->second.get() == rfh)
568 pending_delete_hosts_.erase(site_instance_id); 586 pending_delete_hosts_.erase(site_instance_id);
569 } 587 }
570 588
571 void RenderFrameHostManager::ResetProxyHosts() { 589 void RenderFrameHostManager::ResetProxyHosts() {
572 STLDeleteValues(&proxy_hosts_); 590 STLDeleteValues(&proxy_hosts_);
573 } 591 }
574 592
593 // PlzNavigate
575 void RenderFrameHostManager::OnBeginNavigation( 594 void RenderFrameHostManager::OnBeginNavigation(
576 const FrameHostMsg_BeginNavigation_Params& params) { 595 const FrameHostMsg_BeginNavigation_Params& params,
596 const NavigationEntryImpl& entry) {
597 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
598 switches::kEnableBrowserSideNavigation));
577 // TODO(clamy): Check if navigations are blocked and if so, return 599 // TODO(clamy): Check if navigations are blocked and if so, return
578 // immediately. 600 // immediately.
579 NavigationRequestInfo info(params); 601 NavigationRequestInfo info(params);
580 602
581 info.first_party_for_cookies = frame_tree_node_->IsMainFrame() ? 603 info.first_party_for_cookies = frame_tree_node_->IsMainFrame() ?
582 params.url : frame_tree_node_->frame_tree()->root()->current_url(); 604 params.url : frame_tree_node_->frame_tree()->root()->current_url();
583 info.is_main_frame = frame_tree_node_->IsMainFrame(); 605 info.is_main_frame = frame_tree_node_->IsMainFrame();
584 info.parent_is_main_frame = !frame_tree_node_->parent() ? 606 info.parent_is_main_frame = !frame_tree_node_->parent() ?
585 false : frame_tree_node_->parent()->IsMainFrame(); 607 false : frame_tree_node_->parent()->IsMainFrame();
586 info.is_showing = GetRenderWidgetHostView()->IsShowing(); 608 info.is_showing = GetRenderWidgetHostView()->IsShowing();
587 609
588 navigation_request_.reset( 610 // TODO(clamy): Check if the current RFH should be initialized (in case it has
589 new NavigationRequest(info, frame_tree_node_->frame_tree_node_id())); 611 // crashed) not to display a sad tab while navigating.
612 // TODO(clamy): Spawn a speculative renderer process if we do not have one to
613 // use for the navigation.
614 navigation_request_.reset(new NavigationRequest(
615 info, entry, frame_tree_node_->frame_tree_node_id()));
590 navigation_request_->BeginNavigation(params.request_body); 616 navigation_request_->BeginNavigation(params.request_body);
Charlie Reis 2014/08/08 20:25:28 Looks like this goes to RDH::NavigationRequest, wh
clamy 2014/08/12 12:13:16 Apparently NOTIMPLEMENTED just prints an error mes
591 // TODO(clamy): If we have no live RenderFrameHost to handle the request (eg 617 }
592 // cross-site navigation) spawn one speculatively here and keep track of it. 618
619 // PlzNavigate
620 void RenderFrameHostManager::CommitNavigation(
621 const NavigationBeforeCommitInfo& info) {
622 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(
623 switches::kEnableBrowserSideNavigation));
624 // Update the stored NavigationEntry for commit.
625 // TODO(clamy): Check if some more state should be updated at that point.
626 navigation_request_->UpdateEntryForCommit(info.navigation_url);
Charlie Reis 2014/08/08 20:25:28 Since we haven't actually committed yet, I don't t
clamy 2014/08/12 12:13:16 We don't get the new site instance right if we don
627
628 // Pick the right RenderFrameHost to commit the navigation.
629 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
630 SiteInstance* new_instance = GetSiteInstanceForNavigation(
Charlie Reis 2014/08/08 20:25:28 I'm really excited about waiting until this point
631 navigation_request_->entry());
632 DCHECK(!pending_render_frame_host_.get());
633
634 if (current_instance != new_instance) {
Charlie Reis 2014/08/08 20:25:28 We may want a TODO to update how pending WebUI obj
clamy 2014/08/12 12:13:16 Done.
635 RenderFrameHostImpl * new_rfh = CreateRenderFrameHostForNewSiteInstance(
636 current_instance, new_instance, frame_tree_node_->IsMainFrame());
637 DCHECK(new_rfh);
638 // TODO(clamy): The old RenderFrameHost should be asked to run its unload
Charlie Reis 2014/08/08 20:25:28 Side note: I'm thinking we want to wait until the
clamy 2014/08/12 12:13:16 Done.
639 // handler.
640 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
641 SetRenderFrameHost(pending_render_frame_host_.Pass());
clamy 2014/08/08 12:02:46 Right now the newly created RenderFrameHost for th
Charlie Reis 2014/08/08 20:25:28 Acknowledged.
642 if (frame_tree_node_->IsMainFrame())
643 render_frame_host_->render_view_host()->AttachToFrameTree();
644 }
645
646 frame_tree_node_->navigator()->CommitNavigation(
647 render_frame_host_.get(), info);
648 navigation_request_.reset();
593 } 649 }
594 650
595 void RenderFrameHostManager::Observe( 651 void RenderFrameHostManager::Observe(
596 int type, 652 int type,
597 const NotificationSource& source, 653 const NotificationSource& source,
598 const NotificationDetails& details) { 654 const NotificationDetails& details) {
599 switch (type) { 655 switch (type) {
600 case NOTIFICATION_RENDERER_PROCESS_CLOSED: 656 case NOTIFICATION_RENDERER_PROCESS_CLOSED:
601 case NOTIFICATION_RENDERER_PROCESS_CLOSING: 657 case NOTIFICATION_RENDERER_PROCESS_CLOSING:
602 RendererProcessClosing( 658 RendererProcessClosing(
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 const NavigationEntryImpl* new_entry) const { 785 const NavigationEntryImpl* new_entry) const {
730 NavigationControllerImpl& controller = 786 NavigationControllerImpl& controller =
731 delegate_->GetControllerForRenderManager(); 787 delegate_->GetControllerForRenderManager();
732 return current_entry && web_ui_.get() && 788 return current_entry && web_ui_.get() &&
733 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 789 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
734 controller.GetBrowserContext(), current_entry->GetURL()) == 790 controller.GetBrowserContext(), current_entry->GetURL()) ==
735 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( 791 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
736 controller.GetBrowserContext(), new_entry->GetURL())); 792 controller.GetBrowserContext(), new_entry->GetURL()));
737 } 793 }
738 794
795 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
796 const NavigationEntryImpl& entry) {
797 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
798 SiteInstance* new_instance = current_instance;
799
800 // We do not currently swap processes for navigations in webview tag guests.
801 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme);
802
803 // Determine if we need a new BrowsingInstance for this entry. If true, this
804 // implies that it will get a new SiteInstance (and likely process), and that
805 // other tabs in the current BrowsingInstance will be unable to script it.
806 // This is used for cases that require a process swap even in the
807 // process-per-tab model, such as WebUI pages.
808 const NavigationEntry* current_entry =
809 delegate_->GetLastCommittedNavigationEntryForRenderManager();
810 bool force_swap = !is_guest_scheme &&
811 ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry);
812 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap))
813 new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap);
814
815 // If force_swap is true, we must use a different SiteInstance. If we didn't,
816 // we would have two RenderFrameHosts in the same SiteInstance and the same
817 // frame, resulting in page_id conflicts for their NavigationEntries.
818 if (force_swap)
819 CHECK_NE(new_instance, current_instance);
820
821 return new_instance;
822 }
823
739 SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry( 824 SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry(
740 const NavigationEntryImpl& entry, 825 const NavigationEntryImpl& entry,
741 SiteInstance* current_instance, 826 SiteInstance* current_instance,
742 bool force_browsing_instance_swap) { 827 bool force_browsing_instance_swap) {
743 // Determine which SiteInstance to use for navigating to |entry|. 828 // Determine which SiteInstance to use for navigating to |entry|.
744 const GURL& dest_url = entry.GetURL(); 829 const GURL& dest_url = entry.GetURL();
745 NavigationControllerImpl& controller = 830 NavigationControllerImpl& controller =
746 delegate_->GetControllerForRenderManager(); 831 delegate_->GetControllerForRenderManager();
747 BrowserContext* browser_context = controller.GetBrowserContext(); 832 BrowserContext* browser_context = controller.GetBrowserContext();
748 833
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 } 981 }
897 982
898 // Start the new renderer in a new SiteInstance, but in the current 983 // Start the new renderer in a new SiteInstance, but in the current
899 // BrowsingInstance. It is important to immediately give this new 984 // BrowsingInstance. It is important to immediately give this new
900 // SiteInstance to a RenderViewHost (if it is different than our current 985 // SiteInstance to a RenderViewHost (if it is different than our current
901 // SiteInstance), so that it is ref counted. This will happen in 986 // SiteInstance), so that it is ref counted. This will happen in
902 // CreateRenderView. 987 // CreateRenderView.
903 return current_instance->GetRelatedSiteInstance(dest_url); 988 return current_instance->GetRelatedSiteInstance(dest_url);
904 } 989 }
905 990
991 RenderFrameHostImpl* RenderFrameHostManager::
Charlie Reis 2014/08/08 20:25:28 It feels awkward to return a raw pointer of someth
clamy 2014/08/12 12:13:16 Done.
992 CreateRenderFrameHostForNewSiteInstance(
993 SiteInstance* old_instance,
994 SiteInstance* new_instance,
995 bool is_main_frame) {
996 // Ensure that we have created RFHs for the new RFH's opener chain if
997 // we are staying in the same BrowsingInstance. This allows the new RFH
998 // to send cross-process script calls to its opener(s).
999 int opener_route_id = MSG_ROUTING_NONE;
1000 if (new_instance->IsRelatedSiteInstance(old_instance)) {
1001 opener_route_id =
1002 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
1003 if (CommandLine::ForCurrentProcess()->HasSwitch(
1004 switches::kSitePerProcess)) {
1005 // Ensure that the frame tree has RenderFrameProxyHosts for the new
1006 // SiteInstance in all nodes except the current one.
1007 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance(
1008 frame_tree_node_, new_instance);
1009 }
1010 }
1011
1012 // Create a non-swapped-out RFH with the given opener.
1013 int route_id = CreateRenderFrame(
1014 new_instance, opener_route_id, false, is_main_frame,
1015 delegate_->IsHidden());
1016 if (route_id == MSG_ROUTING_NONE) {
1017 pending_render_frame_host_.reset();
1018 return NULL;
1019 }
1020 return pending_render_frame_host_.get();
1021 }
1022
906 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost( 1023 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
907 SiteInstance* site_instance, 1024 SiteInstance* site_instance,
908 int view_routing_id, 1025 int view_routing_id,
909 int frame_routing_id, 1026 int frame_routing_id,
910 bool swapped_out, 1027 bool swapped_out,
911 bool hidden) { 1028 bool hidden) {
912 if (frame_routing_id == MSG_ROUTING_NONE) 1029 if (frame_routing_id == MSG_ROUTING_NONE)
913 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID(); 1030 frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
914 1031
915 // Create a RVH for main frames, or find the existing one for subframes. 1032 // Create a RVH for main frames, or find the existing one for subframes.
(...skipping 12 matching lines...) Expand all
928 scoped_ptr<RenderFrameHostImpl> render_frame_host = 1045 scoped_ptr<RenderFrameHostImpl> render_frame_host =
929 make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host, 1046 make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host,
930 render_frame_delegate_, 1047 render_frame_delegate_,
931 frame_tree, 1048 frame_tree,
932 frame_tree_node_, 1049 frame_tree_node_,
933 frame_routing_id, 1050 frame_routing_id,
934 swapped_out).release()); 1051 swapped_out).release());
935 return render_frame_host.Pass(); 1052 return render_frame_host.Pass();
936 } 1053 }
937 1054
938 int RenderFrameHostManager::CreateRenderFrame(SiteInstance* instance, 1055 int RenderFrameHostManager::CreateRenderFrame(
939 int opener_route_id, 1056 SiteInstance* instance,
940 bool swapped_out, 1057 int opener_route_id,
941 bool for_main_frame_navigation, 1058 bool swapped_out,
942 bool hidden) { 1059 bool for_main_frame_navigation,
1060 bool hidden) {
943 CHECK(instance); 1061 CHECK(instance);
944 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden. 1062 DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden.
945 1063
946 // TODO(nasko): Remove the following CHECK once cross-site navigation no 1064 // TODO(nasko): Remove the following CHECK once cross-site navigation no
947 // longer relies on swapped out RFH for the top-level frame. 1065 // longer relies on swapped out RFH for the top-level frame.
948 if (!frame_tree_node_->IsMainFrame()) { 1066 if (!frame_tree_node_->IsMainFrame()) {
949 CHECK(!swapped_out); 1067 CHECK(!swapped_out);
950 } 1068 }
951 1069
952 scoped_ptr<RenderFrameHostImpl> new_render_frame_host; 1070 scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 proxy_hosts_[instance->GetId()]->InitRenderFrameProxy(); 1142 proxy_hosts_[instance->GetId()]->InitRenderFrameProxy();
1025 } 1143 }
1026 } else if (!swapped_out && pending_render_frame_host_) { 1144 } else if (!swapped_out && pending_render_frame_host_) {
1027 CancelPending(); 1145 CancelPending();
1028 } 1146 }
1029 routing_id = render_view_host->GetRoutingID(); 1147 routing_id = render_view_host->GetRoutingID();
1030 frame_to_announce = new_render_frame_host.get(); 1148 frame_to_announce = new_render_frame_host.get();
1031 } 1149 }
1032 1150
1033 // Use this as our new pending RFH if it isn't swapped out. 1151 // Use this as our new pending RFH if it isn't swapped out.
1034 if (!swapped_out) 1152 if (!swapped_out) {
Charlie Reis 2014/08/08 20:25:29 Nit: I don't think this change is necessary.
clamy 2014/08/12 12:13:16 Done.
1035 pending_render_frame_host_ = new_render_frame_host.Pass(); 1153 pending_render_frame_host_ = new_render_frame_host.Pass();
1154 }
1036 1155
1037 // If a brand new RFH was created, announce it to observers. 1156 // If a brand new RFH was created, announce it to observers.
1038 if (frame_to_announce) 1157 if (frame_to_announce)
1039 render_frame_delegate_->RenderFrameCreated(frame_to_announce); 1158 render_frame_delegate_->RenderFrameCreated(frame_to_announce);
1040 1159
1041 return routing_id; 1160 return routing_id;
1042 } 1161 }
1043 1162
1044 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { 1163 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
1045 // A RenderFrameProxyHost should never be created in the same SiteInstance as 1164 // A RenderFrameProxyHost should never be created in the same SiteInstance as
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 return render_frame_host_->GetRoutingID(); 1230 return render_frame_host_->GetRoutingID();
1112 1231
1113 RenderFrameProxyHostMap::iterator iter = 1232 RenderFrameProxyHostMap::iterator iter =
1114 proxy_hosts_.find(site_instance->GetId()); 1233 proxy_hosts_.find(site_instance->GetId());
1115 if (iter != proxy_hosts_.end()) 1234 if (iter != proxy_hosts_.end())
1116 return iter->second->GetRoutingID(); 1235 return iter->second->GetRoutingID();
1117 1236
1118 return MSG_ROUTING_NONE; 1237 return MSG_ROUTING_NONE;
1119 } 1238 }
1120 1239
1240 bool RenderFrameHostManager::InitRenderFrameHostsBeforeNavigation(
1241 RenderFrameHostImpl* dest_render_frame_host) {
1242 // If the current render_frame_host_ isn't live, we should create it so
1243 // that we don't show a sad tab while the dest_render_frame_host fetches
1244 // its first page. (crbug.com/1145340)
1245 if (dest_render_frame_host != render_frame_host_ &&
1246 !render_frame_host_->render_view_host()->IsRenderViewLive()) {
1247 // Note: we don't call InitRenderView here because we are navigating away
1248 // soon anyway, and we don't have the NavigationEntry for this host.
1249 delegate_->CreateRenderViewForRenderManager(
1250 render_frame_host_->render_view_host(), MSG_ROUTING_NONE,
1251 MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame());
1252 }
1253
1254 // If the renderer crashed, then try to create a new one to satisfy this
1255 // navigation request.
1256 if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) {
1257 // Recreate the opener chain.
1258 int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
1259 dest_render_frame_host->GetSiteInstance());
1260 if (!InitRenderView(dest_render_frame_host->render_view_host(),
1261 opener_route_id,
1262 MSG_ROUTING_NONE,
1263 frame_tree_node_->IsMainFrame()))
1264 return false;
1265
1266 // Now that we've created a new renderer, be sure to hide it if it isn't
1267 // our primary one. Otherwise, we might crash if we try to call Show()
1268 // on it later.
1269 if (dest_render_frame_host != render_frame_host_ &&
1270 dest_render_frame_host->render_view_host()->GetView()) {
1271 dest_render_frame_host->render_view_host()->GetView()->Hide();
1272 } else {
1273 // Notify here as we won't be calling CommitPending (which does the
1274 // notify).
1275 delegate_->NotifySwappedFromRenderManager(
1276 NULL, render_frame_host_.get(), frame_tree_node_->IsMainFrame());
1277 }
1278 }
1279 return true;
1280 }
1281
1121 void RenderFrameHostManager::CommitPending() { 1282 void RenderFrameHostManager::CommitPending() {
1122 // First check whether we're going to want to focus the location bar after 1283 // First check whether we're going to want to focus the location bar after
1123 // this commit. We do this now because the navigation hasn't formally 1284 // this commit. We do this now because the navigation hasn't formally
1124 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 1285 // committed yet, so if we've already cleared |pending_web_ui_| the call chain
1125 // this triggers won't be able to figure out what's going on. 1286 // this triggers won't be able to figure out what's going on.
1126 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 1287 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
1127 1288
1128 // We expect SwapOutOldPage to have canceled any modal dialogs and told the 1289 // We expect SwapOutOldPage to have canceled any modal dialogs and told the
1129 // renderer to suppress any further dialogs until it is swapped out. However, 1290 // renderer to suppress any further dialogs until it is swapped out. However,
1130 // crash reports indicate that it's still possible for modal dialogs to exist 1291 // crash reports indicate that it's still possible for modal dialogs to exist
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 const NavigationEntryImpl& entry) { 1483 const NavigationEntryImpl& entry) {
1323 // If we are currently navigating cross-process, we want to get back to normal 1484 // If we are currently navigating cross-process, we want to get back to normal
1324 // and then navigate as usual. 1485 // and then navigate as usual.
1325 if (cross_navigation_pending_) { 1486 if (cross_navigation_pending_) {
1326 if (pending_render_frame_host_) 1487 if (pending_render_frame_host_)
1327 CancelPending(); 1488 CancelPending();
1328 cross_navigation_pending_ = false; 1489 cross_navigation_pending_ = false;
1329 } 1490 }
1330 1491
1331 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1492 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1332 scoped_refptr<SiteInstance> new_instance = current_instance; 1493 scoped_refptr<SiteInstance> new_instance =
1494 GetSiteInstanceForNavigation(entry);
1333 1495
1334 // We do not currently swap processes for navigations in webview tag guests.
1335 bool is_guest_scheme = current_instance->GetSiteURL().SchemeIs(kGuestScheme);
1336
1337 // Determine if we need a new BrowsingInstance for this entry. If true, this
1338 // implies that it will get a new SiteInstance (and likely process), and that
1339 // other tabs in the current BrowsingInstance will be unable to script it.
1340 // This is used for cases that require a process swap even in the
1341 // process-per-tab model, such as WebUI pages.
1342 const NavigationEntry* current_entry = 1496 const NavigationEntry* current_entry =
1343 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 1497 delegate_->GetLastCommittedNavigationEntryForRenderManager();
1344 bool force_swap = !is_guest_scheme &&
1345 ShouldSwapBrowsingInstancesForNavigation(current_entry, &entry);
1346 if (!is_guest_scheme && (ShouldTransitionCrossSite() || force_swap))
1347 new_instance = GetSiteInstanceForEntry(entry, current_instance, force_swap);
1348
1349 // If force_swap is true, we must use a different SiteInstance. If we didn't,
1350 // we would have two RenderFrameHosts in the same SiteInstance and the same
1351 // frame, resulting in page_id conflicts for their NavigationEntries.
1352 if (force_swap)
1353 CHECK_NE(new_instance, current_instance);
1354 1498
1355 if (new_instance != current_instance) { 1499 if (new_instance != current_instance) {
1356 // New SiteInstance: create a pending RFH to navigate. 1500 // New SiteInstance: create a pending RFH to navigate.
1357 DCHECK(!cross_navigation_pending_); 1501 DCHECK(!cross_navigation_pending_);
1358 1502
1359 // This will possibly create (set to NULL) a Web UI object for the pending 1503 // This will possibly create (set to NULL) a Web UI object for the pending
1360 // page. We'll use this later to give the page special access. This must 1504 // page. We'll use this later to give the page special access. This must
1361 // happen before the new renderer is created below so it will get bindings. 1505 // happen before the new renderer is created below so it will get bindings.
1362 // It must also happen after the above conditional call to CancelPending(), 1506 // It must also happen after the above conditional call to CancelPending(),
1363 // otherwise CancelPending may clear the pending_web_ui_ and the page will 1507 // otherwise CancelPending may clear the pending_web_ui_ and the page will
1364 // not have its bindings set appropriately. 1508 // not have its bindings set appropriately.
1365 SetPendingWebUI(entry); 1509 SetPendingWebUI(entry);
1366 1510
1367 // Ensure that we have created RFHs for the new RFH's opener chain if 1511 if (!CreateRenderFrameHostForNewSiteInstance(
1368 // we are staying in the same BrowsingInstance. This allows the pending RFH 1512 current_instance, new_instance,
1369 // to send cross-process script calls to its opener(s). 1513 frame_tree_node_->IsMainFrame())) {
1370 int opener_route_id = MSG_ROUTING_NONE; 1514 return NULL;
1371 if (new_instance->IsRelatedSiteInstance(current_instance)) {
1372 opener_route_id =
1373 delegate_->CreateOpenerRenderViewsForRenderManager(new_instance);
1374
1375 if (CommandLine::ForCurrentProcess()->HasSwitch(
1376 switches::kSitePerProcess)) {
1377 // Ensure that the frame tree has RenderFrameProxyHosts for the new
1378 // SiteInstance in all nodes except the current one.
1379 frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance(
1380 frame_tree_node_, new_instance);
1381 }
1382 } 1515 }
1383 1516
1384 // Create a non-swapped-out pending RFH with the given opener and navigate
1385 // it.
1386 int route_id = CreateRenderFrame(new_instance,
1387 opener_route_id,
1388 false,
1389 frame_tree_node_->IsMainFrame(),
1390 delegate_->IsHidden());
1391 if (route_id == MSG_ROUTING_NONE)
1392 return NULL;
1393
1394 // Check if our current RFH is live before we set up a transition. 1517 // Check if our current RFH is live before we set up a transition.
1395 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) { 1518 if (!render_frame_host_->render_view_host()->IsRenderViewLive()) {
1396 if (!cross_navigation_pending_) { 1519 if (!cross_navigation_pending_) {
1397 // The current RFH is not live. There's no reason to sit around with a 1520 // The current RFH is not live. There's no reason to sit around with a
1398 // sad tab or a newly created RFH while we wait for the pending RFH to 1521 // sad tab or a newly created RFH while we wait for the pending RFH to
1399 // navigate. Just switch to the pending RFH now and go back to non 1522 // navigate. Just switch to the pending RFH now and go back to non
1400 // cross-navigating (Note that we don't care about on{before}unload 1523 // cross-navigating (Note that we don't care about on{before}unload
1401 // handlers if the current RFH isn't live.) 1524 // handlers if the current RFH isn't live.)
1402 CommitPending(); 1525 CommitPending();
1403 return render_frame_host_.get(); 1526 return render_frame_host_.get();
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 SiteInstance* instance) const { 1708 SiteInstance* instance) const {
1586 RenderFrameProxyHostMap::const_iterator iter = 1709 RenderFrameProxyHostMap::const_iterator iter =
1587 proxy_hosts_.find(instance->GetId()); 1710 proxy_hosts_.find(instance->GetId());
1588 if (iter != proxy_hosts_.end()) 1711 if (iter != proxy_hosts_.end())
1589 return iter->second; 1712 return iter->second;
1590 1713
1591 return NULL; 1714 return NULL;
1592 } 1715 }
1593 1716
1594 } // namespace content 1717 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698