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

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: Got to an almost working state and addressed reviewer 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 337
345 void RenderFrameHostManager::RemoveOuterDelegateFrame() { 338 void RenderFrameHostManager::RemoveOuterDelegateFrame() {
346 FrameTreeNode* outer_delegate_frame_tree_node = 339 FrameTreeNode* outer_delegate_frame_tree_node =
347 FrameTreeNode::GloballyFindByID( 340 FrameTreeNode::GloballyFindByID(
348 delegate_->GetOuterDelegateFrameTreeNodeID()); 341 delegate_->GetOuterDelegateFrameTreeNodeID());
349 DCHECK(outer_delegate_frame_tree_node->parent()); 342 DCHECK(outer_delegate_frame_tree_node->parent());
350 outer_delegate_frame_tree_node->frame_tree()->RemoveFrame( 343 outer_delegate_frame_tree_node->frame_tree()->RemoveFrame(
351 outer_delegate_frame_tree_node); 344 outer_delegate_frame_tree_node);
352 } 345 }
353 346
354 void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) {
355 pending_web_ui_ = CreateWebUI(url, bindings);
356 pending_and_current_web_ui_.reset();
357 }
358
359 scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url,
360 int bindings) {
361 scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url));
362
363 // If we have assigned (zero or more) bindings to this NavigationEntry in the
364 // past, make sure we're not granting it different bindings than it had
365 // before. If so, note it and don't give it any bindings, to avoid a
366 // potential privilege escalation.
367 if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings &&
368 new_web_ui->GetBindings() != bindings) {
369 RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
370 return nullptr;
371 }
372 return new_web_ui.Pass();
373 }
374
375 RenderFrameHostImpl* RenderFrameHostManager::Navigate( 347 RenderFrameHostImpl* RenderFrameHostManager::Navigate(
376 const GURL& dest_url, 348 const GURL& dest_url,
377 const FrameNavigationEntry& frame_entry, 349 const FrameNavigationEntry& frame_entry,
378 const NavigationEntryImpl& entry) { 350 const NavigationEntryImpl& entry) {
379 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate", 351 TRACE_EVENT1("navigation", "RenderFrameHostManager:Navigate",
380 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 352 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
381 // Create a pending RenderFrameHost to use for the navigation. 353 // Create a pending RenderFrameHost to use for the navigation.
382 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate( 354 RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate(
383 dest_url, 355 dest_url,
384 // TODO(creis): Move source_site_instance to FNE. 356 // TODO(creis): Move source_site_instance to FNE.
(...skipping 26 matching lines...) Expand all
411 // RenderView can cause browser-side code to execute that expects the this 383 // RenderView can cause browser-side code to execute that expects the this
412 // RFH's ServiceRegistry to be initialized (e.g., if the site is a WebUI 384 // RFH's ServiceRegistry to be initialized (e.g., if the site is a WebUI
413 // site that is handled via Mojo, then Mojo WebUI code in //chrome will 385 // site that is handled via Mojo, then Mojo WebUI code in //chrome will
414 // add a service to this RFH's ServiceRegistry). 386 // add a service to this RFH's ServiceRegistry).
415 dest_render_frame_host->SetUpMojoIfNeeded(); 387 dest_render_frame_host->SetUpMojoIfNeeded();
416 388
417 // Recreate the opener chain. 389 // Recreate the opener chain.
418 CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(), 390 CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(),
419 frame_tree_node_); 391 frame_tree_node_);
420 if (!InitRenderView(dest_render_frame_host->render_view_host(), 392 if (!InitRenderView(dest_render_frame_host->render_view_host(),
421 MSG_ROUTING_NONE)) 393 MSG_ROUTING_NONE, pending_web_ui()))
422 return nullptr; 394 return nullptr;
423 395
424 // Now that we've created a new renderer, be sure to hide it if it isn't 396 // 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() 397 // our primary one. Otherwise, we might crash if we try to call Show()
426 // on it later. 398 // on it later.
427 if (dest_render_frame_host != render_frame_host_) { 399 if (dest_render_frame_host != render_frame_host_) {
428 if (dest_render_frame_host->GetView()) 400 if (dest_render_frame_host->GetView())
429 dest_render_frame_host->GetView()->Hide(); 401 dest_render_frame_host->GetView()->Hide();
430 } else { 402 } else {
431 // After a renderer crash we'd have marked the host as invisible, so we 403 // After a renderer crash we'd have marked the host as invisible, so we
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 635
664 // Make sure any dynamic changes to this frame's sandbox flags that were made 636 // Make sure any dynamic changes to this frame's sandbox flags that were made
665 // prior to navigation take effect. 637 // prior to navigation take effect.
666 CommitPendingSandboxFlags(); 638 CommitPendingSandboxFlags();
667 } 639 }
668 640
669 void RenderFrameHostManager::CommitPendingIfNecessary( 641 void RenderFrameHostManager::CommitPendingIfNecessary(
670 RenderFrameHostImpl* render_frame_host, 642 RenderFrameHostImpl* render_frame_host,
671 bool was_caused_by_user_gesture) { 643 bool was_caused_by_user_gesture) {
672 if (!pending_render_frame_host_ && !speculative_render_frame_host_) { 644 if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
673 DCHECK_IMPLIES(should_reuse_web_ui_, web_ui_);
674 645
675 // We should only hear this from our current renderer. 646 // We should only hear this from our current renderer.
676 DCHECK_EQ(render_frame_host_, render_frame_host); 647 DCHECK_EQ(render_frame_host_, render_frame_host);
677 648
678 // Even when there is no pending RVH, there may be a pending Web UI. 649 // If current RenderFrameHost has a pending Web UI, commit it.
679 if (pending_web_ui() || speculative_web_ui_) 650 if (render_frame_host_->pending_web_ui())
680 CommitPending(); 651 CommitPending();
681 return; 652 return;
682 } 653 }
683 654
684 if (render_frame_host == pending_render_frame_host_ || 655 if (render_frame_host == pending_render_frame_host_ ||
685 render_frame_host == speculative_render_frame_host_) { 656 render_frame_host == speculative_render_frame_host_) {
686 // The pending cross-process navigation completed, so show the renderer. 657 // The pending cross-process navigation completed, so show the renderer.
687 CommitPending(); 658 CommitPending();
688 } else if (render_frame_host == render_frame_host_) { 659 } else if (render_frame_host == render_frame_host_) {
689 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 660 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 if (current_site_instance == dest_site_instance.get() || 973 if (current_site_instance == dest_site_instance.get() ||
1003 (!request.browser_initiated() && is_main_frame) || 974 (!request.browser_initiated() && is_main_frame) ||
1004 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() && 975 (!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() &&
1005 !current_site_instance->RequiresDedicatedProcess())) { 976 !current_site_instance->RequiresDedicatedProcess())) {
1006 // Reuse the current RFH if its SiteInstance matches the the navigation's 977 // Reuse the current RFH if its SiteInstance matches the the navigation's
1007 // or if this is a subframe navigation. We only swap RFHs for subframes when 978 // or if this is a subframe navigation. We only swap RFHs for subframes when
1008 // --site-per-process is enabled. 979 // --site-per-process is enabled.
1009 CleanUpNavigation(); 980 CleanUpNavigation();
1010 navigation_rfh = render_frame_host_.get(); 981 navigation_rfh = render_frame_host_.get();
1011 982
1012 // As SiteInstances are the same, check if the WebUI should be reused. 983 // As SiteInstances are the same, make the RFH update its possible pending
1013 const NavigationEntry* current_navigation_entry = 984 // WebUI.
1014 delegate_->GetLastCommittedNavigationEntryForRenderManager(); 985 render_frame_host_->UpdatePendingWebUI(request.common_params().url,
1015 should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry, 986 request.bindings());
1016 request.common_params().url); 987 DCHECK(!speculative_render_frame_host_);
1017 if (!should_reuse_web_ui_) { 988 DCHECK(speculative_web_ui() == render_frame_host_->pending_web_ui());
1018 speculative_web_ui_ = CreateWebUI(request.common_params().url,
1019 request.bindings());
1020 // Make sure the current RenderViewHost has the right bindings.
1021 if (speculative_web_ui() &&
1022 !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
1023 render_frame_host_->render_view_host()->AllowBindings(
1024 speculative_web_ui()->GetBindings());
1025 }
1026 }
1027 } else { 989 } else {
1028 // If the SiteInstance for the final URL doesn't match the one from the 990 // If the SiteInstance for the final URL doesn't match the one from the
1029 // speculatively created RenderFrameHost, create a new RenderFrameHost using 991 // speculatively created RenderFrameHost, create a new RenderFrameHost using
1030 // this new SiteInstance. 992 // this new SiteInstance.
1031 if (!speculative_render_frame_host_ || 993 if (!speculative_render_frame_host_ ||
1032 speculative_render_frame_host_->GetSiteInstance() != 994 speculative_render_frame_host_->GetSiteInstance() !=
1033 dest_site_instance.get()) { 995 dest_site_instance.get()) {
1034 CleanUpNavigation(); 996 CleanUpNavigation();
1035 bool success = CreateSpeculativeRenderFrameHost( 997 bool success = CreateSpeculativeRenderFrameHost(
1036 request.common_params().url, current_site_instance, 998 request.common_params().url, current_site_instance,
1037 dest_site_instance.get(), request.bindings()); 999 dest_site_instance.get(), request.bindings());
1038 DCHECK(success); 1000 DCHECK(success);
1001 } else {
1002 // When reusing an existing speculative RenderFrameHost its active WebUI
1003 // must be updated to make sure it matches the current URL. As it is not a
1004 // new RenderFrameHost instance it must be done by updating the pending
1005 // WebUI and immediately making it active.
1006 speculative_render_frame_host_->UpdatePendingWebUI(
1007 request.common_params().url, request.bindings());
1008 speculative_render_frame_host_->CommitPendingWebUI();
clamy 2015/10/01 13:15:13 Is the CommitPendingWebUI method idempotent? (that
carlosk 2015/10/01 16:00:22 I don't understand your point here. It's a commit
clamy 2015/10/02 14:20:01 I was thinking of something along the lines of hav
1039 } 1009 }
1040 DCHECK(speculative_render_frame_host_); 1010 DCHECK(speculative_render_frame_host_);
1011 DCHECK_EQ(speculative_web_ui(), speculative_render_frame_host_->web_ui());
1012
1041 navigation_rfh = speculative_render_frame_host_.get(); 1013 navigation_rfh = speculative_render_frame_host_.get();
1042 1014
1043 // Check if our current RFH is live. 1015 // Check if our current RFH is live.
1044 if (!render_frame_host_->IsRenderFrameLive()) { 1016 if (!render_frame_host_->IsRenderFrameLive()) {
1045 // The current RFH is not live. There's no reason to sit around with a 1017 // The current RFH is not live. There's no reason to sit around with a
1046 // sad tab or a newly created RFH while we wait for the navigation to 1018 // sad tab or a newly created RFH while we wait for the navigation to
1047 // complete. Just switch to the speculative RFH now and go back to normal. 1019 // complete. Just switch to the speculative RFH now and go back to normal.
1048 // (Note that we don't care about on{before}unload handlers if the current 1020 // (Note that we don't care about on{before}unload handlers if the current
1049 // RFH isn't live.) 1021 // RFH isn't live.)
1050 CommitPending(); 1022 CommitPending();
1051 } 1023 }
1052 } 1024 }
1053 DCHECK(navigation_rfh && 1025 DCHECK(navigation_rfh &&
1054 (navigation_rfh == render_frame_host_.get() || 1026 (navigation_rfh == render_frame_host_.get() ||
1055 navigation_rfh == speculative_render_frame_host_.get())); 1027 navigation_rfh == speculative_render_frame_host_.get()));
1056 1028
1057 // If the RenderFrame that needs to navigate is not live (its process was just 1029 // If the RenderFrame that needs to navigate is not live (its process was just
1058 // created or has crashed), initialize it. 1030 // created or has crashed), initialize it.
1059 if (!navigation_rfh->IsRenderFrameLive()) { 1031 if (!navigation_rfh->IsRenderFrameLive()) {
1060 // Recreate the opener chain. 1032 // Recreate the opener chain.
1061 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); 1033 CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_);
1062 if (!InitRenderView(navigation_rfh->render_view_host(), MSG_ROUTING_NONE)) { 1034 if (!InitRenderView(navigation_rfh->render_view_host(), MSG_ROUTING_NONE,
1035 speculative_web_ui())) {
1063 return nullptr; 1036 return nullptr;
1064 } 1037 }
1065 1038
1066 if (navigation_rfh == render_frame_host_) { 1039 if (navigation_rfh == render_frame_host_) {
1067 // TODO(nasko): This is a very ugly hack. The Chrome extensions process 1040 // TODO(nasko): This is a very ugly hack. The Chrome extensions process
1068 // manager still uses NotificationService and expects to see a 1041 // manager still uses NotificationService and expects to see a
1069 // RenderViewHost changed notification after WebContents and 1042 // RenderViewHost changed notification after WebContents and
1070 // RenderFrameHostManager are completely initialized. This should be 1043 // RenderFrameHostManager are completely initialized. This should be
1071 // removed once the process manager moves away from NotificationService. 1044 // removed once the process manager moves away from NotificationService.
1072 // See https://crbug.com/462682. 1045 // See https://crbug.com/462682.
1073 delegate_->NotifyMainFrameSwappedFromRenderManager( 1046 delegate_->NotifyMainFrameSwappedFromRenderManager(
1074 nullptr, render_frame_host_->render_view_host()); 1047 nullptr, render_frame_host_->render_view_host());
1075 } 1048 }
1076 } 1049 }
1077 1050
1078 return navigation_rfh; 1051 return navigation_rfh;
1079 } 1052 }
1080 1053
1081 // PlzNavigate 1054 // PlzNavigate
1082 void RenderFrameHostManager::CleanUpNavigation() { 1055 void RenderFrameHostManager::CleanUpNavigation() {
1083 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 1056 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
1084 switches::kEnableBrowserSideNavigation)); 1057 switches::kEnableBrowserSideNavigation));
1085 speculative_web_ui_.reset(); 1058 render_frame_host_->DiscardPendingWebUI();
1086 should_reuse_web_ui_ = false;
1087 if (speculative_render_frame_host_) 1059 if (speculative_render_frame_host_)
1088 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); 1060 DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
1089 } 1061 }
1090 1062
1091 // PlzNavigate 1063 // PlzNavigate
1092 scoped_ptr<RenderFrameHostImpl> 1064 scoped_ptr<RenderFrameHostImpl>
1093 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() { 1065 RenderFrameHostManager::UnsetSpeculativeRenderFrameHost() {
1094 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( 1066 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
1095 switches::kEnableBrowserSideNavigation)); 1067 switches::kEnableBrowserSideNavigation));
1096 speculative_render_frame_host_->GetProcess()->RemovePendingView(); 1068 speculative_render_frame_host_->GetProcess()->RemovePendingView();
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 // We can't switch a RenderView between view source and non-view source mode 1232 // We can't switch a RenderView between view source and non-view source mode
1261 // without screwing up the session history sometimes (when navigating between 1233 // without screwing up the session history sometimes (when navigating between
1262 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat 1234 // "view-source:http://foo.com/" and "http://foo.com/", Blink doesn't treat
1263 // it as a new navigation). So require a BrowsingInstance switch. 1235 // it as a new navigation). So require a BrowsingInstance switch.
1264 if (current_is_view_source_mode != new_is_view_source_mode) 1236 if (current_is_view_source_mode != new_is_view_source_mode)
1265 return true; 1237 return true;
1266 1238
1267 return false; 1239 return false;
1268 } 1240 }
1269 1241
1270 bool RenderFrameHostManager::ShouldReuseWebUI(
1271 const NavigationEntry* current_entry,
1272 const GURL& new_url) const {
1273 NavigationControllerImpl& controller =
1274 delegate_->GetControllerForRenderManager();
1275 return current_entry && web_ui_ &&
1276 (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
1277 controller.GetBrowserContext(), current_entry->GetURL()) ==
1278 WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
1279 controller.GetBrowserContext(), new_url));
1280 }
1281
1282 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation( 1242 SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
1283 const GURL& dest_url, 1243 const GURL& dest_url,
1284 SiteInstance* source_instance, 1244 SiteInstance* source_instance,
1285 SiteInstance* dest_instance, 1245 SiteInstance* dest_instance,
1286 SiteInstance* candidate_instance, 1246 SiteInstance* candidate_instance,
1287 ui::PageTransition transition, 1247 ui::PageTransition transition,
1288 bool dest_is_restore, 1248 bool dest_is_restore,
1289 bool dest_is_view_source_mode) { 1249 bool dest_is_view_source_mode) {
1290 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 1250 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
1291 1251
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 // to open a new tab to an interstitial-inducing URL, and then navigates 1515 // to open a new tab to an interstitial-inducing URL, and then navigates
1556 // the page to a different same-site URL. (This seems very unlikely in 1516 // the page to a different same-site URL. (This seems very unlikely in
1557 // practice.) 1517 // practice.)
1558 if (current_entry) 1518 if (current_entry)
1559 return current_entry->GetURL(); 1519 return current_entry->GetURL();
1560 return current_instance->GetSiteURL(); 1520 return current_instance->GetSiteURL();
1561 } 1521 }
1562 1522
1563 void RenderFrameHostManager::CreatePendingRenderFrameHost( 1523 void RenderFrameHostManager::CreatePendingRenderFrameHost(
1564 SiteInstance* old_instance, 1524 SiteInstance* old_instance,
1565 SiteInstance* new_instance) { 1525 SiteInstance* new_instance,
1526 const GURL& url,
1527 int bindings) {
1566 int create_render_frame_flags = 0; 1528 int create_render_frame_flags = 0;
1567 if (delegate_->IsHidden()) 1529 if (delegate_->IsHidden())
1568 create_render_frame_flags |= CREATE_RF_HIDDEN; 1530 create_render_frame_flags |= CREATE_RF_HIDDEN;
1569 1531
1570 if (pending_render_frame_host_) 1532 if (pending_render_frame_host_)
1571 CancelPending(); 1533 CancelPending();
1572 1534
1573 // The process for the new SiteInstance may (if we're sharing a process with 1535 // The process for the new SiteInstance may (if we're sharing a process with
1574 // another host that already initialized it) or may not (we have our own 1536 // another host that already initialized it) or may not (we have our own
1575 // process or the existing process crashed) have been initialized. Calling 1537 // process or the existing process crashed) have been initialized. Calling
1576 // Init multiple times will be ignored, so this is safe. 1538 // Init multiple times will be ignored, so this is safe.
1577 if (!new_instance->GetProcess()->Init()) 1539 if (!new_instance->GetProcess()->Init())
1578 return; 1540 return;
1579 1541
1580 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); 1542 CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
1581 1543
1582 // Create a non-swapped-out RFH with the given opener. 1544 // Create a non-swapped-out RFH with the given opener.
1583 pending_render_frame_host_ = CreateRenderFrame( 1545 pending_render_frame_host_ = CreateRenderFrameInternal(
1584 new_instance, pending_web_ui(), create_render_frame_flags, nullptr); 1546 new_instance, url, bindings, create_render_frame_flags, nullptr);
1585 } 1547 }
1586 1548
1587 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost( 1549 void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
1588 SiteInstance* old_instance, 1550 SiteInstance* old_instance,
1589 SiteInstance* new_instance) { 1551 SiteInstance* new_instance) {
1590 // Only create opener proxies if they are in the same BrowsingInstance. 1552 // Only create opener proxies if they are in the same BrowsingInstance.
1591 if (new_instance->IsRelatedSiteInstance(old_instance)) { 1553 if (new_instance->IsRelatedSiteInstance(old_instance)) {
1592 CreateOpenerProxies(new_instance, frame_tree_node_); 1554 CreateOpenerProxies(new_instance, frame_tree_node_);
1593 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) { 1555 } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
1594 // Ensure that the frame tree has RenderFrameProxyHosts for the 1556 // Ensure that the frame tree has RenderFrameProxyHosts for the
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 } 1624 }
1663 1625
1664 // PlzNavigate 1626 // PlzNavigate
1665 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost( 1627 bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
1666 const GURL& url, 1628 const GURL& url,
1667 SiteInstance* old_instance, 1629 SiteInstance* old_instance,
1668 SiteInstance* new_instance, 1630 SiteInstance* new_instance,
1669 int bindings) { 1631 int bindings) {
1670 CHECK(new_instance); 1632 CHECK(new_instance);
1671 CHECK_NE(old_instance, new_instance); 1633 CHECK_NE(old_instance, new_instance);
1672 CHECK(!should_reuse_web_ui_);
1673
1674 // Note: |speculative_web_ui_| must be initialized before starting the
1675 // |speculative_render_frame_host_| creation steps otherwise the WebUI
1676 // won't be properly initialized.
1677 speculative_web_ui_ = CreateWebUI(url, bindings);
1678 1634
1679 // The process for the new SiteInstance may (if we're sharing a process with 1635 // The process for the new SiteInstance may (if we're sharing a process with
1680 // another host that already initialized it) or may not (we have our own 1636 // another host that already initialized it) or may not (we have our own
1681 // process or the existing process crashed) have been initialized. Calling 1637 // process or the existing process crashed) have been initialized. Calling
1682 // Init multiple times will be ignored, so this is safe. 1638 // Init multiple times will be ignored, so this is safe.
1683 if (!new_instance->GetProcess()->Init()) 1639 if (!new_instance->GetProcess()->Init())
1684 return false; 1640 return false;
1685 1641
1686 CreateProxiesForNewRenderFrameHost(old_instance, new_instance); 1642 CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
1687 1643
1688 int create_render_frame_flags = 0; 1644 int create_render_frame_flags = 0;
1689 if (delegate_->IsHidden()) 1645 if (delegate_->IsHidden())
1690 create_render_frame_flags |= CREATE_RF_HIDDEN; 1646 create_render_frame_flags |= CREATE_RF_HIDDEN;
1691 speculative_render_frame_host_ = 1647 speculative_render_frame_host_ = CreateRenderFrameInternal(
1692 CreateRenderFrame(new_instance, speculative_web_ui_.get(), 1648 new_instance, url, bindings, create_render_frame_flags, nullptr);
1693 create_render_frame_flags, nullptr);
1694 1649
1695 if (!speculative_render_frame_host_) {
1696 speculative_web_ui_.reset();
1697 return false;
1698 }
1699 return true; 1650 return true;
1700 } 1651 }
1701 1652
1702 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame( 1653 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
1703 SiteInstance* instance, 1654 SiteInstance* instance,
1704 WebUIImpl* web_ui,
1705 int flags, 1655 int flags,
1706 int* view_routing_id_ptr) { 1656 int* view_routing_id_ptr) {
1657 return CreateRenderFrameInternal(instance, GURL(),
1658 NavigationEntryImpl::kInvalidBindings, flags,
1659 view_routing_id_ptr);
1660 }
1661
1662 scoped_ptr<RenderFrameHostImpl>
1663 RenderFrameHostManager::CreateRenderFrameInternal(SiteInstance* instance,
carlosk 2015/09/30 19:37:27 I chose to leave the implementation of CreateRende
clamy 2015/10/01 13:15:13 Acknowledged.
1664 const GURL& url,
1665 int bindings,
1666 int flags,
1667 int* view_routing_id_ptr) {
1707 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT); 1668 bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
1708 bool swapped_out_forbidden = 1669 bool swapped_out_forbidden =
1709 SiteIsolationPolicy::IsSwappedOutStateForbidden(); 1670 SiteIsolationPolicy::IsSwappedOutStateForbidden();
1710 1671
1711 CHECK(instance); 1672 CHECK(instance);
1712 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out); 1673 CHECK_IMPLIES(swapped_out_forbidden, !swapped_out);
1713 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(), 1674 CHECK_IMPLIES(!SiteIsolationPolicy::AreCrossProcessFramesPossible(),
1714 frame_tree_node_->IsMainFrame()); 1675 frame_tree_node_->IsMainFrame());
1715 1676
1716 // Swapped out views should always be hidden. 1677 // Swapped out views should always be hidden.
(...skipping 14 matching lines...) Expand all
1731 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1692 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1732 if (proxy && proxy->render_frame_host()) { 1693 if (proxy && proxy->render_frame_host()) {
1733 RenderViewHost* render_view_host = proxy->GetRenderViewHost(); 1694 RenderViewHost* render_view_host = proxy->GetRenderViewHost();
1734 CHECK(!swapped_out_forbidden); 1695 CHECK(!swapped_out_forbidden);
1735 if (view_routing_id_ptr) 1696 if (view_routing_id_ptr)
1736 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID(); 1697 *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID();
1737 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost. 1698 // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
1738 // Prevent the process from exiting while we're trying to use it. 1699 // Prevent the process from exiting while we're trying to use it.
1739 if (!swapped_out) { 1700 if (!swapped_out) {
1740 new_render_frame_host = proxy->PassFrameHostOwnership(); 1701 new_render_frame_host = proxy->PassFrameHostOwnership();
1702 new_render_frame_host->InitializeWebUI(url, bindings);
1741 new_render_frame_host->GetProcess()->AddPendingView(); 1703 new_render_frame_host->GetProcess()->AddPendingView();
1742 1704
1743 proxy_hosts_->Remove(instance->GetId()); 1705 proxy_hosts_->Remove(instance->GetId());
1744 // NB |proxy| is deleted at this point. 1706 // NB |proxy| is deleted at this point.
1745 1707
1746 // If we are reusing the RenderViewHost and it doesn't already have a 1708 // If we are reusing the RenderViewHost and it doesn't already have a
1747 // RenderWidgetHostView, we need to create one if this is the main frame. 1709 // RenderWidgetHostView, we need to create one if this is the main frame.
1748 if (!render_view_host->GetView() && frame_tree_node_->IsMainFrame()) 1710 if (!render_view_host->GetView() && frame_tree_node_->IsMainFrame())
1749 delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host); 1711 delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host);
1750 } 1712 }
1751 } else { 1713 } else {
1752 // Create a new RenderFrameHost if we don't find an existing one. 1714 // Create a new RenderFrameHost if we don't find an existing one.
1753 1715
1754 int32 widget_routing_id = MSG_ROUTING_NONE; 1716 int32 widget_routing_id = MSG_ROUTING_NONE;
1755 // A RenderFrame in a different process from its parent RenderFrame 1717 // A RenderFrame in a different process from its parent RenderFrame
1756 // requires a RenderWidget for input/layout/painting. 1718 // requires a RenderWidget for input/layout/painting.
1757 if (frame_tree_node_->parent() && 1719 if (frame_tree_node_->parent() &&
1758 frame_tree_node_->parent()->current_frame_host()->GetSiteInstance() != 1720 frame_tree_node_->parent()->current_frame_host()->GetSiteInstance() !=
1759 instance) { 1721 instance) {
1760 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible()); 1722 CHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible());
1761 widget_routing_id = instance->GetProcess()->GetNextRoutingID(); 1723 widget_routing_id = instance->GetProcess()->GetNextRoutingID();
1762 } 1724 }
1763 1725
1764 new_render_frame_host = CreateRenderFrameHost( 1726 new_render_frame_host = CreateRenderFrameHost(
1765 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, widget_routing_id, flags); 1727 instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, widget_routing_id, flags);
1728 new_render_frame_host->InitializeWebUI(url, bindings);
1766 RenderViewHostImpl* render_view_host = 1729 RenderViewHostImpl* render_view_host =
1767 new_render_frame_host->render_view_host(); 1730 new_render_frame_host->render_view_host();
1768 int proxy_routing_id = MSG_ROUTING_NONE; 1731 int proxy_routing_id = MSG_ROUTING_NONE;
1769 1732
1770 // Prevent the process from exiting while we're trying to navigate in it. 1733 // Prevent the process from exiting while we're trying to navigate in it.
1771 // Otherwise, if the new RFH is swapped out already, store it. 1734 // Otherwise, if the new RFH is swapped out already, store it.
1772 if (!swapped_out) { 1735 if (!swapped_out) {
1773 new_render_frame_host->GetProcess()->AddPendingView(); 1736 new_render_frame_host->GetProcess()->AddPendingView();
1774 } else { 1737 } else {
1775 proxy = new RenderFrameProxyHost( 1738 proxy = new RenderFrameProxyHost(
1776 new_render_frame_host->GetSiteInstance(), 1739 new_render_frame_host->GetSiteInstance(),
1777 new_render_frame_host->render_view_host(), frame_tree_node_); 1740 new_render_frame_host->render_view_host(), frame_tree_node_);
1778 proxy_hosts_->Add(instance->GetId(), make_scoped_ptr(proxy)); 1741 proxy_hosts_->Add(instance->GetId(), make_scoped_ptr(proxy));
1779 proxy_routing_id = proxy->GetRoutingID(); 1742 proxy_routing_id = proxy->GetRoutingID();
1780 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass()); 1743 proxy->TakeFrameHostOwnership(new_render_frame_host.Pass());
1781 } 1744 }
1782 1745
1783 if (frame_tree_node_->IsMainFrame()) { 1746 if (frame_tree_node_->IsMainFrame()) {
1784 success = InitRenderView(render_view_host, proxy_routing_id); 1747 success = InitRenderView(
1748 render_view_host, proxy_routing_id,
1749 swapped_out ? nullptr : new_render_frame_host->web_ui());
1785 1750
1786 // If we are reusing the RenderViewHost and it doesn't already have a 1751 // If we are reusing the RenderViewHost and it doesn't already have a
1787 // RenderWidgetHostView, we need to create one if this is the main frame. 1752 // RenderWidgetHostView, we need to create one if this is the main frame.
1788 if (!swapped_out && !render_view_host->GetView()) 1753 if (!swapped_out && !render_view_host->GetView())
1789 delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host); 1754 delegate_->CreateRenderWidgetHostViewForRenderManager(render_view_host);
1790 } else { 1755 } else {
1791 DCHECK(render_view_host->IsRenderViewLive()); 1756 DCHECK(render_view_host->IsRenderViewLive());
1792 } 1757 }
1793 1758
1794 if (success) { 1759 if (success) {
(...skipping 18 matching lines...) Expand all
1813 success = InitRenderFrame(new_render_frame_host.get()); 1778 success = InitRenderFrame(new_render_frame_host.get());
1814 } 1779 }
1815 } 1780 }
1816 1781
1817 if (success) { 1782 if (success) {
1818 if (view_routing_id_ptr) 1783 if (view_routing_id_ptr)
1819 *view_routing_id_ptr = render_view_host->GetRoutingID(); 1784 *view_routing_id_ptr = render_view_host->GetRoutingID();
1820 } 1785 }
1821 } 1786 }
1822 1787
1823 // When a new RenderView is created by the renderer process, the new
1824 // WebContents gets a RenderViewHost in the SiteInstance of its opener
1825 // WebContents. If not used in the first navigation, this RVH is swapped out
1826 // and is not granted bindings, so we may need to grant them when swapping it
1827 // in.
1828 if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) {
1829 int required_bindings = web_ui->GetBindings();
1830 RenderViewHost* render_view_host =
1831 new_render_frame_host->render_view_host();
1832 if ((render_view_host->GetEnabledBindings() & required_bindings) !=
1833 required_bindings) {
1834 render_view_host->AllowBindings(required_bindings);
1835 }
1836 }
1837
1838 // Returns the new RFH if it isn't swapped out. 1788 // Returns the new RFH if it isn't swapped out.
1839 if (success && !swapped_out) { 1789 if (success && !swapped_out) {
1840 DCHECK(new_render_frame_host->GetSiteInstance() == instance); 1790 DCHECK(new_render_frame_host->GetSiteInstance() == instance);
1841 return new_render_frame_host.Pass(); 1791 return new_render_frame_host.Pass();
1842 } 1792 }
1843 return nullptr; 1793 return nullptr;
1844 } 1794 }
1845 1795
1846 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) { 1796 int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
1847 // A RenderFrameProxyHost should never be created in the same SiteInstance as 1797 // A RenderFrameProxyHost should never be created in the same SiteInstance as
(...skipping 20 matching lines...) Expand all
1868 return proxy->GetRoutingID(); 1818 return proxy->GetRoutingID();
1869 1819
1870 if (!proxy) { 1820 if (!proxy) {
1871 proxy = 1821 proxy =
1872 new RenderFrameProxyHost(instance, render_view_host, frame_tree_node_); 1822 new RenderFrameProxyHost(instance, render_view_host, frame_tree_node_);
1873 proxy_hosts_->Add(instance->GetId(), make_scoped_ptr(proxy)); 1823 proxy_hosts_->Add(instance->GetId(), make_scoped_ptr(proxy));
1874 } 1824 }
1875 1825
1876 if (SiteIsolationPolicy::IsSwappedOutStateForbidden() && 1826 if (SiteIsolationPolicy::IsSwappedOutStateForbidden() &&
1877 frame_tree_node_->IsMainFrame()) { 1827 frame_tree_node_->IsMainFrame()) {
1878 InitRenderView(render_view_host, proxy->GetRoutingID()); 1828 InitRenderView(render_view_host, proxy->GetRoutingID(), nullptr);
1879 proxy->set_render_frame_proxy_created(true); 1829 proxy->set_render_frame_proxy_created(true);
1880 } else { 1830 } else {
1881 proxy->InitRenderFrameProxy(); 1831 proxy->InitRenderFrameProxy();
1882 } 1832 }
1883 1833
1884 return proxy->GetRoutingID(); 1834 return proxy->GetRoutingID();
1885 } 1835 }
1886 1836
1887 void RenderFrameHostManager::CreateProxiesForChildFrame(FrameTreeNode* child) { 1837 void RenderFrameHostManager::CreateProxiesForChildFrame(FrameTreeNode* child) {
1888 for (const auto& pair : *proxy_hosts_) { 1838 for (const auto& pair : *proxy_hosts_) {
(...skipping 14 matching lines...) Expand all
1903 1853
1904 if (render_view_host->IsRenderViewLive()) 1854 if (render_view_host->IsRenderViewLive())
1905 return; 1855 return;
1906 1856
1907 // If the proxy in |instance| doesn't exist, this RenderView is not swapped 1857 // If the proxy in |instance| doesn't exist, this RenderView is not swapped
1908 // out and shouldn't be reinitialized here. 1858 // out and shouldn't be reinitialized here.
1909 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance); 1859 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
1910 if (!proxy) 1860 if (!proxy)
1911 return; 1861 return;
1912 1862
1913 InitRenderView(render_view_host, proxy->GetRoutingID()); 1863 InitRenderView(render_view_host, proxy->GetRoutingID(), nullptr);
1914 proxy->set_render_frame_proxy_created(true); 1864 proxy->set_render_frame_proxy_created(true);
1915 } 1865 }
1916 1866
1917 void RenderFrameHostManager::CreateOuterDelegateProxy( 1867 void RenderFrameHostManager::CreateOuterDelegateProxy(
1918 SiteInstance* outer_contents_site_instance, 1868 SiteInstance* outer_contents_site_instance,
1919 RenderFrameHostImpl* render_frame_host) { 1869 RenderFrameHostImpl* render_frame_host) {
1920 CHECK(BrowserPluginGuestMode::UseCrossProcessFramesForGuests()); 1870 CHECK(BrowserPluginGuestMode::UseCrossProcessFramesForGuests());
1921 RenderFrameProxyHost* proxy = new RenderFrameProxyHost( 1871 RenderFrameProxyHost* proxy = new RenderFrameProxyHost(
1922 outer_contents_site_instance, nullptr, frame_tree_node_); 1872 outer_contents_site_instance, nullptr, frame_tree_node_);
1923 proxy_hosts_->Add(outer_contents_site_instance->GetId(), 1873 proxy_hosts_->Add(outer_contents_site_instance->GetId(),
(...skipping 14 matching lines...) Expand all
1938 } 1888 }
1939 1889
1940 void RenderFrameHostManager::SetRWHViewForInnerContents( 1890 void RenderFrameHostManager::SetRWHViewForInnerContents(
1941 RenderWidgetHostView* child_rwhv) { 1891 RenderWidgetHostView* child_rwhv) {
1942 DCHECK(ForInnerDelegate() && frame_tree_node_->IsMainFrame()); 1892 DCHECK(ForInnerDelegate() && frame_tree_node_->IsMainFrame());
1943 GetProxyToOuterDelegate()->SetChildRWHView(child_rwhv); 1893 GetProxyToOuterDelegate()->SetChildRWHView(child_rwhv);
1944 } 1894 }
1945 1895
1946 bool RenderFrameHostManager::InitRenderView( 1896 bool RenderFrameHostManager::InitRenderView(
1947 RenderViewHostImpl* render_view_host, 1897 RenderViewHostImpl* render_view_host,
1948 int proxy_routing_id) { 1898 int proxy_routing_id,
1899 WebUIImpl* dest_web_ui) {
1949 // Ensure the renderer process is initialized before creating the 1900 // Ensure the renderer process is initialized before creating the
1950 // RenderView. 1901 // RenderView.
1951 if (!render_view_host->GetProcess()->Init()) 1902 if (!render_view_host->GetProcess()->Init())
1952 return false; 1903 return false;
1953 1904
1954 // We may have initialized this RenderViewHost for another RenderFrameHost. 1905 // We may have initialized this RenderViewHost for another RenderFrameHost.
1955 if (render_view_host->IsRenderViewLive()) 1906 if (render_view_host->IsRenderViewLive())
1956 return true; 1907 return true;
1957 1908
1958 // If the ongoing navigation is to a WebUI and the RenderView is not in a 1909 // If the ongoing navigation is not to a WebUI or the RenderView is in a
1959 // guest process, tell the RenderViewHost about any bindings it will need 1910 // guest process, ensure that we don't create an unprivileged RenderView in a
1960 // enabled. 1911 // WebUI-enabled process unless it's swapped out.
1961 WebUIImpl* dest_web_ui = nullptr; 1912 if ((!dest_web_ui || render_view_host->GetProcess()->IsForGuestsOnly()) &&
1962 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 1913 render_view_host->is_active()) {
1963 switches::kEnableBrowserSideNavigation)) { 1914 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1964 dest_web_ui = 1915 render_view_host->GetProcess()->GetID()));
carlosk 2015/09/30 19:37:27 In the previous patch set I tried to centralize th
carlosk 2015/10/06 17:03:21 Bump on this: - The first part I already know the
1965 should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
1966 } else {
1967 dest_web_ui = pending_web_ui();
1968 }
1969 if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) {
1970 render_view_host->AllowBindings(dest_web_ui->GetBindings());
1971 } else {
1972 // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
1973 // process unless it's swapped out.
1974 if (render_view_host->is_active()) {
1975 CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1976 render_view_host->GetProcess()->GetID()));
1977 }
1978 } 1916 }
1979 1917
1980 int opener_frame_routing_id = 1918 int opener_frame_routing_id =
1981 GetOpenerRoutingID(render_view_host->GetSiteInstance()); 1919 GetOpenerRoutingID(render_view_host->GetSiteInstance());
1982 1920
1983 return delegate_->CreateRenderViewForRenderManager( 1921 return delegate_->CreateRenderViewForRenderManager(
1984 render_view_host, opener_frame_routing_id, proxy_routing_id, 1922 render_view_host, opener_frame_routing_id, proxy_routing_id,
1985 frame_tree_node_->current_replication_state()); 1923 frame_tree_node_->current_replication_state());
1986 } 1924 }
1987 1925
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance); 1993 RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(site_instance);
2056 if (proxy) 1994 if (proxy)
2057 return proxy->GetRoutingID(); 1995 return proxy->GetRoutingID();
2058 1996
2059 return MSG_ROUTING_NONE; 1997 return MSG_ROUTING_NONE;
2060 } 1998 }
2061 1999
2062 void RenderFrameHostManager::CommitPending() { 2000 void RenderFrameHostManager::CommitPending() {
2063 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending", 2001 TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
2064 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 2002 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
2065 bool browser_side_navigation =
2066 base::CommandLine::ForCurrentProcess()->HasSwitch(
2067 switches::kEnableBrowserSideNavigation);
2068
2069 // First check whether we're going to want to focus the location bar after 2003 // First check whether we're going to want to focus the location bar after
2070 // this commit. We do this now because the navigation hasn't formally 2004 // this commit. We do this now because the navigation hasn't formally
2071 // committed yet, so if we've already cleared |pending_web_ui_| the call chain 2005 // committed yet, so if we've already cleared the pending WebUI the call chain
2072 // this triggers won't be able to figure out what's going on. 2006 // this triggers won't be able to figure out what's going on.
2073 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault(); 2007 bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
2074 2008
2075 // Next commit the Web UI, if any. Either replace |web_ui_| with 2009 // If the current RenderFrameHost has a pending Web UI then just commit it and
2076 // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or 2010 // return (there should be nothing else to commit).
2077 // leave |web_ui_| as is if reusing it. 2011 if (render_frame_host_->pending_web_ui()) {
2078 DCHECK(!(pending_web_ui_ && pending_and_current_web_ui_)); 2012 DCHECK(!pending_render_frame_host_ && !speculative_render_frame_host_);
2079 if (pending_web_ui_ || speculative_web_ui_) { 2013 render_frame_host_->CommitPendingWebUI();
2080 DCHECK(!should_reuse_web_ui_);
2081 web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release()
2082 : pending_web_ui_.release());
2083 } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) {
2084 if (browser_side_navigation) {
2085 DCHECK(web_ui_);
2086 should_reuse_web_ui_ = false;
2087 } else {
2088 DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
2089 pending_and_current_web_ui_.reset();
2090 }
2091 } else {
2092 web_ui_.reset();
2093 }
2094 DCHECK(!speculative_web_ui_);
2095 DCHECK(!should_reuse_web_ui_);
2096
2097 // It's possible for the pending_render_frame_host_ to be nullptr when we
2098 // aren't crossing process boundaries. If so, we just needed to handle the Web
2099 // UI committing above and we're done.
2100 if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
2101 if (will_focus_location_bar) 2014 if (will_focus_location_bar)
2102 delegate_->SetFocusToLocationBar(false); 2015 delegate_->SetFocusToLocationBar(false);
2103 return; 2016 return;
2104 } 2017 }
2105 2018
2106 // Remember if the page was focused so we can focus the new renderer in 2019 // Remember if the page was focused so we can focus the new renderer in
2107 // that case. 2020 // that case.
2108 bool focus_render_view = !will_focus_location_bar && 2021 bool focus_render_view = !will_focus_location_bar &&
2109 render_frame_host_->GetView() && 2022 render_frame_host_->GetView() &&
2110 render_frame_host_->GetView()->HasFocus(); 2023 render_frame_host_->GetView()->HasFocus();
2111 2024
2112 bool is_main_frame = frame_tree_node_->IsMainFrame(); 2025 bool is_main_frame = frame_tree_node_->IsMainFrame();
2113 2026
2114 // Swap in the pending or speculative frame and make it active. Also ensure 2027 // Swap in the pending or speculative frame and make it active. Also ensure
2115 // the FrameTree stays in sync. 2028 // the FrameTree stays in sync.
2116 scoped_ptr<RenderFrameHostImpl> old_render_frame_host; 2029 scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
2117 if (!browser_side_navigation) { 2030 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
2031 switches::kEnableBrowserSideNavigation)) {
2118 DCHECK(!speculative_render_frame_host_); 2032 DCHECK(!speculative_render_frame_host_);
2119 old_render_frame_host = 2033 old_render_frame_host =
2120 SetRenderFrameHost(pending_render_frame_host_.Pass()); 2034 SetRenderFrameHost(pending_render_frame_host_.Pass());
2121 } else { 2035 } else {
2122 // PlzNavigate 2036 // PlzNavigate
2123 DCHECK(speculative_render_frame_host_); 2037 DCHECK(speculative_render_frame_host_);
2124 old_render_frame_host = 2038 old_render_frame_host =
2125 SetRenderFrameHost(speculative_render_frame_host_.Pass()); 2039 SetRenderFrameHost(speculative_render_frame_host_.Pass());
2126 } 2040 }
2127 2041
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 // If we are currently navigating cross-process, we want to get back to normal 2183 // If we are currently navigating cross-process, we want to get back to normal
2270 // and then navigate as usual. 2184 // and then navigate as usual.
2271 if (pending_render_frame_host_) 2185 if (pending_render_frame_host_)
2272 CancelPending(); 2186 CancelPending();
2273 2187
2274 SiteInstance* current_instance = render_frame_host_->GetSiteInstance(); 2188 SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
2275 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation( 2189 scoped_refptr<SiteInstance> new_instance = GetSiteInstanceForNavigation(
2276 dest_url, source_instance, dest_instance, nullptr, transition, 2190 dest_url, source_instance, dest_instance, nullptr, transition,
2277 dest_is_restore, dest_is_view_source_mode); 2191 dest_is_restore, dest_is_view_source_mode);
2278 2192
2279 const NavigationEntry* current_entry =
2280 delegate_->GetLastCommittedNavigationEntryForRenderManager();
2281
2282 DCHECK(!pending_render_frame_host_); 2193 DCHECK(!pending_render_frame_host_);
2283 2194
2284 if (new_instance.get() != current_instance) { 2195 if (new_instance.get() != current_instance) {
2285 TRACE_EVENT_INSTANT2( 2196 TRACE_EVENT_INSTANT2(
2286 "navigation", 2197 "navigation",
2287 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance", 2198 "RenderFrameHostManager::UpdateStateForNavigate:New SiteInstance",
2288 TRACE_EVENT_SCOPE_THREAD, 2199 TRACE_EVENT_SCOPE_THREAD,
2289 "current_instance id", current_instance->GetId(), 2200 "current_instance id", current_instance->GetId(),
2290 "new_instance id", new_instance->GetId()); 2201 "new_instance id", new_instance->GetId());
2291 2202
2292 // New SiteInstance: create a pending RFH to navigate. 2203 // New SiteInstance: create a pending RFH to navigate.
2293 2204
2294 // This will possibly create (set to nullptr) a Web UI object for the 2205 CreatePendingRenderFrameHost(current_instance, new_instance.get(), dest_url,
2295 // pending page. We'll use this later to give the page special access. This 2206 bindings);
2296 // must happen before the new renderer is created below so it will get
2297 // bindings. It must also happen after the above conditional call to
2298 // CancelPending(), otherwise CancelPending may clear the pending_web_ui_
2299 // and the page will not have its bindings set appropriately.
2300 SetPendingWebUI(dest_url, bindings);
2301 CreatePendingRenderFrameHost(current_instance, new_instance.get());
2302 if (!pending_render_frame_host_) 2207 if (!pending_render_frame_host_)
2303 return nullptr; 2208 return nullptr;
2304 2209
2305 // Check if our current RFH is live before we set up a transition. 2210 // Check if our current RFH is live before we set up a transition.
2306 if (!render_frame_host_->IsRenderFrameLive()) { 2211 if (!render_frame_host_->IsRenderFrameLive()) {
2307 // The current RFH is not live. There's no reason to sit around with a 2212 // The current RFH is not live. There's no reason to sit around with a
2308 // sad tab or a newly created RFH while we wait for the pending RFH to 2213 // sad tab or a newly created RFH while we wait for the pending RFH to
2309 // navigate. Just switch to the pending RFH now and go back to normal. 2214 // navigate. Just switch to the pending RFH now and go back to normal.
2310 // (Note that we don't care about on{before}unload handlers if the current 2215 // (Note that we don't care about on{before}unload handlers if the current
2311 // RFH isn't live.) 2216 // RFH isn't live.)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 2256
2352 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_. 2257 // Otherwise the same SiteInstance can be used. Navigate render_frame_host_.
2353 2258
2354 // It's possible to swap out the current RFH and then decide to navigate in it 2259 // It's possible to swap out the current RFH and then decide to navigate in it
2355 // anyway (e.g., a cross-process navigation that redirects back to the 2260 // anyway (e.g., a cross-process navigation that redirects back to the
2356 // original site). In that case, we have a proxy for the current RFH but 2261 // original site). In that case, we have a proxy for the current RFH but
2357 // haven't deleted it yet. The new navigation will swap it back in, so we can 2262 // haven't deleted it yet. The new navigation will swap it back in, so we can
2358 // delete the proxy. 2263 // delete the proxy.
2359 proxy_hosts_->Remove(new_instance.get()->GetId()); 2264 proxy_hosts_->Remove(new_instance.get()->GetId());
2360 2265
2361 if (ShouldReuseWebUI(current_entry, dest_url)) { 2266 render_frame_host_->UpdatePendingWebUI(dest_url, bindings);
2362 pending_web_ui_.reset();
2363 pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
2364 } else {
2365 SetPendingWebUI(dest_url, bindings);
2366 // Make sure the new RenderViewHost has the right bindings.
2367 if (pending_web_ui() &&
2368 !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
2369 render_frame_host_->render_view_host()->AllowBindings(
2370 pending_web_ui()->GetBindings());
2371 }
2372 }
2373
2374 if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) {
2375 pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(),
2376 frame_tree_node_->IsMainFrame());
2377 }
2378 2267
2379 // The renderer can exit view source mode when any error or cancellation 2268 // The renderer can exit view source mode when any error or cancellation
2380 // happen. We must overwrite to recover the mode. 2269 // happen. We must overwrite to recover the mode.
2381 if (dest_is_view_source_mode) { 2270 if (dest_is_view_source_mode) {
2382 render_frame_host_->render_view_host()->Send( 2271 render_frame_host_->render_view_host()->Send(
2383 new ViewMsg_EnableViewSourceMode( 2272 new ViewMsg_EnableViewSourceMode(
2384 render_frame_host_->render_view_host()->GetRoutingID())); 2273 render_frame_host_->render_view_host()->GetRoutingID()));
2385 } 2274 }
2386 2275
2387 return render_frame_host_.get(); 2276 return render_frame_host_.get();
2388 } 2277 }
2389 2278
2390 void RenderFrameHostManager::CancelPending() { 2279 void RenderFrameHostManager::CancelPending() {
2391 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending", 2280 TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
2392 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id()); 2281 "FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
2393 DiscardUnusedFrame(UnsetPendingRenderFrameHost()); 2282 DiscardUnusedFrame(UnsetPendingRenderFrameHost());
2283 render_frame_host_->DiscardPendingWebUI();
2394 } 2284 }
2395 2285
2396 scoped_ptr<RenderFrameHostImpl> 2286 scoped_ptr<RenderFrameHostImpl>
2397 RenderFrameHostManager::UnsetPendingRenderFrameHost() { 2287 RenderFrameHostManager::UnsetPendingRenderFrameHost() {
2398 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host = 2288 scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
2399 pending_render_frame_host_.Pass(); 2289 pending_render_frame_host_.Pass();
2400 2290
2401 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation( 2291 RenderFrameDevToolsAgentHost::OnCancelPendingNavigation(
2402 pending_render_frame_host.get(), 2292 pending_render_frame_host.get(),
2403 render_frame_host_.get()); 2293 render_frame_host_.get());
2404 2294
2405 // We no longer need to prevent the process from exiting. 2295 // We no longer need to prevent the process from exiting.
2406 pending_render_frame_host->GetProcess()->RemovePendingView(); 2296 pending_render_frame_host->GetProcess()->RemovePendingView();
2407 2297
2408 pending_web_ui_.reset();
2409 pending_and_current_web_ui_.reset();
2410
2411 return pending_render_frame_host.Pass(); 2298 return pending_render_frame_host.Pass();
2412 } 2299 }
2413 2300
2414 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost( 2301 scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::SetRenderFrameHost(
2415 scoped_ptr<RenderFrameHostImpl> render_frame_host) { 2302 scoped_ptr<RenderFrameHostImpl> render_frame_host) {
2416 // Swap the two. 2303 // Swap the two.
2417 scoped_ptr<RenderFrameHostImpl> old_render_frame_host = 2304 scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
2418 render_frame_host_.Pass(); 2305 render_frame_host_.Pass();
2419 render_frame_host_ = render_frame_host.Pass(); 2306 render_frame_host_ = render_frame_host.Pass();
2420 2307
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2575 if (rvh && !rvh->IsRenderViewLive()) { 2462 if (rvh && !rvh->IsRenderViewLive()) {
2576 EnsureRenderViewInitialized(rvh, instance); 2463 EnsureRenderViewInitialized(rvh, instance);
2577 } else { 2464 } else {
2578 // Create a swapped out RenderView in the given SiteInstance if none 2465 // Create a swapped out RenderView in the given SiteInstance if none
2579 // exists. Since an opener can point to a subframe, do this on the root 2466 // exists. Since an opener can point to a subframe, do this on the root
2580 // frame of the current opener's frame tree. 2467 // frame of the current opener's frame tree.
2581 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) { 2468 if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) {
2582 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance); 2469 frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance);
2583 } else { 2470 } else {
2584 frame_tree->root()->render_manager()->CreateRenderFrame( 2471 frame_tree->root()->render_manager()->CreateRenderFrame(
2585 instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, 2472 instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr);
2586 nullptr);
2587 } 2473 }
2588 } 2474 }
2589 } 2475 }
2590 } 2476 }
2591 2477
2592 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { 2478 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) {
2593 if (!frame_tree_node_->opener()) 2479 if (!frame_tree_node_->opener())
2594 return MSG_ROUTING_NONE; 2480 return MSG_ROUTING_NONE;
2595 2481
2596 return frame_tree_node_->opener() 2482 return frame_tree_node_->opener()
2597 ->render_manager() 2483 ->render_manager()
2598 ->GetRoutingIdForSiteInstance(instance); 2484 ->GetRoutingIdForSiteInstance(instance);
2599 } 2485 }
2600 2486
2601 } // namespace content 2487 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698