Chromium Code Reviews| 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 28 matching lines...) Expand all Loading... | |
| 414 // site that is handled via Mojo, then Mojo WebUI code in //chrome will | 386 // site that is handled via Mojo, then Mojo WebUI code in //chrome will |
| 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(), nullptr)) | 393 if (!InitRenderView(dest_render_frame_host->render_view_host(), nullptr)) |
| 422 return nullptr; | 394 return nullptr; |
| 423 | 395 |
| 396 if (pending_web_ui()) { | |
| 397 pending_web_ui()->RenderViewCreated( | |
| 398 dest_render_frame_host->render_view_host()); | |
| 399 } | |
| 400 | |
| 424 // Now that we've created a new renderer, be sure to hide it if it isn't | 401 // Now that we've created a new renderer, be sure to hide it if it isn't |
| 425 // our primary one. Otherwise, we might crash if we try to call Show() | 402 // our primary one. Otherwise, we might crash if we try to call Show() |
| 426 // on it later. | 403 // on it later. |
| 427 if (dest_render_frame_host != render_frame_host_) { | 404 if (dest_render_frame_host != render_frame_host_) { |
| 428 if (dest_render_frame_host->GetView()) | 405 if (dest_render_frame_host->GetView()) |
| 429 dest_render_frame_host->GetView()->Hide(); | 406 dest_render_frame_host->GetView()->Hide(); |
| 430 } else { | 407 } else { |
| 431 // After a renderer crash we'd have marked the host as invisible, so we | 408 // After a renderer crash we'd have marked the host as invisible, so we |
| 432 // need to set the visibility of the new View to the correct value here | 409 // need to set the visibility of the new View to the correct value here |
| 433 // after reload. | 410 // after reload. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 | 641 |
| 665 // Make sure any dynamic changes to this frame's sandbox flags that were made | 642 // Make sure any dynamic changes to this frame's sandbox flags that were made |
| 666 // prior to navigation take effect. | 643 // prior to navigation take effect. |
| 667 CommitPendingSandboxFlags(); | 644 CommitPendingSandboxFlags(); |
| 668 } | 645 } |
| 669 | 646 |
| 670 void RenderFrameHostManager::CommitPendingIfNecessary( | 647 void RenderFrameHostManager::CommitPendingIfNecessary( |
| 671 RenderFrameHostImpl* render_frame_host, | 648 RenderFrameHostImpl* render_frame_host, |
| 672 bool was_caused_by_user_gesture) { | 649 bool was_caused_by_user_gesture) { |
| 673 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { | 650 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { |
| 674 DCHECK_IMPLIES(should_reuse_web_ui_, web_ui_); | |
| 675 | 651 |
| 676 // We should only hear this from our current renderer. | 652 // We should only hear this from our current renderer. |
| 677 DCHECK_EQ(render_frame_host_, render_frame_host); | 653 DCHECK_EQ(render_frame_host_, render_frame_host); |
| 678 | 654 |
| 679 // Even when there is no pending RVH, there may be a pending Web UI. | 655 // If current RenderFrameHost has a pending WebUI, commit it. |
| 680 if (pending_web_ui() || speculative_web_ui_) | 656 if (render_frame_host_->pending_web_ui()) |
| 681 CommitPending(); | 657 CommitPending(); |
| 682 return; | 658 return; |
| 683 } | 659 } |
| 684 | 660 |
| 685 if (render_frame_host == pending_render_frame_host_ || | 661 if (render_frame_host == pending_render_frame_host_ || |
| 686 render_frame_host == speculative_render_frame_host_) { | 662 render_frame_host == speculative_render_frame_host_) { |
| 687 // The pending cross-process navigation completed, so show the renderer. | 663 // The pending cross-process navigation completed, so show the renderer. |
| 688 CommitPending(); | 664 CommitPending(); |
| 689 } else if (render_frame_host == render_frame_host_) { | 665 } else if (render_frame_host == render_frame_host_) { |
| 690 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 666 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1019 if (current_site_instance == dest_site_instance.get() || | 995 if (current_site_instance == dest_site_instance.get() || |
| 1020 (!request.browser_initiated() && is_main_frame) || | 996 (!request.browser_initiated() && is_main_frame) || |
| 1021 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() && | 997 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() && |
| 1022 !current_site_instance->RequiresDedicatedProcess())) { | 998 !current_site_instance->RequiresDedicatedProcess())) { |
| 1023 // Reuse the current RFH if its SiteInstance matches the the navigation's | 999 // Reuse the current RFH if its SiteInstance matches the the navigation's |
| 1024 // or if this is a subframe navigation. We only swap RFHs for subframes when | 1000 // or if this is a subframe navigation. We only swap RFHs for subframes when |
| 1025 // --site-per-process is enabled. | 1001 // --site-per-process is enabled. |
| 1026 CleanUpNavigation(); | 1002 CleanUpNavigation(); |
| 1027 navigation_rfh = render_frame_host_.get(); | 1003 navigation_rfh = render_frame_host_.get(); |
| 1028 | 1004 |
| 1029 // As SiteInstances are the same, check if the WebUI should be reused. | 1005 // As SiteInstances are the same, make the RFH update its possible pending |
| 1030 const NavigationEntry* current_navigation_entry = | 1006 // WebUI. |
| 1031 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | 1007 render_frame_host_->UpdatePendingWebUI(request.common_params().url, |
| 1032 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, | 1008 request.bindings()); |
| 1033 request.common_params().url); | 1009 DCHECK(speculative_web_ui() == render_frame_host_->pending_web_ui()); |
| 1034 if (!should_reuse_web_ui_) { | 1010 |
| 1035 speculative_web_ui_ = CreateWebUI(request.common_params().url, | 1011 // If a pending WebUI was set on the current RenderFrameHost (be it a new |
| 1036 request.bindings()); | 1012 // one or the reused current one) and the associated RenderFrame is alive, |
| 1037 // Make sure the current RenderViewHost has the right bindings. | 1013 // notify the WebUI the RenderView is being reused. |
| 1038 if (speculative_web_ui() && | 1014 if (speculative_web_ui() && render_frame_host_->IsRenderFrameLive()) { |
| 1039 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | 1015 speculative_web_ui()->RenderViewReused( |
| 1040 render_frame_host_->render_view_host()->AllowBindings( | 1016 render_frame_host_->render_view_host(), |
| 1041 speculative_web_ui()->GetBindings()); | 1017 frame_tree_node_->IsMainFrame()); |
|
carlosk
2015/10/27 14:35:44
This is a bugfix.
| |
| 1042 } | |
| 1043 } | 1018 } |
| 1019 | |
| 1020 DCHECK(!speculative_render_frame_host_); | |
| 1044 } else { | 1021 } else { |
| 1045 // 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 |
| 1046 // speculatively created RenderFrameHost, create a new RenderFrameHost using | 1023 // speculatively created RenderFrameHost, create a new RenderFrameHost using |
| 1047 // this new SiteInstance. | 1024 // this new SiteInstance. |
| 1048 if (!speculative_render_frame_host_ || | 1025 if (!speculative_render_frame_host_ || |
| 1049 speculative_render_frame_host_->GetSiteInstance() != | 1026 speculative_render_frame_host_->GetSiteInstance() != |
| 1050 dest_site_instance.get()) { | 1027 dest_site_instance.get()) { |
| 1051 CleanUpNavigation(); | 1028 CleanUpNavigation(); |
| 1052 bool success = CreateSpeculativeRenderFrameHost( | 1029 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, |
| 1053 request.common_params().url, current_site_instance, | 1030 dest_site_instance.get()); |
| 1054 dest_site_instance.get(), request.bindings()); | |
| 1055 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(); | |
| 1056 } | 1041 } |
| 1057 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 | |
| 1058 navigation_rfh = speculative_render_frame_host_.get(); | 1047 navigation_rfh = speculative_render_frame_host_.get(); |
| 1059 | 1048 |
| 1060 // Check if our current RFH is live. | 1049 // Check if our current RFH is live. |
| 1061 if (!render_frame_host_->IsRenderFrameLive()) { | 1050 if (!render_frame_host_->IsRenderFrameLive()) { |
| 1062 // 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 |
| 1063 // 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 |
| 1064 // 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. |
| 1065 // (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 |
| 1066 // RFH isn't live.) | 1055 // RFH isn't live.) |
| 1067 CommitPending(); | 1056 CommitPending(); |
| 1068 } | 1057 } |
| 1069 } | 1058 } |
| 1070 DCHECK(navigation_rfh && | 1059 DCHECK(navigation_rfh && |
| 1071 (navigation_rfh == render_frame_host_.get() || | 1060 (navigation_rfh == render_frame_host_.get() || |
| 1072 navigation_rfh == speculative_render_frame_host_.get())); | 1061 navigation_rfh == speculative_render_frame_host_.get())); |
| 1073 | 1062 |
| 1074 // 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 |
| 1075 // created or has crashed), initialize it. | 1064 // created or has crashed), initialize it. |
| 1076 if (!navigation_rfh->IsRenderFrameLive()) { | 1065 if (!navigation_rfh->IsRenderFrameLive()) { |
| 1077 // Recreate the opener chain. | 1066 // Recreate the opener chain. |
| 1078 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); | 1067 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); |
| 1079 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) { | 1068 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) |
| 1080 return nullptr; | 1069 return nullptr; |
| 1070 | |
| 1071 if (speculative_web_ui()) { | |
| 1072 speculative_web_ui()->RenderViewCreated( | |
| 1073 navigation_rfh->render_view_host()); | |
| 1081 } | 1074 } |
| 1082 | 1075 |
| 1083 if (navigation_rfh == render_frame_host_) { | 1076 if (navigation_rfh == render_frame_host_) { |
| 1084 // 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 |
| 1085 // manager still uses NotificationService and expects to see a | 1078 // manager still uses NotificationService and expects to see a |
| 1086 // RenderViewHost changed notification after WebContents and | 1079 // RenderViewHost changed notification after WebContents and |
| 1087 // RenderFrameHostManager are completely initialized. This should be | 1080 // RenderFrameHostManager are completely initialized. This should be |
| 1088 // removed once the process manager moves away from NotificationService. | 1081 // removed once the process manager moves away from NotificationService. |
| 1089 // See https://crbug.com/462682. | 1082 // See https://crbug.com/462682. |
| 1090 delegate_->NotifyMainFrameSwappedFromRenderManager( | 1083 delegate_->NotifyMainFrameSwappedFromRenderManager( |
| 1091 nullptr, render_frame_host_->render_view_host()); | 1084 nullptr, render_frame_host_->render_view_host()); |
| 1092 } | 1085 } |
| 1093 } | 1086 } |
| 1094 | 1087 |
| 1095 return navigation_rfh; | 1088 return navigation_rfh; |
| 1096 } | 1089 } |
| 1097 | 1090 |
| 1098 // PlzNavigate | 1091 // PlzNavigate |
| 1099 void RenderFrameHostManager::CleanUpNavigation() { | 1092 void RenderFrameHostManager::CleanUpNavigation() { |
| 1100 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1093 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1101 switches::kEnableBrowserSideNavigation)); | 1094 switches::kEnableBrowserSideNavigation)); |
| 1102 speculative_web_ui_.reset(); | 1095 // TODO(carlosk): the discarding of the current RFH WebUI and the cleanup of |
| 1103 should_reuse_web_ui_ = false; | 1096 // the speculative RFH should not always happen together. |
| 1097 render_frame_host_->DiscardPendingWebUI(); | |
| 1104 if (speculative_render_frame_host_) | 1098 if (speculative_render_frame_host_) |
| 1105 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 1099 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
| 1106 } | 1100 } |
| 1107 | 1101 |
| 1108 // PlzNavigate | 1102 // PlzNavigate |
| 1109 scoped_ptr<RenderFrameHostImpl> | 1103 scoped_ptr<RenderFrameHostImpl> |
| 1110 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { | 1104 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { |
| 1111 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1105 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1112 switches::kEnableBrowserSideNavigation)); | 1106 switches::kEnableBrowserSideNavigation)); |
| 1113 speculative_render_frame_host_->GetProcess()->RemovePendingView(); | 1107 speculative_render_frame_host_->GetProcess()->RemovePendingView(); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1290 // We can't switch a RenderView between view source and non-view source mode | 1284 // We can't switch a RenderView between view source and non-view source mode |
| 1291 // without screwing up the session history sometimes (when navigating between | 1285 // without screwing up the session history sometimes (when navigating between |
| 1292 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat | 1286 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat |
| 1293 // it as a new navigation). So require a BrowsingInstance switch. | 1287 // it as a new navigation). So require a BrowsingInstance switch. |
| 1294 if (current_is_view_source_mode != new_is_view_source_mode) | 1288 if (current_is_view_source_mode != new_is_view_source_mode) |
| 1295 return true; | 1289 return true; |
| 1296 | 1290 |
| 1297 return false; | 1291 return false; |
| 1298 } | 1292 } |
| 1299 | 1293 |
| 1300 bool RenderFrameHostManager::ShouldReuseWebUI( | |
| 1301 const NavigationEntry* current_entry, | |
| 1302 const GURL& new_url) const { | |
| 1303 NavigationControllerImpl& controller = | |
| 1304 delegate_->GetControllerForRenderManager(); | |
| 1305 return current_entry && web_ui_ && | |
| 1306 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
| 1307 controller.GetBrowserContext(), current_entry->GetURL()) == | |
| 1308 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType( | |
| 1309 controller.GetBrowserContext(), new_url)); | |
| 1310 } | |
| 1311 | |
| 1312 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( | 1294 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( |
| 1313 const GURL& dest_url, | 1295 const GURL& dest_url, |
| 1314 SiteInstance* source_instance, | 1296 SiteInstance* source_instance, |
| 1315 SiteInstance* dest_instance, | 1297 SiteInstance* dest_instance, |
| 1316 SiteInstance* candidate_instance, | 1298 SiteInstance* candidate_instance, |
| 1317 ui::PageTransition transition, | 1299 ui::PageTransition transition, |
| 1318 bool dest_is_restore, | 1300 bool dest_is_restore, |
| 1319 bool dest_is_view_source_mode) { | 1301 bool dest_is_view_source_mode) { |
| 1320 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1302 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 1321 | 1303 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1634 // The process for the new SiteInstance may (if we're sharing a process with | 1616 // The process for the new SiteInstance may (if we're sharing a process with |
| 1635 // another host that already initialized it) or may not (we have our own | 1617 // another host that already initialized it) or may not (we have our own |
| 1636 // process or the existing process crashed) have been initialized. Calling | 1618 // process or the existing process crashed) have been initialized. Calling |
| 1637 // Init multiple times will be ignored, so this is safe. | 1619 // Init multiple times will be ignored, so this is safe. |
| 1638 if (!new_instance->GetProcess()->Init()) | 1620 if (!new_instance->GetProcess()->Init()) |
| 1639 return; | 1621 return; |
| 1640 | 1622 |
| 1641 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1623 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
| 1642 | 1624 |
| 1643 // Create a non-swapped-out RFH with the given opener. | 1625 // Create a non-swapped-out RFH with the given opener. |
| 1644 pending_render_frame_host_ = CreateRenderFrame( | 1626 pending_render_frame_host_ = |
| 1645 new_instance, pending_web_ui(), create_render_frame_flags, nullptr); | 1627 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
| 1646 } | 1628 } |
| 1647 | 1629 |
| 1648 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( | 1630 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( |
| 1649 SiteInstance* old_instance, | 1631 SiteInstance* old_instance, |
| 1650 SiteInstance* new_instance) { | 1632 SiteInstance* new_instance) { |
| 1651 // Only create opener proxies if they are in the same BrowsingInstance. | 1633 // Only create opener proxies if they are in the same BrowsingInstance. |
| 1652 if (new_instance->IsRelatedSiteInstance(old_instance)) { | 1634 if (new_instance->IsRelatedSiteInstance(old_instance)) { |
| 1653 CreateOpenerProxies(new_instance, frame_tree_node_); | 1635 CreateOpenerProxies(new_instance, frame_tree_node_); |
| 1654 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { | 1636 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { |
| 1655 // Ensure that the frame tree has RenderFrameProxyHosts for the | 1637 // Ensure that the frame tree has RenderFrameProxyHosts for the |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1717 } | 1699 } |
| 1718 | 1700 |
| 1719 return RenderFrameHostFactory::Create( | 1701 return RenderFrameHostFactory::Create( |
| 1720 site_instance, render_view_host, render_frame_delegate_, | 1702 site_instance, render_view_host, render_frame_delegate_, |
| 1721 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, | 1703 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, |
| 1722 widget_routing_id, flags); | 1704 widget_routing_id, flags); |
| 1723 } | 1705 } |
| 1724 | 1706 |
| 1725 // PlzNavigate | 1707 // PlzNavigate |
| 1726 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( | 1708 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( |
| 1727 const GURL& url, | |
| 1728 SiteInstance* old_instance, | 1709 SiteInstance* old_instance, |
| 1729 SiteInstance* new_instance, | 1710 SiteInstance* new_instance) { |
| 1730 int bindings) { | |
| 1731 CHECK(new_instance); | 1711 CHECK(new_instance); |
| 1732 CHECK_NE(old_instance, new_instance); | 1712 CHECK_NE(old_instance, new_instance); |
| 1733 CHECK(!should_reuse_web_ui_); | |
| 1734 | |
| 1735 // Note: |speculative_web_ui_| must be initialized before starting the | |
| 1736 // |speculative_render_frame_host_| creation steps otherwise the WebUI | |
| 1737 // won't be properly initialized. | |
| 1738 speculative_web_ui_ = CreateWebUI(url, bindings); | |
| 1739 | 1713 |
| 1740 // The process for the new SiteInstance may (if we're sharing a process with | 1714 // The process for the new SiteInstance may (if we're sharing a process with |
| 1741 // another host that already initialized it) or may not (we have our own | 1715 // another host that already initialized it) or may not (we have our own |
| 1742 // process or the existing process crashed) have been initialized. Calling | 1716 // process or the existing process crashed) have been initialized. Calling |
| 1743 // Init multiple times will be ignored, so this is safe. | 1717 // Init multiple times will be ignored, so this is safe. |
| 1744 if (!new_instance->GetProcess()->Init()) | 1718 if (!new_instance->GetProcess()->Init()) |
| 1745 return false; | 1719 return false; |
| 1746 | 1720 |
| 1747 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1721 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
| 1748 | 1722 |
| 1749 int create_render_frame_flags = 0; | 1723 int create_render_frame_flags = 0; |
| 1750 if (delegate_->IsHidden()) | 1724 if (delegate_->IsHidden()) |
| 1751 create_render_frame_flags |= CREATE_RF_HIDDEN; | 1725 create_render_frame_flags |= CREATE_RF_HIDDEN; |
| 1752 speculative_render_frame_host_ = | 1726 speculative_render_frame_host_ = |
| 1753 CreateRenderFrame(new_instance, speculative_web_ui_.get(), | 1727 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
| 1754 create_render_frame_flags, nullptr); | |
| 1755 | 1728 |
| 1756 if (!speculative_render_frame_host_) { | 1729 return !!speculative_render_frame_host_; |
| 1757 speculative_web_ui_.reset(); | 1730 } |
| 1758 return false; | 1731 |
| 1732 void RenderFrameHostManager::InitializeWebUI(const GURL& url, int bindings) { | |
| 1733 RenderFrameHostImpl* rfh = nullptr; | |
| 1734 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 1735 switches::kEnableBrowserSideNavigation)) { | |
| 1736 rfh = speculative_render_frame_host_.get(); | |
| 1737 } else { | |
| 1738 rfh = pending_render_frame_host_.get(); | |
| 1759 } | 1739 } |
| 1760 return true; | 1740 DCHECK(rfh); |
| 1741 | |
| 1742 // Clear any pending WebUI on the current RenderFrameHost as it won't | |
| 1743 // be used. | |
| 1744 render_frame_host_->DiscardPendingWebUI(); | |
| 1745 | |
| 1746 // For new RenderFrameHosts the WebUI should always be kept as active: | |
| 1747 // - It should only have one WebUI so it doesn't need the pending one. | |
| 1748 // - If it commits there's no need to also commit the WebUI. | |
| 1749 rfh->UpdatePendingWebUI(url, bindings); | |
| 1750 rfh->CommitPendingWebUI(); | |
| 1751 RenderViewHostImpl* rvh = rfh->render_view_host(); | |
| 1752 | |
| 1753 if (rfh->web_ui()) | |
| 1754 rfh->web_ui()->RenderViewCreated(rvh); | |
| 1761 } | 1755 } |
| 1762 | 1756 |
| 1763 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( | 1757 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( |
| 1764 SiteInstance* instance, | 1758 SiteInstance* instance, |
| 1765 WebUIImpl* web_ui, | |
| 1766 int flags, | 1759 int flags, |
| 1767 int* view_routing_id_ptr) { | 1760 int* view_routing_id_ptr) { |
| 1768 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1761 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
| 1769 bool swapped_out_forbidden = | 1762 bool swapped_out_forbidden = |
| 1770 SiteIsolationPolicy::IsSwappedOutStateForbidden(); | 1763 SiteIsolationPolicy::IsSwappedOutStateForbidden(); |
| 1771 | 1764 |
| 1772 CHECK(instance); | 1765 CHECK(instance); |
| 1773 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out); | 1766 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out); |
| 1774 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(), | 1767 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(), |
| 1775 frame_tree_node_->IsMainFrame()); | 1768 frame_tree_node_->IsMainFrame()); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1873 success = InitRenderFrame(new_render_frame_host.get()); | 1866 success = InitRenderFrame(new_render_frame_host.get()); |
| 1874 } | 1867 } |
| 1875 } | 1868 } |
| 1876 | 1869 |
| 1877 if (success) { | 1870 if (success) { |
| 1878 if (view_routing_id_ptr) | 1871 if (view_routing_id_ptr) |
| 1879 *view_routing_id_ptr = render_view_host->GetRoutingID(); | 1872 *view_routing_id_ptr = render_view_host->GetRoutingID(); |
| 1880 } | 1873 } |
| 1881 } | 1874 } |
| 1882 | 1875 |
| 1883 // When a new RenderView is created by the renderer process, the new | |
| 1884 // WebContents gets a RenderViewHost in the SiteInstance of its opener | |
| 1885 // WebContents. If not used in the first navigation, this RVH is swapped out | |
| 1886 // and is not granted bindings, so we may need to grant them when swapping it | |
| 1887 // in. | |
| 1888 if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) { | |
| 1889 int required_bindings = web_ui->GetBindings(); | |
| 1890 RenderViewHost* render_view_host = | |
| 1891 new_render_frame_host->render_view_host(); | |
| 1892 if ((render_view_host->GetEnabledBindings() & required_bindings) != | |
| 1893 required_bindings) { | |
| 1894 render_view_host->AllowBindings(required_bindings); | |
| 1895 } | |
| 1896 } | |
| 1897 | |
| 1898 // Returns the new RFH if it isn't swapped out. | 1876 // Returns the new RFH if it isn't swapped out. |
| 1899 if (success && !swapped_out) { | 1877 if (success && !swapped_out) { |
| 1900 DCHECK(new_render_frame_host->GetSiteInstance() == instance); | 1878 DCHECK(new_render_frame_host->GetSiteInstance() == instance); |
| 1879 DCHECK(new_render_frame_host->render_view_host()->IsRenderViewLive()); | |
| 1901 return new_render_frame_host.Pass(); | 1880 return new_render_frame_host.Pass(); |
| 1902 } | 1881 } |
| 1903 return nullptr; | 1882 return nullptr; |
| 1904 } | 1883 } |
| 1905 | 1884 |
| 1906 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { | 1885 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { |
| 1907 // A RenderFrameProxyHost should never be created in the same SiteInstance as | 1886 // A RenderFrameProxyHost should never be created in the same SiteInstance as |
| 1908 // the current RFH. | 1887 // the current RFH. |
| 1909 CHECK(instance); | 1888 CHECK(instance); |
| 1910 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); | 1889 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2006 RenderFrameProxyHost* proxy) { | 1985 RenderFrameProxyHost* proxy) { |
| 2007 // Ensure the renderer process is initialized before creating the | 1986 // Ensure the renderer process is initialized before creating the |
| 2008 // RenderView. | 1987 // RenderView. |
| 2009 if (!render_view_host->GetProcess()->Init()) | 1988 if (!render_view_host->GetProcess()->Init()) |
| 2010 return false; | 1989 return false; |
| 2011 | 1990 |
| 2012 // We may have initialized this RenderViewHost for another RenderFrameHost. | 1991 // We may have initialized this RenderViewHost for another RenderFrameHost. |
| 2013 if (render_view_host->IsRenderViewLive()) | 1992 if (render_view_host->IsRenderViewLive()) |
| 2014 return true; | 1993 return true; |
| 2015 | 1994 |
| 2016 // If |render_view_host| is not for a proxy and the navigation is to a WebUI, | |
| 2017 // and if the RenderView is not in a guest process, tell |render_view_host| | |
| 2018 // about any bindings it will need enabled. | |
| 2019 // TODO(carlosk): Move WebUI to RenderFrameHost in https://crbug.com/508850. | |
| 2020 WebUIImpl* dest_web_ui = nullptr; | |
| 2021 if (!proxy) { | |
| 2022 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 2023 switches::kEnableBrowserSideNavigation)) { | |
| 2024 dest_web_ui = | |
| 2025 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get(); | |
| 2026 } else { | |
| 2027 dest_web_ui = pending_web_ui(); | |
| 2028 } | |
| 2029 } | |
| 2030 if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) { | |
| 2031 render_view_host->AllowBindings(dest_web_ui->GetBindings()); | |
| 2032 } else { | |
| 2033 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled | |
| 2034 // process unless it's swapped out. | |
| 2035 if (render_view_host->is_active()) { | |
| 2036 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( | |
| 2037 render_view_host->GetProcess()->GetID())); | |
| 2038 } | |
| 2039 } | |
| 2040 | |
| 2041 int opener_frame_routing_id = | 1995 int opener_frame_routing_id = |
| 2042 GetOpenerRoutingID(render_view_host->GetSiteInstance()); | 1996 GetOpenerRoutingID(render_view_host->GetSiteInstance()); |
| 2043 | 1997 |
| 2044 bool created = delegate_->CreateRenderViewForRenderManager( | 1998 bool created = delegate_->CreateRenderViewForRenderManager( |
| 2045 render_view_host, opener_frame_routing_id, | 1999 render_view_host, opener_frame_routing_id, |
| 2046 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE, | 2000 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE, |
| 2047 frame_tree_node_->current_replication_state()); | 2001 frame_tree_node_->current_replication_state()); |
| 2048 | 2002 |
| 2049 if (created && proxy) | 2003 if (created && proxy) |
| 2050 proxy->set_render_frame_proxy_created(true); | 2004 proxy->set_render_frame_proxy_created(true); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2122 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); | 2076 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); |
| 2123 if (proxy) | 2077 if (proxy) |
| 2124 return proxy->GetRoutingID(); | 2078 return proxy->GetRoutingID(); |
| 2125 | 2079 |
| 2126 return MSG_ROUTING_NONE; | 2080 return MSG_ROUTING_NONE; |
| 2127 } | 2081 } |
| 2128 | 2082 |
| 2129 void RenderFrameHostManager::CommitPending() { | 2083 void RenderFrameHostManager::CommitPending() { |
| 2130 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 2084 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
| 2131 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2085 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 2132 bool browser_side_navigation = | |
| 2133 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 2134 switches::kEnableBrowserSideNavigation); | |
| 2135 | |
| 2136 // First check whether we're going to want to focus the location bar after | 2086 // First check whether we're going to want to focus the location bar after |
| 2137 // this commit. We do this now because the navigation hasn't formally | 2087 // this commit. We do this now because the navigation hasn't formally |
| 2138 // committed yet, so if we've already cleared |pending_web_ui_| the call chain | 2088 // committed yet, so if we've already cleared the pending WebUI the call chain |
| 2139 // this triggers won't be able to figure out what's going on. | 2089 // this triggers won't be able to figure out what's going on. |
| 2140 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 2090 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 2141 | 2091 |
| 2142 // Next commit the Web UI, if any. Either replace |web_ui_| with | 2092 // If the current RenderFrameHost has a pending WebUI then just commit it and |
| 2143 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or | 2093 // return (there should be nothing else to commit). |
| 2144 // leave |web_ui_| as is if reusing it. | 2094 if (render_frame_host_->pending_web_ui()) { |
| 2145 DCHECK(!(pending_web_ui_ && pending_and_current_web_ui_)); | 2095 DCHECK(!pending_render_frame_host_ && !speculative_render_frame_host_); |
| 2146 if (pending_web_ui_ || speculative_web_ui_) { | 2096 render_frame_host_->CommitPendingWebUI(); |
| 2147 DCHECK(!should_reuse_web_ui_); | |
| 2148 web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release() | |
| 2149 : pending_web_ui_.release()); | |
| 2150 } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) { | |
| 2151 if (browser_side_navigation) { | |
| 2152 DCHECK(web_ui_); | |
| 2153 should_reuse_web_ui_ = false; | |
| 2154 } else { | |
| 2155 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get()); | |
| 2156 pending_and_current_web_ui_.reset(); | |
| 2157 } | |
| 2158 } else { | |
| 2159 web_ui_.reset(); | |
| 2160 } | |
| 2161 DCHECK(!speculative_web_ui_); | |
| 2162 DCHECK(!should_reuse_web_ui_); | |
| 2163 | |
| 2164 // It's possible for the pending_render_frame_host_ to be nullptr when we | |
| 2165 // aren't crossing process boundaries. If so, we just needed to handle the Web | |
| 2166 // UI committing above and we're done. | |
| 2167 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { | |
| 2168 if (will_focus_location_bar) | 2097 if (will_focus_location_bar) |
| 2169 delegate_->SetFocusToLocationBar(false); | 2098 delegate_->SetFocusToLocationBar(false); |
| 2170 return; | 2099 return; |
| 2171 } | 2100 } |
| 2172 | 2101 |
| 2173 // Remember if the page was focused so we can focus the new renderer in | 2102 // Remember if the page was focused so we can focus the new renderer in |
| 2174 // that case. | 2103 // that case. |
| 2175 bool focus_render_view = !will_focus_location_bar && | 2104 bool focus_render_view = !will_focus_location_bar && |
| 2176 render_frame_host_->GetView() && | 2105 render_frame_host_->GetView() && |
| 2177 render_frame_host_->GetView()->HasFocus(); | 2106 render_frame_host_->GetView()->HasFocus(); |
| 2178 | 2107 |
| 2179 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 2108 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 2180 | 2109 |
| 2181 // Swap in the pending or speculative frame and make it active. Also ensure | 2110 // Swap in the pending or speculative frame and make it active. Also ensure |
| 2182 // the FrameTree stays in sync. | 2111 // the FrameTree stays in sync. |
| 2183 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; | 2112 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
| 2184 if (!browser_side_navigation) { | 2113 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 2114 switches::kEnableBrowserSideNavigation)) { | |
| 2185 DCHECK(!speculative_render_frame_host_); | 2115 DCHECK(!speculative_render_frame_host_); |
| 2186 old_render_frame_host = | 2116 old_render_frame_host = |
| 2187 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 2117 SetRenderFrameHost(pending_render_frame_host_.Pass()); |
| 2188 } else { | 2118 } else { |
| 2189 // PlzNavigate | 2119 // PlzNavigate |
| 2190 DCHECK(speculative_render_frame_host_); | 2120 DCHECK(speculative_render_frame_host_); |
| 2191 old_render_frame_host = | 2121 old_render_frame_host = |
| 2192 SetRenderFrameHost(speculative_render_frame_host_.Pass()); | 2122 SetRenderFrameHost(speculative_render_frame_host_.Pass()); |
| 2193 } | 2123 } |
| 2194 | 2124 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2338 // If we are currently navigating cross-process, we want to get back to normal | 2268 // If we are currently navigating cross-process, we want to get back to normal |
| 2339 // and then navigate as usual. | 2269 // and then navigate as usual. |
| 2340 if (pending_render_frame_host_) | 2270 if (pending_render_frame_host_) |
| 2341 CancelPending(); | 2271 CancelPending(); |
| 2342 | 2272 |
| 2343 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 2273 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 2344 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( | 2274 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
| 2345 dest_url, source_instance, dest_instance, nullptr, transition, | 2275 dest_url, source_instance, dest_instance, nullptr, transition, |
| 2346 dest_is_restore, dest_is_view_source_mode); | 2276 dest_is_restore, dest_is_view_source_mode); |
| 2347 | 2277 |
| 2348 const NavigationEntry* current_entry = | |
| 2349 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
| 2350 | |
| 2351 DCHECK(!pending_render_frame_host_); | 2278 DCHECK(!pending_render_frame_host_); |
| 2352 | 2279 |
| 2353 if (new_instance.get() != current_instance) { | 2280 if (new_instance.get() != current_instance) { |
| 2354 TRACE_EVENT_INSTANT2( | 2281 TRACE_EVENT_INSTANT2( |
| 2355 "navigation", | 2282 "navigation", |
| 2356 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 2283 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
| 2357 TRACE_EVENT_SCOPE_THREAD, | 2284 TRACE_EVENT_SCOPE_THREAD, |
| 2358 "current_instance id", current_instance->GetId(), | 2285 "current_instance id", current_instance->GetId(), |
| 2359 "new_instance id", new_instance->GetId()); | 2286 "new_instance id", new_instance->GetId()); |
| 2360 | 2287 |
| 2361 // New SiteInstance: create a pending RFH to navigate. | 2288 // New SiteInstance: create a pending RFH to navigate. |
| 2362 | 2289 |
| 2363 // This will possibly create (set to nullptr) a Web UI object for the | |
| 2364 // pending page. We'll use this later to give the page special access. This | |
| 2365 // must happen before the new renderer is created below so it will get | |
| 2366 // bindings. It must also happen after the above conditional call to | |
| 2367 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_ | |
| 2368 // and the page will not have its bindings set appropriately. | |
| 2369 SetPendingWebUI(dest_url, bindings); | |
| 2370 CreatePendingRenderFrameHost(current_instance, new_instance.get()); | 2290 CreatePendingRenderFrameHost(current_instance, new_instance.get()); |
| 2371 if (!pending_render_frame_host_) | 2291 if (!pending_render_frame_host_) |
| 2372 return nullptr; | 2292 return nullptr; |
| 2373 | 2293 |
| 2294 InitializeWebUI(dest_url, bindings); | |
| 2295 | |
| 2374 // Check if our current RFH is live before we set up a transition. | 2296 // Check if our current RFH is live before we set up a transition. |
| 2375 if (!render_frame_host_->IsRenderFrameLive()) { | 2297 if (!render_frame_host_->IsRenderFrameLive()) { |
| 2376 // The current RFH is not live. There's no reason to sit around with a | 2298 // The current RFH is not live. There's no reason to sit around with a |
| 2377 // sad tab or a newly created RFH while we wait for the pending RFH to | 2299 // sad tab or a newly created RFH while we wait for the pending RFH to |
| 2378 // navigate. Just switch to the pending RFH now and go back to normal. | 2300 // navigate. Just switch to the pending RFH now and go back to normal. |
| 2379 // (Note that we don't care about on{before}unload handlers if the current | 2301 // (Note that we don't care about on{before}unload handlers if the current |
| 2380 // RFH isn't live.) | 2302 // RFH isn't live.) |
| 2381 CommitPending(); | 2303 CommitPending(); |
| 2382 return render_frame_host_.get(); | 2304 return render_frame_host_.get(); |
| 2383 } | 2305 } |
| 2384 // Otherwise, it's safe to treat this as a pending cross-process transition. | 2306 // Otherwise, it's safe to treat this as a pending cross-process transition. |
| 2385 | 2307 |
| 2386 // We now have a pending RFH. | 2308 // We now have a pending RFH and possibly an associated pending WebUI. |
| 2387 DCHECK(pending_render_frame_host_); | 2309 DCHECK(pending_render_frame_host_); |
| 2310 DCHECK_EQ(pending_web_ui(), pending_render_frame_host_->web_ui()); | |
| 2311 DCHECK(!pending_render_frame_host_->pending_web_ui()); | |
| 2312 DCHECK(!render_frame_host_->pending_web_ui()); | |
| 2388 | 2313 |
| 2389 // We need to wait until the beforeunload handler has run, unless we are | 2314 // We need to wait until the beforeunload handler has run, unless we are |
| 2390 // transferring an existing request (in which case it has already run). | 2315 // transferring an existing request (in which case it has already run). |
| 2391 // Suspend the new render view (i.e., don't let it send the cross-process | 2316 // Suspend the new render view (i.e., don't let it send the cross-process |
| 2392 // Navigate message) until we hear back from the old renderer's | 2317 // Navigate message) until we hear back from the old renderer's |
| 2393 // beforeunload handler. If the handler returns false, we'll have to | 2318 // beforeunload handler. If the handler returns false, we'll have to |
| 2394 // cancel the request. | 2319 // cancel the request. |
| 2395 // | 2320 // |
| 2396 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); | 2321 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); |
| 2397 bool is_transfer = transferred_request_id != GlobalRequestID(); | 2322 bool is_transfer = transferred_request_id != GlobalRequestID(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2420 | 2345 |
| 2421 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. | 2346 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. |
| 2422 | 2347 |
| 2423 // It's possible to swap out the current RFH and then decide to navigate in it | 2348 // It's possible to swap out the current RFH and then decide to navigate in it |
| 2424 // anyway (e.g., a cross-process navigation that redirects back to the | 2349 // anyway (e.g., a cross-process navigation that redirects back to the |
| 2425 // original site). In that case, we have a proxy for the current RFH but | 2350 // original site). In that case, we have a proxy for the current RFH but |
| 2426 // haven't deleted it yet. The new navigation will swap it back in, so we can | 2351 // haven't deleted it yet. The new navigation will swap it back in, so we can |
| 2427 // delete the proxy. | 2352 // delete the proxy. |
| 2428 proxy_hosts_->Remove(new_instance.get()->GetId()); | 2353 proxy_hosts_->Remove(new_instance.get()->GetId()); |
| 2429 | 2354 |
| 2430 if (ShouldReuseWebUI(current_entry, dest_url)) { | 2355 render_frame_host_->UpdatePendingWebUI(dest_url, bindings); |
| 2431 pending_web_ui_.reset(); | 2356 DCHECK(pending_web_ui() == render_frame_host_->pending_web_ui()); |
| 2432 pending_and_current_web_ui_ = web_ui_->AsWeakPtr(); | |
| 2433 } else { | |
| 2434 SetPendingWebUI(dest_url, bindings); | |
| 2435 // Make sure the new RenderViewHost has the right bindings. | |
| 2436 if (pending_web_ui() && | |
| 2437 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | |
| 2438 render_frame_host_->render_view_host()->AllowBindings( | |
| 2439 pending_web_ui()->GetBindings()); | |
| 2440 } | |
| 2441 } | |
| 2442 | 2357 |
| 2358 // If a pending WebUI was set on the current RenderFrameHost (be it a new one | |
| 2359 // or the reused current one) and the associated RenderFrame is alive, notify | |
| 2360 // the WebUI the RenderView is being reused. | |
| 2443 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { | 2361 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { |
| 2444 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), | 2362 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), |
| 2445 frame_tree_node_->IsMainFrame()); | 2363 frame_tree_node_->IsMainFrame()); |
| 2446 } | 2364 } |
| 2447 | 2365 |
| 2448 // The renderer can exit view source mode when any error or cancellation | 2366 // The renderer can exit view source mode when any error or cancellation |
| 2449 // happen. We must overwrite to recover the mode. | 2367 // happen. We must overwrite to recover the mode. |
| 2450 if (dest_is_view_source_mode) { | 2368 if (dest_is_view_source_mode) { |
| 2451 render_frame_host_->render_view_host()->Send( | 2369 render_frame_host_->render_view_host()->Send( |
| 2452 new ViewMsg_EnableViewSourceMode( | 2370 new ViewMsg_EnableViewSourceMode( |
| 2453 render_frame_host_->render_view_host()->GetRoutingID())); | 2371 render_frame_host_->render_view_host()->GetRoutingID())); |
| 2454 } | 2372 } |
| 2455 | 2373 |
| 2456 return render_frame_host_.get(); | 2374 return render_frame_host_.get(); |
| 2457 } | 2375 } |
| 2458 | 2376 |
| 2459 void RenderFrameHostManager::CancelPending() { | 2377 void RenderFrameHostManager::CancelPending() { |
| 2460 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", | 2378 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", |
| 2461 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2379 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 2380 render_frame_host_->DiscardPendingWebUI(); | |
| 2462 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); | 2381 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); |
| 2463 } | 2382 } |
| 2464 | 2383 |
| 2465 scoped_ptr<RenderFrameHostImpl> | 2384 scoped_ptr<RenderFrameHostImpl> |
| 2466 RenderFrameHostManager::UnsetPendingRenderFrameHost() { | 2385 RenderFrameHostManager::UnsetPendingRenderFrameHost() { |
| 2467 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = | 2386 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = |
| 2468 pending_render_frame_host_.Pass(); | 2387 pending_render_frame_host_.Pass(); |
| 2469 | 2388 |
| 2470 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( | 2389 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( |
| 2471 pending_render_frame_host.get(), | 2390 pending_render_frame_host.get(), |
| 2472 render_frame_host_.get()); | 2391 render_frame_host_.get()); |
| 2473 | 2392 |
| 2474 // We no longer need to prevent the process from exiting. | 2393 // We no longer need to prevent the process from exiting. |
| 2475 pending_render_frame_host->GetProcess()->RemovePendingView(); | 2394 pending_render_frame_host->GetProcess()->RemovePendingView(); |
| 2476 | 2395 |
| 2477 pending_web_ui_.reset(); | |
| 2478 pending_and_current_web_ui_.reset(); | |
| 2479 | |
| 2480 return pending_render_frame_host.Pass(); | 2396 return pending_render_frame_host.Pass(); |
| 2481 } | 2397 } |
| 2482 | 2398 |
| 2483 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 2399 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
| 2484 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 2400 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 2485 // Swap the two. | 2401 // Swap the two. |
| 2486 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 2402 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
| 2487 render_frame_host_.Pass(); | 2403 render_frame_host_.Pass(); |
| 2488 render_frame_host_ = render_frame_host.Pass(); | 2404 render_frame_host_ = render_frame_host.Pass(); |
| 2489 | 2405 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2644 if (rvh && !rvh->IsRenderViewLive()) { | 2560 if (rvh && !rvh->IsRenderViewLive()) { |
| 2645 EnsureRenderViewInitialized(rvh, instance); | 2561 EnsureRenderViewInitialized(rvh, instance); |
| 2646 } else { | 2562 } else { |
| 2647 // Create a swapped out RenderView in the given SiteInstance if none | 2563 // Create a swapped out RenderView in the given SiteInstance if none |
| 2648 // exists. Since an opener can point to a subframe, do this on the root | 2564 // exists. Since an opener can point to a subframe, do this on the root |
| 2649 // frame of the current opener's frame tree. | 2565 // frame of the current opener's frame tree. |
| 2650 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { | 2566 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { |
| 2651 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); | 2567 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); |
| 2652 } else { | 2568 } else { |
| 2653 frame_tree->root()->render_manager()->CreateRenderFrame( | 2569 frame_tree->root()->render_manager()->CreateRenderFrame( |
| 2654 instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, | 2570 instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr); |
| 2655 nullptr); | |
| 2656 } | 2571 } |
| 2657 } | 2572 } |
| 2658 } | 2573 } |
| 2659 } | 2574 } |
| 2660 | 2575 |
| 2661 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { | 2576 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { |
| 2662 if (!frame_tree_node_->opener()) | 2577 if (!frame_tree_node_->opener()) |
| 2663 return MSG_ROUTING_NONE; | 2578 return MSG_ROUTING_NONE; |
| 2664 | 2579 |
| 2665 return frame_tree_node_->opener() | 2580 return frame_tree_node_->opener() |
| 2666 ->render_manager() | 2581 ->render_manager() |
| 2667 ->GetRoutingIdForSiteInstance(instance); | 2582 ->GetRoutingIdForSiteInstance(instance); |
| 2668 } | 2583 } |
| 2669 | 2584 |
| 2670 } // namespace content | 2585 } // namespace content |
| OLD | NEW |