Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

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

Powered by Google App Engine
This is Rietveld 408576698