| 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
|
|
|