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

Unified Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 1422043007: Revert of Move WebUI ownership from the RenderFrameHostManager to the RenderFrameHost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/frame_host/render_frame_host_manager.cc
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index e4c7fd7f0eb44e0417a87ccb26a498e45084f89e..1f6101d375b5172ea843a7e52505c5285766a6aa 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -30,6 +30,7 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
+#include "content/browser/webui/web_ui_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
@@ -38,6 +39,7 @@
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/user_metrics.h"
+#include "content/public/browser/web_ui_controller.h"
#include "content/public/common/browser_plugin_guest_mode.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/referrer.h"
@@ -218,7 +220,7 @@
render_widget_delegate_(render_widget_delegate),
proxy_hosts_(new RenderFrameProxyHostMap(this)),
interstitial_page_(nullptr),
- current_web_ui_is_navigating_(false),
+ should_reuse_web_ui_(false),
weak_factory_(this) {
DCHECK(frame_tree_node_);
}
@@ -242,6 +244,10 @@
// RenderFrameProxyHost) points to the RenderWidgetHostView associated with
// the current RenderFrameHost and uses it during its destructor.
ResetProxyHosts();
+
+ // Release the WebUI prior to resetting the current RenderFrameHost, as the
+ // WebUI accesses the RenderFrameHost during cleanup.
+ web_ui_.reset();
// We should always have a current RenderFrameHost except in some tests.
SetRenderFrameHost(scoped_ptr<RenderFrameHostImpl>());
@@ -283,21 +289,6 @@
return pending_render_frame_host_->render_view_host();
}
-WebUIImpl* RenderFrameHostManager::GetNavigatingWebUI() const {
- if (current_web_ui_is_navigating_)
- return render_frame_host_->web_ui();
-
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
- if (speculative_render_frame_host_)
- return speculative_render_frame_host_->web_ui();
- } else {
- if (pending_render_frame_host_)
- return pending_render_frame_host_->web_ui();
- }
- return nullptr;
-}
-
RenderWidgetHostView* RenderFrameHostManager::GetRenderWidgetHostView() const {
if (interstitial_page_)
return interstitial_page_->GetView();
@@ -364,6 +355,27 @@
DCHECK(outer_delegate_frame_tree_node->parent());
outer_delegate_frame_tree_node->frame_tree()->RemoveFrame(
outer_delegate_frame_tree_node);
+}
+
+void RenderFrameHostManager::SetPendingWebUI(const GURL& url, int bindings) {
+ pending_web_ui_ = CreateWebUI(url, bindings);
+ pending_and_current_web_ui_.reset();
+}
+
+scoped_ptr<WebUIImpl> RenderFrameHostManager::CreateWebUI(const GURL& url,
+ int bindings) {
+ scoped_ptr<WebUIImpl> new_web_ui(delegate_->CreateWebUIForRenderManager(url));
+
+ // If we have assigned (zero or more) bindings to this NavigationEntry in the
+ // past, make sure we're not granting it different bindings than it had
+ // before. If so, note it and don't give it any bindings, to avoid a
+ // potential privilege escalation.
+ if (new_web_ui && bindings != NavigationEntryImpl::kInvalidBindings &&
+ new_web_ui->GetBindings() != bindings) {
+ RecordAction(base::UserMetricsAction("ProcessSwapBindingsMismatch_RVHM"));
+ return nullptr;
+ }
+ return new_web_ui.Pass();
}
RenderFrameHostImpl* RenderFrameHostManager::Navigate(
@@ -413,11 +425,6 @@
frame_tree_node_);
if (!InitRenderView(dest_render_frame_host->render_view_host(), nullptr))
return nullptr;
-
- if (GetNavigatingWebUI()) {
- GetNavigatingWebUI()->RenderViewCreated(
- dest_render_frame_host->render_view_host());
- }
// Now that we've created a new renderer, be sure to hide it if it isn't
// our primary one. Otherwise, we might crash if we try to call Show()
@@ -669,14 +676,13 @@
RenderFrameHostImpl* render_frame_host,
bool was_caused_by_user_gesture) {
if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
- DCHECK(!current_web_ui_is_navigating_ || render_frame_host_->web_ui());
+ DCHECK(!should_reuse_web_ui_ || web_ui_);
// We should only hear this from our current renderer.
DCHECK_EQ(render_frame_host_, render_frame_host);
- // A commit is required if there is a navigating WebUI, even without a
- // pending or speculative RenderFrameHost.
- if (GetNavigatingWebUI())
+ // Even when there is no pending RVH, there may be a pending Web UI.
+ if (pending_web_ui() || speculative_web_ui_)
CommitPending();
return;
}
@@ -1019,44 +1025,41 @@
(!request.browser_initiated() && is_main_frame) ||
(!is_main_frame && !dest_site_instance->RequiresDedicatedProcess() &&
!current_site_instance->RequiresDedicatedProcess())) {
- // Reuse the current RenderFrameHost if its SiteInstance matches the the
- // navigation's or if this is a subframe navigation. We only swap RFHs for
- // subframes when --site-per-process is enabled.
+ // Reuse the current RFH if its SiteInstance matches the the navigation's
+ // or if this is a subframe navigation. We only swap RFHs for subframes when
+ // --site-per-process is enabled.
CleanUpNavigation();
navigation_rfh = render_frame_host_.get();
- UpdateWebUIOnCurrentFrameHost(
- request.common_params().url,
- request.restore_type() != NavigationEntryImpl::RESTORE_NONE,
- request.bindings());
-
- DCHECK(!speculative_render_frame_host_);
+ // As SiteInstances are the same, check if the WebUI should be reused.
+ const NavigationEntry* current_navigation_entry =
+ delegate_->GetLastCommittedNavigationEntryForRenderManager();
+ should_reuse_web_ui_ = ShouldReuseWebUI(current_navigation_entry,
+ request.common_params().url);
+ if (!should_reuse_web_ui_) {
+ speculative_web_ui_ = CreateWebUI(request.common_params().url,
+ request.bindings());
+ // Make sure the current RenderViewHost has the right bindings.
+ if (speculative_web_ui() &&
+ !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
+ render_frame_host_->render_view_host()->AllowBindings(
+ speculative_web_ui()->GetBindings());
+ }
+ }
} else {
- // If the current RenderFrameHost cannot be used a new speculative one is
- // created with the SiteInstance for the current URL.
-
- // Check if an existing speculative RenderFrameHost can be reused.
+ // If the SiteInstance for the final URL doesn't match the one from the
+ // speculatively created RenderFrameHost, create a new RenderFrameHost using
+ // this new SiteInstance.
if (!speculative_render_frame_host_ ||
speculative_render_frame_host_->GetSiteInstance() !=
dest_site_instance.get()) {
- // If a previous speculative RenderFrameHost didn't exist or if its
- // SiteInstace differs from the one for the current URL, a new one needs
- // to be created.
CleanUpNavigation();
- bool success = CreateSpeculativeRenderFrameHost(current_site_instance,
- dest_site_instance.get());
+ bool success = CreateSpeculativeRenderFrameHost(
+ request.common_params().url, current_site_instance,
+ dest_site_instance.get(), request.bindings());
DCHECK(success);
}
-
- bool changed_web_ui = speculative_render_frame_host_->UpdateWebUI(
- request.common_params().url, request.bindings());
- if (changed_web_ui && speculative_render_frame_host_->web_ui()) {
- speculative_render_frame_host_->web_ui()->RenderViewCreated(
- speculative_render_frame_host_->render_view_host());
- }
DCHECK(speculative_render_frame_host_);
- DCHECK_EQ(GetNavigatingWebUI(), speculative_render_frame_host_->web_ui());
-
navigation_rfh = speculative_render_frame_host_.get();
// Check if our current RFH is live.
@@ -1068,7 +1071,6 @@
// RFH isn't live.)
CommitPending();
}
- DCHECK(!current_web_ui_is_navigating_);
}
DCHECK(navigation_rfh &&
(navigation_rfh == render_frame_host_.get() ||
@@ -1079,12 +1081,8 @@
if (!navigation_rfh->IsRenderFrameLive()) {
// Recreate the opener chain.
CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_);
- if (!InitRenderView(navigation_rfh->render_view_host(), nullptr))
+ if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) {
return nullptr;
-
- if (GetNavigatingWebUI()) {
- GetNavigatingWebUI()->RenderViewCreated(
- navigation_rfh->render_view_host());
}
if (navigation_rfh == render_frame_host_) {
@@ -1106,9 +1104,8 @@
void RenderFrameHostManager::CleanUpNavigation() {
CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBrowserSideNavigation));
- // TODO(carlosk): the discarding of the current RFH WebUI and the cleanup of
- // the speculative RFH should not always happen together.
- current_web_ui_is_navigating_ = false;
+ speculative_web_ui_.reset();
+ should_reuse_web_ui_ = false;
if (speculative_render_frame_host_)
DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
}
@@ -1299,6 +1296,18 @@
return true;
return false;
+}
+
+bool RenderFrameHostManager::ShouldReuseWebUI(
+ const NavigationEntry* current_entry,
+ const GURL& new_url) const {
+ NavigationControllerImpl& controller =
+ delegate_->GetControllerForRenderManager();
+ return current_entry && web_ui_ &&
+ (WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
+ controller.GetBrowserContext(), current_entry->GetURL()) ==
+ WebUIControllerFactoryRegistry::GetInstance()->GetWebUIType(
+ controller.GetBrowserContext(), new_url));
}
SiteInstance* RenderFrameHostManager::GetSiteInstanceForNavigation(
@@ -1633,8 +1642,8 @@
CreateProxiesForNewRenderFrameHost(old_instance, new_instance);
// Create a non-swapped-out RFH with the given opener.
- pending_render_frame_host_ =
- CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
+ pending_render_frame_host_ = CreateRenderFrame(
+ new_instance, pending_web_ui(), create_render_frame_flags, nullptr);
}
void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
@@ -1730,11 +1739,18 @@
// PlzNavigate
bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
+ const GURL& url,
SiteInstance* old_instance,
- SiteInstance* new_instance) {
+ SiteInstance* new_instance,
+ int bindings) {
CHECK(new_instance);
CHECK_NE(old_instance, new_instance);
- CHECK(!current_web_ui_is_navigating_);
+ CHECK(!should_reuse_web_ui_);
+
+ // Note: |speculative_web_ui_| must be initialized before starting the
+ // |speculative_render_frame_host_| creation steps otherwise the WebUI
+ // won't be properly initialized.
+ speculative_web_ui_ = CreateWebUI(url, bindings);
// The process for the new SiteInstance may (if we're sharing a process with
// another host that already initialized it) or may not (we have our own
@@ -1749,13 +1765,19 @@
if (delegate_->IsHidden())
create_render_frame_flags |= CREATE_RF_HIDDEN;
speculative_render_frame_host_ =
- CreateRenderFrame(new_instance, create_render_frame_flags, nullptr);
-
- return !!speculative_render_frame_host_;
+ CreateRenderFrame(new_instance, speculative_web_ui_.get(),
+ create_render_frame_flags, nullptr);
+
+ if (!speculative_render_frame_host_) {
+ speculative_web_ui_.reset();
+ return false;
+ }
+ return true;
}
scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
SiteInstance* instance,
+ WebUIImpl* web_ui,
int flags,
int* view_routing_id_ptr) {
bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
@@ -1873,6 +1895,21 @@
}
}
+ // When a new RenderView is created by the renderer process, the new
+ // WebContents gets a RenderViewHost in the SiteInstance of its opener
+ // WebContents. If not used in the first navigation, this RVH is swapped out
+ // and is not granted bindings, so we may need to grant them when swapping it
+ // in.
+ if (web_ui && !new_render_frame_host->GetProcess()->IsForGuestsOnly()) {
+ int required_bindings = web_ui->GetBindings();
+ RenderViewHost* render_view_host =
+ new_render_frame_host->render_view_host();
+ if ((render_view_host->GetEnabledBindings() & required_bindings) !=
+ required_bindings) {
+ render_view_host->AllowBindings(required_bindings);
+ }
+ }
+
// Returns the new RFH if it isn't swapped out.
if (success && !swapped_out) {
DCHECK(new_render_frame_host->GetSiteInstance() == instance);
@@ -1990,6 +2027,31 @@
// We may have initialized this RenderViewHost for another RenderFrameHost.
if (render_view_host->IsRenderViewLive())
return true;
+
+ // If |render_view_host| is not for a proxy and the navigation is to a WebUI,
+ // and if the RenderView is not in a guest process, tell |render_view_host|
+ // about any bindings it will need enabled.
+ // TODO(carlosk): Move WebUI to RenderFrameHost in https://crbug.com/508850.
+ WebUIImpl* dest_web_ui = nullptr;
+ if (!proxy) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation)) {
+ dest_web_ui =
+ should_reuse_web_ui_ ? web_ui_.get() : speculative_web_ui_.get();
+ } else {
+ dest_web_ui = pending_web_ui();
+ }
+ }
+ if (dest_web_ui && !render_view_host->GetProcess()->IsForGuestsOnly()) {
+ render_view_host->AllowBindings(dest_web_ui->GetBindings());
+ } else {
+ // Ensure that we don't create an unprivileged RenderView in a WebUI-enabled
+ // process unless it's swapped out.
+ if (render_view_host->is_active()) {
+ CHECK(!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ render_view_host->GetProcess()->GetID()));
+ }
+ }
int opener_frame_routing_id =
GetOpenerRoutingID(render_view_host->GetSiteInstance());
@@ -2082,17 +2144,42 @@
void RenderFrameHostManager::CommitPending() {
TRACE_EVENT1("navigation", "RenderFrameHostManager::CommitPending",
"FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
+ bool browser_side_navigation =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableBrowserSideNavigation);
+
// First check whether we're going to want to focus the location bar after
// this commit. We do this now because the navigation hasn't formally
- // committed yet, so if we've already cleared the pending WebUI the call chain
+ // committed yet, so if we've already cleared |pending_web_ui_| the call chain
// 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. 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_ && pending_and_current_web_ui_));
+ if (pending_web_ui_ || speculative_web_ui_) {
+ DCHECK(!should_reuse_web_ui_);
+ web_ui_.reset(browser_side_navigation ? speculative_web_ui_.release()
+ : pending_web_ui_.release());
+ } else if (pending_and_current_web_ui_ || should_reuse_web_ui_) {
+ if (browser_side_navigation) {
+ DCHECK(web_ui_);
+ should_reuse_web_ui_ = false;
+ } else {
+ DCHECK_EQ(pending_and_current_web_ui_.get(), web_ui_.get());
+ pending_and_current_web_ui_.reset();
+ }
+ } else {
+ web_ui_.reset();
+ }
+ DCHECK(!speculative_web_ui_);
+ DCHECK(!should_reuse_web_ui_);
+
+ // It's possible for the pending_render_frame_host_ to be nullptr when we
+ // aren't crossing process boundaries. If so, we just needed to handle the Web
+ // UI committing above and we're done.
if (!pending_render_frame_host_ && !speculative_render_frame_host_) {
- DCHECK_EQ(current_web_ui_is_navigating_, !!render_frame_host_->web_ui());
- current_web_ui_is_navigating_ = false;
- // If there's no pending/speculative RenderFrameHost then the current
- // RenderFrameHost is committing.
if (will_focus_location_bar)
delegate_->SetFocusToLocationBar(false);
return;
@@ -2109,8 +2196,7 @@
// Swap in the pending or speculative frame and make it active. Also ensure
// the FrameTree stays in sync.
scoped_ptr<RenderFrameHostImpl> old_render_frame_host;
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBrowserSideNavigation)) {
+ if (!browser_side_navigation) {
DCHECK(!speculative_render_frame_host_);
old_render_frame_host =
SetRenderFrameHost(pending_render_frame_host_.Pass());
@@ -2280,6 +2366,9 @@
dest_url, source_instance, dest_instance, nullptr, transition,
dest_is_restore, dest_is_view_source_mode);
+ const NavigationEntry* current_entry =
+ delegate_->GetLastCommittedNavigationEntryForRenderManager();
+
DCHECK(!pending_render_frame_host_);
if (new_instance.get() != current_instance) {
@@ -2292,20 +2381,16 @@
// New SiteInstance: create a pending RFH to navigate.
- current_web_ui_is_navigating_ = false;
+ // This will possibly create (set to nullptr) 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.
+ SetPendingWebUI(dest_url, bindings);
CreatePendingRenderFrameHost(current_instance, new_instance.get());
- DCHECK(pending_render_frame_host_);
if (!pending_render_frame_host_)
return nullptr;
-
- pending_render_frame_host_->UpdateWebUI(dest_url, bindings);
- if (pending_render_frame_host_->web_ui()) {
- pending_render_frame_host_->web_ui()->RenderViewCreated(
- pending_render_frame_host_->render_view_host());
- }
-
- // We now have a pending RFH and possibly an associated pending WebUI.
- DCHECK_EQ(GetNavigatingWebUI(), pending_render_frame_host_->web_ui());
// Check if our current RFH is live before we set up a transition.
if (!render_frame_host_->IsRenderFrameLive()) {
@@ -2319,12 +2404,16 @@
}
// Otherwise, it's safe to treat this as a pending cross-process transition.
+ // We now have a pending RFH.
+ DCHECK(pending_render_frame_host_);
+
// We need to wait until the beforeunload handler has run, unless we are
// transferring an existing request (in which case it has already run).
// Suspend the new render view (i.e., don't let it send the cross-process
// Navigate message) until we hear back from the old renderer's
// beforeunload handler. If the handler returns false, we'll have to
// cancel the request.
+ //
DCHECK(!pending_render_frame_host_->are_navigations_suspended());
bool is_transfer = transferred_request_id != GlobalRequestID();
if (is_transfer) {
@@ -2359,7 +2448,23 @@
// delete the proxy.
proxy_hosts_->Remove(new_instance.get()->GetId());
- UpdateWebUIOnCurrentFrameHost(dest_url, dest_is_restore, bindings);
+ if (ShouldReuseWebUI(current_entry, dest_url)) {
+ pending_web_ui_.reset();
+ pending_and_current_web_ui_ = web_ui_->AsWeakPtr();
+ } else {
+ SetPendingWebUI(dest_url, bindings);
+ // Make sure the new RenderViewHost has the right bindings.
+ if (pending_web_ui() &&
+ !render_frame_host_->GetProcess()->IsForGuestsOnly()) {
+ render_frame_host_->render_view_host()->AllowBindings(
+ pending_web_ui()->GetBindings());
+ }
+ }
+
+ if (pending_web_ui() && render_frame_host_->IsRenderFrameLive()) {
+ pending_web_ui()->RenderViewReused(render_frame_host_->render_view_host(),
+ frame_tree_node_->IsMainFrame());
+ }
// The renderer can exit view source mode when any error or cancellation
// happen. We must overwrite to recover the mode.
@@ -2372,39 +2477,9 @@
return render_frame_host_.get();
}
-void RenderFrameHostManager::UpdateWebUIOnCurrentFrameHost(const GURL& dest_url,
- bool dest_is_restore,
- int bindings) {
- WebUI::TypeID previous_web_ui_type = render_frame_host_->web_ui_type();
- bool changed_web_ui = render_frame_host_->UpdateWebUI(dest_url, bindings);
-
- // If a change in WebUI happened, check this is an acceptable case.
- if (changed_web_ui)
- CheckWebUITransition(previous_web_ui_type, dest_url, dest_is_restore);
-
- // If there is a WebUI in the current RenderFrameHost, it will navigate.
- current_web_ui_is_navigating_ = !!render_frame_host_->web_ui();
- DCHECK_EQ(GetNavigatingWebUI(), render_frame_host_->web_ui());
-
- // If the current RenderFrameHost has a WebUI and the associated RenderFrame
- // is alive, notify to the WebUI that the RenderView is being created or
- // reused depending on whether the WebUI was changed or not.
- if (GetNavigatingWebUI() && render_frame_host_->IsRenderFrameLive()) {
- if (changed_web_ui) {
- GetNavigatingWebUI()->RenderViewCreated(
- render_frame_host_->render_view_host());
- } else {
- GetNavigatingWebUI()->RenderViewReused(
- render_frame_host_->render_view_host(),
- frame_tree_node_->IsMainFrame());
- }
- }
-}
-
void RenderFrameHostManager::CancelPending() {
TRACE_EVENT1("navigation", "RenderFrameHostManager::CancelPending",
"FrameTreeNode id", frame_tree_node_->frame_tree_node_id());
- current_web_ui_is_navigating_ = false;
DiscardUnusedFrame(UnsetPendingRenderFrameHost());
}
@@ -2417,10 +2492,11 @@
pending_render_frame_host.get(),
render_frame_host_.get());
- current_web_ui_is_navigating_ = false;
-
// We no longer need to prevent the process from exiting.
pending_render_frame_host->GetProcess()->RemovePendingView();
+
+ pending_web_ui_.reset();
+ pending_and_current_web_ui_.reset();
return pending_render_frame_host.Pass();
}
@@ -2596,7 +2672,8 @@
frame_tree->root()->render_manager()->CreateRenderFrameProxy(instance);
} else {
frame_tree->root()->render_manager()->CreateRenderFrame(
- instance, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN, nullptr);
+ instance, nullptr, CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
+ nullptr);
}
}
}
@@ -2611,51 +2688,4 @@
->GetRoutingIdForSiteInstance(instance);
}
-void RenderFrameHostManager::CheckWebUITransition(
- WebUI::TypeID previous_web_ui_type,
- const GURL& dest_url,
- bool dest_is_restore) {
- // There are a few navigation cases that allow for changes to the WebUI of
- // the current RenderFrameHost.
- BrowserContext* browser_context =
- delegate_->GetControllerForRenderManager().GetBrowserContext();
- if (render_frame_host_->web_ui()) {
- // Switching WebUI from one type to another while keeping the
- // RenderFrameHost is never acceptable.
- CHECK(previous_web_ui_type == WebUI::kNoWebUI);
-
- // Going from not having to having a WebUI is acceptable for:
- // - The first navigation of this frame.
- const NavigationEntry* current_entry =
- delegate_->GetLastCommittedNavigationEntryForRenderManager();
- bool is_first_navigation_for_frame = !current_entry;
-
- // - A restore navigation to a WebUI URL.
- const GURL& current_effective_url =
- current_entry ? SiteInstanceImpl::GetEffectiveURL(
- browser_context, current_entry->GetURL())
- : render_frame_host_->GetSiteInstance()->GetSiteURL();
- bool is_webui_restore =
- dest_is_restore &&
- WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
- browser_context, current_effective_url);
-
- // - Navigating back from a special renderer URL.
- bool is_back_from_renderer_url =
- current_entry && IsRendererDebugURL(current_entry->GetURL());
-
- // - Navigating in webview tag guest.
- bool is_webview_tag_guest =
- render_frame_host_->GetSiteInstance()->GetSiteURL().SchemeIs(
- kGuestScheme);
- CHECK(is_first_navigation_for_frame || is_webui_restore ||
- is_back_from_renderer_url || is_webview_tag_guest);
- } else {
- // Going from having to not having a WebUI is acceptable when Navigating to
- // a special renderer URL.
- CHECK(IsRendererDebugURL(
- SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url)));
- }
-}
-
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698