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 <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 12 matching lines...) Expand all Loading... | |
23 #include "content/browser/frame_host/navigation_request.h" | 23 #include "content/browser/frame_host/navigation_request.h" |
24 #include "content/browser/frame_host/navigator.h" | 24 #include "content/browser/frame_host/navigator.h" |
25 #include "content/browser/frame_host/render_frame_host_factory.h" | 25 #include "content/browser/frame_host/render_frame_host_factory.h" |
26 #include "content/browser/frame_host/render_frame_host_impl.h" | 26 #include "content/browser/frame_host/render_frame_host_impl.h" |
27 #include "content/browser/frame_host/render_frame_proxy_host.h" | 27 #include "content/browser/frame_host/render_frame_proxy_host.h" |
28 #include "content/browser/renderer_host/render_process_host_impl.h" | 28 #include "content/browser/renderer_host/render_process_host_impl.h" |
29 #include "content/browser/renderer_host/render_view_host_factory.h" | 29 #include "content/browser/renderer_host/render_view_host_factory.h" |
30 #include "content/browser/renderer_host/render_view_host_impl.h" | 30 #include "content/browser/renderer_host/render_view_host_impl.h" |
31 #include "content/browser/site_instance_impl.h" | 31 #include "content/browser/site_instance_impl.h" |
32 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 32 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
33 #include "content/browser/webui/web_ui_impl.h" | |
34 #include "content/common/frame_messages.h" | 33 #include "content/common/frame_messages.h" |
35 #include "content/common/site_isolation_policy.h" | 34 #include "content/common/site_isolation_policy.h" |
36 #include "content/common/view_messages.h" | 35 #include "content/common/view_messages.h" |
37 #include "content/public/browser/content_browser_client.h" | 36 #include "content/public/browser/content_browser_client.h" |
38 #include "content/public/browser/render_process_host_observer.h" | 37 #include "content/public/browser/render_process_host_observer.h" |
39 #include "content/public/browser/render_widget_host_iterator.h" | 38 #include "content/public/browser/render_widget_host_iterator.h" |
40 #include "content/public/browser/render_widget_host_view.h" | 39 #include "content/public/browser/render_widget_host_view.h" |
41 #include "content/public/browser/user_metrics.h" | 40 #include "content/public/browser/user_metrics.h" |
42 #include "content/public/browser/web_ui_controller.h" | |
43 #include "content/public/common/browser_plugin_guest_mode.h" | 41 #include "content/public/common/browser_plugin_guest_mode.h" |
44 #include "content/public/common/content_switches.h" | 42 #include "content/public/common/content_switches.h" |
45 #include "content/public/common/referrer.h" | 43 #include "content/public/common/referrer.h" |
46 #include "content/public/common/url_constants.h" | 44 #include "content/public/common/url_constants.h" |
47 | 45 |
48 namespace content { | 46 namespace content { |
49 | 47 |
50 namespace { | 48 namespace { |
51 | 49 |
52 // Helper function to add the FrameTree of the given node's opener to the list | 50 // Helper function to add the FrameTree of the given node's opener to the list |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 RenderViewHostDelegate* render_view_delegate, | 211 RenderViewHostDelegate* render_view_delegate, |
214 RenderWidgetHostDelegate* render_widget_delegate, | 212 RenderWidgetHostDelegate* render_widget_delegate, |
215 Delegate* delegate) | 213 Delegate* delegate) |
216 : frame_tree_node_(frame_tree_node), | 214 : frame_tree_node_(frame_tree_node), |
217 delegate_(delegate), | 215 delegate_(delegate), |
218 render_frame_delegate_(render_frame_delegate), | 216 render_frame_delegate_(render_frame_delegate), |
219 render_view_delegate_(render_view_delegate), | 217 render_view_delegate_(render_view_delegate), |
220 render_widget_delegate_(render_widget_delegate), | 218 render_widget_delegate_(render_widget_delegate), |
221 proxy_hosts_(new RenderFrameProxyHostMap(this)), | 219 proxy_hosts_(new RenderFrameProxyHostMap(this)), |
222 interstitial_page_(nullptr), | 220 interstitial_page_(nullptr), |
223 should_reuse_web_ui_(false), | |
224 weak_factory_(this) { | 221 weak_factory_(this) { |
225 DCHECK(frame_tree_node_); | 222 DCHECK(frame_tree_node_); |
226 } | 223 } |
227 | 224 |
228 RenderFrameHostManager::~RenderFrameHostManager() { | 225 RenderFrameHostManager::~RenderFrameHostManager() { |
229 if (pending_render_frame_host_) { | 226 if (pending_render_frame_host_) { |
230 scoped_ptr<RenderFrameHostImpl> relic = UnsetPendingRenderFrameHost(); | 227 scoped_ptr<RenderFrameHostImpl> relic = UnsetPendingRenderFrameHost(); |
231 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); | 228 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); |
232 } | 229 } |
233 | 230 |
234 if (speculative_render_frame_host_) { | 231 if (speculative_render_frame_host_) { |
235 scoped_ptr<RenderFrameHostImpl> relic = UnsetSpeculativeRenderFrameHost(); | 232 scoped_ptr<RenderFrameHostImpl> relic = UnsetSpeculativeRenderFrameHost(); |
236 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); | 233 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); |
237 } | 234 } |
238 | 235 |
239 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host_.get()); | 236 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host_.get()); |
240 | 237 |
241 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts. | 238 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts. |
242 // It is important to delete those prior to deleting the current | 239 // It is important to delete those prior to deleting the current |
243 // RenderFrameHost, since the CrossProcessFrameConnector (owned by | 240 // RenderFrameHost, since the CrossProcessFrameConnector (owned by |
244 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with | 241 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with |
245 // the current RenderFrameHost and uses it during its destructor. | 242 // the current RenderFrameHost and uses it during its destructor. |
246 ResetProxyHosts(); | 243 ResetProxyHosts(); |
247 | 244 |
248 // Release the WebUI prior to resetting the current RenderFrameHost, as the | |
249 // WebUI accesses the RenderFrameHost during cleanup. | |
250 web_ui_.reset(); | |
251 | |
252 // We should always have a current RenderFrameHost except in some tests. | 245 // We should always have a current RenderFrameHost except in some tests. |
253 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); | 246 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); |
254 } | 247 } |
255 | 248 |
256 void RenderFrameHostManager::Init(BrowserContext* browser_context, | 249 void RenderFrameHostManager::Init(BrowserContext* browser_context, |
257 SiteInstance* site_instance, | 250 SiteInstance* site_instance, |
258 int32 view_routing_id, | 251 int32 view_routing_id, |
259 int32 frame_routing_id, | 252 int32 frame_routing_id, |
260 int32 widget_routing_id) { | 253 int32 widget_routing_id) { |
261 // Create a RenderViewHost and RenderFrameHost, once we have an instance. It | 254 // Create a RenderViewHost and RenderFrameHost, once we have an instance. It |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 | 338 |
346 void RenderFrameHostManager::RemoveOuterDelegateFrame() { | 339 void RenderFrameHostManager::RemoveOuterDelegateFrame() { |
347 FrameTreeNode* outer_delegate_frame_tree_node = | 340 FrameTreeNode* outer_delegate_frame_tree_node = |
348 FrameTreeNode::GloballyFindByID( | 341 FrameTreeNode::GloballyFindByID( |
349 delegate_->GetOuterDelegateFrameTreeNodeID()); | 342 delegate_->GetOuterDelegateFrameTreeNodeID()); |
350 DCHECK(outer_delegate_frame_tree_node->parent()); | 343 DCHECK(outer_delegate_frame_tree_node->parent()); |
351 outer_delegate_frame_tree_node->frame_tree()->RemoveFrame( | 344 outer_delegate_frame_tree_node->frame_tree()->RemoveFrame( |
352 outer_delegate_frame_tree_node); | 345 outer_delegate_frame_tree_node); |
353 } | 346 } |
354 | 347 |
355 void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) { | |
356 pending_web_ui_ = CreateWebUI(url, bindings); | |
357 pending_and_current_web_ui_.reset(); | |
358 } | |
359 | |
360 scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url, | |
361 int bindings) { | |
362 scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url)); | |
363 | |
364 // If we have assigned (zero or more) bindings to this NavigationEntry in the | |
365 // past, make sure we're not granting it different bindings than it had | |
366 // before. If so, note it and don't give it any bindings, to avoid a | |
367 // potential privilege escalation. | |
368 if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings && | |
369 new_web_ui->GetBindings() != bindings) { | |
370 RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); | |
371 return nullptr; | |
372 } | |
373 return new_web_ui.Pass(); | |
374 } | |
375 | |
376 RenderFrameHostImpl* RenderFrameHostManager::Navigate( | 348 RenderFrameHostImpl* RenderFrameHostManager::Navigate( |
377 const GURL& dest_url, | 349 const GURL& dest_url, |
378 const FrameNavigationEntry& frame_entry, | 350 const FrameNavigationEntry& frame_entry, |
379 const NavigationEntryImpl& entry) { | 351 const NavigationEntryImpl& entry) { |
380 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", | 352 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", |
381 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 353 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
382 // Create a pending RenderFrameHost to use for the navigation. | 354 // Create a pending RenderFrameHost to use for the navigation. |
383 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( | 355 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( |
384 dest_url, | 356 dest_url, |
385 // TODO(creis): Move source_site_instance to FNE. | 357 // TODO(creis): Move source_site_instance to FNE. |
(...skipping 29 matching lines...) Expand all Loading... | |
415 // add a service to this RFH's ServiceRegistry). | 387 // add a service to this RFH's ServiceRegistry). |
416 dest_render_frame_host->SetUpMojoIfNeeded(); | 388 dest_render_frame_host->SetUpMojoIfNeeded(); |
417 | 389 |
418 // Recreate the opener chain. | 390 // Recreate the opener chain. |
419 CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(), | 391 CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(), |
420 frame_tree_node_); | 392 frame_tree_node_); |
421 if (!InitRenderView(dest_render_frame_host->render_view_host(), | 393 if (!InitRenderView(dest_render_frame_host->render_view_host(), |
422 MSG_ROUTING_NONE)) | 394 MSG_ROUTING_NONE)) |
423 return nullptr; | 395 return nullptr; |
424 | 396 |
397 if (pending_web_ui()) { | |
Charlie Reis
2015/10/23 06:39:25
This doesn't look safe. pending_web_ui() can retu
carlosk
2015/10/27 14:35:44
I am uncertain about this. It seems this would gen
| |
398 pending_web_ui()->RenderViewCreated( | |
399 dest_render_frame_host->render_view_host()); | |
400 } | |
401 | |
425 // Now that we've created a new renderer, be sure to hide it if it isn't | 402 // Now that we've created a new renderer, be sure to hide it if it isn't |
426 // our primary one. Otherwise, we might crash if we try to call Show() | 403 // our primary one. Otherwise, we might crash if we try to call Show() |
427 // on it later. | 404 // on it later. |
428 if (dest_render_frame_host != render_frame_host_) { | 405 if (dest_render_frame_host != render_frame_host_) { |
429 if (dest_render_frame_host->GetView()) | 406 if (dest_render_frame_host->GetView()) |
430 dest_render_frame_host->GetView()->Hide(); | 407 dest_render_frame_host->GetView()->Hide(); |
431 } else { | 408 } else { |
432 // After a renderer crash we'd have marked the host as invisible, so we | 409 // After a renderer crash we'd have marked the host as invisible, so we |
433 // need to set the visibility of the new View to the correct value here | 410 // need to set the visibility of the new View to the correct value here |
434 // after reload. | 411 // after reload. |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
665 | 642 |
666 // Make sure any dynamic changes to this frame's sandbox flags that were made | 643 // Make sure any dynamic changes to this frame's sandbox flags that were made |
667 // prior to navigation take effect. | 644 // prior to navigation take effect. |
668 CommitPendingSandboxFlags(); | 645 CommitPendingSandboxFlags(); |
669 } | 646 } |
670 | 647 |
671 void RenderFrameHostManager::CommitPendingIfNecessary( | 648 void RenderFrameHostManager::CommitPendingIfNecessary( |
672 RenderFrameHostImpl* render_frame_host, | 649 RenderFrameHostImpl* render_frame_host, |
673 bool was_caused_by_user_gesture) { | 650 bool was_caused_by_user_gesture) { |
674 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { | 651 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { |
675 DCHECK_IMPLIES(should_reuse_web_ui_, web_ui_); | |
676 | 652 |
677 // We should only hear this from our current renderer. | 653 // We should only hear this from our current renderer. |
678 DCHECK_EQ(render_frame_host_, render_frame_host); | 654 DCHECK_EQ(render_frame_host_, render_frame_host); |
679 | 655 |
680 // Even when there is no pending RVH, there may be a pending Web UI. | 656 // If current RenderFrameHost has a pending WebUI, commit it. |
Charlie Reis
2015/10/23 06:39:25
Could this be handled inside RenderFrameHostImpl::
carlosk
2015/10/30 10:35:22
See reply in CommitPending.
| |
681 if (pending_web_ui() || speculative_web_ui_) | 657 if (render_frame_host_->pending_web_ui()) |
682 CommitPending(); | 658 CommitPending(); |
683 return; | 659 return; |
684 } | 660 } |
685 | 661 |
686 if (render_frame_host == pending_render_frame_host_ || | 662 if (render_frame_host == pending_render_frame_host_ || |
687 render_frame_host == speculative_render_frame_host_) { | 663 render_frame_host == speculative_render_frame_host_) { |
688 // The pending cross-process navigation completed, so show the renderer. | 664 // The pending cross-process navigation completed, so show the renderer. |
689 CommitPending(); | 665 CommitPending(); |
690 } else if (render_frame_host == render_frame_host_) { | 666 } else if (render_frame_host == render_frame_host_) { |
691 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 667 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1020 if (current_site_instance == dest_site_instance.get() || | 996 if (current_site_instance == dest_site_instance.get() || |
1021 (!request.browser_initiated() && is_main_frame) || | 997 (!request.browser_initiated() && is_main_frame) || |
1022 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() && | 998 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() && |
1023 !current_site_instance->RequiresDedicatedProcess())) { | 999 !current_site_instance->RequiresDedicatedProcess())) { |
1024 // Reuse the current RFH if its SiteInstance matches the the navigation's | 1000 // Reuse the current RFH if its SiteInstance matches the the navigation's |
1025 // or if this is a subframe navigation. We only swap RFHs for subframes when | 1001 // or if this is a subframe navigation. We only swap RFHs for subframes when |
1026 // --site-per-process is enabled. | 1002 // --site-per-process is enabled. |
1027 CleanUpNavigation(); | 1003 CleanUpNavigation(); |
1028 navigation_rfh = render_frame_host_.get(); | 1004 navigation_rfh = render_frame_host_.get(); |
1029 | 1005 |
1030 // As SiteInstances are the same, check if the WebUI should be reused. | 1006 // As SiteInstances are the same, make the RFH update its possible pending |
1031 const NavigationEntry* current_navigation_entry = | 1007 // WebUI. |
1032 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1008 render_frame_host_->UpdatePendingWebUI(request.common_params().url, |
1033 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, | 1009 request.bindings()); |
1034 request.common_params().url); | 1010 DCHECK(speculative_web_ui() == render_frame_host_->pending_web_ui()); |
1035 if (!should_reuse_web_ui_) { | 1011 |
1036 speculative_web_ui_ = CreateWebUI(request.common_params().url, | 1012 // If a pending WebUI was set on the current RenderFrameHost (be it a new |
1037 request.bindings()); | 1013 // one or the reused current one) and the associated RenderFrame is alive, |
1038 // Make sure the current RenderViewHost has the right bindings. | 1014 // notify the WebUI the RenderView is being reused. |
1039 if (speculative_web_ui() && | 1015 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { |
1040 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | 1016 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), |
1041 render_frame_host_->render_view_host()->AllowBindings( | 1017 frame_tree_node_->IsMainFrame()); |
1042 speculative_web_ui()->GetBindings()); | |
1043 } | |
1044 } | 1018 } |
1019 | |
1020 DCHECK(!speculative_render_frame_host_); | |
1045 } else { | 1021 } else { |
1046 // If the SiteInstance for the final URL doesn't match the one from the | 1022 // If the SiteInstance for the final URL doesn't match the one from the |
1047 // speculatively created RenderFrameHost, create a new RenderFrameHost using | 1023 // speculatively created RenderFrameHost, create a new RenderFrameHost using |
1048 // this new SiteInstance. | 1024 // this new SiteInstance. |
1049 if (!speculative_render_frame_host_ || | 1025 if (!speculative_render_frame_host_ || |
1050 speculative_render_frame_host_->GetSiteInstance() != | 1026 speculative_render_frame_host_->GetSiteInstance() != |
1051 dest_site_instance.get()) { | 1027 dest_site_instance.get()) { |
1052 CleanUpNavigation(); | 1028 CleanUpNavigation(); |
1053 bool success = CreateSpeculativeRenderFrameHost( | 1029 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, |
1054 request.common_params().url, current_site_instance, | 1030 dest_site_instance.get()); |
1055 dest_site_instance.get(), request.bindings()); | |
1056 DCHECK(success); | 1031 DCHECK(success); |
1032 | |
1033 InitializeWebUI(request.common_params().url, request.bindings()); | |
1034 } else { | |
1035 // The speculative RenderFrameHost should only have an active WebUI. So | |
1036 // when reusing an existing one its pending WebUI is updated with the | |
1037 // current (possibly changed) URL and immediately committed. | |
1038 speculative_render_frame_host_->UpdatePendingWebUI( | |
1039 request.common_params().url, request.bindings()); | |
1040 speculative_render_frame_host_->CommitPendingWebUI(); | |
1057 } | 1041 } |
1058 DCHECK(speculative_render_frame_host_); | 1042 DCHECK(speculative_render_frame_host_); |
1043 DCHECK_EQ(speculative_web_ui(), speculative_render_frame_host_->web_ui()); | |
1044 DCHECK(!speculative_render_frame_host_->pending_web_ui()); | |
1045 DCHECK(!render_frame_host_->pending_web_ui()); | |
1046 | |
1059 navigation_rfh = speculative_render_frame_host_.get(); | 1047 navigation_rfh = speculative_render_frame_host_.get(); |
1060 | 1048 |
1061 // Check if our current RFH is live. | 1049 // Check if our current RFH is live. |
1062 if (!render_frame_host_->IsRenderFrameLive()) { | 1050 if (!render_frame_host_->IsRenderFrameLive()) { |
1063 // The current RFH is not live. There's no reason to sit around with a | 1051 // The current RFH is not live. There's no reason to sit around with a |
1064 // sad tab or a newly created RFH while we wait for the navigation to | 1052 // sad tab or a newly created RFH while we wait for the navigation to |
1065 // complete. Just switch to the speculative RFH now and go back to normal. | 1053 // complete. Just switch to the speculative RFH now and go back to normal. |
1066 // (Note that we don't care about on{before}unload handlers if the current | 1054 // (Note that we don't care about on{before}unload handlers if the current |
1067 // RFH isn't live.) | 1055 // RFH isn't live.) |
1068 CommitPending(); | 1056 CommitPending(); |
1069 } | 1057 } |
1070 } | 1058 } |
1071 DCHECK(navigation_rfh && | 1059 DCHECK(navigation_rfh && |
1072 (navigation_rfh == render_frame_host_.get() || | 1060 (navigation_rfh == render_frame_host_.get() || |
1073 navigation_rfh == speculative_render_frame_host_.get())); | 1061 navigation_rfh == speculative_render_frame_host_.get())); |
1074 | 1062 |
1075 // If the RenderFrame that needs to navigate is not live (its process was just | 1063 // If the RenderFrame that needs to navigate is not live (its process was just |
1076 // created or has crashed), initialize it. | 1064 // created or has crashed), initialize it. |
1077 if (!navigation_rfh->IsRenderFrameLive()) { | 1065 if (!navigation_rfh->IsRenderFrameLive()) { |
1078 // Recreate the opener chain. | 1066 // Recreate the opener chain. |
1079 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); | 1067 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); |
1080 if (!InitRenderView(navigation_rfh->render_view_host(), MSG_ROUTING_NONE)) { | 1068 if (!InitRenderView(navigation_rfh->render_view_host(), MSG_ROUTING_NONE)) |
1081 return nullptr; | 1069 return nullptr; |
1070 | |
1071 if (speculative_web_ui()) { | |
1072 speculative_web_ui()->RenderViewCreated( | |
1073 navigation_rfh->render_view_host()); | |
1082 } | 1074 } |
1083 | 1075 |
1084 if (navigation_rfh == render_frame_host_) { | 1076 if (navigation_rfh == render_frame_host_) { |
1085 // TODO(nasko): This is a very ugly hack. The Chrome extensions process | 1077 // TODO(nasko): This is a very ugly hack. The Chrome extensions process |
1086 // manager still uses NotificationService and expects to see a | 1078 // manager still uses NotificationService and expects to see a |
1087 // RenderViewHost changed notification after WebContents and | 1079 // RenderViewHost changed notification after WebContents and |
1088 // RenderFrameHostManager are completely initialized. This should be | 1080 // RenderFrameHostManager are completely initialized. This should be |
1089 // removed once the process manager moves away from NotificationService. | 1081 // removed once the process manager moves away from NotificationService. |
1090 // See https://crbug.com/462682. | 1082 // See https://crbug.com/462682. |
1091 delegate_->NotifyMainFrameSwappedFromRenderManager( | 1083 delegate_->NotifyMainFrameSwappedFromRenderManager( |
1092 nullptr, render_frame_host_->render_view_host()); | 1084 nullptr, render_frame_host_->render_view_host()); |
1093 } | 1085 } |
1094 } | 1086 } |
1095 | 1087 |
1096 return navigation_rfh; | 1088 return navigation_rfh; |
1097 } | 1089 } |
1098 | 1090 |
1099 // PlzNavigate | 1091 // PlzNavigate |
1100 void RenderFrameHostManager::CleanUpNavigation() { | 1092 void RenderFrameHostManager::CleanUpNavigation() { |
1101 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1093 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
1102 switches::kEnableBrowserSideNavigation)); | 1094 switches::kEnableBrowserSideNavigation)); |
1103 speculative_web_ui_.reset(); | 1095 // TODO(carlosk): the discarding of the current RFH WebUI and the cleanup of |
1104 should_reuse_web_ui_ = false; | 1096 // the speculative RFH should not always happen together. |
1097 render_frame_host_->DiscardPendingWebUI(); | |
1105 if (speculative_render_frame_host_) | 1098 if (speculative_render_frame_host_) |
1106 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 1099 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
1107 } | 1100 } |
1108 | 1101 |
1109 // PlzNavigate | 1102 // PlzNavigate |
1110 scoped_ptr<RenderFrameHostImpl> | 1103 scoped_ptr<RenderFrameHostImpl> |
1111 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { | 1104 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { |
1112 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1105 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
1113 switches::kEnableBrowserSideNavigation)); | 1106 switches::kEnableBrowserSideNavigation)); |
1114 speculative_render_frame_host_->GetProcess()->RemovePendingView(); | 1107 speculative_render_frame_host_->GetProcess()->RemovePendingView(); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1278 // We can't switch a RenderView between view source and non-view source mode | 1271 // We can't switch a RenderView between view source and non-view source mode |
1279 // without screwing up the session history sometimes (when navigating between | 1272 // without screwing up the session history sometimes (when navigating between |
1280 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat | 1273 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat |
1281 // it as a new navigation). So require a BrowsingInstance switch. | 1274 // it as a new navigation). So require a BrowsingInstance switch. |
1282 if (current_is_view_source_mode != new_is_view_source_mode) | 1275 if (current_is_view_source_mode != new_is_view_source_mode) |
1283 return true; | 1276 return true; |
1284 | 1277 |
1285 return false; | 1278 return false; |
1286 } | 1279 } |
1287 | 1280 |
1288 bool RenderFrameHostManager::ShouldReuseWebUI( | |
1289 const NavigationEntry* current_entry, | |
1290 const GURL& new_url) const { | |
1291 NavigationControllerImpl& controller = | |
1292 delegate_->GetControllerForRenderManager(); | |
1293 return current_entry && web_ui_ && | |
1294 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
1295 controller.GetBrowserContext(), current_entry->GetURL()) == | |
1296 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
1297 controller.GetBrowserContext(), new_url)); | |
1298 } | |
1299 | |
1300 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( | 1281 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( |
1301 const GURL& dest_url, | 1282 const GURL& dest_url, |
1302 SiteInstance* source_instance, | 1283 SiteInstance* source_instance, |
1303 SiteInstance* dest_instance, | 1284 SiteInstance* dest_instance, |
1304 SiteInstance* candidate_instance, | 1285 SiteInstance* candidate_instance, |
1305 ui::PageTransition transition, | 1286 ui::PageTransition transition, |
1306 bool dest_is_restore, | 1287 bool dest_is_restore, |
1307 bool dest_is_view_source_mode) { | 1288 bool dest_is_view_source_mode) { |
1308 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1289 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
1309 | 1290 |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1622 // The process for the new SiteInstance may (if we're sharing a process with | 1603 // The process for the new SiteInstance may (if we're sharing a process with |
1623 // another host that already initialized it) or may not (we have our own | 1604 // another host that already initialized it) or may not (we have our own |
1624 // process or the existing process crashed) have been initialized. Calling | 1605 // process or the existing process crashed) have been initialized. Calling |
1625 // Init multiple times will be ignored, so this is safe. | 1606 // Init multiple times will be ignored, so this is safe. |
1626 if (!new_instance->GetProcess()->Init()) | 1607 if (!new_instance->GetProcess()->Init()) |
1627 return; | 1608 return; |
1628 | 1609 |
1629 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1610 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
1630 | 1611 |
1631 // Create a non-swapped-out RFH with the given opener. | 1612 // Create a non-swapped-out RFH with the given opener. |
1632 pending_render_frame_host_ = CreateRenderFrame( | 1613 pending_render_frame_host_ = |
1633 new_instance, pending_web_ui(), create_render_frame_flags, nullptr); | 1614 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
1634 } | 1615 } |
1635 | 1616 |
1636 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( | 1617 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( |
1637 SiteInstance* old_instance, | 1618 SiteInstance* old_instance, |
1638 SiteInstance* new_instance) { | 1619 SiteInstance* new_instance) { |
1639 // Only create opener proxies if they are in the same BrowsingInstance. | 1620 // Only create opener proxies if they are in the same BrowsingInstance. |
1640 if (new_instance->IsRelatedSiteInstance(old_instance)) { | 1621 if (new_instance->IsRelatedSiteInstance(old_instance)) { |
1641 CreateOpenerProxies(new_instance, frame_tree_node_); | 1622 CreateOpenerProxies(new_instance, frame_tree_node_); |
1642 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { | 1623 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { |
1643 // Ensure that the frame tree has RenderFrameProxyHosts for the | 1624 // Ensure that the frame tree has RenderFrameProxyHosts for the |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1705 } | 1686 } |
1706 | 1687 |
1707 return RenderFrameHostFactory::Create( | 1688 return RenderFrameHostFactory::Create( |
1708 site_instance, render_view_host, render_frame_delegate_, | 1689 site_instance, render_view_host, render_frame_delegate_, |
1709 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, | 1690 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, |
1710 widget_routing_id, flags); | 1691 widget_routing_id, flags); |
1711 } | 1692 } |
1712 | 1693 |
1713 // PlzNavigate | 1694 // PlzNavigate |
1714 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( | 1695 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( |
1715 const GURL& url, | |
1716 SiteInstance* old_instance, | 1696 SiteInstance* old_instance, |
1717 SiteInstance* new_instance, | 1697 SiteInstance* new_instance) { |
1718 int bindings) { | |
1719 CHECK(new_instance); | 1698 CHECK(new_instance); |
1720 CHECK_NE(old_instance, new_instance); | 1699 CHECK_NE(old_instance, new_instance); |
1721 CHECK(!should_reuse_web_ui_); | |
1722 | |
1723 // Note: |speculative_web_ui_| must be initialized before starting the | |
1724 // |speculative_render_frame_host_| creation steps otherwise the WebUI | |
1725 // won't be properly initialized. | |
1726 speculative_web_ui_ = CreateWebUI(url, bindings); | |
1727 | 1700 |
1728 // The process for the new SiteInstance may (if we're sharing a process with | 1701 // The process for the new SiteInstance may (if we're sharing a process with |
1729 // another host that already initialized it) or may not (we have our own | 1702 // another host that already initialized it) or may not (we have our own |
1730 // process or the existing process crashed) have been initialized. Calling | 1703 // process or the existing process crashed) have been initialized. Calling |
1731 // Init multiple times will be ignored, so this is safe. | 1704 // Init multiple times will be ignored, so this is safe. |
1732 if (!new_instance->GetProcess()->Init()) | 1705 if (!new_instance->GetProcess()->Init()) |
1733 return false; | 1706 return false; |
1734 | 1707 |
1735 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1708 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
1736 | 1709 |
1737 int create_render_frame_flags = 0; | 1710 int create_render_frame_flags = 0; |
1738 if (delegate_->IsHidden()) | 1711 if (delegate_->IsHidden()) |
1739 create_render_frame_flags |= CREATE_RF_HIDDEN; | 1712 create_render_frame_flags |= CREATE_RF_HIDDEN; |
1740 speculative_render_frame_host_ = | 1713 speculative_render_frame_host_ = |
1741 CreateRenderFrame(new_instance, speculative_web_ui_.get(), | 1714 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
1742 create_render_frame_flags, nullptr); | |
1743 | 1715 |
1744 if (!speculative_render_frame_host_) { | 1716 return !!speculative_render_frame_host_; |
1745 speculative_web_ui_.reset(); | 1717 } |
1746 return false; | 1718 |
1719 void RenderFrameHostManager::InitializeWebUI(const GURL& url, int bindings) { | |
1720 RenderFrameHostImpl* rfh; | |
Charlie Reis
2015/10/23 06:39:26
nit: Initialize to nullptr. (Safer in case future
carlosk
2015/10/27 14:35:44
Done.
| |
1721 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
1722 switches::kEnableBrowserSideNavigation)) { | |
1723 rfh = speculative_render_frame_host_.get(); | |
1724 } else { | |
1725 rfh = pending_render_frame_host_.get(); | |
1747 } | 1726 } |
1748 return true; | 1727 DCHECK(rfh); |
1728 | |
1729 // Clear any pending WebUI on the current RenderFrameHost as it won't | |
1730 // be used. | |
1731 render_frame_host_->DiscardPendingWebUI(); | |
1732 | |
1733 // For new RenderFrameHosts the WebUI should always be kept as active: | |
1734 // - It should only have one WebUI so it doesn't need the pending one. | |
1735 // - When (and if) it commits there's no need to also commit the WebUI. | |
Charlie Reis
2015/10/23 06:39:25
s/When (and if)/If/
carlosk
2015/10/27 14:35:44
Done.
| |
1736 rfh->UpdatePendingWebUI(url, bindings); | |
1737 rfh->CommitPendingWebUI(); | |
1738 RenderViewHostImpl* rvh = rfh->render_view_host(); | |
1739 | |
1740 if (rfh->web_ui()) | |
1741 rfh->web_ui()->RenderViewCreated(rvh); | |
1742 | |
1743 // If the ongoing navigation is not to a WebUI or the RenderView is in a | |
Charlie Reis
2015/10/23 06:39:26
Should this block be inside RenderFrameHost (e.g.,
carlosk
2015/10/27 14:35:44
Done. I wanted this from the start and tried it qu
| |
1744 // guest process, ensure that we don't create an unprivileged RenderView in a | |
1745 // WebUI-enabled process unless it's swapped out. | |
1746 if ((!rfh->web_ui() || rvh->GetProcess()->IsForGuestsOnly()) && | |
1747 rvh->is_active()) { | |
1748 bool url_acceptable_for_webui = | |
1749 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI( | |
1750 delegate_->GetControllerForRenderManager().GetBrowserContext(), | |
1751 url); | |
1752 if (!url_acceptable_for_webui) { | |
1753 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | |
1754 rvh->GetProcess()->GetID())); | |
1755 } | |
1756 } | |
1749 } | 1757 } |
1750 | 1758 |
1751 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( | 1759 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( |
1752 SiteInstance* instance, | 1760 SiteInstance* instance, |
1753 WebUIImpl* web_ui, | |
1754 int flags, | 1761 int flags, |
1755 int* view_routing_id_ptr) { | 1762 int* view_routing_id_ptr) { |
1756 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1763 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
1757 bool swapped_out_forbidden = | 1764 bool swapped_out_forbidden = |
1758 SiteIsolationPolicy::IsSwappedOutStateForbidden(); | 1765 SiteIsolationPolicy::IsSwappedOutStateForbidden(); |
1759 | 1766 |
1760 CHECK(instance); | 1767 CHECK(instance); |
1761 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out); | 1768 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out); |
1762 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(), | 1769 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(), |
1763 frame_tree_node_->IsMainFrame()); | 1770 frame_tree_node_->IsMainFrame()); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1864 success = InitRenderFrame(new_render_frame_host.get()); | 1871 success = InitRenderFrame(new_render_frame_host.get()); |
1865 } | 1872 } |
1866 } | 1873 } |
1867 | 1874 |
1868 if (success) { | 1875 if (success) { |
1869 if (view_routing_id_ptr) | 1876 if (view_routing_id_ptr) |
1870 *view_routing_id_ptr = render_view_host->GetRoutingID(); | 1877 *view_routing_id_ptr = render_view_host->GetRoutingID(); |
1871 } | 1878 } |
1872 } | 1879 } |
1873 | 1880 |
1874 // When a new RenderView is created by the renderer process, the new | |
1875 // WebContents gets a RenderViewHost in the SiteInstance of its opener | |
1876 // WebContents. If not used in the first navigation, this RVH is swapped out | |
1877 // and is not granted bindings, so we may need to grant them when swapping it | |
1878 // in. | |
1879 if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) { | |
1880 int required_bindings = web_ui->GetBindings(); | |
1881 RenderViewHost* render_view_host = | |
1882 new_render_frame_host->render_view_host(); | |
1883 if ((render_view_host->GetEnabledBindings() & required_bindings) != | |
1884 required_bindings) { | |
1885 render_view_host->AllowBindings(required_bindings); | |
1886 } | |
1887 } | |
1888 | |
1889 // Returns the new RFH if it isn't swapped out. | 1881 // Returns the new RFH if it isn't swapped out. |
1890 if (success && !swapped_out) { | 1882 if (success && !swapped_out) { |
1891 DCHECK(new_render_frame_host->GetSiteInstance() == instance); | 1883 DCHECK(new_render_frame_host->GetSiteInstance() == instance); |
1884 DCHECK(new_render_frame_host->render_view_host()->IsRenderViewLive()); | |
1892 return new_render_frame_host.Pass(); | 1885 return new_render_frame_host.Pass(); |
1893 } | 1886 } |
1894 return nullptr; | 1887 return nullptr; |
1895 } | 1888 } |
1896 | 1889 |
1897 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { | 1890 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { |
1898 // A RenderFrameProxyHost should never be created in the same SiteInstance as | 1891 // A RenderFrameProxyHost should never be created in the same SiteInstance as |
1899 // the current RFH. | 1892 // the current RFH. |
1900 CHECK(instance); | 1893 CHECK(instance); |
1901 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); | 1894 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1999 int proxy_routing_id) { | 1992 int proxy_routing_id) { |
2000 // Ensure the renderer process is initialized before creating the | 1993 // Ensure the renderer process is initialized before creating the |
2001 // RenderView. | 1994 // RenderView. |
2002 if (!render_view_host->GetProcess()->Init()) | 1995 if (!render_view_host->GetProcess()->Init()) |
2003 return false; | 1996 return false; |
2004 | 1997 |
2005 // We may have initialized this RenderViewHost for another RenderFrameHost. | 1998 // We may have initialized this RenderViewHost for another RenderFrameHost. |
2006 if (render_view_host->IsRenderViewLive()) | 1999 if (render_view_host->IsRenderViewLive()) |
2007 return true; | 2000 return true; |
2008 | 2001 |
2009 // If |render_view_host| is not for a proxy and the navigation is to a WebUI, | |
2010 // and if the RenderView is not in a guest process, tell |render_view_host| | |
2011 // about any bindings it will need enabled. | |
2012 // TODO(carlosk): Move WebUI to RenderFrameHost in https://crbug.com/508850. | |
2013 WebUIImpl* dest_web_ui = nullptr; | |
2014 DCHECK_EQ(render_view_host->is_active(), | |
2015 proxy_routing_id == MSG_ROUTING_NONE); | |
2016 if (proxy_routing_id == MSG_ROUTING_NONE) { | |
2017 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
2018 switches::kEnableBrowserSideNavigation)) { | |
2019 dest_web_ui = | |
2020 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get(); | |
2021 } else { | |
2022 dest_web_ui = pending_web_ui(); | |
2023 } | |
2024 } | |
2025 if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) { | |
2026 render_view_host->AllowBindings(dest_web_ui->GetBindings()); | |
2027 } else { | |
2028 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | |
2029 // process unless it's swapped out. | |
2030 if (render_view_host->is_active()) { | |
2031 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | |
2032 render_view_host->GetProcess()->GetID())); | |
2033 } | |
2034 } | |
2035 | |
2036 int opener_frame_routing_id = | 2002 int opener_frame_routing_id = |
2037 GetOpenerRoutingID(render_view_host->GetSiteInstance()); | 2003 GetOpenerRoutingID(render_view_host->GetSiteInstance()); |
2038 | 2004 |
2039 return delegate_->CreateRenderViewForRenderManager( | 2005 return delegate_->CreateRenderViewForRenderManager( |
2040 render_view_host, opener_frame_routing_id, proxy_routing_id, | 2006 render_view_host, opener_frame_routing_id, proxy_routing_id, |
2041 frame_tree_node_->current_replication_state()); | 2007 frame_tree_node_->current_replication_state()); |
2042 } | 2008 } |
2043 | 2009 |
2044 bool RenderFrameHostManager::InitRenderFrame( | 2010 bool RenderFrameHostManager::InitRenderFrame( |
2045 RenderFrameHostImpl* render_frame_host) { | 2011 RenderFrameHostImpl* render_frame_host) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2111 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); | 2077 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); |
2112 if (proxy) | 2078 if (proxy) |
2113 return proxy->GetRoutingID(); | 2079 return proxy->GetRoutingID(); |
2114 | 2080 |
2115 return MSG_ROUTING_NONE; | 2081 return MSG_ROUTING_NONE; |
2116 } | 2082 } |
2117 | 2083 |
2118 void RenderFrameHostManager::CommitPending() { | 2084 void RenderFrameHostManager::CommitPending() { |
2119 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 2085 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
2120 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2086 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
2121 bool browser_side_navigation = | |
2122 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
2123 switches::kEnableBrowserSideNavigation); | |
2124 | |
2125 // First check whether we're going to want to focus the location bar after | 2087 // First check whether we're going to want to focus the location bar after |
2126 // this commit. We do this now because the navigation hasn't formally | 2088 // this commit. We do this now because the navigation hasn't formally |
2127 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 2089 // committed yet, so if we've already cleared the pending WebUI the call chain |
2128 // this triggers won't be able to figure out what's going on. | 2090 // this triggers won't be able to figure out what's going on. |
2129 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 2091 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
2130 | 2092 |
2131 // Next commit the Web UI, if any. Either replace |web_ui_| with | 2093 // If the current RenderFrameHost has a pending WebUI then just commit it and |
2132 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or | 2094 // return (there should be nothing else to commit). |
2133 // leave |web_ui_| as is if reusing it. | 2095 if (render_frame_host_->pending_web_ui()) { |
2134 DCHECK(!(pending_web_ui_ && pending_and_current_web_ui_)); | 2096 DCHECK(!pending_render_frame_host_ && !speculative_render_frame_host_); |
2135 if (pending_web_ui_ || speculative_web_ui_) { | 2097 render_frame_host_->CommitPendingWebUI(); |
Charlie Reis
2015/10/23 06:39:25
As mentioned earlier, it would be great to avoid h
carlosk
2015/10/30 10:35:22
As we discussed offline, this change is not that s
| |
2136 DCHECK(!should_reuse_web_ui_); | |
2137 web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release() | |
2138 : pending_web_ui_.release()); | |
2139 } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) { | |
2140 if (browser_side_navigation) { | |
2141 DCHECK(web_ui_); | |
2142 should_reuse_web_ui_ = false; | |
2143 } else { | |
2144 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | |
2145 pending_and_current_web_ui_.reset(); | |
2146 } | |
2147 } else { | |
2148 web_ui_.reset(); | |
2149 } | |
2150 DCHECK(!speculative_web_ui_); | |
2151 DCHECK(!should_reuse_web_ui_); | |
2152 | |
2153 // It's possible for the pending_render_frame_host_ to be nullptr when we | |
2154 // aren't crossing process boundaries. If so, we just needed to handle the Web | |
2155 // UI committing above and we're done. | |
2156 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { | |
2157 if (will_focus_location_bar) | 2098 if (will_focus_location_bar) |
2158 delegate_->SetFocusToLocationBar(false); | 2099 delegate_->SetFocusToLocationBar(false); |
2159 return; | 2100 return; |
2160 } | 2101 } |
2161 | 2102 |
2162 // Remember if the page was focused so we can focus the new renderer in | 2103 // Remember if the page was focused so we can focus the new renderer in |
2163 // that case. | 2104 // that case. |
2164 bool focus_render_view = !will_focus_location_bar && | 2105 bool focus_render_view = !will_focus_location_bar && |
2165 render_frame_host_->GetView() && | 2106 render_frame_host_->GetView() && |
2166 render_frame_host_->GetView()->HasFocus(); | 2107 render_frame_host_->GetView()->HasFocus(); |
2167 | 2108 |
2168 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 2109 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
2169 | 2110 |
2170 // Swap in the pending or speculative frame and make it active. Also ensure | 2111 // Swap in the pending or speculative frame and make it active. Also ensure |
2171 // the FrameTree stays in sync. | 2112 // the FrameTree stays in sync. |
2172 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; | 2113 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
2173 if (!browser_side_navigation) { | 2114 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
2115 switches::kEnableBrowserSideNavigation)) { | |
2174 DCHECK(!speculative_render_frame_host_); | 2116 DCHECK(!speculative_render_frame_host_); |
2175 old_render_frame_host = | 2117 old_render_frame_host = |
2176 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 2118 SetRenderFrameHost(pending_render_frame_host_.Pass()); |
2177 } else { | 2119 } else { |
2178 // PlzNavigate | 2120 // PlzNavigate |
2179 DCHECK(speculative_render_frame_host_); | 2121 DCHECK(speculative_render_frame_host_); |
2180 old_render_frame_host = | 2122 old_render_frame_host = |
2181 SetRenderFrameHost(speculative_render_frame_host_.Pass()); | 2123 SetRenderFrameHost(speculative_render_frame_host_.Pass()); |
2182 } | 2124 } |
2183 | 2125 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2327 // If we are currently navigating cross-process, we want to get back to normal | 2269 // If we are currently navigating cross-process, we want to get back to normal |
2328 // and then navigate as usual. | 2270 // and then navigate as usual. |
2329 if (pending_render_frame_host_) | 2271 if (pending_render_frame_host_) |
2330 CancelPending(); | 2272 CancelPending(); |
2331 | 2273 |
2332 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 2274 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
2333 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( | 2275 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
2334 dest_url, source_instance, dest_instance, nullptr, transition, | 2276 dest_url, source_instance, dest_instance, nullptr, transition, |
2335 dest_is_restore, dest_is_view_source_mode); | 2277 dest_is_restore, dest_is_view_source_mode); |
2336 | 2278 |
2337 const NavigationEntry* current_entry = | |
2338 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
2339 | |
2340 DCHECK(!pending_render_frame_host_); | 2279 DCHECK(!pending_render_frame_host_); |
2341 | 2280 |
2342 if (new_instance.get() != current_instance) { | 2281 if (new_instance.get() != current_instance) { |
2343 TRACE_EVENT_INSTANT2( | 2282 TRACE_EVENT_INSTANT2( |
2344 "navigation", | 2283 "navigation", |
2345 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 2284 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
2346 TRACE_EVENT_SCOPE_THREAD, | 2285 TRACE_EVENT_SCOPE_THREAD, |
2347 "current_instance id", current_instance->GetId(), | 2286 "current_instance id", current_instance->GetId(), |
2348 "new_instance id", new_instance->GetId()); | 2287 "new_instance id", new_instance->GetId()); |
2349 | 2288 |
2350 // New SiteInstance: create a pending RFH to navigate. | 2289 // New SiteInstance: create a pending RFH to navigate. |
2351 | 2290 |
2352 // This will possibly create (set to nullptr) a Web UI object for the | |
2353 // pending page. We'll use this later to give the page special access. This | |
2354 // must happen before the new renderer is created below so it will get | |
2355 // bindings. It must also happen after the above conditional call to | |
2356 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_ | |
2357 // and the page will not have its bindings set appropriately. | |
2358 SetPendingWebUI(dest_url, bindings); | |
2359 CreatePendingRenderFrameHost(current_instance, new_instance.get()); | 2291 CreatePendingRenderFrameHost(current_instance, new_instance.get()); |
2360 if (!pending_render_frame_host_) | 2292 if (!pending_render_frame_host_) |
2361 return nullptr; | 2293 return nullptr; |
2362 | 2294 |
2295 InitializeWebUI(dest_url, bindings); | |
2296 | |
2363 // Check if our current RFH is live before we set up a transition. | 2297 // Check if our current RFH is live before we set up a transition. |
2364 if (!render_frame_host_->IsRenderFrameLive()) { | 2298 if (!render_frame_host_->IsRenderFrameLive()) { |
2365 // The current RFH is not live. There's no reason to sit around with a | 2299 // The current RFH is not live. There's no reason to sit around with a |
2366 // sad tab or a newly created RFH while we wait for the pending RFH to | 2300 // sad tab or a newly created RFH while we wait for the pending RFH to |
2367 // navigate. Just switch to the pending RFH now and go back to normal. | 2301 // navigate. Just switch to the pending RFH now and go back to normal. |
2368 // (Note that we don't care about on{before}unload handlers if the current | 2302 // (Note that we don't care about on{before}unload handlers if the current |
2369 // RFH isn't live.) | 2303 // RFH isn't live.) |
2370 CommitPending(); | 2304 CommitPending(); |
2371 return render_frame_host_.get(); | 2305 return render_frame_host_.get(); |
2372 } | 2306 } |
2373 // Otherwise, it's safe to treat this as a pending cross-process transition. | 2307 // Otherwise, it's safe to treat this as a pending cross-process transition. |
2374 | 2308 |
2375 // We now have a pending RFH. | 2309 // We now have a pending RFH and possibly an associated pending WebUI. |
2376 DCHECK(pending_render_frame_host_); | 2310 DCHECK(pending_render_frame_host_); |
2311 DCHECK_EQ(pending_web_ui(), pending_render_frame_host_->web_ui()); | |
2312 DCHECK(!pending_render_frame_host_->pending_web_ui()); | |
2313 DCHECK(!render_frame_host_->pending_web_ui()); | |
2377 | 2314 |
2378 // We need to wait until the beforeunload handler has run, unless we are | 2315 // We need to wait until the beforeunload handler has run, unless we are |
2379 // transferring an existing request (in which case it has already run). | 2316 // transferring an existing request (in which case it has already run). |
2380 // Suspend the new render view (i.e., don't let it send the cross-process | 2317 // Suspend the new render view (i.e., don't let it send the cross-process |
2381 // Navigate message) until we hear back from the old renderer's | 2318 // Navigate message) until we hear back from the old renderer's |
2382 // beforeunload handler. If the handler returns false, we'll have to | 2319 // beforeunload handler. If the handler returns false, we'll have to |
2383 // cancel the request. | 2320 // cancel the request. |
2384 // | 2321 // |
2385 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); | 2322 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); |
2386 bool is_transfer = transferred_request_id != GlobalRequestID(); | 2323 bool is_transfer = transferred_request_id != GlobalRequestID(); |
(...skipping 22 matching lines...) Expand all Loading... | |
2409 | 2346 |
2410 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. | 2347 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. |
2411 | 2348 |
2412 // It's possible to swap out the current RFH and then decide to navigate in it | 2349 // It's possible to swap out the current RFH and then decide to navigate in it |
2413 // anyway (e.g., a cross-process navigation that redirects back to the | 2350 // anyway (e.g., a cross-process navigation that redirects back to the |
2414 // original site). In that case, we have a proxy for the current RFH but | 2351 // original site). In that case, we have a proxy for the current RFH but |
2415 // haven't deleted it yet. The new navigation will swap it back in, so we can | 2352 // haven't deleted it yet. The new navigation will swap it back in, so we can |
2416 // delete the proxy. | 2353 // delete the proxy. |
2417 proxy_hosts_->Remove(new_instance.get()->GetId()); | 2354 proxy_hosts_->Remove(new_instance.get()->GetId()); |
2418 | 2355 |
2419 if (ShouldReuseWebUI(current_entry, dest_url)) { | 2356 render_frame_host_->UpdatePendingWebUI(dest_url, bindings); |
2420 pending_web_ui_.reset(); | 2357 DCHECK(pending_web_ui() == render_frame_host_->pending_web_ui()); |
2421 pending_and_current_web_ui_ = web_ui_->AsWeakPtr(); | |
2422 } else { | |
2423 SetPendingWebUI(dest_url, bindings); | |
2424 // Make sure the new RenderViewHost has the right bindings. | |
2425 if (pending_web_ui() && | |
2426 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | |
2427 render_frame_host_->render_view_host()->AllowBindings( | |
2428 pending_web_ui()->GetBindings()); | |
2429 } | |
2430 } | |
2431 | 2358 |
2359 // If a pending WebUI was set on the current RenderFrameHost (be it a new one | |
2360 // or the reused current one) and the associated RenderFrame is alive, notify | |
2361 // the WebUI the RenderView is being reused. | |
2432 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { | 2362 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { |
2433 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), | 2363 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), |
2434 frame_tree_node_->IsMainFrame()); | 2364 frame_tree_node_->IsMainFrame()); |
2435 } | 2365 } |
2436 | 2366 |
2437 // The renderer can exit view source mode when any error or cancellation | 2367 // The renderer can exit view source mode when any error or cancellation |
2438 // happen. We must overwrite to recover the mode. | 2368 // happen. We must overwrite to recover the mode. |
2439 if (dest_is_view_source_mode) { | 2369 if (dest_is_view_source_mode) { |
2440 render_frame_host_->render_view_host()->Send( | 2370 render_frame_host_->render_view_host()->Send( |
2441 new ViewMsg_EnableViewSourceMode( | 2371 new ViewMsg_EnableViewSourceMode( |
2442 render_frame_host_->render_view_host()->GetRoutingID())); | 2372 render_frame_host_->render_view_host()->GetRoutingID())); |
2443 } | 2373 } |
2444 | 2374 |
2445 return render_frame_host_.get(); | 2375 return render_frame_host_.get(); |
2446 } | 2376 } |
2447 | 2377 |
2448 void RenderFrameHostManager::CancelPending() { | 2378 void RenderFrameHostManager::CancelPending() { |
2449 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", | 2379 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", |
2450 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2380 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
2381 render_frame_host_->DiscardPendingWebUI(); | |
2451 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); | 2382 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); |
2452 } | 2383 } |
2453 | 2384 |
2454 scoped_ptr<RenderFrameHostImpl> | 2385 scoped_ptr<RenderFrameHostImpl> |
2455 RenderFrameHostManager::UnsetPendingRenderFrameHost() { | 2386 RenderFrameHostManager::UnsetPendingRenderFrameHost() { |
2456 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = | 2387 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = |
2457 pending_render_frame_host_.Pass(); | 2388 pending_render_frame_host_.Pass(); |
2458 | 2389 |
2459 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( | 2390 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( |
2460 pending_render_frame_host.get(), | 2391 pending_render_frame_host.get(), |
2461 render_frame_host_.get()); | 2392 render_frame_host_.get()); |
2462 | 2393 |
2463 // We no longer need to prevent the process from exiting. | 2394 // We no longer need to prevent the process from exiting. |
2464 pending_render_frame_host->GetProcess()->RemovePendingView(); | 2395 pending_render_frame_host->GetProcess()->RemovePendingView(); |
2465 | 2396 |
2466 pending_web_ui_.reset(); | |
2467 pending_and_current_web_ui_.reset(); | |
2468 | |
2469 return pending_render_frame_host.Pass(); | 2397 return pending_render_frame_host.Pass(); |
2470 } | 2398 } |
2471 | 2399 |
2472 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 2400 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
2473 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 2401 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
2474 // Swap the two. | 2402 // Swap the two. |
2475 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 2403 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
2476 render_frame_host_.Pass(); | 2404 render_frame_host_.Pass(); |
2477 render_frame_host_ = render_frame_host.Pass(); | 2405 render_frame_host_ = render_frame_host.Pass(); |
2478 | 2406 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2633 if (rvh && !rvh->IsRenderViewLive()) { | 2561 if (rvh && !rvh->IsRenderViewLive()) { |
2634 EnsureRenderViewInitialized(rvh, instance); | 2562 EnsureRenderViewInitialized(rvh, instance); |
2635 } else { | 2563 } else { |
2636 // Create a swapped out RenderView in the given SiteInstance if none | 2564 // Create a swapped out RenderView in the given SiteInstance if none |
2637 // exists. Since an opener can point to a subframe, do this on the root | 2565 // exists. Since an opener can point to a subframe, do this on the root |
2638 // frame of the current opener's frame tree. | 2566 // frame of the current opener's frame tree. |
2639 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { | 2567 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { |
2640 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); | 2568 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); |
2641 } else { | 2569 } else { |
2642 frame_tree->root()->render_manager()->CreateRenderFrame( | 2570 frame_tree->root()->render_manager()->CreateRenderFrame( |
2643 instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, | 2571 instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr); |
2644 nullptr); | |
2645 } | 2572 } |
2646 } | 2573 } |
2647 } | 2574 } |
2648 } | 2575 } |
2649 | 2576 |
2650 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { | 2577 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { |
2651 if (!frame_tree_node_->opener()) | 2578 if (!frame_tree_node_->opener()) |
2652 return MSG_ROUTING_NONE; | 2579 return MSG_ROUTING_NONE; |
2653 | 2580 |
2654 return frame_tree_node_->opener() | 2581 return frame_tree_node_->opener() |
2655 ->render_manager() | 2582 ->render_manager() |
2656 ->GetRoutingIdForSiteInstance(instance); | 2583 ->GetRoutingIdForSiteInstance(instance); |
2657 } | 2584 } |
2658 | 2585 |
2659 } // namespace content | 2586 } // namespace content |
OLD | NEW |