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), | 221 current_web_ui_is_navigating_(false), |
| 224 weak_factory_(this) { | 222 weak_factory_(this) { |
| 225 DCHECK(frame_tree_node_); | 223 DCHECK(frame_tree_node_); |
| 226 } | 224 } |
| 227 | 225 |
| 228 RenderFrameHostManager::~RenderFrameHostManager() { | 226 RenderFrameHostManager::~RenderFrameHostManager() { |
| 229 if (pending_render_frame_host_) { | 227 if (pending_render_frame_host_) { |
| 230 scoped_ptr<RenderFrameHostImpl> relic = UnsetPendingRenderFrameHost(); | 228 scoped_ptr<RenderFrameHostImpl> relic = UnsetPendingRenderFrameHost(); |
| 231 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); | 229 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); |
| 232 } | 230 } |
| 233 | 231 |
| 234 if (speculative_render_frame_host_) { | 232 if (speculative_render_frame_host_) { |
| 235 scoped_ptr<RenderFrameHostImpl> relic = UnsetSpeculativeRenderFrameHost(); | 233 scoped_ptr<RenderFrameHostImpl> relic = UnsetSpeculativeRenderFrameHost(); |
| 236 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); | 234 ShutdownProxiesIfLastActiveFrameInSiteInstance(relic.get()); |
| 237 } | 235 } |
| 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::GetNavigatingWebUI() const { | |
| 287 if (current_web_ui_is_navigating_) | |
| 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 (GetNavigatingWebUI()) { | |
| 412 GetNavigatingWebUI()->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(!current_web_ui_is_navigating_ || 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. |
|
nasko
2015/11/02 17:00:36
This comment doesn't make as much sense with your
carlosk
2015/11/03 09:50:30
Done.
| |
| 679 if (pending_web_ui() || speculative_web_ui_) | 672 if (GetNavigatingWebUI()) |
| 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 || |
| 1034 speculative_web_ui_ = CreateWebUI(request.common_params().url, | 1027 (IsAcceptableWebUITransition( |
| 1035 request.bindings()); | 1028 previous_web_ui_type, request.common_params().url, |
| 1036 // Make sure the current RenderViewHost has the right bindings. | 1029 request.restore_type() != NavigationEntryImpl::RESTORE_NONE))); |
| 1037 if (speculative_web_ui() && | 1030 |
| 1038 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | 1031 // If there is a WebUI in the current RenderFrameHost, it will navigate. |
| 1039 render_frame_host_->render_view_host()->AllowBindings( | 1032 current_web_ui_is_navigating_ = !!render_frame_host_->web_ui(); |
| 1040 speculative_web_ui()->GetBindings()); | 1033 DCHECK_EQ(GetNavigatingWebUI(), render_frame_host_->web_ui()); |
| 1034 | |
| 1035 // If the current RenderFrameHost has a WebUI and the associated RenderFrame | |
| 1036 // is alive, notify to the WebUI that the RenderView is being created or | |
| 1037 // reused depending on whether the WebUI was changed or not. | |
| 1038 if (GetNavigatingWebUI() && render_frame_host_->IsRenderFrameLive()) { | |
| 1039 if (changed_web_ui) { | |
| 1040 GetNavigatingWebUI()->RenderViewCreated( | |
| 1041 render_frame_host_->render_view_host()); | |
| 1042 } else { | |
| 1043 GetNavigatingWebUI()->RenderViewReused( | |
| 1044 render_frame_host_->render_view_host(), | |
| 1045 frame_tree_node_->IsMainFrame()); | |
| 1041 } | 1046 } |
| 1042 } | 1047 } |
| 1048 | |
| 1049 DCHECK(!speculative_render_frame_host_); | |
| 1043 } else { | 1050 } else { |
| 1044 // If the SiteInstance for the final URL doesn't match the one from the | 1051 // If the SiteInstance for the final URL doesn't match the one from the |
| 1045 // speculatively created RenderFrameHost, create a new RenderFrameHost using | 1052 // speculatively created RenderFrameHost, create a new RenderFrameHost using |
| 1046 // this new SiteInstance. | 1053 // this new SiteInstance. |
| 1047 if (!speculative_render_frame_host_ || | 1054 if (!speculative_render_frame_host_ || |
| 1048 speculative_render_frame_host_->GetSiteInstance() != | 1055 speculative_render_frame_host_->GetSiteInstance() != |
| 1049 dest_site_instance.get()) { | 1056 dest_site_instance.get()) { |
| 1057 // Creates a new speculative RenderFrameHost if the previous one didn't | |
| 1058 // exist or if its SiteInstace differs from the current one. | |
| 1050 CleanUpNavigation(); | 1059 CleanUpNavigation(); |
| 1051 bool success = CreateSpeculativeRenderFrameHost( | 1060 bool success = CreateSpeculativeRenderFrameHost(current_site_instance, |
| 1052 request.common_params().url, current_site_instance, | 1061 dest_site_instance.get()); |
| 1053 dest_site_instance.get(), request.bindings()); | |
| 1054 DCHECK(success); | 1062 DCHECK(success); |
| 1063 | |
| 1064 speculative_render_frame_host_->UpdateWebUI(request.common_params().url, | |
| 1065 request.bindings()); | |
| 1066 if (speculative_render_frame_host_->web_ui()) { | |
| 1067 speculative_render_frame_host_->web_ui()->RenderViewCreated( | |
| 1068 speculative_render_frame_host_->render_view_host()); | |
| 1069 } | |
| 1070 } else { | |
| 1071 // Reuses the previous speculative RenderFrameHost. | |
| 1072 bool changed_web_ui = speculative_render_frame_host_->UpdateWebUI( | |
| 1073 request.common_params().url, request.bindings()); | |
| 1074 if (changed_web_ui && speculative_render_frame_host_->web_ui()) { | |
| 1075 speculative_render_frame_host_->web_ui()->RenderViewCreated( | |
| 1076 speculative_render_frame_host_->render_view_host()); | |
| 1077 } | |
| 1055 } | 1078 } |
| 1056 DCHECK(speculative_render_frame_host_); | 1079 DCHECK(speculative_render_frame_host_); |
| 1080 DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui()); | |
| 1081 | |
| 1057 navigation_rfh = speculative_render_frame_host_.get(); | 1082 navigation_rfh = speculative_render_frame_host_.get(); |
| 1058 | 1083 |
| 1059 // Check if our current RFH is live. | 1084 // Check if our current RFH is live. |
| 1060 if (!render_frame_host_->IsRenderFrameLive()) { | 1085 if (!render_frame_host_->IsRenderFrameLive()) { |
| 1061 // The current RFH is not live. There's no reason to sit around with a | 1086 // 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 | 1087 // 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. | 1088 // 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 | 1089 // (Note that we don't care about on{before}unload handlers if the current |
| 1065 // RFH isn't live.) | 1090 // RFH isn't live.) |
| 1066 CommitPending(); | 1091 CommitPending(); |
| 1067 } | 1092 } |
| 1093 DCHECK(!current_web_ui_is_navigating_); | |
| 1068 } | 1094 } |
| 1069 DCHECK(navigation_rfh && | 1095 DCHECK(navigation_rfh && |
| 1070 (navigation_rfh == render_frame_host_.get() || | 1096 (navigation_rfh == render_frame_host_.get() || |
| 1071 navigation_rfh == speculative_render_frame_host_.get())); | 1097 navigation_rfh == speculative_render_frame_host_.get())); |
| 1072 | 1098 |
| 1073 // If the RenderFrame that needs to navigate is not live (its process was just | 1099 // If the RenderFrame that needs to navigate is not live (its process was just |
| 1074 // created or has crashed), initialize it. | 1100 // created or has crashed), initialize it. |
| 1075 if (!navigation_rfh->IsRenderFrameLive()) { | 1101 if (!navigation_rfh->IsRenderFrameLive()) { |
| 1076 // Recreate the opener chain. | 1102 // Recreate the opener chain. |
| 1077 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); | 1103 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); |
| 1078 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) { | 1104 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) |
| 1079 return nullptr; | 1105 return nullptr; |
| 1106 | |
| 1107 if (GetNavigatingWebUI()) { | |
| 1108 GetNavigatingWebUI()->RenderViewCreated( | |
| 1109 navigation_rfh->render_view_host()); | |
| 1080 } | 1110 } |
| 1081 | 1111 |
| 1082 if (navigation_rfh == render_frame_host_) { | 1112 if (navigation_rfh == render_frame_host_) { |
| 1083 // TODO(nasko): This is a very ugly hack. The Chrome extensions process | 1113 // TODO(nasko): This is a very ugly hack. The Chrome extensions process |
| 1084 // manager still uses NotificationService and expects to see a | 1114 // manager still uses NotificationService and expects to see a |
| 1085 // RenderViewHost changed notification after WebContents and | 1115 // RenderViewHost changed notification after WebContents and |
| 1086 // RenderFrameHostManager are completely initialized. This should be | 1116 // RenderFrameHostManager are completely initialized. This should be |
| 1087 // removed once the process manager moves away from NotificationService. | 1117 // removed once the process manager moves away from NotificationService. |
| 1088 // See https://crbug.com/462682. | 1118 // See https://crbug.com/462682. |
| 1089 delegate_->NotifyMainFrameSwappedFromRenderManager( | 1119 delegate_->NotifyMainFrameSwappedFromRenderManager( |
| 1090 nullptr, render_frame_host_->render_view_host()); | 1120 nullptr, render_frame_host_->render_view_host()); |
| 1091 } | 1121 } |
| 1092 } | 1122 } |
| 1093 | 1123 |
| 1094 return navigation_rfh; | 1124 return navigation_rfh; |
| 1095 } | 1125 } |
| 1096 | 1126 |
| 1097 // PlzNavigate | 1127 // PlzNavigate |
| 1098 void RenderFrameHostManager::CleanUpNavigation() { | 1128 void RenderFrameHostManager::CleanUpNavigation() { |
| 1099 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1129 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1100 switches::kEnableBrowserSideNavigation)); | 1130 switches::kEnableBrowserSideNavigation)); |
| 1101 speculative_web_ui_.reset(); | 1131 // TODO(carlosk): the discarding of the current RFH WebUI and the cleanup of |
| 1102 should_reuse_web_ui_ = false; | 1132 // the speculative RFH should not always happen together. |
| 1133 current_web_ui_is_navigating_ = false; | |
| 1103 if (speculative_render_frame_host_) | 1134 if (speculative_render_frame_host_) |
| 1104 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); | 1135 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); |
| 1105 } | 1136 } |
| 1106 | 1137 |
| 1107 // PlzNavigate | 1138 // PlzNavigate |
| 1108 scoped_ptr<RenderFrameHostImpl> | 1139 scoped_ptr<RenderFrameHostImpl> |
| 1109 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { | 1140 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { |
| 1110 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 1141 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1111 switches::kEnableBrowserSideNavigation)); | 1142 switches::kEnableBrowserSideNavigation)); |
| 1112 speculative_render_frame_host_->GetProcess()->RemovePendingView(); | 1143 speculative_render_frame_host_->GetProcess()->RemovePendingView(); |
| (...skipping 172 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 | 1316 // 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 | 1317 // without screwing up the session history sometimes (when navigating between |
| 1287 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat | 1318 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat |
| 1288 // it as a new navigation). So require a BrowsingInstance switch. | 1319 // it as a new navigation). So require a BrowsingInstance switch. |
| 1289 if (current_is_view_source_mode != new_is_view_source_mode) | 1320 if (current_is_view_source_mode != new_is_view_source_mode) |
| 1290 return true; | 1321 return true; |
| 1291 | 1322 |
| 1292 return false; | 1323 return false; |
| 1293 } | 1324 } |
| 1294 | 1325 |
| 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( | 1326 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( |
| 1308 const GURL& dest_url, | 1327 const GURL& dest_url, |
| 1309 SiteInstance* source_instance, | 1328 SiteInstance* source_instance, |
| 1310 SiteInstance* dest_instance, | 1329 SiteInstance* dest_instance, |
| 1311 SiteInstance* candidate_instance, | 1330 SiteInstance* candidate_instance, |
| 1312 ui::PageTransition transition, | 1331 ui::PageTransition transition, |
| 1313 bool dest_is_restore, | 1332 bool dest_is_restore, |
| 1314 bool dest_is_view_source_mode) { | 1333 bool dest_is_view_source_mode) { |
| 1315 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 1334 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 1316 | 1335 |
| (...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 | 1648 // 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 | 1649 // another host that already initialized it) or may not (we have our own |
| 1631 // process or the existing process crashed) have been initialized. Calling | 1650 // process or the existing process crashed) have been initialized. Calling |
| 1632 // Init multiple times will be ignored, so this is safe. | 1651 // Init multiple times will be ignored, so this is safe. |
| 1633 if (!new_instance->GetProcess()->Init()) | 1652 if (!new_instance->GetProcess()->Init()) |
| 1634 return; | 1653 return; |
| 1635 | 1654 |
| 1636 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1655 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
| 1637 | 1656 |
| 1638 // Create a non-swapped-out RFH with the given opener. | 1657 // Create a non-swapped-out RFH with the given opener. |
| 1639 pending_render_frame_host_ = CreateRenderFrame( | 1658 pending_render_frame_host_ = |
| 1640 new_instance, pending_web_ui(), create_render_frame_flags, nullptr); | 1659 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
| 1641 } | 1660 } |
| 1642 | 1661 |
| 1643 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( | 1662 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( |
| 1644 SiteInstance* old_instance, | 1663 SiteInstance* old_instance, |
| 1645 SiteInstance* new_instance) { | 1664 SiteInstance* new_instance) { |
| 1646 // Only create opener proxies if they are in the same BrowsingInstance. | 1665 // Only create opener proxies if they are in the same BrowsingInstance. |
| 1647 if (new_instance->IsRelatedSiteInstance(old_instance)) { | 1666 if (new_instance->IsRelatedSiteInstance(old_instance)) { |
| 1648 CreateOpenerProxies(new_instance, frame_tree_node_); | 1667 CreateOpenerProxies(new_instance, frame_tree_node_); |
| 1649 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { | 1668 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { |
| 1650 // Ensure that the frame tree has RenderFrameProxyHosts for the | 1669 // Ensure that the frame tree has RenderFrameProxyHosts for the |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1726 } | 1745 } |
| 1727 | 1746 |
| 1728 return RenderFrameHostFactory::Create( | 1747 return RenderFrameHostFactory::Create( |
| 1729 site_instance, render_view_host, render_frame_delegate_, | 1748 site_instance, render_view_host, render_frame_delegate_, |
| 1730 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, | 1749 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, |
| 1731 widget_routing_id, flags); | 1750 widget_routing_id, flags); |
| 1732 } | 1751 } |
| 1733 | 1752 |
| 1734 // PlzNavigate | 1753 // PlzNavigate |
| 1735 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( | 1754 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( |
| 1736 const GURL& url, | |
| 1737 SiteInstance* old_instance, | 1755 SiteInstance* old_instance, |
| 1738 SiteInstance* new_instance, | 1756 SiteInstance* new_instance) { |
| 1739 int bindings) { | |
| 1740 CHECK(new_instance); | 1757 CHECK(new_instance); |
| 1741 CHECK_NE(old_instance, new_instance); | 1758 CHECK_NE(old_instance, new_instance); |
| 1742 CHECK(!should_reuse_web_ui_); | 1759 CHECK(!current_web_ui_is_navigating_); |
| 1743 | |
| 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 | 1760 |
| 1749 // The process for the new SiteInstance may (if we're sharing a process with | 1761 // 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 | 1762 // another host that already initialized it) or may not (we have our own |
| 1751 // process or the existing process crashed) have been initialized. Calling | 1763 // process or the existing process crashed) have been initialized. Calling |
| 1752 // Init multiple times will be ignored, so this is safe. | 1764 // Init multiple times will be ignored, so this is safe. |
| 1753 if (!new_instance->GetProcess()->Init()) | 1765 if (!new_instance->GetProcess()->Init()) |
| 1754 return false; | 1766 return false; |
| 1755 | 1767 |
| 1756 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); | 1768 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); |
| 1757 | 1769 |
| 1758 int create_render_frame_flags = 0; | 1770 int create_render_frame_flags = 0; |
| 1759 if (delegate_->IsHidden()) | 1771 if (delegate_->IsHidden()) |
| 1760 create_render_frame_flags |= CREATE_RF_HIDDEN; | 1772 create_render_frame_flags |= CREATE_RF_HIDDEN; |
| 1761 speculative_render_frame_host_ = | 1773 speculative_render_frame_host_ = |
| 1762 CreateRenderFrame(new_instance, speculative_web_ui_.get(), | 1774 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr); |
| 1763 create_render_frame_flags, nullptr); | |
| 1764 | 1775 |
| 1765 if (!speculative_render_frame_host_) { | 1776 return !!speculative_render_frame_host_; |
| 1766 speculative_web_ui_.reset(); | |
| 1767 return false; | |
| 1768 } | |
| 1769 return true; | |
| 1770 } | 1777 } |
| 1771 | 1778 |
| 1772 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( | 1779 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( |
| 1773 SiteInstance* instance, | 1780 SiteInstance* instance, |
| 1774 WebUIImpl* web_ui, | |
| 1775 int flags, | 1781 int flags, |
| 1776 int* view_routing_id_ptr) { | 1782 int* view_routing_id_ptr) { |
| 1777 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); | 1783 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); |
| 1778 bool swapped_out_forbidden = | 1784 bool swapped_out_forbidden = |
| 1779 SiteIsolationPolicy::IsSwappedOutStateForbidden(); | 1785 SiteIsolationPolicy::IsSwappedOutStateForbidden(); |
| 1780 | 1786 |
| 1781 CHECK(instance); | 1787 CHECK(instance); |
| 1782 CHECK(!swapped_out_forbidden || !swapped_out); | 1788 CHECK(!swapped_out_forbidden || !swapped_out); |
| 1783 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible() || | 1789 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible() || |
| 1784 frame_tree_node_->IsMainFrame()); | 1790 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()); | 1888 success = InitRenderFrame(new_render_frame_host.get()); |
| 1883 } | 1889 } |
| 1884 } | 1890 } |
| 1885 | 1891 |
| 1886 if (success) { | 1892 if (success) { |
| 1887 if (view_routing_id_ptr) | 1893 if (view_routing_id_ptr) |
| 1888 *view_routing_id_ptr = render_view_host->GetRoutingID(); | 1894 *view_routing_id_ptr = render_view_host->GetRoutingID(); |
| 1889 } | 1895 } |
| 1890 } | 1896 } |
| 1891 | 1897 |
| 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. | 1898 // Returns the new RFH if it isn't swapped out. |
| 1908 if (success && !swapped_out) { | 1899 if (success && !swapped_out) { |
| 1909 DCHECK(new_render_frame_host->GetSiteInstance() == instance); | 1900 DCHECK(new_render_frame_host->GetSiteInstance() == instance); |
| 1910 return new_render_frame_host.Pass(); | 1901 return new_render_frame_host.Pass(); |
| 1911 } | 1902 } |
| 1912 return nullptr; | 1903 return nullptr; |
| 1913 } | 1904 } |
| 1914 | 1905 |
| 1915 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { | 1906 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { |
| 1916 // A RenderFrameProxyHost should never be created in the same SiteInstance as | 1907 // 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) { | 2006 RenderFrameProxyHost* proxy) { |
| 2016 // Ensure the renderer process is initialized before creating the | 2007 // Ensure the renderer process is initialized before creating the |
| 2017 // RenderView. | 2008 // RenderView. |
| 2018 if (!render_view_host->GetProcess()->Init()) | 2009 if (!render_view_host->GetProcess()->Init()) |
| 2019 return false; | 2010 return false; |
| 2020 | 2011 |
| 2021 // We may have initialized this RenderViewHost for another RenderFrameHost. | 2012 // We may have initialized this RenderViewHost for another RenderFrameHost. |
| 2022 if (render_view_host->IsRenderViewLive()) | 2013 if (render_view_host->IsRenderViewLive()) |
| 2023 return true; | 2014 return true; |
| 2024 | 2015 |
| 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 = | 2016 int opener_frame_routing_id = |
| 2051 GetOpenerRoutingID(render_view_host->GetSiteInstance()); | 2017 GetOpenerRoutingID(render_view_host->GetSiteInstance()); |
| 2052 | 2018 |
| 2053 bool created = delegate_->CreateRenderViewForRenderManager( | 2019 bool created = delegate_->CreateRenderViewForRenderManager( |
| 2054 render_view_host, opener_frame_routing_id, | 2020 render_view_host, opener_frame_routing_id, |
| 2055 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE, | 2021 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE, |
| 2056 frame_tree_node_->current_replication_state()); | 2022 frame_tree_node_->current_replication_state()); |
| 2057 | 2023 |
| 2058 if (created && proxy) | 2024 if (created && proxy) |
| 2059 proxy->set_render_frame_proxy_created(true); | 2025 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); | 2097 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); |
| 2132 if (proxy) | 2098 if (proxy) |
| 2133 return proxy->GetRoutingID(); | 2099 return proxy->GetRoutingID(); |
| 2134 | 2100 |
| 2135 return MSG_ROUTING_NONE; | 2101 return MSG_ROUTING_NONE; |
| 2136 } | 2102 } |
| 2137 | 2103 |
| 2138 void RenderFrameHostManager::CommitPending() { | 2104 void RenderFrameHostManager::CommitPending() { |
| 2139 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", | 2105 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", |
| 2140 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2106 "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 | 2107 // 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 | 2108 // 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 | 2109 // 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. | 2110 // this triggers won't be able to figure out what's going on. |
| 2149 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); | 2111 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); |
| 2150 | 2112 |
| 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_) { | 2113 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { |
| 2114 DCHECK_EQ(current_web_ui_is_navigating_, !!render_frame_host_->web_ui()); | |
| 2115 current_web_ui_is_navigating_ = false; | |
| 2116 // If there's no pending/speculative RenderFrameHost then the current | |
| 2117 // RenderFrameHost is committing. | |
| 2177 if (will_focus_location_bar) | 2118 if (will_focus_location_bar) |
| 2178 delegate_->SetFocusToLocationBar(false); | 2119 delegate_->SetFocusToLocationBar(false); |
| 2179 return; | 2120 return; |
| 2180 } | 2121 } |
| 2181 | 2122 |
| 2182 // Remember if the page was focused so we can focus the new renderer in | 2123 // Remember if the page was focused so we can focus the new renderer in |
| 2183 // that case. | 2124 // that case. |
| 2184 bool focus_render_view = !will_focus_location_bar && | 2125 bool focus_render_view = !will_focus_location_bar && |
| 2185 render_frame_host_->GetView() && | 2126 render_frame_host_->GetView() && |
| 2186 render_frame_host_->GetView()->HasFocus(); | 2127 render_frame_host_->GetView()->HasFocus(); |
| 2187 | 2128 |
| 2188 bool is_main_frame = frame_tree_node_->IsMainFrame(); | 2129 bool is_main_frame = frame_tree_node_->IsMainFrame(); |
| 2189 | 2130 |
| 2190 // Swap in the pending or speculative frame and make it active. Also ensure | 2131 // Swap in the pending or speculative frame and make it active. Also ensure |
| 2191 // the FrameTree stays in sync. | 2132 // the FrameTree stays in sync. |
| 2192 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; | 2133 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; |
| 2193 if (!browser_side_navigation) { | 2134 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 2135 switches::kEnableBrowserSideNavigation)) { | |
| 2194 DCHECK(!speculative_render_frame_host_); | 2136 DCHECK(!speculative_render_frame_host_); |
| 2195 old_render_frame_host = | 2137 old_render_frame_host = |
| 2196 SetRenderFrameHost(pending_render_frame_host_.Pass()); | 2138 SetRenderFrameHost(pending_render_frame_host_.Pass()); |
| 2197 } else { | 2139 } else { |
| 2198 // PlzNavigate | 2140 // PlzNavigate |
| 2199 DCHECK(speculative_render_frame_host_); | 2141 DCHECK(speculative_render_frame_host_); |
| 2200 old_render_frame_host = | 2142 old_render_frame_host = |
| 2201 SetRenderFrameHost(speculative_render_frame_host_.Pass()); | 2143 SetRenderFrameHost(speculative_render_frame_host_.Pass()); |
| 2202 } | 2144 } |
| 2203 | 2145 |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2353 // If we are currently navigating cross-process, we want to get back to normal | 2295 // If we are currently navigating cross-process, we want to get back to normal |
| 2354 // and then navigate as usual. | 2296 // and then navigate as usual. |
| 2355 if (pending_render_frame_host_) | 2297 if (pending_render_frame_host_) |
| 2356 CancelPending(); | 2298 CancelPending(); |
| 2357 | 2299 |
| 2358 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); | 2300 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); |
| 2359 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( | 2301 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( |
| 2360 dest_url, source_instance, dest_instance, nullptr, transition, | 2302 dest_url, source_instance, dest_instance, nullptr, transition, |
| 2361 dest_is_restore, dest_is_view_source_mode); | 2303 dest_is_restore, dest_is_view_source_mode); |
| 2362 | 2304 |
| 2363 const NavigationEntry* current_entry = | |
| 2364 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
| 2365 | |
| 2366 DCHECK(!pending_render_frame_host_); | 2305 DCHECK(!pending_render_frame_host_); |
| 2367 | 2306 |
| 2368 if (new_instance.get() != current_instance) { | 2307 if (new_instance.get() != current_instance) { |
| 2369 TRACE_EVENT_INSTANT2( | 2308 TRACE_EVENT_INSTANT2( |
| 2370 "navigation", | 2309 "navigation", |
| 2371 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", | 2310 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", |
| 2372 TRACE_EVENT_SCOPE_THREAD, | 2311 TRACE_EVENT_SCOPE_THREAD, |
| 2373 "current_instance id", current_instance->GetId(), | 2312 "current_instance id", current_instance->GetId(), |
| 2374 "new_instance id", new_instance->GetId()); | 2313 "new_instance id", new_instance->GetId()); |
| 2375 | 2314 |
| 2376 // New SiteInstance: create a pending RFH to navigate. | 2315 // New SiteInstance: create a pending RFH to navigate. |
| 2377 | 2316 |
| 2378 // This will possibly create (set to nullptr) a Web UI object for the | 2317 current_web_ui_is_navigating_ = false; |
| 2379 // pending page. We'll use this later to give the page special access. This | |
| 2380 // must happen before the new renderer is created below so it will get | |
| 2381 // bindings. It must also happen after the above conditional call to | |
| 2382 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_ | |
| 2383 // and the page will not have its bindings set appropriately. | |
| 2384 SetPendingWebUI(dest_url, bindings); | |
| 2385 CreatePendingRenderFrameHost(current_instance, new_instance.get()); | 2318 CreatePendingRenderFrameHost(current_instance, new_instance.get()); |
| 2386 if (!pending_render_frame_host_) | 2319 if (!pending_render_frame_host_) |
| 2387 return nullptr; | 2320 return nullptr; |
| 2388 | 2321 |
| 2322 pending_render_frame_host_->UpdateWebUI(dest_url, bindings); | |
| 2323 if (pending_render_frame_host_->web_ui()) { | |
| 2324 pending_render_frame_host_->web_ui()->RenderViewCreated( | |
| 2325 pending_render_frame_host_->render_view_host()); | |
| 2326 } | |
| 2327 | |
| 2328 // We now have a pending RFH and possibly an associated pending WebUI. | |
| 2329 DCHECK(pending_render_frame_host_); | |
|
nasko
2015/11/02 17:00:36
This DCHECK is redundant. The call to UpdateWebUI
carlosk
2015/11/03 09:50:30
I moved this up where it matters.
| |
| 2330 DCHECK_EQ(GetNavigatingWebUI(), pending_render_frame_host_->web_ui()); | |
| 2331 | |
| 2389 // Check if our current RFH is live before we set up a transition. | 2332 // Check if our current RFH is live before we set up a transition. |
| 2390 if (!render_frame_host_->IsRenderFrameLive()) { | 2333 if (!render_frame_host_->IsRenderFrameLive()) { |
| 2391 // The current RFH is not live. There's no reason to sit around with a | 2334 // The current RFH is not live. There's no reason to sit around with a |
| 2392 // sad tab or a newly created RFH while we wait for the pending RFH to | 2335 // sad tab or a newly created RFH while we wait for the pending RFH to |
| 2393 // navigate. Just switch to the pending RFH now and go back to normal. | 2336 // navigate. Just switch to the pending RFH now and go back to normal. |
| 2394 // (Note that we don't care about on{before}unload handlers if the current | 2337 // (Note that we don't care about on{before}unload handlers if the current |
| 2395 // RFH isn't live.) | 2338 // RFH isn't live.) |
| 2396 CommitPending(); | 2339 CommitPending(); |
| 2397 return render_frame_host_.get(); | 2340 return render_frame_host_.get(); |
| 2398 } | 2341 } |
| 2399 // Otherwise, it's safe to treat this as a pending cross-process transition. | 2342 // Otherwise, it's safe to treat this as a pending cross-process transition. |
| 2400 | 2343 |
| 2401 // We now have a pending RFH. | |
| 2402 DCHECK(pending_render_frame_host_); | |
| 2403 | |
| 2404 // We need to wait until the beforeunload handler has run, unless we are | 2344 // We need to wait until the beforeunload handler has run, unless we are |
| 2405 // transferring an existing request (in which case it has already run). | 2345 // transferring an existing request (in which case it has already run). |
| 2406 // Suspend the new render view (i.e., don't let it send the cross-process | 2346 // Suspend the new render view (i.e., don't let it send the cross-process |
| 2407 // Navigate message) until we hear back from the old renderer's | 2347 // Navigate message) until we hear back from the old renderer's |
| 2408 // beforeunload handler. If the handler returns false, we'll have to | 2348 // beforeunload handler. If the handler returns false, we'll have to |
| 2409 // cancel the request. | 2349 // cancel the request. |
| 2410 // | |
| 2411 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); | 2350 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); |
| 2412 bool is_transfer = transferred_request_id != GlobalRequestID(); | 2351 bool is_transfer = transferred_request_id != GlobalRequestID(); |
| 2413 if (is_transfer) { | 2352 if (is_transfer) { |
| 2414 // We don't need to stop the old renderer or run beforeunload/unload | 2353 // We don't need to stop the old renderer or run beforeunload/unload |
| 2415 // handlers, because those have already been done. | 2354 // handlers, because those have already been done. |
| 2416 DCHECK(cross_site_transferring_request_->request_id() == | 2355 DCHECK(cross_site_transferring_request_->request_id() == |
| 2417 transferred_request_id); | 2356 transferred_request_id); |
| 2418 } else { | 2357 } else { |
| 2419 // Also make sure the old render view stops, in case a load is in | 2358 // Also make sure the old render view stops, in case a load is in |
| 2420 // progress. (We don't want to do this for transfers, since it will | 2359 // progress. (We don't want to do this for transfers, since it will |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 2435 | 2374 |
| 2436 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. | 2375 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. |
| 2437 | 2376 |
| 2438 // It's possible to swap out the current RFH and then decide to navigate in it | 2377 // It's possible to swap out the current RFH and then decide to navigate in it |
| 2439 // anyway (e.g., a cross-process navigation that redirects back to the | 2378 // anyway (e.g., a cross-process navigation that redirects back to the |
| 2440 // original site). In that case, we have a proxy for the current RFH but | 2379 // original site). In that case, we have a proxy for the current RFH but |
| 2441 // haven't deleted it yet. The new navigation will swap it back in, so we can | 2380 // haven't deleted it yet. The new navigation will swap it back in, so we can |
| 2442 // delete the proxy. | 2381 // delete the proxy. |
| 2443 proxy_hosts_->Remove(new_instance.get()->GetId()); | 2382 proxy_hosts_->Remove(new_instance.get()->GetId()); |
| 2444 | 2383 |
| 2445 if (ShouldReuseWebUI(current_entry, dest_url)) { | 2384 WebUI::TypeID previous_web_ui_type = render_frame_host_->web_ui_type(); |
| 2446 pending_web_ui_.reset(); | 2385 bool changed_web_ui = render_frame_host_->UpdateWebUI(dest_url, bindings); |
| 2447 pending_and_current_web_ui_ = web_ui_->AsWeakPtr(); | 2386 |
| 2448 } else { | 2387 // If a change in WebUI happened, check this is an acceptable case. |
| 2449 SetPendingWebUI(dest_url, bindings); | 2388 DCHECK(!changed_web_ui || |
| 2450 // Make sure the new RenderViewHost has the right bindings. | 2389 IsAcceptableWebUITransition(previous_web_ui_type, dest_url, |
| 2451 if (pending_web_ui() && | 2390 dest_is_restore)); |
| 2452 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { | 2391 |
| 2453 render_frame_host_->render_view_host()->AllowBindings( | 2392 // If there is a WebUI in the current RenderFrameHost, it will navigate. |
| 2454 pending_web_ui()->GetBindings()); | 2393 current_web_ui_is_navigating_ = !!render_frame_host_->web_ui(); |
| 2394 DCHECK_EQ(GetNavigatingWebUI(), render_frame_host_->web_ui()); | |
| 2395 | |
| 2396 // If the current RenderFrameHost has a WebUI and the associated RenderFrame | |
| 2397 // is alive, notify to the WebUI that the RenderView is being created or | |
| 2398 // reused depending on whether the WebUI was changed or not. | |
| 2399 if (GetNavigatingWebUI() && render_frame_host_->IsRenderFrameLive()) { | |
| 2400 if (changed_web_ui) { | |
| 2401 GetNavigatingWebUI()->RenderViewCreated( | |
| 2402 render_frame_host_->render_view_host()); | |
| 2403 } else { | |
| 2404 GetNavigatingWebUI()->RenderViewReused( | |
| 2405 render_frame_host_->render_view_host(), | |
| 2406 frame_tree_node_->IsMainFrame()); | |
| 2455 } | 2407 } |
| 2456 } | 2408 } |
| 2457 | 2409 |
| 2458 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { | |
| 2459 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), | |
| 2460 frame_tree_node_->IsMainFrame()); | |
| 2461 } | |
| 2462 | |
| 2463 // The renderer can exit view source mode when any error or cancellation | 2410 // The renderer can exit view source mode when any error or cancellation |
| 2464 // happen. We must overwrite to recover the mode. | 2411 // happen. We must overwrite to recover the mode. |
| 2465 if (dest_is_view_source_mode) { | 2412 if (dest_is_view_source_mode) { |
| 2466 render_frame_host_->render_view_host()->Send( | 2413 render_frame_host_->render_view_host()->Send( |
| 2467 new ViewMsg_EnableViewSourceMode( | 2414 new ViewMsg_EnableViewSourceMode( |
| 2468 render_frame_host_->render_view_host()->GetRoutingID())); | 2415 render_frame_host_->render_view_host()->GetRoutingID())); |
| 2469 } | 2416 } |
| 2470 | 2417 |
| 2471 return render_frame_host_.get(); | 2418 return render_frame_host_.get(); |
| 2472 } | 2419 } |
| 2473 | 2420 |
| 2474 void RenderFrameHostManager::CancelPending() { | 2421 void RenderFrameHostManager::CancelPending() { |
| 2475 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", | 2422 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", |
| 2476 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); | 2423 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); |
| 2424 current_web_ui_is_navigating_ = false; | |
| 2477 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); | 2425 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); |
| 2478 } | 2426 } |
| 2479 | 2427 |
| 2480 scoped_ptr<RenderFrameHostImpl> | 2428 scoped_ptr<RenderFrameHostImpl> |
| 2481 RenderFrameHostManager::UnsetPendingRenderFrameHost() { | 2429 RenderFrameHostManager::UnsetPendingRenderFrameHost() { |
| 2482 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = | 2430 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = |
| 2483 pending_render_frame_host_.Pass(); | 2431 pending_render_frame_host_.Pass(); |
| 2484 | 2432 |
| 2485 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( | 2433 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( |
| 2486 pending_render_frame_host.get(), | 2434 pending_render_frame_host.get(), |
| 2487 render_frame_host_.get()); | 2435 render_frame_host_.get()); |
| 2488 | 2436 |
| 2437 current_web_ui_is_navigating_ = false; | |
| 2438 | |
| 2489 // We no longer need to prevent the process from exiting. | 2439 // We no longer need to prevent the process from exiting. |
| 2490 pending_render_frame_host->GetProcess()->RemovePendingView(); | 2440 pending_render_frame_host->GetProcess()->RemovePendingView(); |
| 2491 | 2441 |
| 2492 pending_web_ui_.reset(); | |
| 2493 pending_and_current_web_ui_.reset(); | |
| 2494 | |
| 2495 return pending_render_frame_host.Pass(); | 2442 return pending_render_frame_host.Pass(); |
| 2496 } | 2443 } |
| 2497 | 2444 |
| 2498 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( | 2445 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( |
| 2499 scoped_ptr<RenderFrameHostImpl> render_frame_host) { | 2446 scoped_ptr<RenderFrameHostImpl> render_frame_host) { |
| 2500 // Swap the two. | 2447 // Swap the two. |
| 2501 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = | 2448 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = |
| 2502 render_frame_host_.Pass(); | 2449 render_frame_host_.Pass(); |
| 2503 render_frame_host_ = render_frame_host.Pass(); | 2450 render_frame_host_ = render_frame_host.Pass(); |
| 2504 | 2451 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2659 if (rvh && !rvh->IsRenderViewLive()) { | 2606 if (rvh && !rvh->IsRenderViewLive()) { |
| 2660 EnsureRenderViewInitialized(rvh, instance); | 2607 EnsureRenderViewInitialized(rvh, instance); |
| 2661 } else { | 2608 } else { |
| 2662 // Create a swapped out RenderView in the given SiteInstance if none | 2609 // Create a swapped out RenderView in the given SiteInstance if none |
| 2663 // exists. Since an opener can point to a subframe, do this on the root | 2610 // exists. Since an opener can point to a subframe, do this on the root |
| 2664 // frame of the current opener's frame tree. | 2611 // frame of the current opener's frame tree. |
| 2665 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { | 2612 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { |
| 2666 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); | 2613 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); |
| 2667 } else { | 2614 } else { |
| 2668 frame_tree->root()->render_manager()->CreateRenderFrame( | 2615 frame_tree->root()->render_manager()->CreateRenderFrame( |
| 2669 instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, | 2616 instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr); |
| 2670 nullptr); | |
| 2671 } | 2617 } |
| 2672 } | 2618 } |
| 2673 } | 2619 } |
| 2674 } | 2620 } |
| 2675 | 2621 |
| 2676 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { | 2622 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { |
| 2677 if (!frame_tree_node_->opener()) | 2623 if (!frame_tree_node_->opener()) |
| 2678 return MSG_ROUTING_NONE; | 2624 return MSG_ROUTING_NONE; |
| 2679 | 2625 |
| 2680 return frame_tree_node_->opener() | 2626 return frame_tree_node_->opener() |
| 2681 ->render_manager() | 2627 ->render_manager() |
| 2682 ->GetRoutingIdForSiteInstance(instance); | 2628 ->GetRoutingIdForSiteInstance(instance); |
| 2683 } | 2629 } |
| 2684 | 2630 |
| 2631 bool RenderFrameHostManager::IsAcceptableWebUITransition( | |
| 2632 WebUI::TypeID previous_web_ui_type, | |
| 2633 const GURL& dest_url, | |
| 2634 bool dest_is_restore) { | |
| 2635 // There are a few navigation cases that allow for changes to the WebUI of | |
| 2636 // the current RenderFrameHost. | |
| 2637 BrowserContext* browser_context = | |
| 2638 delegate_->GetControllerForRenderManager().GetBrowserContext(); | |
| 2639 if (render_frame_host_->web_ui()) { | |
| 2640 // Switching WebUI from one type to another is never acceptable. | |
| 2641 DCHECK(previous_web_ui_type == WebUI::kNoWebUI); | |
| 2642 | |
| 2643 // Going from not having to having a WebUI is acceptable for: | |
| 2644 // - The first navigation of this frame. | |
| 2645 const NavigationEntry* current_entry = | |
| 2646 delegate_->GetLastCommittedNavigationEntryForRenderManager(); | |
| 2647 bool is_first_navigation_for_frame = !current_entry; | |
| 2648 // - A restore navigation to a WebUI URL. | |
| 2649 const GURL& current_effective_url = | |
| 2650 current_entry ? SiteInstanceImpl::GetEffectiveURL( | |
| 2651 browser_context, current_entry->GetURL()) | |
| 2652 : render_frame_host_->GetSiteInstance()->GetSiteURL(); | |
| 2653 bool is_webui_restore = | |
| 2654 dest_is_restore && | |
| 2655 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( | |
| 2656 browser_context, current_effective_url); | |
| 2657 // - Navigating back from a special renderer controlled URL. | |
| 2658 bool is_back_from_renderer_url = | |
| 2659 current_entry && IsRendererDebugURL(current_entry->GetURL()); | |
| 2660 // - Navigating in webview tag guest. | |
| 2661 bool is_webview_tag_guest = | |
| 2662 render_frame_host_->GetSiteInstance()->GetSiteURL().SchemeIs( | |
| 2663 kGuestScheme); | |
| 2664 DCHECK(is_first_navigation_for_frame || is_webui_restore || | |
| 2665 is_back_from_renderer_url || is_webview_tag_guest); | |
| 2666 } else { | |
| 2667 // Going from having to not having a WebUI is acceptable for: | |
| 2668 // - Navigating to a special, renderer controlled URL. | |
| 2669 DCHECK(IsRendererDebugURL( | |
| 2670 SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url))); | |
| 2671 } | |
| 2672 return true; | |
| 2673 } | |
| 2674 | |
| 2685 } // namespace content | 2675 } // namespace content |
| OLD | NEW |