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

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

Powered by Google App Engine
This is Rietveld 408576698