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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
238 | 236 |
239 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host_.get()); | 237 ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host_.get()); |
240 | 238 |
241 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts. | 239 // Delete any RenderFrameProxyHosts and swapped out RenderFrameHosts. |
242 // It is important to delete those prior to deleting the current | 240 // It is important to delete those prior to deleting the current |
243 // RenderFrameHost, since the CrossProcessFrameConnector (owned by | 241 // RenderFrameHost, since the CrossProcessFrameConnector (owned by |
244 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with | 242 // RenderFrameProxyHost) points to the RenderWidgetHostView associated with |
245 // the current RenderFrameHost and uses it during its destructor. | 243 // the current RenderFrameHost and uses it during its destructor. |
246 ResetProxyHosts(); | 244 ResetProxyHosts(); |
247 | 245 |
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. | 246 // We should always have a current RenderFrameHost except in some tests. |
253 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); | 247 SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>()); |
254 } | 248 } |
255 | 249 |
256 void RenderFrameHostManager::Init(SiteInstance* site_instance, | 250 void RenderFrameHostManager::Init(SiteInstance* site_instance, |
257 int32 view_routing_id, | 251 int32 view_routing_id, |
258 int32 frame_routing_id, | 252 int32 frame_routing_id, |
259 int32 widget_routing_id) { | 253 int32 widget_routing_id) { |
260 DCHECK(site_instance); | 254 DCHECK(site_instance); |
261 // TODO(avi): While RenderViewHostImpl is-a RenderWidgetHostImpl, this must | 255 // TODO(avi): While RenderViewHostImpl is-a RenderWidgetHostImpl, this must |
(...skipping 20 matching lines...) Expand all Loading... | |
282 return nullptr; | 276 return nullptr; |
283 return render_frame_host_->render_view_host(); | 277 return render_frame_host_->render_view_host(); |
284 } | 278 } |
285 | 279 |
286 RenderViewHostImpl* RenderFrameHostManager::pending_render_view_host() const { | 280 RenderViewHostImpl* RenderFrameHostManager::pending_render_view_host() const { |
287 if (!pending_render_frame_host_) | 281 if (!pending_render_frame_host_) |
288 return nullptr; | 282 return nullptr; |
289 return pending_render_frame_host_->render_view_host(); | 283 return pending_render_frame_host_->render_view_host(); |
290 } | 284 } |
291 | 285 |
286 WebUIImpl* RenderFrameHostManager::pending_web_ui() const { | |
287 if (should_reuse_web_ui_) | |
288 return render_frame_host_->web_ui(); | |
289 | |
290 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
291 switches::kEnableBrowserSideNavigation)) { | |
292 if (speculative_render_frame_host_) | |
293 return speculative_render_frame_host_->web_ui(); | |
294 } else { | |
295 if (pending_render_frame_host_) | |
296 return pending_render_frame_host_->web_ui(); | |
297 } | |
298 return nullptr; | |
299 } | |
300 | |
292 RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const { | 301 RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const { |
293 if (interstitial_page_) | 302 if (interstitial_page_) |
294 return interstitial_page_->GetView(); | 303 return interstitial_page_->GetView(); |
295 if (render_frame_host_) | 304 if (render_frame_host_) |
296 return render_frame_host_->GetView(); | 305 return render_frame_host_->GetView(); |
297 return nullptr; | 306 return nullptr; |
298 } | 307 } |
299 | 308 |
300 bool RenderFrameHostManager::ForInnerDelegate() { | 309 bool RenderFrameHostManager::ForInnerDelegate() { |
301 return delegate_->GetOuterDelegateFrameTreeNodeID() != | 310 return delegate_->GetOuterDelegateFrameTreeNodeID() != |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 | 353 |
345 void RenderFrameHostManager::RemoveOuterDelegateFrame() { | 354 void RenderFrameHostManager::RemoveOuterDelegateFrame() { |
346 FrameTreeNode* outer_delegate_frame_tree_node = | 355 FrameTreeNode* outer_delegate_frame_tree_node = |
347 FrameTreeNode::GloballyFindByID( | 356 FrameTreeNode::GloballyFindByID( |
348 delegate_->GetOuterDelegateFrameTreeNodeID()); | 357 delegate_->GetOuterDelegateFrameTreeNodeID()); |
349 DCHECK(outer_delegate_frame_tree_node->parent()); | 358 DCHECK(outer_delegate_frame_tree_node->parent()); |
350 outer_delegate_frame_tree_node->frame_tree()->RemoveFrame( | 359 outer_delegate_frame_tree_node->frame_tree()->RemoveFrame( |
351 outer_delegate_frame_tree_node); | 360 outer_delegate_frame_tree_node); |
352 } | 361 } |
353 | 362 |
354 void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) { | |
355 pending_web_ui_ = CreateWebUI(url, bindings); | |
356 pending_and_current_web_ui_.reset(); | |
357 } | |
358 | |
359 scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url, | |
360 int bindings) { | |
361 scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url)); | |
362 | |
363 // If we have assigned (zero or more) bindings to this NavigationEntry in the | |
364 // past, make sure we're not granting it different bindings than it had | |
365 // before. If so, note it and don't give it any bindings, to avoid a | |
366 // potential privilege escalation. | |
367 if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings && | |
368 new_web_ui->GetBindings() != bindings) { | |
369 RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM")); | |
370 return nullptr; | |
371 } | |
372 return new_web_ui.Pass(); | |
373 } | |
374 | |
375 RenderFrameHostImpl* RenderFrameHostManager::Navigate( | 363 RenderFrameHostImpl* RenderFrameHostManager::Navigate( |
376 const GURL& dest_url, | 364 const GURL& dest_url, |
377 const FrameNavigationEntry& frame_entry, | 365 const FrameNavigationEntry& frame_entry, |
378 const NavigationEntryImpl& entry) { | 366 const NavigationEntryImpl& entry) { |
379 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", | 367 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", |
380 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 368 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
381 // Create a pending RenderFrameHost to use for the navigation. | 369 // Create a pending RenderFrameHost to use for the navigation. |
382 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( | 370 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( |
383 dest_url, | 371 dest_url, |
384 // TODO(creis): Move source_site_instance to FNE. | 372 // TODO(creis): Move source_site_instance to FNE. |
(...skipping 28 matching lines...) Expand all Loading... | |
413 // site that is handled via Mojo, then Mojo WebUI code in //chrome will | 401 // site that is handled via Mojo, then Mojo WebUI code in //chrome will |
414 // add a service to this RFH's ServiceRegistry). | 402 // add a service to this RFH's ServiceRegistry). |
415 dest_render_frame_host->SetUpMojoIfNeeded(); | 403 dest_render_frame_host->SetUpMojoIfNeeded(); |
416 | 404 |
417 // Recreate the opener chain. | 405 // Recreate the opener chain. |
418 CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(), | 406 CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(), |
419 frame_tree_node_); | 407 frame_tree_node_); |
420 if (!InitRenderView(dest_render_frame_host->render_view_host(), nullptr)) | 408 if (!InitRenderView(dest_render_frame_host->render_view_host(), nullptr)) |
421 return nullptr; | 409 return nullptr; |
422 | 410 |
411 if (pending_web_ui()) { | |
412 pending_web_ui()->RenderViewCreated( | |
413 dest_render_frame_host->render_view_host()); | |
414 } | |
415 | |
423 // Now that we've created a new renderer, be sure to hide it if it isn't | 416 // Now that we've created a new renderer, be sure to hide it if it isn't |
424 // our primary one. Otherwise, we might crash if we try to call Show() | 417 // our primary one. Otherwise, we might crash if we try to call Show() |
425 // on it later. | 418 // on it later. |
426 if (dest_render_frame_host != render_frame_host_) { | 419 if (dest_render_frame_host != render_frame_host_) { |
427 if (dest_render_frame_host->GetView()) | 420 if (dest_render_frame_host->GetView()) |
428 dest_render_frame_host->GetView()->Hide(); | 421 dest_render_frame_host->GetView()->Hide(); |
429 } else { | 422 } else { |
430 // After a renderer crash we'd have marked the host as invisible, so we | 423 // After a renderer crash we'd have marked the host as invisible, so we |
431 // need to set the visibility of the new View to the correct value here | 424 // need to set the visibility of the new View to the correct value here |
432 // after reload. | 425 // after reload. |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
663 | 656 |
664 // Make sure any dynamic changes to this frame's sandbox flags that were made | 657 // Make sure any dynamic changes to this frame's sandbox flags that were made |
665 // prior to navigation take effect. | 658 // prior to navigation take effect. |
666 CommitPendingSandboxFlags(); | 659 CommitPendingSandboxFlags(); |
667 } | 660 } |
668 | 661 |
669 void RenderFrameHostManager::CommitPendingIfNecessary( | 662 void RenderFrameHostManager::CommitPendingIfNecessary( |
670 RenderFrameHostImpl* render_frame_host, | 663 RenderFrameHostImpl* render_frame_host, |
671 bool was_caused_by_user_gesture) { | 664 bool was_caused_by_user_gesture) { |
672 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { | 665 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { |
673 DCHECK(!should_reuse_web_ui_ || web_ui_); | 666 DCHECK(!should_reuse_web_ui_ || render_frame_host_->web_ui()); |
674 | 667 |
675 // We should only hear this from our current renderer. | 668 // We should only hear this from our current renderer. |
676 DCHECK_EQ(render_frame_host_, render_frame_host); | 669 DCHECK_EQ(render_frame_host_, render_frame_host); |
677 | 670 |
678 // Even when there is no pending RVH, there may be a pending Web UI. | 671 // Even when there is no pending RVH, there may be a pending Web UI. |
679 if (pending_web_ui() || speculative_web_ui_) | 672 if (pending_web_ui()) |
680 CommitPending(); | 673 CommitPending(); |
681 return; | 674 return; |
682 } | 675 } |
683 | 676 |
684 if (render_frame_host == pending_render_frame_host_ || | 677 if (render_frame_host == pending_render_frame_host_ || |
685 render_frame_host == speculative_render_frame_host_) { | 678 render_frame_host == speculative_render_frame_host_) { |
686 // The pending cross-process navigation completed, so show the renderer. | 679 // The pending cross-process navigation completed, so show the renderer. |
687 CommitPending(); | 680 CommitPending(); |
688 } else if (render_frame_host == render_frame_host_) { | 681 } else if (render_frame_host == render_frame_host_) { |
689 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 682 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1012 // Subframe navigations will use the current renderer, unless | 1005 // Subframe navigations will use the current renderer, unless |
1013 // --site-per-process is enabled. | 1006 // --site-per-process is enabled. |
1014 // TODO(carlosk): Have renderer-initated main frame navigations swap processes | 1007 // TODO(carlosk): Have renderer-initated main frame navigations swap processes |
1015 // if needed when it no longer breaks OAuth popups (see | 1008 // if needed when it no longer breaks OAuth popups (see |
1016 // https://crbug.com/440266). | 1009 // https://crbug.com/440266). |
1017 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 1010 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
1018 if (current_site_instance == dest_site_instance.get() || | 1011 if (current_site_instance == dest_site_instance.get() || |
1019 (!request.browser_initiated() && is_main_frame) || | 1012 (!request.browser_initiated() && is_main_frame) || |
1020 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() && | 1013 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() && |
1021 !current_site_instance->RequiresDedicatedProcess())) { | 1014 !current_site_instance->RequiresDedicatedProcess())) { |
1022 // Reuse the current RFH if its SiteInstance matches the the navigation's | 1015 // Reuse the current RenderFrameHost if its SiteInstance matches the the |
1023 // or if this is a subframe navigation. We only swap RFHs for subframes when | 1016 // navigation's or if this is a subframe navigation. We only swap RFHs for |
1024 // --site-per-process is enabled. | 1017 // subframes when --site-per-process is enabled. |
1025 CleanUpNavigation(); | 1018 CleanUpNavigation(); |
1026 navigation_rfh = render_frame_host_.get(); | 1019 navigation_rfh = render_frame_host_.get(); |
1027 | 1020 |
1028 // As SiteInstances are the same, check if the WebUI should be reused. | 1021 WebUI::TypeID previous_web_ui_type = render_frame_host_->web_ui_type(); |
1029 const NavigationEntry* current_navigation_entry = | 1022 bool changed_web_ui = render_frame_host_->UpdateWebUI( |
1030 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1023 request.common_params().url, request.bindings()); |
1031 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, | 1024 |
1032 request.common_params().url); | 1025 // If a change in WebUI happened, check this is an acceptable case. |
1033 if (!should_reuse_web_ui_) { | 1026 DCHECK(!changed_web_ui || (IsAcceptableWebUITransition( |
1034 speculative_web_ui_ = CreateWebUI(request.common_params().url, | 1027 previous_web_ui_type, request.common_params().url, |
1035 request.bindings()); | 1028 request.restore_type() != NavigationEntryImpl::RESTORE_NONE))); |
1036 // Make sure the current RenderViewHost has the right bindings. | 1029 |
1037 if (speculative_web_ui() && | 1030 // If there is a WebUI in the current RenderFrameHost, it will be reused. |
1038 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | 1031 should_reuse_web_ui_ = render_frame_host_->web_ui(); |
nasko
2015/10/29 22:13:15
Wouldn't UpdateWebUI above create one if needed? S
carlosk
2015/10/30 10:35:23
Conceptually this is incorrect as you described bu
| |
1039 render_frame_host_->render_view_host()->AllowBindings( | 1032 DCHECK_EQ(pending_web_ui(), render_frame_host_->web_ui()); |
1040 speculative_web_ui()->GetBindings()); | 1033 |
1041 } | 1034 // If the current RenderFrameHost has a WebUI and the associated RenderFrame |
1035 // is alive, notify to the WebUI that the RenderView is being reused. | |
1036 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { | |
1037 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), | |
1038 frame_tree_node_->IsMainFrame()); | |
1042 } | 1039 } |
1040 | |
1041 DCHECK(!speculative_render_frame_host_); | |
1043 } else { | 1042 } else { |
1044 // If the SiteInstance for the final URL doesn't match the one from the | 1043 // If the SiteInstance for the final URL doesn't match the one from the |
1045 // speculatively created RenderFrameHost, create a new RenderFrameHost using | 1044 // speculatively created RenderFrameHost, create a new RenderFrameHost using |
1046 // this new SiteInstance. | 1045 // this new SiteInstance. |
1047 if (!speculative_render_frame_host_ || | 1046 if (!speculative_render_frame_host_ || |
1048 speculative_render_frame_host_->GetSiteInstance() != | 1047 speculative_render_frame_host_->GetSiteInstance() != |
1049 dest_site_instance.get()) { | 1048 dest_site_instance.get()) { |
1049 // Creates a new speculative RenderFrameHost if the previous one didn't | |
1050 // exist or if its SiteInstace differs from the current one. | |
1050 CleanUpNavigation(); | 1051 CleanUpNavigation(); |
1051 bool success = CreateSpeculativeRenderFrameHost( | 1052 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, |
1052 request.common_params().url, current_site_instance, | 1053 dest_site_instance.get()); |
1053 dest_site_instance.get(), request.bindings()); | |
1054 DCHECK(success); | 1054 DCHECK(success); |
1055 | |
1056 speculative_render_frame_host_->UpdateWebUI(request.common_params().url, | |
1057 request.bindings()); | |
1058 if (speculative_render_frame_host_->web_ui()) { | |
1059 speculative_render_frame_host_->web_ui()->RenderViewCreated( | |
1060 speculative_render_frame_host_->render_view_host()); | |
1061 } | |
1062 } else { | |
1063 // Reuses the previous speculative RenderFrameHost. | |
1064 bool changed_web_ui = speculative_render_frame_host_->UpdateWebUI( | |
1065 request.common_params().url, request.bindings()); | |
1066 if (changed_web_ui && speculative_render_frame_host_->web_ui()) { | |
1067 speculative_render_frame_host_->web_ui()->RenderViewCreated( | |
1068 speculative_render_frame_host_->render_view_host()); | |
1069 } | |
1055 } | 1070 } |
1056 DCHECK(speculative_render_frame_host_); | 1071 DCHECK(speculative_render_frame_host_); |
1072 DCHECK_EQ(pending_web_ui(), speculative_render_frame_host_->web_ui()); | |
1073 | |
1057 navigation_rfh = speculative_render_frame_host_.get(); | 1074 navigation_rfh = speculative_render_frame_host_.get(); |
1058 | 1075 |
1059 // Check if our current RFH is live. | 1076 // Check if our current RFH is live. |
1060 if (!render_frame_host_->IsRenderFrameLive()) { | 1077 if (!render_frame_host_->IsRenderFrameLive()) { |
1061 // The current RFH is not live. There's no reason to sit around with a | 1078 // The current RFH is not live. There's no reason to sit around with a |
1062 // sad tab or a newly created RFH while we wait for the navigation to | 1079 // sad tab or a newly created RFH while we wait for the navigation to |
1063 // complete. Just switch to the speculative RFH now and go back to normal. | 1080 // complete. Just switch to the speculative RFH now and go back to normal. |
1064 // (Note that we don't care about on{before}unload handlers if the current | 1081 // (Note that we don't care about on{before}unload handlers if the current |
1065 // RFH isn't live.) | 1082 // RFH isn't live.) |
1066 CommitPending(); | 1083 CommitPending(); |
1067 } | 1084 } |
1085 DCHECK(!should_reuse_web_ui_); | |
1068 } | 1086 } |
1069 DCHECK(navigation_rfh && | 1087 DCHECK(navigation_rfh && |
1070 (navigation_rfh == render_frame_host_.get() || | 1088 (navigation_rfh == render_frame_host_.get() || |
1071 navigation_rfh == speculative_render_frame_host_.get())); | 1089 navigation_rfh == speculative_render_frame_host_.get())); |
1072 | 1090 |
1073 // If the RenderFrame that needs to navigate is not live (its process was just | 1091 // If the RenderFrame that needs to navigate is not live (its process was just |
1074 // created or has crashed), initialize it. | 1092 // created or has crashed), initialize it. |
1075 if (!navigation_rfh->IsRenderFrameLive()) { | 1093 if (!navigation_rfh->IsRenderFrameLive()) { |
1076 // Recreate the opener chain. | 1094 // Recreate the opener chain. |
1077 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); | 1095 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); |
1078 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) { | 1096 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) |
1079 return nullptr; | 1097 return nullptr; |
1098 | |
1099 if (pending_web_ui()) { | |
1100 pending_web_ui()->RenderViewCreated(navigation_rfh->render_view_host()); | |
1080 } | 1101 } |
1081 | 1102 |
1082 if (navigation_rfh == render_frame_host_) { | 1103 if (navigation_rfh == render_frame_host_) { |
1083 // TODO(nasko): This is a very ugly hack. The Chrome extensions process | 1104 // TODO(nasko): This is a very ugly hack. The Chrome extensions process |
1084 // manager still uses NotificationService and expects to see a | 1105 // manager still uses NotificationService and expects to see a |
1085 // RenderViewHost changed notification after WebContents and | 1106 // RenderViewHost changed notification after WebContents and |
1086 // RenderFrameHostManager are completely initialized. This should be | 1107 // RenderFrameHostManager are completely initialized. This should be |
1087 // removed once the process manager moves away from NotificationService. | 1108 // removed once the process manager moves away from NotificationService. |
1088 // See https://crbug.com/462682. | 1109 // See https://crbug.com/462682. |
1089 delegate_->NotifyMainFrameSwappedFromRenderManager( | 1110 delegate_->NotifyMainFrameSwappedFromRenderManager( |
1090 nullptr, render_frame_host_->render_view_host()); | 1111 nullptr, render_frame_host_->render_view_host()); |
1091 } | 1112 } |
1092 } | 1113 } |
1093 | 1114 |
1094 return navigation_rfh; | 1115 return navigation_rfh; |
1095 } | 1116 } |
1096 | 1117 |
1097 // PlzNavigate | 1118 // PlzNavigate |
1098 void RenderFrameHostManager::CleanUpNavigation() { | 1119 void RenderFrameHostManager::CleanUpNavigation() { |
1099 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1120 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
1100 switches::kEnableBrowserSideNavigation)); | 1121 switches::kEnableBrowserSideNavigation)); |
1101 speculative_web_ui_.reset(); | 1122 // TODO(carlosk): the discarding of the current RFH WebUI and the cleanup of |
1123 // the speculative RFH should not always happen together. | |
1102 should_reuse_web_ui_ = false; | 1124 should_reuse_web_ui_ = false; |
1103 if (speculative_render_frame_host_) | 1125 if (speculative_render_frame_host_) |
1104 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 1126 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
1105 } | 1127 } |
1106 | 1128 |
1107 // PlzNavigate | 1129 // PlzNavigate |
1108 scoped_ptr<RenderFrameHostImpl> | 1130 scoped_ptr<RenderFrameHostImpl> |
1109 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { | 1131 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { |
1110 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1132 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
1111 switches::kEnableBrowserSideNavigation)); | 1133 switches::kEnableBrowserSideNavigation)); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1285 // We can't switch a RenderView between view source and non-view source mode | 1307 // We can't switch a RenderView between view source and non-view source mode |
1286 // without screwing up the session history sometimes (when navigating between | 1308 // without screwing up the session history sometimes (when navigating between |
1287 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat | 1309 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat |
1288 // it as a new navigation). So require a BrowsingInstance switch. | 1310 // it as a new navigation). So require a BrowsingInstance switch. |
1289 if (current_is_view_source_mode != new_is_view_source_mode) | 1311 if (current_is_view_source_mode != new_is_view_source_mode) |
1290 return true; | 1312 return true; |
1291 | 1313 |
1292 return false; | 1314 return false; |
1293 } | 1315 } |
1294 | 1316 |
1295 bool RenderFrameHostManager::ShouldReuseWebUI( | |
1296 const NavigationEntry* current_entry, | |
1297 const GURL& new_url) const { | |
1298 NavigationControllerImpl& controller = | |
1299 delegate_->GetControllerForRenderManager(); | |
1300 return current_entry && web_ui_ && | |
1301 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
1302 controller.GetBrowserContext(), current_entry->GetURL()) == | |
1303 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
1304 controller.GetBrowserContext(), new_url)); | |
1305 } | |
1306 | |
1307 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( | 1317 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( |
1308 const GURL& dest_url, | 1318 const GURL& dest_url, |
1309 SiteInstance* source_instance, | 1319 SiteInstance* source_instance, |
1310 SiteInstance* dest_instance, | 1320 SiteInstance* dest_instance, |
1311 SiteInstance* candidate_instance, | 1321 SiteInstance* candidate_instance, |
1312 ui::PageTransition transition, | 1322 ui::PageTransition transition, |
1313 bool dest_is_restore, | 1323 bool dest_is_restore, |
1314 bool dest_is_view_source_mode) { | 1324 bool dest_is_view_source_mode) { |
1315 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1325 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
1316 | 1326 |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1629 // The process for the new SiteInstance may (if we're sharing a process with | 1639 // The process for the new SiteInstance may (if we're sharing a process with |
1630 // another host that already initialized it) or may not (we have our own | 1640 // another host that already initialized it) or may not (we have our own |
1631 // process or the existing process crashed) have been initialized. Calling | 1641 // process or the existing process crashed) have been initialized. Calling |
1632 // Init multiple times will be ignored, so this is safe. | 1642 // Init multiple times will be ignored, so this is safe. |
1633 if (!new_instance->GetProcess()->Init()) | 1643 if (!new_instance->GetProcess()->Init()) |
1634 return; | 1644 return; |
1635 | 1645 |
1636 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1646 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
1637 | 1647 |
1638 // Create a non-swapped-out RFH with the given opener. | 1648 // Create a non-swapped-out RFH with the given opener. |
1639 pending_render_frame_host_ = CreateRenderFrame( | 1649 pending_render_frame_host_ = |
1640 new_instance, pending_web_ui(), create_render_frame_flags, nullptr); | 1650 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
1641 } | 1651 } |
1642 | 1652 |
1643 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( | 1653 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( |
1644 SiteInstance* old_instance, | 1654 SiteInstance* old_instance, |
1645 SiteInstance* new_instance) { | 1655 SiteInstance* new_instance) { |
1646 // Only create opener proxies if they are in the same BrowsingInstance. | 1656 // Only create opener proxies if they are in the same BrowsingInstance. |
1647 if (new_instance->IsRelatedSiteInstance(old_instance)) { | 1657 if (new_instance->IsRelatedSiteInstance(old_instance)) { |
1648 CreateOpenerProxies(new_instance, frame_tree_node_); | 1658 CreateOpenerProxies(new_instance, frame_tree_node_); |
1649 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { | 1659 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { |
1650 // Ensure that the frame tree has RenderFrameProxyHosts for the | 1660 // Ensure that the frame tree has RenderFrameProxyHosts for the |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1726 } | 1736 } |
1727 | 1737 |
1728 return RenderFrameHostFactory::Create( | 1738 return RenderFrameHostFactory::Create( |
1729 site_instance, render_view_host, render_frame_delegate_, | 1739 site_instance, render_view_host, render_frame_delegate_, |
1730 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, | 1740 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, |
1731 widget_routing_id, flags); | 1741 widget_routing_id, flags); |
1732 } | 1742 } |
1733 | 1743 |
1734 // PlzNavigate | 1744 // PlzNavigate |
1735 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( | 1745 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( |
1736 const GURL& url, | |
1737 SiteInstance* old_instance, | 1746 SiteInstance* old_instance, |
1738 SiteInstance* new_instance, | 1747 SiteInstance* new_instance) { |
1739 int bindings) { | |
1740 CHECK(new_instance); | 1748 CHECK(new_instance); |
1741 CHECK_NE(old_instance, new_instance); | 1749 CHECK_NE(old_instance, new_instance); |
1742 CHECK(!should_reuse_web_ui_); | 1750 CHECK(!should_reuse_web_ui_); |
1743 | 1751 |
1744 // Note: |speculative_web_ui_| must be initialized before starting the | |
1745 // |speculative_render_frame_host_| creation steps otherwise the WebUI | |
1746 // won't be properly initialized. | |
1747 speculative_web_ui_ = CreateWebUI(url, bindings); | |
1748 | |
1749 // The process for the new SiteInstance may (if we're sharing a process with | 1752 // The process for the new SiteInstance may (if we're sharing a process with |
1750 // another host that already initialized it) or may not (we have our own | 1753 // another host that already initialized it) or may not (we have our own |
1751 // process or the existing process crashed) have been initialized. Calling | 1754 // process or the existing process crashed) have been initialized. Calling |
1752 // Init multiple times will be ignored, so this is safe. | 1755 // Init multiple times will be ignored, so this is safe. |
1753 if (!new_instance->GetProcess()->Init()) | 1756 if (!new_instance->GetProcess()->Init()) |
1754 return false; | 1757 return false; |
1755 | 1758 |
1756 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1759 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
1757 | 1760 |
1758 int create_render_frame_flags = 0; | 1761 int create_render_frame_flags = 0; |
1759 if (delegate_->IsHidden()) | 1762 if (delegate_->IsHidden()) |
1760 create_render_frame_flags |= CREATE_RF_HIDDEN; | 1763 create_render_frame_flags |= CREATE_RF_HIDDEN; |
1761 speculative_render_frame_host_ = | 1764 speculative_render_frame_host_ = |
1762 CreateRenderFrame(new_instance, speculative_web_ui_.get(), | 1765 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
1763 create_render_frame_flags, nullptr); | |
1764 | 1766 |
1765 if (!speculative_render_frame_host_) { | 1767 return !!speculative_render_frame_host_; |
1766 speculative_web_ui_.reset(); | |
1767 return false; | |
1768 } | |
1769 return true; | |
1770 } | 1768 } |
1771 | 1769 |
1772 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( | 1770 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( |
1773 SiteInstance* instance, | 1771 SiteInstance* instance, |
1774 WebUIImpl* web_ui, | |
1775 int flags, | 1772 int flags, |
1776 int* view_routing_id_ptr) { | 1773 int* view_routing_id_ptr) { |
1777 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1774 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
1778 bool swapped_out_forbidden = | 1775 bool swapped_out_forbidden = |
1779 SiteIsolationPolicy::IsSwappedOutStateForbidden(); | 1776 SiteIsolationPolicy::IsSwappedOutStateForbidden(); |
1780 | 1777 |
1781 CHECK(instance); | 1778 CHECK(instance); |
1782 CHECK(!swapped_out_forbidden || !swapped_out); | 1779 CHECK(!swapped_out_forbidden || !swapped_out); |
1783 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible() || | 1780 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible() || |
1784 frame_tree_node_->IsMainFrame()); | 1781 frame_tree_node_->IsMainFrame()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1882 success = InitRenderFrame(new_render_frame_host.get()); | 1879 success = InitRenderFrame(new_render_frame_host.get()); |
1883 } | 1880 } |
1884 } | 1881 } |
1885 | 1882 |
1886 if (success) { | 1883 if (success) { |
1887 if (view_routing_id_ptr) | 1884 if (view_routing_id_ptr) |
1888 *view_routing_id_ptr = render_view_host->GetRoutingID(); | 1885 *view_routing_id_ptr = render_view_host->GetRoutingID(); |
1889 } | 1886 } |
1890 } | 1887 } |
1891 | 1888 |
1892 // When a new RenderView is created by the renderer process, the new | |
1893 // WebContents gets a RenderViewHost in the SiteInstance of its opener | |
1894 // WebContents. If not used in the first navigation, this RVH is swapped out | |
1895 // and is not granted bindings, so we may need to grant them when swapping it | |
1896 // in. | |
1897 if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) { | |
1898 int required_bindings = web_ui->GetBindings(); | |
1899 RenderViewHost* render_view_host = | |
1900 new_render_frame_host->render_view_host(); | |
1901 if ((render_view_host->GetEnabledBindings() & required_bindings) != | |
1902 required_bindings) { | |
1903 render_view_host->AllowBindings(required_bindings); | |
1904 } | |
1905 } | |
1906 | |
1907 // Returns the new RFH if it isn't swapped out. | 1889 // Returns the new RFH if it isn't swapped out. |
1908 if (success && !swapped_out) { | 1890 if (success && !swapped_out) { |
1909 DCHECK(new_render_frame_host->GetSiteInstance() == instance); | 1891 DCHECK(new_render_frame_host->GetSiteInstance() == instance); |
1910 return new_render_frame_host.Pass(); | 1892 return new_render_frame_host.Pass(); |
1911 } | 1893 } |
1912 return nullptr; | 1894 return nullptr; |
1913 } | 1895 } |
1914 | 1896 |
1915 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { | 1897 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { |
1916 // A RenderFrameProxyHost should never be created in the same SiteInstance as | 1898 // A RenderFrameProxyHost should never be created in the same SiteInstance as |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2015 RenderFrameProxyHost* proxy) { | 1997 RenderFrameProxyHost* proxy) { |
2016 // Ensure the renderer process is initialized before creating the | 1998 // Ensure the renderer process is initialized before creating the |
2017 // RenderView. | 1999 // RenderView. |
2018 if (!render_view_host->GetProcess()->Init()) | 2000 if (!render_view_host->GetProcess()->Init()) |
2019 return false; | 2001 return false; |
2020 | 2002 |
2021 // We may have initialized this RenderViewHost for another RenderFrameHost. | 2003 // We may have initialized this RenderViewHost for another RenderFrameHost. |
2022 if (render_view_host->IsRenderViewLive()) | 2004 if (render_view_host->IsRenderViewLive()) |
2023 return true; | 2005 return true; |
2024 | 2006 |
2025 // If |render_view_host| is not for a proxy and the navigation is to a WebUI, | |
2026 // and if the RenderView is not in a guest process, tell |render_view_host| | |
2027 // about any bindings it will need enabled. | |
2028 // TODO(carlosk): Move WebUI to RenderFrameHost in https://crbug.com/508850. | |
2029 WebUIImpl* dest_web_ui = nullptr; | |
2030 if (!proxy) { | |
2031 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
2032 switches::kEnableBrowserSideNavigation)) { | |
2033 dest_web_ui = | |
2034 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get(); | |
2035 } else { | |
2036 dest_web_ui = pending_web_ui(); | |
2037 } | |
2038 } | |
2039 if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) { | |
2040 render_view_host->AllowBindings(dest_web_ui->GetBindings()); | |
2041 } else { | |
2042 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | |
2043 // process unless it's swapped out. | |
2044 if (render_view_host->is_active()) { | |
2045 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | |
2046 render_view_host->GetProcess()->GetID())); | |
2047 } | |
2048 } | |
2049 | |
2050 int opener_frame_routing_id = | 2007 int opener_frame_routing_id = |
2051 GetOpenerRoutingID(render_view_host->GetSiteInstance()); | 2008 GetOpenerRoutingID(render_view_host->GetSiteInstance()); |
2052 | 2009 |
2053 bool created = delegate_->CreateRenderViewForRenderManager( | 2010 bool created = delegate_->CreateRenderViewForRenderManager( |
2054 render_view_host, opener_frame_routing_id, | 2011 render_view_host, opener_frame_routing_id, |
2055 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE, | 2012 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE, |
2056 frame_tree_node_->current_replication_state()); | 2013 frame_tree_node_->current_replication_state()); |
2057 | 2014 |
2058 if (created && proxy) | 2015 if (created && proxy) |
2059 proxy->set_render_frame_proxy_created(true); | 2016 proxy->set_render_frame_proxy_created(true); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2131 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); | 2088 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); |
2132 if (proxy) | 2089 if (proxy) |
2133 return proxy->GetRoutingID(); | 2090 return proxy->GetRoutingID(); |
2134 | 2091 |
2135 return MSG_ROUTING_NONE; | 2092 return MSG_ROUTING_NONE; |
2136 } | 2093 } |
2137 | 2094 |
2138 void RenderFrameHostManager::CommitPending() { | 2095 void RenderFrameHostManager::CommitPending() { |
2139 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 2096 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
2140 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2097 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
2141 bool browser_side_navigation = | |
2142 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
2143 switches::kEnableBrowserSideNavigation); | |
2144 | |
2145 // First check whether we're going to want to focus the location bar after | 2098 // First check whether we're going to want to focus the location bar after |
2146 // this commit. We do this now because the navigation hasn't formally | 2099 // this commit. We do this now because the navigation hasn't formally |
2147 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 2100 // committed yet, so if we've already cleared the pending WebUI the call chain |
2148 // this triggers won't be able to figure out what's going on. | 2101 // this triggers won't be able to figure out what's going on. |
2149 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 2102 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
2150 | 2103 |
2151 // Next commit the Web UI, if any. Either replace |web_ui_| with | |
2152 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or | |
2153 // leave |web_ui_| as is if reusing it. | |
2154 DCHECK(!(pending_web_ui_ && pending_and_current_web_ui_)); | |
2155 if (pending_web_ui_ || speculative_web_ui_) { | |
2156 DCHECK(!should_reuse_web_ui_); | |
2157 web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release() | |
2158 : pending_web_ui_.release()); | |
2159 } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) { | |
2160 if (browser_side_navigation) { | |
2161 DCHECK(web_ui_); | |
2162 should_reuse_web_ui_ = false; | |
2163 } else { | |
2164 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | |
2165 pending_and_current_web_ui_.reset(); | |
2166 } | |
2167 } else { | |
2168 web_ui_.reset(); | |
2169 } | |
2170 DCHECK(!speculative_web_ui_); | |
2171 DCHECK(!should_reuse_web_ui_); | |
2172 | |
2173 // It's possible for the pending_render_frame_host_ to be nullptr when we | |
2174 // aren't crossing process boundaries. If so, we just needed to handle the Web | |
2175 // UI committing above and we're done. | |
2176 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { | 2104 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { |
2105 DCHECK_EQ(should_reuse_web_ui_, !!render_frame_host_->web_ui()); | |
2106 should_reuse_web_ui_ = false; | |
2107 // If there's no pending/speculative RenderFrameHost then the current | |
2108 // RenderFrameHost is committing. | |
2177 if (will_focus_location_bar) | 2109 if (will_focus_location_bar) |
2178 delegate_->SetFocusToLocationBar(false); | 2110 delegate_->SetFocusToLocationBar(false); |
2179 return; | 2111 return; |
2180 } | 2112 } |
2181 | 2113 |
2182 // Remember if the page was focused so we can focus the new renderer in | 2114 // Remember if the page was focused so we can focus the new renderer in |
2183 // that case. | 2115 // that case. |
2184 bool focus_render_view = !will_focus_location_bar && | 2116 bool focus_render_view = !will_focus_location_bar && |
2185 render_frame_host_->GetView() && | 2117 render_frame_host_->GetView() && |
2186 render_frame_host_->GetView()->HasFocus(); | 2118 render_frame_host_->GetView()->HasFocus(); |
2187 | 2119 |
2188 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 2120 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
2189 | 2121 |
2190 // Swap in the pending or speculative frame and make it active. Also ensure | 2122 // Swap in the pending or speculative frame and make it active. Also ensure |
2191 // the FrameTree stays in sync. | 2123 // the FrameTree stays in sync. |
2192 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; | 2124 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
2193 if (!browser_side_navigation) { | 2125 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
2126 switches::kEnableBrowserSideNavigation)) { | |
2194 DCHECK(!speculative_render_frame_host_); | 2127 DCHECK(!speculative_render_frame_host_); |
2195 old_render_frame_host = | 2128 old_render_frame_host = |
2196 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 2129 SetRenderFrameHost(pending_render_frame_host_.Pass()); |
2197 } else { | 2130 } else { |
2198 // PlzNavigate | 2131 // PlzNavigate |
2199 DCHECK(speculative_render_frame_host_); | 2132 DCHECK(speculative_render_frame_host_); |
2200 old_render_frame_host = | 2133 old_render_frame_host = |
2201 SetRenderFrameHost(speculative_render_frame_host_.Pass()); | 2134 SetRenderFrameHost(speculative_render_frame_host_.Pass()); |
2202 } | 2135 } |
2203 | 2136 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2346 // If we are currently navigating cross-process, we want to get back to normal | 2279 // If we are currently navigating cross-process, we want to get back to normal |
2347 // and then navigate as usual. | 2280 // and then navigate as usual. |
2348 if (pending_render_frame_host_) | 2281 if (pending_render_frame_host_) |
2349 CancelPending(); | 2282 CancelPending(); |
2350 | 2283 |
2351 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 2284 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
2352 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( | 2285 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
2353 dest_url, source_instance, dest_instance, nullptr, transition, | 2286 dest_url, source_instance, dest_instance, nullptr, transition, |
2354 dest_is_restore, dest_is_view_source_mode); | 2287 dest_is_restore, dest_is_view_source_mode); |
2355 | 2288 |
2356 const NavigationEntry* current_entry = | |
2357 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
2358 | |
2359 DCHECK(!pending_render_frame_host_); | 2289 DCHECK(!pending_render_frame_host_); |
2360 | 2290 |
2361 if (new_instance.get() != current_instance) { | 2291 if (new_instance.get() != current_instance) { |
2362 TRACE_EVENT_INSTANT2( | 2292 TRACE_EVENT_INSTANT2( |
2363 "navigation", | 2293 "navigation", |
2364 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 2294 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
2365 TRACE_EVENT_SCOPE_THREAD, | 2295 TRACE_EVENT_SCOPE_THREAD, |
2366 "current_instance id", current_instance->GetId(), | 2296 "current_instance id", current_instance->GetId(), |
2367 "new_instance id", new_instance->GetId()); | 2297 "new_instance id", new_instance->GetId()); |
2368 | 2298 |
2369 // New SiteInstance: create a pending RFH to navigate. | 2299 // New SiteInstance: create a pending RFH to navigate. |
2370 | 2300 |
2371 // This will possibly create (set to nullptr) a Web UI object for the | 2301 should_reuse_web_ui_ = false; |
2372 // pending page. We'll use this later to give the page special access. This | |
2373 // must happen before the new renderer is created below so it will get | |
2374 // bindings. It must also happen after the above conditional call to | |
2375 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_ | |
2376 // and the page will not have its bindings set appropriately. | |
2377 SetPendingWebUI(dest_url, bindings); | |
2378 CreatePendingRenderFrameHost(current_instance, new_instance.get()); | 2302 CreatePendingRenderFrameHost(current_instance, new_instance.get()); |
2379 if (!pending_render_frame_host_) | 2303 if (!pending_render_frame_host_) |
2380 return nullptr; | 2304 return nullptr; |
2381 | 2305 |
2306 pending_render_frame_host_->UpdateWebUI(dest_url, bindings); | |
2307 if (pending_render_frame_host_->web_ui()) { | |
2308 pending_render_frame_host_->web_ui()->RenderViewCreated( | |
nasko
2015/10/29 22:13:15
I know the naming will be weird, but can't we fold
carlosk
2015/10/30 10:35:23
That's what I tried before and I had to move them
| |
2309 pending_render_frame_host_->render_view_host()); | |
2310 } | |
2311 | |
2312 // We now have a pending RFH and possibly an associated pending WebUI. | |
2313 DCHECK(pending_render_frame_host_); | |
2314 DCHECK_EQ(pending_web_ui(), pending_render_frame_host_->web_ui()); | |
2315 | |
2382 // Check if our current RFH is live before we set up a transition. | 2316 // Check if our current RFH is live before we set up a transition. |
2383 if (!render_frame_host_->IsRenderFrameLive()) { | 2317 if (!render_frame_host_->IsRenderFrameLive()) { |
2384 // The current RFH is not live. There's no reason to sit around with a | 2318 // The current RFH is not live. There's no reason to sit around with a |
2385 // sad tab or a newly created RFH while we wait for the pending RFH to | 2319 // sad tab or a newly created RFH while we wait for the pending RFH to |
2386 // navigate. Just switch to the pending RFH now and go back to normal. | 2320 // navigate. Just switch to the pending RFH now and go back to normal. |
2387 // (Note that we don't care about on{before}unload handlers if the current | 2321 // (Note that we don't care about on{before}unload handlers if the current |
2388 // RFH isn't live.) | 2322 // RFH isn't live.) |
2389 CommitPending(); | 2323 CommitPending(); |
2390 return render_frame_host_.get(); | 2324 return render_frame_host_.get(); |
2391 } | 2325 } |
2392 // Otherwise, it's safe to treat this as a pending cross-process transition. | 2326 // Otherwise, it's safe to treat this as a pending cross-process transition. |
2393 | 2327 |
2394 // We now have a pending RFH. | |
2395 DCHECK(pending_render_frame_host_); | |
2396 | |
2397 // We need to wait until the beforeunload handler has run, unless we are | 2328 // We need to wait until the beforeunload handler has run, unless we are |
2398 // transferring an existing request (in which case it has already run). | 2329 // transferring an existing request (in which case it has already run). |
2399 // Suspend the new render view (i.e., don't let it send the cross-process | 2330 // Suspend the new render view (i.e., don't let it send the cross-process |
2400 // Navigate message) until we hear back from the old renderer's | 2331 // Navigate message) until we hear back from the old renderer's |
2401 // beforeunload handler. If the handler returns false, we'll have to | 2332 // beforeunload handler. If the handler returns false, we'll have to |
2402 // cancel the request. | 2333 // cancel the request. |
2403 // | |
2404 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); | 2334 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); |
2405 bool is_transfer = transferred_request_id != GlobalRequestID(); | 2335 bool is_transfer = transferred_request_id != GlobalRequestID(); |
2406 if (is_transfer) { | 2336 if (is_transfer) { |
2407 // We don't need to stop the old renderer or run beforeunload/unload | 2337 // We don't need to stop the old renderer or run beforeunload/unload |
2408 // handlers, because those have already been done. | 2338 // handlers, because those have already been done. |
2409 DCHECK(cross_site_transferring_request_->request_id() == | 2339 DCHECK(cross_site_transferring_request_->request_id() == |
2410 transferred_request_id); | 2340 transferred_request_id); |
2411 } else { | 2341 } else { |
2412 // Also make sure the old render view stops, in case a load is in | 2342 // Also make sure the old render view stops, in case a load is in |
2413 // progress. (We don't want to do this for transfers, since it will | 2343 // progress. (We don't want to do this for transfers, since it will |
(...skipping 14 matching lines...) Expand all Loading... | |
2428 | 2358 |
2429 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. | 2359 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. |
2430 | 2360 |
2431 // It's possible to swap out the current RFH and then decide to navigate in it | 2361 // It's possible to swap out the current RFH and then decide to navigate in it |
2432 // anyway (e.g., a cross-process navigation that redirects back to the | 2362 // anyway (e.g., a cross-process navigation that redirects back to the |
2433 // original site). In that case, we have a proxy for the current RFH but | 2363 // original site). In that case, we have a proxy for the current RFH but |
2434 // haven't deleted it yet. The new navigation will swap it back in, so we can | 2364 // haven't deleted it yet. The new navigation will swap it back in, so we can |
2435 // delete the proxy. | 2365 // delete the proxy. |
2436 proxy_hosts_->Remove(new_instance.get()->GetId()); | 2366 proxy_hosts_->Remove(new_instance.get()->GetId()); |
2437 | 2367 |
2438 if (ShouldReuseWebUI(current_entry, dest_url)) { | 2368 WebUI::TypeID previous_web_ui_type = render_frame_host_->web_ui_type(); |
2439 pending_web_ui_.reset(); | 2369 bool changed_web_ui = render_frame_host_->UpdateWebUI(dest_url, bindings); |
2440 pending_and_current_web_ui_ = web_ui_->AsWeakPtr(); | |
2441 } else { | |
2442 SetPendingWebUI(dest_url, bindings); | |
2443 // Make sure the new RenderViewHost has the right bindings. | |
2444 if (pending_web_ui() && | |
2445 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | |
2446 render_frame_host_->render_view_host()->AllowBindings( | |
2447 pending_web_ui()->GetBindings()); | |
2448 } | |
2449 } | |
2450 | 2370 |
2371 // If a change in WebUI happened, check this is an acceptable case. | |
nasko
2015/10/29 22:13:15
In general, what happens if this is not an accepta
carlosk
2015/10/30 10:35:23
Right now the navigation would simply continue in
nasko
2015/11/02 17:00:35
I think it should be a CHECK. Allocating WebUI whe
carlosk
2015/11/03 09:50:30
Done.
| |
2372 DCHECK(!changed_web_ui || | |
2373 IsAcceptableWebUITransition(previous_web_ui_type, dest_url, | |
2374 dest_is_restore)); | |
2375 | |
2376 // If there is a WebUI in the current RenderFrameHost, it will be reused. | |
2377 should_reuse_web_ui_ = render_frame_host_->web_ui(); | |
2378 DCHECK_EQ(pending_web_ui(), render_frame_host_->web_ui()); | |
2379 | |
2380 // If the current RenderFrameHost has a WebUI and the associated RenderFrame | |
2381 // is alive, notify to the WebUI that the RenderView is being reused. | |
2451 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { | 2382 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { |
2452 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), | 2383 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), |
2453 frame_tree_node_->IsMainFrame()); | 2384 frame_tree_node_->IsMainFrame()); |
2454 } | 2385 } |
2455 | 2386 |
2456 // The renderer can exit view source mode when any error or cancellation | 2387 // The renderer can exit view source mode when any error or cancellation |
2457 // happen. We must overwrite to recover the mode. | 2388 // happen. We must overwrite to recover the mode. |
2458 if (dest_is_view_source_mode) { | 2389 if (dest_is_view_source_mode) { |
2459 render_frame_host_->render_view_host()->Send( | 2390 render_frame_host_->render_view_host()->Send( |
2460 new ViewMsg_EnableViewSourceMode( | 2391 new ViewMsg_EnableViewSourceMode( |
2461 render_frame_host_->render_view_host()->GetRoutingID())); | 2392 render_frame_host_->render_view_host()->GetRoutingID())); |
2462 } | 2393 } |
2463 | 2394 |
2464 return render_frame_host_.get(); | 2395 return render_frame_host_.get(); |
2465 } | 2396 } |
2466 | 2397 |
2467 void RenderFrameHostManager::CancelPending() { | 2398 void RenderFrameHostManager::CancelPending() { |
2468 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", | 2399 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", |
2469 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2400 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
2401 should_reuse_web_ui_ = false; | |
2470 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); | 2402 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); |
2471 } | 2403 } |
2472 | 2404 |
2473 scoped_ptr<RenderFrameHostImpl> | 2405 scoped_ptr<RenderFrameHostImpl> |
2474 RenderFrameHostManager::UnsetPendingRenderFrameHost() { | 2406 RenderFrameHostManager::UnsetPendingRenderFrameHost() { |
2475 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = | 2407 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = |
2476 pending_render_frame_host_.Pass(); | 2408 pending_render_frame_host_.Pass(); |
2477 | 2409 |
2478 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( | 2410 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( |
2479 pending_render_frame_host.get(), | 2411 pending_render_frame_host.get(), |
2480 render_frame_host_.get()); | 2412 render_frame_host_.get()); |
2481 | 2413 |
2414 should_reuse_web_ui_ = false; | |
2415 | |
2482 // We no longer need to prevent the process from exiting. | 2416 // We no longer need to prevent the process from exiting. |
2483 pending_render_frame_host->GetProcess()->RemovePendingView(); | 2417 pending_render_frame_host->GetProcess()->RemovePendingView(); |
2484 | 2418 |
2485 pending_web_ui_.reset(); | |
2486 pending_and_current_web_ui_.reset(); | |
2487 | |
2488 return pending_render_frame_host.Pass(); | 2419 return pending_render_frame_host.Pass(); |
2489 } | 2420 } |
2490 | 2421 |
2491 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 2422 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
2492 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 2423 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
2493 // Swap the two. | 2424 // Swap the two. |
2494 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 2425 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
2495 render_frame_host_.Pass(); | 2426 render_frame_host_.Pass(); |
2496 render_frame_host_ = render_frame_host.Pass(); | 2427 render_frame_host_ = render_frame_host.Pass(); |
2497 | 2428 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2652 if (rvh && !rvh->IsRenderViewLive()) { | 2583 if (rvh && !rvh->IsRenderViewLive()) { |
2653 EnsureRenderViewInitialized(rvh, instance); | 2584 EnsureRenderViewInitialized(rvh, instance); |
2654 } else { | 2585 } else { |
2655 // Create a swapped out RenderView in the given SiteInstance if none | 2586 // Create a swapped out RenderView in the given SiteInstance if none |
2656 // exists. Since an opener can point to a subframe, do this on the root | 2587 // exists. Since an opener can point to a subframe, do this on the root |
2657 // frame of the current opener's frame tree. | 2588 // frame of the current opener's frame tree. |
2658 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { | 2589 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { |
2659 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); | 2590 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); |
2660 } else { | 2591 } else { |
2661 frame_tree->root()->render_manager()->CreateRenderFrame( | 2592 frame_tree->root()->render_manager()->CreateRenderFrame( |
2662 instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, | 2593 instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr); |
2663 nullptr); | |
2664 } | 2594 } |
2665 } | 2595 } |
2666 } | 2596 } |
2667 } | 2597 } |
2668 | 2598 |
2669 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { | 2599 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { |
2670 if (!frame_tree_node_->opener()) | 2600 if (!frame_tree_node_->opener()) |
2671 return MSG_ROUTING_NONE; | 2601 return MSG_ROUTING_NONE; |
2672 | 2602 |
2673 return frame_tree_node_->opener() | 2603 return frame_tree_node_->opener() |
2674 ->render_manager() | 2604 ->render_manager() |
2675 ->GetRoutingIdForSiteInstance(instance); | 2605 ->GetRoutingIdForSiteInstance(instance); |
2676 } | 2606 } |
2677 | 2607 |
2608 bool RenderFrameHostManager::IsAcceptableWebUITransition( | |
2609 WebUI::TypeID previous_web_ui_type, | |
2610 const GURL& dest_url, | |
2611 bool dest_is_restore) { | |
2612 // There are a few navigation cases that allow for changes to the WebUI of | |
2613 // the current RenderFrameHost. | |
2614 BrowserContext* browser_context = | |
2615 delegate_->GetControllerForRenderManager().GetBrowserContext(); | |
2616 if (render_frame_host_->web_ui()) { | |
2617 // Switching WebUI from one type to another is never acceptable. | |
2618 DCHECK(previous_web_ui_type == WebUI::kNoWebUI); | |
2619 | |
2620 // Going from not having to having a WebUI is acceptable for: | |
2621 // - The first navigation of this frame. | |
2622 const NavigationEntry* current_entry = | |
2623 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
2624 bool is_first_navigation_for_frame = !current_entry; | |
2625 // - A restore navigation to a WebUI URL. | |
2626 const GURL& current_effective_url = | |
2627 current_entry ? SiteInstanceImpl::GetEffectiveURL( | |
2628 browser_context, current_entry->GetURL()) | |
2629 : render_frame_host_->GetSiteInstance()->GetSiteURL(); | |
2630 bool is_webui_restore = | |
2631 dest_is_restore && | |
2632 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( | |
2633 browser_context, current_effective_url); | |
2634 // - Navigating back from a special renderer controlled URL. | |
2635 bool is_back_from_renderer_url = | |
2636 current_entry && IsRendererDebugURL(current_entry->GetURL()); | |
2637 DCHECK(is_first_navigation_for_frame || is_webui_restore || | |
2638 is_back_from_renderer_url); | |
2639 } else { | |
2640 // Going from having to not having a WebUI is acceptable for: | |
2641 // - Navigating to a special, renderer controlled URL. | |
2642 DCHECK(IsRendererDebugURL( | |
2643 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url))); | |
2644 } | |
2645 return true; | |
2646 } | |
2647 | |
2678 } // namespace content | 2648 } // namespace content |
OLD | NEW |