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

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: Minor fixes and changes from CR comments. 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 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 (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) {
nasko 2015/10/20 01:13:21 Doesn't this depend on whether we had a different
carlosk 2015/10/20 12:58:51 That's exactly what I'm proposing as an error and
1039 !render_frame_host_->GetProcess()->IsForGuestsOnly()) { 1015 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(),
1040 render_frame_host_->render_view_host()->AllowBindings( 1016 frame_tree_node_->IsMainFrame());
1041 speculative_web_ui()->GetBindings());
1042 }
1043 } 1017 }
1018
1019 DCHECK(!speculative_render_frame_host_);
1044 } else { 1020 } else {
1045 // If the SiteInstance for the final URL doesn't match the one from the 1021 // If the SiteInstance for the final URL doesn't match the one from the
1046 // speculatively created RenderFrameHost, create a new RenderFrameHost using 1022 // speculatively created RenderFrameHost, create a new RenderFrameHost using
1047 // this new SiteInstance. 1023 // this new SiteInstance.
1048 if (!speculative_render_frame_host_ || 1024 if (!speculative_render_frame_host_ ||
1049 speculative_render_frame_host_->GetSiteInstance() != 1025 speculative_render_frame_host_->GetSiteInstance() !=
1050 dest_site_instance.get()) { 1026 dest_site_instance.get()) {
1051 CleanUpNavigation(); 1027 CleanUpNavigation();
1052 bool success = CreateSpeculativeRenderFrameHost( 1028 bool success = CreateSpeculativeRenderFrameHost(current_site_instance,
1053 request.common_params().url, current_site_instance, 1029 dest_site_instance.get());
1054 dest_site_instance.get(), request.bindings());
1055 DCHECK(success); 1030 DCHECK(success);
1031
1032 InitializeWebUI(request.common_params().url, request.bindings());
1033 } else {
1034 // When reusing an existing speculative RenderFrameHost its *active* WebUI
1035 // must be updated to make sure it matches the current URL.
nasko 2015/10/20 01:13:22 Why does it have to be committed? It isn't immedia
carlosk 2015/10/20 12:58:51 Because as described in the design doc [1], the pe
1036 speculative_render_frame_host_->UpdatePendingWebUI(
1037 request.common_params().url, request.bindings());
1038 speculative_render_frame_host_->CommitPendingWebUI();
1056 } 1039 }
1057 DCHECK(speculative_render_frame_host_); 1040 DCHECK(speculative_render_frame_host_);
1041 DCHECK_EQ(speculative_web_ui(), speculative_render_frame_host_->web_ui());
1042 DCHECK(!speculative_render_frame_host_->pending_web_ui());
1043 DCHECK(!render_frame_host_->pending_web_ui());
1044
1058 navigation_rfh = speculative_render_frame_host_.get(); 1045 navigation_rfh = speculative_render_frame_host_.get();
1059 1046
1060 // Check if our current RFH is live. 1047 // Check if our current RFH is live.
1061 if (!render_frame_host_->IsRenderFrameLive()) { 1048 if (!render_frame_host_->IsRenderFrameLive()) {
1062 // The current RFH is not live. There's no reason to sit around with a 1049 // 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 1050 // 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. 1051 // 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 1052 // (Note that we don't care about on{before}unload handlers if the current
1066 // RFH isn't live.) 1053 // RFH isn't live.)
1067 CommitPending(); 1054 CommitPending();
1068 } 1055 }
1069 } 1056 }
1070 DCHECK(navigation_rfh && 1057 DCHECK(navigation_rfh &&
1071 (navigation_rfh == render_frame_host_.get() || 1058 (navigation_rfh == render_frame_host_.get() ||
1072 navigation_rfh == speculative_render_frame_host_.get())); 1059 navigation_rfh == speculative_render_frame_host_.get()));
1073 1060
1074 // If the RenderFrame that needs to navigate is not live (its process was just 1061 // If the RenderFrame that needs to navigate is not live (its process was just
1075 // created or has crashed), initialize it. 1062 // created or has crashed), initialize it.
1076 if (!navigation_rfh->IsRenderFrameLive()) { 1063 if (!navigation_rfh->IsRenderFrameLive()) {
1077 // Recreate the opener chain. 1064 // Recreate the opener chain.
1078 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); 1065 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_);
1079 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) { 1066 if (!InitRenderView(navigation_rfh->render_view_host(), nullptr))
1080 return nullptr; 1067 return nullptr;
1068
1069 if (speculative_web_ui()) {
1070 speculative_web_ui()->RenderViewCreated(
1071 navigation_rfh->render_view_host());
1081 } 1072 }
1082 1073
1083 if (navigation_rfh == render_frame_host_) { 1074 if (navigation_rfh == render_frame_host_) {
1084 // TODO(nasko): This is a very ugly hack. The Chrome extensions process 1075 // TODO(nasko): This is a very ugly hack. The Chrome extensions process
1085 // manager still uses NotificationService and expects to see a 1076 // manager still uses NotificationService and expects to see a
1086 // RenderViewHost changed notification after WebContents and 1077 // RenderViewHost changed notification after WebContents and
1087 // RenderFrameHostManager are completely initialized. This should be 1078 // RenderFrameHostManager are completely initialized. This should be
1088 // removed once the process manager moves away from NotificationService. 1079 // removed once the process manager moves away from NotificationService.
1089 // See https://crbug.com/462682. 1080 // See https://crbug.com/462682.
1090 delegate_->NotifyMainFrameSwappedFromRenderManager( 1081 delegate_->NotifyMainFrameSwappedFromRenderManager(
1091 nullptr, render_frame_host_->render_view_host()); 1082 nullptr, render_frame_host_->render_view_host());
1092 } 1083 }
1093 } 1084 }
1094 1085
1095 return navigation_rfh; 1086 return navigation_rfh;
1096 } 1087 }
1097 1088
1098 // PlzNavigate 1089 // PlzNavigate
1099 void RenderFrameHostManager::CleanUpNavigation() { 1090 void RenderFrameHostManager::CleanUpNavigation() {
1100 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 1091 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
1101 switches::kEnableBrowserSideNavigation)); 1092 switches::kEnableBrowserSideNavigation));
1102 speculative_web_ui_.reset(); 1093 render_frame_host_->DiscardPendingWebUI();
1103 should_reuse_web_ui_ = false;
1104 if (speculative_render_frame_host_) 1094 if (speculative_render_frame_host_)
1105 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); 1095 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
1106 } 1096 }
1107 1097
1108 // PlzNavigate 1098 // PlzNavigate
1109 scoped_ptr<RenderFrameHostImpl> 1099 scoped_ptr<RenderFrameHostImpl>
1110 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { 1100 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() {
1111 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 1101 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
1112 switches::kEnableBrowserSideNavigation)); 1102 switches::kEnableBrowserSideNavigation));
1113 speculative_render_frame_host_->GetProcess()->RemovePendingView(); 1103 speculative_render_frame_host_->GetProcess()->RemovePendingView();
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 // We can't switch a RenderView between view source and non-view source mode 1267 // We can't switch a RenderView between view source and non-view source mode
1278 // without screwing up the session history sometimes (when navigating between 1268 // without screwing up the session history sometimes (when navigating between
1279 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat 1269 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat
1280 // it as a new navigation). So require a BrowsingInstance switch. 1270 // it as a new navigation). So require a BrowsingInstance switch.
1281 if (current_is_view_source_mode != new_is_view_source_mode) 1271 if (current_is_view_source_mode != new_is_view_source_mode)
1282 return true; 1272 return true;
1283 1273
1284 return false; 1274 return false;
1285 } 1275 }
1286 1276
1287 bool RenderFrameHostManager::ShouldReuseWebUI(
1288 const NavigationEntry* current_entry,
1289 const GURL& new_url) const {
1290 NavigationControllerImpl& controller =
1291 delegate_->GetControllerForRenderManager();
1292 return current_entry && web_ui_ &&
1293 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
1294 controller.GetBrowserContext(), current_entry->GetURL()) ==
1295 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
1296 controller.GetBrowserContext(), new_url));
1297 }
1298
1299 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( 1277 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
1300 const GURL& dest_url, 1278 const GURL& dest_url,
1301 SiteInstance* source_instance, 1279 SiteInstance* source_instance,
1302 SiteInstance* dest_instance, 1280 SiteInstance* dest_instance,
1303 SiteInstance* candidate_instance, 1281 SiteInstance* candidate_instance,
1304 ui::PageTransition transition, 1282 ui::PageTransition transition,
1305 bool dest_is_restore, 1283 bool dest_is_restore,
1306 bool dest_is_view_source_mode) { 1284 bool dest_is_view_source_mode) {
1307 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1285 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1308 1286
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 // The process for the new SiteInstance may (if we're sharing a process with 1599 // The process for the new SiteInstance may (if we're sharing a process with
1622 // another host that already initialized it) or may not (we have our own 1600 // another host that already initialized it) or may not (we have our own
1623 // process or the existing process crashed) have been initialized. Calling 1601 // process or the existing process crashed) have been initialized. Calling
1624 // Init multiple times will be ignored, so this is safe. 1602 // Init multiple times will be ignored, so this is safe.
1625 if (!new_instance->GetProcess()->Init()) 1603 if (!new_instance->GetProcess()->Init())
1626 return; 1604 return;
1627 1605
1628 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); 1606 CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
1629 1607
1630 // Create a non-swapped-out RFH with the given opener. 1608 // Create a non-swapped-out RFH with the given opener.
1631 pending_render_frame_host_ = CreateRenderFrame( 1609 pending_render_frame_host_ =
1632 new_instance, pending_web_ui(), create_render_frame_flags, nullptr); 1610 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
1633 } 1611 }
1634 1612
1635 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( 1613 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
1636 SiteInstance* old_instance, 1614 SiteInstance* old_instance,
1637 SiteInstance* new_instance) { 1615 SiteInstance* new_instance) {
1638 // Only create opener proxies if they are in the same BrowsingInstance. 1616 // Only create opener proxies if they are in the same BrowsingInstance.
1639 if (new_instance->IsRelatedSiteInstance(old_instance)) { 1617 if (new_instance->IsRelatedSiteInstance(old_instance)) {
1640 CreateOpenerProxies(new_instance, frame_tree_node_); 1618 CreateOpenerProxies(new_instance, frame_tree_node_);
1641 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { 1619 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
1642 // Ensure that the frame tree has RenderFrameProxyHosts for the 1620 // Ensure that the frame tree has RenderFrameProxyHosts for the
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 } 1682 }
1705 1683
1706 return RenderFrameHostFactory::Create( 1684 return RenderFrameHostFactory::Create(
1707 site_instance, render_view_host, render_frame_delegate_, 1685 site_instance, render_view_host, render_frame_delegate_,
1708 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id, 1686 render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id,
1709 widget_routing_id, flags); 1687 widget_routing_id, flags);
1710 } 1688 }
1711 1689
1712 // PlzNavigate 1690 // PlzNavigate
1713 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( 1691 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
1714 const GURL& url,
1715 SiteInstance* old_instance, 1692 SiteInstance* old_instance,
1716 SiteInstance* new_instance, 1693 SiteInstance* new_instance) {
1717 int bindings) {
1718 CHECK(new_instance); 1694 CHECK(new_instance);
1719 CHECK_NE(old_instance, new_instance); 1695 CHECK_NE(old_instance, new_instance);
1720 CHECK(!should_reuse_web_ui_);
1721
1722 // Note: |speculative_web_ui_| must be initialized before starting the
1723 // |speculative_render_frame_host_| creation steps otherwise the WebUI
1724 // won't be properly initialized.
1725 speculative_web_ui_ = CreateWebUI(url, bindings);
1726 1696
1727 // The process for the new SiteInstance may (if we're sharing a process with 1697 // The process for the new SiteInstance may (if we're sharing a process with
1728 // another host that already initialized it) or may not (we have our own 1698 // another host that already initialized it) or may not (we have our own
1729 // process or the existing process crashed) have been initialized. Calling 1699 // process or the existing process crashed) have been initialized. Calling
1730 // Init multiple times will be ignored, so this is safe. 1700 // Init multiple times will be ignored, so this is safe.
1731 if (!new_instance->GetProcess()->Init()) 1701 if (!new_instance->GetProcess()->Init())
1732 return false; 1702 return false;
1733 1703
1734 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); 1704 CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
1735 1705
1736 int create_render_frame_flags = 0; 1706 int create_render_frame_flags = 0;
1737 if (delegate_->IsHidden()) 1707 if (delegate_->IsHidden())
1738 create_render_frame_flags |= CREATE_RF_HIDDEN; 1708 create_render_frame_flags |= CREATE_RF_HIDDEN;
1739 speculative_render_frame_host_ = 1709 speculative_render_frame_host_ =
1740 CreateRenderFrame(new_instance, speculative_web_ui_.get(), 1710 CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
1741 create_render_frame_flags, nullptr);
1742 1711
1743 if (!speculative_render_frame_host_) { 1712 return !!speculative_render_frame_host_;
1744 speculative_web_ui_.reset(); 1713 }
1745 return false; 1714
1715 void RenderFrameHostManager::InitializeWebUI(const GURL& url, int bindings) {
1716 RenderFrameHostImpl* rfh;
1717 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1718 switches::kEnableBrowserSideNavigation)) {
1719 rfh = speculative_render_frame_host_.get();
1720 } else {
1721 rfh = pending_render_frame_host_.get();
1746 } 1722 }
1747 return true; 1723
1724 CHECK(rfh);
nasko 2015/10/20 01:13:22 DCHECK
carlosk 2015/10/20 12:58:51 Done.
1725 rfh->UpdatePendingWebUI(url, bindings);
1726 rfh->CommitPendingWebUI();
1727 RenderViewHostImpl* rvh = rfh->render_view_host();
1728
1729 if (rfh->web_ui())
1730 rfh->web_ui()->RenderViewCreated(rvh);
1731
1732 // If the ongoing navigation is not to a WebUI or the RenderView is in a
1733 // guest process, ensure that we don't create an unprivileged RenderView in a
1734 // WebUI-enabled process unless it's swapped out.
1735 if ((!rfh->web_ui() || rvh->GetProcess()->IsForGuestsOnly()) &&
1736 rvh->is_active()) {
1737 bool url_acceptable_for_webui =
1738 WebUIControllerFactoryRegistry::GetInstance()->IsURLAcceptableForWebUI(
1739 delegate_->GetControllerForRenderManager().GetBrowserContext(),
1740 url);
1741 if (!url_acceptable_for_webui) {
1742 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1743 rvh->GetProcess()->GetID()));
1744 }
1745 }
1748 } 1746 }
1749 1747
1750 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( 1748 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
1751 SiteInstance* instance, 1749 SiteInstance* instance,
1752 WebUIImpl* web_ui,
1753 int flags, 1750 int flags,
1754 int* view_routing_id_ptr) { 1751 int* view_routing_id_ptr) {
1755 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1752 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
1756 bool swapped_out_forbidden = 1753 bool swapped_out_forbidden =
1757 SiteIsolationPolicy::IsSwappedOutStateForbidden(); 1754 SiteIsolationPolicy::IsSwappedOutStateForbidden();
1758 1755
1759 CHECK(instance); 1756 CHECK(instance);
1760 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out); 1757 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out);
1761 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(), 1758 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(),
1762 frame_tree_node_->IsMainFrame()); 1759 frame_tree_node_->IsMainFrame());
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 success = InitRenderFrame(new_render_frame_host.get()); 1856 success = InitRenderFrame(new_render_frame_host.get());
1860 } 1857 }
1861 } 1858 }
1862 1859
1863 if (success) { 1860 if (success) {
1864 if (view_routing_id_ptr) 1861 if (view_routing_id_ptr)
1865 *view_routing_id_ptr = render_view_host->GetRoutingID(); 1862 *view_routing_id_ptr = render_view_host->GetRoutingID();
1866 } 1863 }
1867 } 1864 }
1868 1865
1869 // When a new RenderView is created by the renderer process, the new
1870 // WebContents gets a RenderViewHost in the SiteInstance of its opener
1871 // WebContents. If not used in the first navigation, this RVH is swapped out
1872 // and is not granted bindings, so we may need to grant them when swapping it
1873 // in.
1874 if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) {
1875 int required_bindings = web_ui->GetBindings();
1876 RenderViewHost* render_view_host =
1877 new_render_frame_host->render_view_host();
1878 if ((render_view_host->GetEnabledBindings() & required_bindings) !=
1879 required_bindings) {
1880 render_view_host->AllowBindings(required_bindings);
1881 }
1882 }
1883
1884 // Returns the new RFH if it isn't swapped out. 1866 // Returns the new RFH if it isn't swapped out.
1885 if (success && !swapped_out) { 1867 if (success && !swapped_out) {
1886 DCHECK(new_render_frame_host->GetSiteInstance() == instance); 1868 DCHECK(new_render_frame_host->GetSiteInstance() == instance);
1869 DCHECK(new_render_frame_host->render_view_host()->IsRenderViewLive());
1887 return new_render_frame_host.Pass(); 1870 return new_render_frame_host.Pass();
1888 } 1871 }
1889 return nullptr; 1872 return nullptr;
1890 } 1873 }
1891 1874
1892 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { 1875 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
1893 // A RenderFrameProxyHost should never be created in the same SiteInstance as 1876 // A RenderFrameProxyHost should never be created in the same SiteInstance as
1894 // the current RFH. 1877 // the current RFH.
1895 CHECK(instance); 1878 CHECK(instance);
1896 CHECK_NE(instance, render_frame_host_->GetSiteInstance()); 1879 CHECK_NE(instance, render_frame_host_->GetSiteInstance());
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1992 RenderFrameProxyHost* proxy) { 1975 RenderFrameProxyHost* proxy) {
1993 // Ensure the renderer process is initialized before creating the 1976 // Ensure the renderer process is initialized before creating the
1994 // RenderView. 1977 // RenderView.
1995 if (!render_view_host->GetProcess()->Init()) 1978 if (!render_view_host->GetProcess()->Init())
1996 return false; 1979 return false;
1997 1980
1998 // We may have initialized this RenderViewHost for another RenderFrameHost. 1981 // We may have initialized this RenderViewHost for another RenderFrameHost.
1999 if (render_view_host->IsRenderViewLive()) 1982 if (render_view_host->IsRenderViewLive())
2000 return true; 1983 return true;
2001 1984
2002 // If |render_view_host| is not for a proxy and the navigation is to a WebUI,
2003 // and if the RenderView is not in a guest process, tell |render_view_host|
2004 // about any bindings it will need enabled.
2005 // TODO(carlosk): Move WebUI to RenderFrameHost in https://crbug.com/508850.
2006 WebUIImpl* dest_web_ui = nullptr;
2007 if (!proxy) {
2008 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2009 switches::kEnableBrowserSideNavigation)) {
2010 dest_web_ui =
2011 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
2012 } else {
2013 dest_web_ui = pending_web_ui();
2014 }
2015 }
2016 if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) {
2017 render_view_host->AllowBindings(dest_web_ui->GetBindings());
2018 } else {
2019 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
2020 // process unless it's swapped out.
2021 if (render_view_host->is_active()) {
2022 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
2023 render_view_host->GetProcess()->GetID()));
2024 }
2025 }
2026
2027 int opener_frame_routing_id = 1985 int opener_frame_routing_id =
2028 GetOpenerRoutingID(render_view_host->GetSiteInstance()); 1986 GetOpenerRoutingID(render_view_host->GetSiteInstance());
2029 1987
2030 bool created = delegate_->CreateRenderViewForRenderManager( 1988 bool created = delegate_->CreateRenderViewForRenderManager(
2031 render_view_host, opener_frame_routing_id, 1989 render_view_host, opener_frame_routing_id,
2032 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE, 1990 proxy ? proxy->GetRoutingID() : MSG_ROUTING_NONE,
2033 frame_tree_node_->current_replication_state()); 1991 frame_tree_node_->current_replication_state());
2034 1992
2035 if (created && proxy) 1993 if (created && proxy)
2036 proxy->set_render_frame_proxy_created(true); 1994 proxy->set_render_frame_proxy_created(true);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2108 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); 2066 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance);
2109 if (proxy) 2067 if (proxy)
2110 return proxy->GetRoutingID(); 2068 return proxy->GetRoutingID();
2111 2069
2112 return MSG_ROUTING_NONE; 2070 return MSG_ROUTING_NONE;
2113 } 2071 }
2114 2072
2115 void RenderFrameHostManager::CommitPending() { 2073 void RenderFrameHostManager::CommitPending() {
2116 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 2074 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
2117 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 2075 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
2118 bool browser_side_navigation =
2119 base::CommandLine::ForCurrentProcess()->HasSwitch(
2120 switches::kEnableBrowserSideNavigation);
2121
2122 // First check whether we're going to want to focus the location bar after 2076 // First check whether we're going to want to focus the location bar after
2123 // this commit. We do this now because the navigation hasn't formally 2077 // this commit. We do this now because the navigation hasn't formally
2124 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 2078 // committed yet, so if we've already cleared the pending WebUI the call chain
2125 // this triggers won't be able to figure out what's going on. 2079 // this triggers won't be able to figure out what's going on.
2126 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 2080 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
2127 2081
2128 // Next commit the Web UI, if any. Either replace |web_ui_| with 2082 // If the current RenderFrameHost has a pending WebUI then just commit it and
2129 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 2083 // return (there should be nothing else to commit).
2130 // leave |web_ui_| as is if reusing it. 2084 if (render_frame_host_->pending_web_ui()) {
2131 DCHECK(!(pending_web_ui_ && pending_and_current_web_ui_)); 2085 DCHECK(!pending_render_frame_host_ && !speculative_render_frame_host_);
2132 if (pending_web_ui_ || speculative_web_ui_) { 2086 render_frame_host_->CommitPendingWebUI();
2133 DCHECK(!should_reuse_web_ui_);
2134 web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release()
2135 : pending_web_ui_.release());
2136 } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) {
2137 if (browser_side_navigation) {
2138 DCHECK(web_ui_);
2139 should_reuse_web_ui_ = false;
2140 } else {
2141 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
2142 pending_and_current_web_ui_.reset();
2143 }
2144 } else {
2145 web_ui_.reset();
2146 }
2147 DCHECK(!speculative_web_ui_);
2148 DCHECK(!should_reuse_web_ui_);
2149
2150 // It's possible for the pending_render_frame_host_ to be nullptr when we
2151 // aren't crossing process boundaries. If so, we just needed to handle the Web
2152 // UI committing above and we're done.
2153 if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
2154 if (will_focus_location_bar) 2087 if (will_focus_location_bar)
2155 delegate_->SetFocusToLocationBar(false); 2088 delegate_->SetFocusToLocationBar(false);
2156 return; 2089 return;
2157 } 2090 }
2158 2091
2159 // Remember if the page was focused so we can focus the new renderer in 2092 // Remember if the page was focused so we can focus the new renderer in
2160 // that case. 2093 // that case.
2161 bool focus_render_view = !will_focus_location_bar && 2094 bool focus_render_view = !will_focus_location_bar &&
2162 render_frame_host_->GetView() && 2095 render_frame_host_->GetView() &&
2163 render_frame_host_->GetView()->HasFocus(); 2096 render_frame_host_->GetView()->HasFocus();
2164 2097
2165 bool is_main_frame = frame_tree_node_->IsMainFrame(); 2098 bool is_main_frame = frame_tree_node_->IsMainFrame();
2166 2099
2167 // Swap in the pending or speculative frame and make it active. Also ensure 2100 // Swap in the pending or speculative frame and make it active. Also ensure
2168 // the FrameTree stays in sync. 2101 // the FrameTree stays in sync.
2169 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; 2102 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
2170 if (!browser_side_navigation) { 2103 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
2104 switches::kEnableBrowserSideNavigation)) {
2171 DCHECK(!speculative_render_frame_host_); 2105 DCHECK(!speculative_render_frame_host_);
2172 old_render_frame_host = 2106 old_render_frame_host =
2173 SetRenderFrameHost(pending_render_frame_host_.Pass()); 2107 SetRenderFrameHost(pending_render_frame_host_.Pass());
2174 } else { 2108 } else {
2175 // PlzNavigate 2109 // PlzNavigate
2176 DCHECK(speculative_render_frame_host_); 2110 DCHECK(speculative_render_frame_host_);
2177 old_render_frame_host = 2111 old_render_frame_host =
2178 SetRenderFrameHost(speculative_render_frame_host_.Pass()); 2112 SetRenderFrameHost(speculative_render_frame_host_.Pass());
2179 } 2113 }
2180 2114
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2324 // If we are currently navigating cross-process, we want to get back to normal 2258 // If we are currently navigating cross-process, we want to get back to normal
2325 // and then navigate as usual. 2259 // and then navigate as usual.
2326 if (pending_render_frame_host_) 2260 if (pending_render_frame_host_)
2327 CancelPending(); 2261 CancelPending();
2328 2262
2329 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 2263 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
2330 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( 2264 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
2331 dest_url, source_instance, dest_instance, nullptr, transition, 2265 dest_url, source_instance, dest_instance, nullptr, transition,
2332 dest_is_restore, dest_is_view_source_mode); 2266 dest_is_restore, dest_is_view_source_mode);
2333 2267
2334 const NavigationEntry* current_entry =
2335 delegate_->GetLastCommittedNavigationEntryForRenderManager();
2336
2337 DCHECK(!pending_render_frame_host_); 2268 DCHECK(!pending_render_frame_host_);
2338 2269
2339 if (new_instance.get() != current_instance) { 2270 if (new_instance.get() != current_instance) {
2340 TRACE_EVENT_INSTANT2( 2271 TRACE_EVENT_INSTANT2(
2341 "navigation", 2272 "navigation",
2342 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 2273 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
2343 TRACE_EVENT_SCOPE_THREAD, 2274 TRACE_EVENT_SCOPE_THREAD,
2344 "current_instance id", current_instance->GetId(), 2275 "current_instance id", current_instance->GetId(),
2345 "new_instance id", new_instance->GetId()); 2276 "new_instance id", new_instance->GetId());
2346 2277
2278 // Clear any pending WebUI on the current RenderFrameHost as it won't
2279 // be used.
2280 render_frame_host_->DiscardPendingWebUI();
nasko 2015/10/20 01:13:22 Can't this move either closer to InitializeWebUI o
carlosk 2015/10/20 12:58:51 Done.
2281
2347 // New SiteInstance: create a pending RFH to navigate. 2282 // New SiteInstance: create a pending RFH to navigate.
2348 2283
2349 // This will possibly create (set to nullptr) a Web UI object for the
2350 // pending page. We'll use this later to give the page special access. This
2351 // must happen before the new renderer is created below so it will get
2352 // bindings. It must also happen after the above conditional call to
2353 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_
2354 // and the page will not have its bindings set appropriately.
2355 SetPendingWebUI(dest_url, bindings);
2356 CreatePendingRenderFrameHost(current_instance, new_instance.get()); 2284 CreatePendingRenderFrameHost(current_instance, new_instance.get());
2357 if (!pending_render_frame_host_) 2285 if (!pending_render_frame_host_)
2358 return nullptr; 2286 return nullptr;
2359 2287
2288 InitializeWebUI(dest_url, bindings);
2289
2360 // Check if our current RFH is live before we set up a transition. 2290 // Check if our current RFH is live before we set up a transition.
2361 if (!render_frame_host_->IsRenderFrameLive()) { 2291 if (!render_frame_host_->IsRenderFrameLive()) {
2362 // The current RFH is not live. There's no reason to sit around with a 2292 // The current RFH is not live. There's no reason to sit around with a
2363 // sad tab or a newly created RFH while we wait for the pending RFH to 2293 // sad tab or a newly created RFH while we wait for the pending RFH to
2364 // navigate. Just switch to the pending RFH now and go back to normal. 2294 // navigate. Just switch to the pending RFH now and go back to normal.
2365 // (Note that we don't care about on{before}unload handlers if the current 2295 // (Note that we don't care about on{before}unload handlers if the current
2366 // RFH isn't live.) 2296 // RFH isn't live.)
2367 CommitPending(); 2297 CommitPending();
2368 return render_frame_host_.get(); 2298 return render_frame_host_.get();
2369 } 2299 }
2370 // Otherwise, it's safe to treat this as a pending cross-process transition. 2300 // Otherwise, it's safe to treat this as a pending cross-process transition.
2371 2301
2372 // We now have a pending RFH. 2302 // We now have a pending RFH and possibly an associated pending WebUI.
2373 DCHECK(pending_render_frame_host_); 2303 DCHECK(pending_render_frame_host_);
2304 DCHECK_EQ(pending_web_ui(), pending_render_frame_host_->web_ui());
2305 DCHECK(!pending_render_frame_host_->pending_web_ui());
2306 DCHECK(!render_frame_host_->pending_web_ui());
2374 2307
2375 // We need to wait until the beforeunload handler has run, unless we are 2308 // We need to wait until the beforeunload handler has run, unless we are
2376 // transferring an existing request (in which case it has already run). 2309 // transferring an existing request (in which case it has already run).
2377 // Suspend the new render view (i.e., don't let it send the cross-process 2310 // Suspend the new render view (i.e., don't let it send the cross-process
2378 // Navigate message) until we hear back from the old renderer's 2311 // Navigate message) until we hear back from the old renderer's
2379 // beforeunload handler. If the handler returns false, we'll have to 2312 // beforeunload handler. If the handler returns false, we'll have to
2380 // cancel the request. 2313 // cancel the request.
2381 // 2314 //
2382 DCHECK(!pending_render_frame_host_->are_navigations_suspended()); 2315 DCHECK(!pending_render_frame_host_->are_navigations_suspended());
2383 bool is_transfer = transferred_request_id != GlobalRequestID(); 2316 bool is_transfer = transferred_request_id != GlobalRequestID();
(...skipping 22 matching lines...) Expand all
2406 2339
2407 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. 2340 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_.
2408 2341
2409 // It's possible to swap out the current RFH and then decide to navigate in it 2342 // It's possible to swap out the current RFH and then decide to navigate in it
2410 // anyway (e.g., a cross-process navigation that redirects back to the 2343 // anyway (e.g., a cross-process navigation that redirects back to the
2411 // original site). In that case, we have a proxy for the current RFH but 2344 // original site). In that case, we have a proxy for the current RFH but
2412 // haven't deleted it yet. The new navigation will swap it back in, so we can 2345 // haven't deleted it yet. The new navigation will swap it back in, so we can
2413 // delete the proxy. 2346 // delete the proxy.
2414 proxy_hosts_->Remove(new_instance.get()->GetId()); 2347 proxy_hosts_->Remove(new_instance.get()->GetId());
2415 2348
2416 if (ShouldReuseWebUI(current_entry, dest_url)) { 2349 render_frame_host_->UpdatePendingWebUI(dest_url, bindings);
2417 pending_web_ui_.reset(); 2350 DCHECK(pending_web_ui() == render_frame_host_->pending_web_ui());
2418 pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
2419 } else {
2420 SetPendingWebUI(dest_url, bindings);
2421 // Make sure the new RenderViewHost has the right bindings.
2422 if (pending_web_ui() &&
2423 !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
2424 render_frame_host_->render_view_host()->AllowBindings(
2425 pending_web_ui()->GetBindings());
2426 }
2427 }
2428 2351
2352 // If a pending WebUI was set on the current RenderFrameHost (be it a new one
2353 // or the reused current one) and the associated RenderFrame is alive, notify
2354 // the WebUI the RenderView is being reused.
2429 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) { 2355 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) {
2430 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(), 2356 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(),
2431 frame_tree_node_->IsMainFrame()); 2357 frame_tree_node_->IsMainFrame());
2432 } 2358 }
2433 2359
2434 // The renderer can exit view source mode when any error or cancellation 2360 // The renderer can exit view source mode when any error or cancellation
2435 // happen. We must overwrite to recover the mode. 2361 // happen. We must overwrite to recover the mode.
2436 if (dest_is_view_source_mode) { 2362 if (dest_is_view_source_mode) {
2437 render_frame_host_->render_view_host()->Send( 2363 render_frame_host_->render_view_host()->Send(
2438 new ViewMsg_EnableViewSourceMode( 2364 new ViewMsg_EnableViewSourceMode(
2439 render_frame_host_->render_view_host()->GetRoutingID())); 2365 render_frame_host_->render_view_host()->GetRoutingID()));
2440 } 2366 }
2441 2367
2442 return render_frame_host_.get(); 2368 return render_frame_host_.get();
2443 } 2369 }
2444 2370
2445 void RenderFrameHostManager::CancelPending() { 2371 void RenderFrameHostManager::CancelPending() {
2446 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", 2372 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
2447 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 2373 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
2374 render_frame_host_->DiscardPendingWebUI();
2448 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); 2375 DiscardUnusedFrame(UnsetPendingRenderFrameHost());
2449 } 2376 }
2450 2377
2451 scoped_ptr<RenderFrameHostImpl> 2378 scoped_ptr<RenderFrameHostImpl>
2452 RenderFrameHostManager::UnsetPendingRenderFrameHost() { 2379 RenderFrameHostManager::UnsetPendingRenderFrameHost() {
2453 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = 2380 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
2454 pending_render_frame_host_.Pass(); 2381 pending_render_frame_host_.Pass();
2455 2382
2456 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( 2383 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation(
2457 pending_render_frame_host.get(), 2384 pending_render_frame_host.get(),
2458 render_frame_host_.get()); 2385 render_frame_host_.get());
2459 2386
2460 // We no longer need to prevent the process from exiting. 2387 // We no longer need to prevent the process from exiting.
2461 pending_render_frame_host->GetProcess()->RemovePendingView(); 2388 pending_render_frame_host->GetProcess()->RemovePendingView();
2462 2389
2463 pending_web_ui_.reset();
2464 pending_and_current_web_ui_.reset();
2465
2466 return pending_render_frame_host.Pass(); 2390 return pending_render_frame_host.Pass();
2467 } 2391 }
2468 2392
2469 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( 2393 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
2470 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 2394 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
2471 // Swap the two. 2395 // Swap the two.
2472 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 2396 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
2473 render_frame_host_.Pass(); 2397 render_frame_host_.Pass();
2474 render_frame_host_ = render_frame_host.Pass(); 2398 render_frame_host_ = render_frame_host.Pass();
2475 2399
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2630 if (rvh && !rvh->IsRenderViewLive()) { 2554 if (rvh && !rvh->IsRenderViewLive()) {
2631 EnsureRenderViewInitialized(rvh, instance); 2555 EnsureRenderViewInitialized(rvh, instance);
2632 } else { 2556 } else {
2633 // Create a swapped out RenderView in the given SiteInstance if none 2557 // Create a swapped out RenderView in the given SiteInstance if none
2634 // exists. Since an opener can point to a subframe, do this on the root 2558 // exists. Since an opener can point to a subframe, do this on the root
2635 // frame of the current opener's frame tree. 2559 // frame of the current opener's frame tree.
2636 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { 2560 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) {
2637 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); 2561 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance);
2638 } else { 2562 } else {
2639 frame_tree->root()->render_manager()->CreateRenderFrame( 2563 frame_tree->root()->render_manager()->CreateRenderFrame(
2640 instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, 2564 instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr);
2641 nullptr);
2642 } 2565 }
2643 } 2566 }
2644 } 2567 }
2645 } 2568 }
2646 2569
2647 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { 2570 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) {
2648 if (!frame_tree_node_->opener()) 2571 if (!frame_tree_node_->opener())
2649 return MSG_ROUTING_NONE; 2572 return MSG_ROUTING_NONE;
2650 2573
2651 return frame_tree_node_->opener() 2574 return frame_tree_node_->opener()
2652 ->render_manager() 2575 ->render_manager()
2653 ->GetRoutingIdForSiteInstance(instance); 2576 ->GetRoutingIdForSiteInstance(instance);
2654 } 2577 }
2655 2578
2656 } // namespace content 2579 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698