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

Unified Diff: content/browser/web_contents/render_view_host_manager.cc

Issue 10546029: Revert 139933 - Clean up RenderViewHostManager swapping logic. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/web_contents/render_view_host_manager.cc
===================================================================
--- content/browser/web_contents/render_view_host_manager.cc (revision 140789)
+++ content/browser/web_contents/render_view_host_manager.cc (working copy)
@@ -8,7 +8,6 @@
#include "base/command_line.h"
#include "base/logging.h"
-#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/debugger/devtools_manager_impl.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -24,7 +23,6 @@
#include "content/public/browser/web_contents_view.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/web_ui_controller_factory.h"
-#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
@@ -360,63 +358,51 @@
return !CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerTab);
}
-bool RenderViewHostManager::ShouldSwapBrowsingInstanceForNavigation(
- const NavigationEntry* current_entry,
+bool RenderViewHostManager::ShouldSwapProcessesForNavigation(
+ const NavigationEntry* curr_entry,
const NavigationEntryImpl* new_entry) const {
DCHECK(new_entry);
- // If new_entry already has a SiteInstance, assume it is correct and use it.
- if (new_entry->site_instance())
- return false;
-
// Check for reasons to swap processes even if we are in a process model that
- // doesn't usually swap (e.g., process-per-tab). Any time we return true,
- // the new_entry will be rendered in a new SiteInstance AND BrowsingInstance.
+ // doesn't usually swap (e.g., process-per-tab).
// For security, we should transition between processes when one is a Web UI
- // page and one isn't. If there's no current_entry, check the current RVH's
+ // page and one isn't. If there's no curr_entry, check the current RVH's
// site, which might already be committed to a Web UI URL (such as the NTP).
- const GURL& current_url = current_entry ? current_entry->GetURL() :
+ const GURL& current_url = (curr_entry) ? curr_entry->GetURL() :
render_view_host_->GetSiteInstance()->GetSite();
- const GURL& new_url = new_entry->GetURL();
content::BrowserContext* browser_context =
delegate_->GetControllerForRenderManager().GetBrowserContext();
const WebUIControllerFactory* web_ui_factory =
content::GetContentClient()->browser()->GetWebUIControllerFactory();
if (web_ui_factory) {
- int enabled_bindings = render_view_host_->GetEnabledBindings();
-
- // Check if we're currently in a WebUI RenderViewHost, based on either URL
- // or bindings.
- if (enabled_bindings & content::BINDINGS_POLICY_WEB_UI ||
- web_ui_factory->UseWebUIForURL(browser_context, current_url)) {
- // If so, force a swap if destination not an acceptable URL for Web UI.
+ if (web_ui_factory->UseWebUIForURL(browser_context, current_url)) {
+ // Force swap if it's not an acceptable URL for Web UI.
// Here, data URLs are never allowed.
- if (!web_ui_factory->IsURLAcceptableForWebUI(browser_context, new_url,
- false))
+ if (!web_ui_factory->IsURLAcceptableForWebUI(browser_context,
+ new_entry->GetURL(), false))
return true;
} else {
- // Force a swap if it's a Web UI URL.
- if (web_ui_factory->UseWebUIForURL(browser_context, new_url))
+ // Force swap if it's a Web UI URL.
+ if (web_ui_factory->UseWebUIForURL(browser_context, new_entry->GetURL()))
return true;
}
}
- // Also let the embedder decide if a BrowsingInstance swap is required.
- if (content::GetContentClient()->browser()->
- ShouldSwapBrowsingInstanceForNavigation(browser_context,
- current_url, new_url)) {
+ if (content::GetContentClient()->browser()->ShouldSwapProcessesForNavigation(
+ curr_entry ? curr_entry->GetURL() : GURL(), new_entry->GetURL())) {
return true;
}
+ if (!curr_entry)
+ return false;
+
// We can't switch a RenderView between view source and non-view source mode
// without screwing up the session history sometimes (when navigating between
// "view-source:http://foo.com/" and "http://foo.com/", WebKit doesn't treat
- // it as a new navigation). So require a BrowsingInstance switch.
- if (current_entry &&
- current_entry->IsViewSourceMode() != new_entry->IsViewSourceMode()) {
+ // it as a new navigation). So require a view switch.
+ if (curr_entry->IsViewSourceMode() != new_entry->IsViewSourceMode())
return true;
- }
return false;
}
@@ -437,37 +423,28 @@
SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
const NavigationEntryImpl& entry,
- SiteInstance* curr_instance,
- bool force_swap) {
- // Determine which SiteInstance to use for navigating to |entry|.
+ SiteInstance* curr_instance) {
+ // NOTE: This is only called when ShouldTransitionCrossSite is true.
+
const GURL& dest_url = entry.GetURL();
NavigationControllerImpl& controller =
delegate_->GetControllerForRenderManager();
content::BrowserContext* browser_context = controller.GetBrowserContext();
- // If a swap is required, we need to force the SiteInstance AND
- // BrowsingInstance to be different ones. This addresses special cases where
- // we use a single BrowsingInstance for all pages of a certain type (e.g., New
- // Tab Pages), keeping them in the same process. When you navigate away from
- // that page, we want to explicity ignore that BrowsingInstance and group this
- // page into the appropriate SiteInstance for its URL.
- if (force_swap) {
- // We shouldn't be forcing a swap if an entry already has a SiteInstance.
- DCHECK(!entry.site_instance());
- return SiteInstance::CreateForURL(browser_context, dest_url);
- }
-
// If the entry has an instance already we should use it.
if (entry.site_instance())
return entry.site_instance();
// (UGLY) HEURISTIC, process-per-site only:
+ //
// If this navigation is generated, then it probably corresponds to a search
// query. Given that search results typically lead to users navigating to
// other sites, we don't really want to use the search engine hostname to
// determine the site instance for this navigation.
+ //
// NOTE: This can be removed once we have a way to transition between
// RenderViews in response to a link click.
+ //
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kProcessPerSite) &&
entry.GetTransitionType() == content::PAGE_TRANSITION_GENERATED)
return curr_instance;
@@ -510,7 +487,7 @@
return curr_site_instance;
}
- // Otherwise, only create a new SiteInstance for a cross-site navigation.
+ // Otherwise, only create a new SiteInstance for cross-site navigation.
// TODO(creis): Once we intercept links and script-based navigations, we
// will be able to enforce that all entries in a SiteInstance actually have
@@ -551,16 +528,25 @@
// process type is correct. (The URL may have been installed as an app since
// the last time we visited it.)
if (SiteInstance::IsSameWebSite(browser_context, current_url, dest_url) &&
- !curr_site_instance->HasWrongProcessForURL(dest_url)) {
+ !static_cast<SiteInstanceImpl*>(curr_instance)->HasWrongProcessForURL(
+ dest_url)) {
return curr_instance;
+ } else if (ShouldSwapProcessesForNavigation(curr_entry, &entry)) {
+ // When we're swapping, we need to force the site instance AND browsing
+ // instance to be different ones. This addresses special cases where we use
+ // a single BrowsingInstance for all pages of a certain type (e.g., New Tab
+ // Pages), keeping them in the same process. When you navigate away from
+ // that page, we want to explicity ignore that BrowsingInstance and group
+ // this page into the appropriate SiteInstance for its URL.
+ return SiteInstance::CreateForURL(browser_context, dest_url);
+ } else {
+ // Start the new renderer in a new SiteInstance, but in the current
+ // BrowsingInstance. It is important to immediately give this new
+ // SiteInstance to a RenderViewHost (if it is different than our current
+ // SiteInstance), so that it is ref counted. This will happen in
+ // CreateRenderView.
+ return curr_instance->GetRelatedSiteInstance(dest_url);
}
-
- // Otherwise start the new renderer in a new SiteInstance, but in the current
- // BrowsingInstance. It is important to immediately give this new
- // SiteInstance to a RenderViewHost (if it is different than our current
- // SiteInstance), so that it is ref counted. This will happen in
- // CreateRenderView.
- return curr_instance->GetRelatedSiteInstance(dest_url);
}
int RenderViewHostManager::CreateRenderView(
@@ -614,14 +600,8 @@
int opener_route_id) {
// If the pending navigation is to a WebUI, tell the RenderView about any
// bindings it will need enabled.
- if (pending_web_ui()) {
+ if (pending_web_ui())
render_view_host->AllowBindings(pending_web_ui()->GetBindings());
- } else {
- // Ensure that we don't create an unprivileged view in a WebUI-enabled
- // process.
- CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
- render_view_host->GetProcess()->GetID()));
- }
return delegate_->CreateRenderViewForRenderManager(render_view_host,
opener_route_id);
@@ -727,40 +707,30 @@
RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
const NavigationEntryImpl& entry) {
- // If we are currently navigating cross-process, we want to get back to normal
- // and then navigate as usual.
+ // If we are cross-navigating, then we want to get back to normal and navigate
+ // as usual.
if (cross_navigation_pending_) {
if (pending_render_view_host_)
CancelPending();
cross_navigation_pending_ = false;
}
- // render_view_host_'s SiteInstance and new_instance will not be deleted
- // before the end of this method, so we don't have to worry about their ref
- // counts dropping to zero.
+ // render_view_host_ will not be deleted before the end of this method, so we
+ // don't have to worry about this SiteInstance's ref count dropping to zero.
SiteInstance* curr_instance = render_view_host_->GetSiteInstance();
- SiteInstance* new_instance = curr_instance;
- // Determine if we need a new BrowsingInstance for this entry. If true,
- // this implies it will get a new SiteInstance (and likely process), and
- // that other tabs in the current BrowsingInstance will be unable to script
- // it. This is used for cases that require a process swap even in the
- // process-per-tab model, such as WebUI pages.
+ // Determine if we need a new SiteInstance for this entry.
+ // Again, new_instance won't be deleted before the end of this method, so it
+ // is safe to use a normal pointer here.
+ SiteInstance* new_instance = curr_instance;
const content::NavigationEntry* curr_entry =
delegate_->GetLastCommittedNavigationEntryForRenderManager();
- bool force_swap = ShouldSwapBrowsingInstanceForNavigation(curr_entry,
- &entry);
+ bool force_swap = ShouldSwapProcessesForNavigation(curr_entry, &entry);
if (ShouldTransitionCrossSite() || force_swap)
- new_instance = GetSiteInstanceForEntry(entry, curr_instance, force_swap);
+ new_instance = GetSiteInstanceForEntry(entry, curr_instance);
- // If force_swap is true, we must use a different SiteInstance. If we didn't,
- // we would have two RenderViewHosts in the same SiteInstance and the same
- // tab, resulting in page_id conflicts for their NavigationEntries.
- if (force_swap)
- CHECK_NE(new_instance, curr_instance);
-
- if (new_instance != curr_instance) {
- // New SiteInstance: create a pending RVH to navigate.
+ if (new_instance != curr_instance || force_swap) {
+ // New SiteInstance.
DCHECK(!cross_navigation_pending_);
// This will possibly create (set to NULL) a Web UI object for the pending
@@ -831,29 +801,30 @@
render_view_host_->FirePageBeforeUnload(true);
return pending_render_view_host_;
- }
-
- // Otherwise the same SiteInstance can be used. Navigate render_view_host_.
- DCHECK(!cross_navigation_pending_);
- if (ShouldReuseWebUI(curr_entry, &entry)) {
- pending_web_ui_.reset();
- pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
} else {
- pending_and_current_web_ui_.reset();
- pending_web_ui_.reset(
- delegate_->CreateWebUIForRenderManager(entry.GetURL()));
- }
+ if (ShouldReuseWebUI(curr_entry, &entry)) {
+ pending_web_ui_.reset();
+ pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
+ } else {
+ pending_and_current_web_ui_.reset();
+ pending_web_ui_.reset(
+ delegate_->CreateWebUIForRenderManager(entry.GetURL()));
+ }
- if (pending_web_ui() && render_view_host_->IsRenderViewLive())
- pending_web_ui()->GetController()->RenderViewReused(render_view_host_);
+ if (pending_web_ui() && render_view_host_->IsRenderViewLive())
+ pending_web_ui()->GetController()->RenderViewReused(render_view_host_);
- // The renderer can exit view source mode when any error or cancellation
- // happen. We must overwrite to recover the mode.
- if (entry.IsViewSourceMode()) {
- render_view_host_->Send(
- new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
+ // The renderer can exit view source mode when any error or cancellation
+ // happen. We must overwrite to recover the mode.
+ if (entry.IsViewSourceMode()) {
+ render_view_host_->Send(
+ new ViewMsg_EnableViewSourceMode(render_view_host_->GetRoutingID()));
+ }
}
+ // Same SiteInstance can be used. Navigate render_view_host_ if we are not
+ // cross navigating.
+ DCHECK(!cross_navigation_pending_);
return render_view_host_;
}

Powered by Google App Engine
This is Rietveld 408576698