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

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

Issue 10154004: re-use WebUIs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: WeakPtr solution Created 8 years, 8 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
diff --git a/content/browser/web_contents/render_view_host_manager.cc b/content/browser/web_contents/render_view_host_manager.cc
index 95021bfbf2be75f0d7b09e1e628278fa3c28eea6..c167333623d82f11f32401fb98e9ff652ba7646f 100644
--- a/content/browser/web_contents/render_view_host_manager.cc
+++ b/content/browser/web_contents/render_view_host_manager.cc
@@ -206,7 +206,7 @@ void RenderViewHostManager::DidNavigateMainFrame(
DCHECK(render_view_host == render_view_host_);
// Even when there is no pending RVH, there may be a pending Web UI.
- if (pending_web_ui_.get())
+ if (pending_web_ui())
CommitPending();
return;
}
@@ -358,7 +358,7 @@ bool RenderViewHostManager::ShouldTransitionCrossSite() {
}
bool RenderViewHostManager::ShouldSwapProcessesForNavigation(
- const NavigationEntry* cur_entry,
+ const NavigationEntry* curr_entry,
const NavigationEntryImpl* new_entry) const {
DCHECK(new_entry);
@@ -366,9 +366,9 @@ bool RenderViewHostManager::ShouldSwapProcessesForNavigation(
// 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 cur_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 = (cur_entry) ? cur_entry->GetURL() :
+ const GURL& current_url = (curr_entry) ? curr_entry->GetURL() :
render_view_host_->GetSiteInstance()->GetSite();
content::BrowserContext* browser_context =
delegate_->GetControllerForRenderManager().GetBrowserContext();
@@ -389,23 +389,37 @@ bool RenderViewHostManager::ShouldSwapProcessesForNavigation(
}
if (content::GetContentClient()->browser()->ShouldSwapProcessesForNavigation(
- cur_entry ? cur_entry->GetURL() : GURL(), new_entry->GetURL())) {
+ curr_entry ? curr_entry->GetURL() : GURL(), new_entry->GetURL())) {
return true;
}
- if (!cur_entry)
+ 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 view switch.
- if (cur_entry->IsViewSourceMode() != new_entry->IsViewSourceMode())
+ if (curr_entry->IsViewSourceMode() != new_entry->IsViewSourceMode())
return true;
return false;
}
+bool RenderViewHostManager::ShouldReuseWebUI(
+ const NavigationEntry* curr_entry,
+ const NavigationEntryImpl* new_entry) const {
+ NavigationControllerImpl& controller =
+ delegate_->GetControllerForRenderManager();
+ WebUIControllerFactory* factory =
+ content::GetContentClient()->browser()->GetWebUIControllerFactory();
+ return curr_entry && web_ui_.get() &&
+ (factory->GetWebUIType(controller.GetBrowserContext(),
+ curr_entry->GetURL()) ==
+ factory->GetWebUIType(controller.GetBrowserContext(),
+ new_entry->GetURL()));
+}
+
SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
const NavigationEntryImpl& entry,
SiteInstance* curr_instance) {
@@ -581,8 +595,8 @@ bool RenderViewHostManager::InitRenderView(RenderViewHost* render_view_host,
const NavigationEntryImpl& entry) {
// If the pending navigation is to a WebUI, tell the RenderView about any
// bindings it will need enabled.
- if (pending_web_ui_.get())
- render_view_host->AllowBindings(pending_web_ui_->GetBindings());
+ if (pending_web_ui())
+ render_view_host->AllowBindings(pending_web_ui()->GetBindings());
return delegate_->CreateRenderViewForRenderManager(render_view_host);
}
@@ -594,11 +608,14 @@ void RenderViewHostManager::CommitPending() {
// this triggers won't be able to figure out what's going on.
bool will_focus_location_bar = delegate_->FocusLocationBarByDefault();
- // Next commit the Web UI, if any.
- web_ui_.swap(pending_web_ui_);
- if (web_ui_.get() && pending_web_ui_.get() && !pending_render_view_host_)
- web_ui_->GetController()->DidBecomeActiveForReusedRenderView();
- pending_web_ui_.reset();
+ // Next commit the Web UI, if any. Either replace |web_ui_| with
+ // |pending_web_ui_|, or clear |web_ui_| if there is no pending WebUI, or
+ // leave |web_ui_| as is if reusing it.
+ DCHECK(!(pending_web_ui_.get() && pending_and_current_web_ui_.get()));
+ if (pending_web_ui_.get())
+ web_ui_.reset(pending_web_ui_.release());
+ else if (!pending_and_current_web_ui_.get())
+ web_ui_.reset();
// It's possible for the pending_render_view_host_ to be NULL when we aren't
// crossing process boundaries. If so, we just needed to handle the Web UI
@@ -692,14 +709,6 @@ RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
cross_navigation_pending_ = false;
}
- // This will possibly create (set to NULL) a Web UI object for the pending
- // page. We'll use this later to give the page special access. This must
- // happen before the new renderer is created below so it will get bindings.
- // It must also happen after the above conditional call to CancelPending(),
- // otherwise CancelPending may clear the pending_web_ui_ and the page will
- // not have it's bindings set appropriately.
- pending_web_ui_.reset(delegate_->CreateWebUIForRenderManager(entry.GetURL()));
-
// 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();
@@ -708,8 +717,9 @@ RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
// 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;
- bool force_swap = ShouldSwapProcessesForNavigation(
- delegate_->GetLastCommittedNavigationEntryForRenderManager(), &entry);
+ const content::NavigationEntry* curr_entry =
+ delegate_->GetLastCommittedNavigationEntryForRenderManager();
+ bool force_swap = ShouldSwapProcessesForNavigation(curr_entry, &entry);
if (ShouldTransitionCrossSite() || force_swap)
new_instance = GetSiteInstanceForEntry(entry, curr_instance);
@@ -717,6 +727,16 @@ RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
// New SiteInstance.
DCHECK(!cross_navigation_pending_);
+ // This will possibly create (set to NULL) a Web UI object for the pending
+ // page. We'll use this later to give the page special access. This must
+ // happen before the new renderer is created below so it will get bindings.
+ // It must also happen after the above conditional call to CancelPending(),
+ // otherwise CancelPending may clear the pending_web_ui_ and the page will
+ // not have its bindings set appropriately.
+ pending_web_ui_.reset(
+ delegate_->CreateWebUIForRenderManager(entry.GetURL()));
+ pending_and_current_web_ui_.reset();
+
// Create a pending RVH and navigate it.
bool success = CreatePendingRenderView(entry, new_instance);
if (!success)
@@ -766,8 +786,17 @@ RenderViewHostImpl* RenderViewHostManager::UpdateRendererStateForNavigate(
return pending_render_view_host_;
} else {
- if (pending_web_ui_.get() && render_view_host_->IsRenderViewLive())
- pending_web_ui_->GetController()->RenderViewReused(render_view_host_);
+ 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_);
// The renderer can exit view source mode when any error or cancellation
// happen. We must overwrite to recover the mode.
@@ -811,6 +840,7 @@ void RenderViewHostManager::CancelPending() {
}
pending_web_ui_.reset();
+ pending_and_current_web_ui_.reset();
}
void RenderViewHostManager::RenderViewDeleted(RenderViewHost* rvh) {
« no previous file with comments | « content/browser/web_contents/render_view_host_manager.h ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698