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