diff options
Diffstat (limited to 'chrome/browser/render_view_host_manager.cc')
-rw-r--r-- | chrome/browser/render_view_host_manager.cc | 551 |
1 files changed, 48 insertions, 503 deletions
diff --git a/chrome/browser/render_view_host_manager.cc b/chrome/browser/render_view_host_manager.cc index 81e95aa..5ad576b 100644 --- a/chrome/browser/render_view_host_manager.cc +++ b/chrome/browser/render_view_host_manager.cc @@ -6,7 +6,6 @@ #include "base/command_line.h" #include "base/logging.h" -#include "chrome/browser/interstitial_page.h" #include "chrome/browser/navigation_controller.h" #include "chrome/browser/navigation_entry.h" #include "chrome/browser/render_widget_host_view.h" @@ -16,37 +15,23 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/notification_service.h" -// Destroys the given |**render_view_host| and NULLs out |*render_view_host| -// and then NULLs the field. Callers should only pass pointers to the -// pending_render_view_host_, interstitial_render_view_host_, or -// original_render_view_host_ fields of this object. -static void CancelRenderView(RenderViewHost** render_view_host) { - (*render_view_host)->Shutdown(); - (*render_view_host) = NULL; -} - RenderViewHostManager::RenderViewHostManager( RenderViewHostFactory* render_view_factory, RenderViewHostDelegate* render_view_delegate, Delegate* delegate) : delegate_(delegate), - renderer_state_(NORMAL), + cross_navigation_pending_(false), render_view_factory_(render_view_factory), render_view_delegate_(render_view_delegate), render_view_host_(NULL), - original_render_view_host_(NULL), - interstitial_render_view_host_(NULL), pending_render_view_host_(NULL), - interstitial_page_(NULL), - showing_repost_interstitial_(false) { + interstitial_page_(NULL) { } RenderViewHostManager::~RenderViewHostManager() { // Shutdown should have been called which should have cleaned these up. DCHECK(!render_view_host_); DCHECK(!pending_render_view_host_); - DCHECK(!original_render_view_host_); - DCHECK(!interstitial_render_view_host_); } void RenderViewHostManager::Init(Profile* profile, @@ -63,21 +48,8 @@ void RenderViewHostManager::Init(Profile* profile, } void RenderViewHostManager::Shutdown() { - if (showing_interstitial_page()) { - // The tab is closed while the interstitial page is showing, hide and - // destroy it. - HideInterstitialPage(false, false); - } - DCHECK(!interstitial_render_view_host_) << "Should have been deleted by Hide"; - - if (pending_render_view_host_) { - pending_render_view_host_->Shutdown(); - pending_render_view_host_ = NULL; - } - if (original_render_view_host_) { - original_render_view_host_->Shutdown(); - original_render_view_host_ = NULL; - } + if (pending_render_view_host_) + CancelPendingRenderView(); // We should always have a main RenderViewHost. render_view_host_->Shutdown(); @@ -123,29 +95,17 @@ RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { } } - showing_repost_interstitial_ = false; return dest_render_view_host; } void RenderViewHostManager::Stop() { render_view_host_->Stop(); - // If we aren't in the NORMAL renderer state, we should stop the pending - // renderers. This will lead to a DidFailProvisionalLoad, which will - // properly destroy them. - if (renderer_state_ == PENDING) { + // If we are cross-navigating, we should stop the pending renderers. This + // will lead to a DidFailProvisionalLoad, which will properly destroy them. + if (cross_navigation_pending_) { pending_render_view_host_->Stop(); - } else if (renderer_state_ == ENTERING_INTERSTITIAL) { - interstitial_render_view_host_->Stop(); - if (pending_render_view_host_) { - pending_render_view_host_->Stop(); - } - - } else if (renderer_state_ == LEAVING_INTERSTITIAL) { - if (pending_render_view_host_) { - pending_render_view_host_->Stop(); - } } } @@ -153,12 +113,10 @@ void RenderViewHostManager::SetIsLoading(bool is_loading) { render_view_host_->SetIsLoading(is_loading); if (pending_render_view_host_) pending_render_view_host_->SetIsLoading(is_loading); - if (original_render_view_host_) - original_render_view_host_->SetIsLoading(is_loading); } bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() { - if (renderer_state_ != PENDING) + if (!cross_navigation_pending_) return true; // If the tab becomes unresponsive during unload while doing a @@ -178,119 +136,31 @@ bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() { void RenderViewHostManager::DidNavigateMainFrame( RenderViewHost* render_view_host) { - if (renderer_state_ == NORMAL) { + if (!cross_navigation_pending_) { // We should only hear this from our current renderer. DCHECK(render_view_host == render_view_host_); return; - } else if (renderer_state_ == PENDING) { - if (render_view_host == pending_render_view_host_) { - // The pending cross-site navigation completed, so show the renderer. - SwapToRenderView(&pending_render_view_host_, true); - renderer_state_ = NORMAL; - } else if (render_view_host == render_view_host_) { - // A navigation in the original page has taken place. Cancel the pending - // one. - CancelRenderView(&pending_render_view_host_); - renderer_state_ = NORMAL; - } else { - // No one else should be sending us DidNavigate in this state. - DCHECK(false); - return; - } - - } else if (renderer_state_ == ENTERING_INTERSTITIAL) { - if (render_view_host == interstitial_render_view_host_) { - // The interstitial renderer is ready, so show it, and keep the old - // RenderViewHost around. - original_render_view_host_ = render_view_host_; - SwapToRenderView(&interstitial_render_view_host_, false); - renderer_state_ = INTERSTITIAL; - } else if (render_view_host == render_view_host_) { - // We shouldn't get here, because the original render view was the one - // that caused the ShowInterstitial. - // However, until we intercept navigation events from JavaScript, it is - // possible to get here, if another tab tells render_view_host_ to - // navigate. To be safe, we'll cancel the interstitial and show the - // page that caused the DidNavigate. - CancelRenderView(&interstitial_render_view_host_); - if (pending_render_view_host_) - CancelRenderView(&pending_render_view_host_); - renderer_state_ = NORMAL; - } else if (render_view_host == pending_render_view_host_) { - // We shouldn't get here, because the original render view was the one - // that caused the ShowInterstitial. - // However, until we intercept navigation events from JavaScript, it is - // possible to get here, if another tab tells pending_render_view_host_ - // to navigate. To be safe, we'll cancel the interstitial and show the - // page that caused the DidNavigate. - CancelRenderView(&interstitial_render_view_host_); - SwapToRenderView(&pending_render_view_host_, true); - renderer_state_ = NORMAL; - } else { - // No one else should be sending us DidNavigate in this state. - DCHECK(false); - return; - } - - } else if (renderer_state_ == INTERSTITIAL) { - if (render_view_host == original_render_view_host_) { - // We shouldn't get here, because the original render view was the one - // that caused the ShowInterstitial. - // However, until we intercept navigation events from JavaScript, it is - // possible to get here, if another tab tells render_view_host_ to - // navigate. To be safe, we'll cancel the interstitial and show the - // page that caused the DidNavigate. - SwapToRenderView(&original_render_view_host_, true); - if (pending_render_view_host_) - CancelRenderView(&pending_render_view_host_); - renderer_state_ = NORMAL; - } else if (render_view_host == pending_render_view_host_) { - // No one else should be sending us DidNavigate in this state. - // However, until we intercept navigation events from JavaScript, it is - // possible to get here, if another tab tells pending_render_view_host_ - // to navigate. To be safe, we'll cancel the interstitial and show the - // page that caused the DidNavigate. - SwapToRenderView(&pending_render_view_host_, true); - CancelRenderView(&original_render_view_host_); - renderer_state_ = NORMAL; - } else { - // No one else should be sending us DidNavigate in this state. - DCHECK(false); - return; - } - InterstitialPageGone(); - - } else if (renderer_state_ == LEAVING_INTERSTITIAL) { - if (render_view_host == original_render_view_host_) { - // We navigated to something in the original renderer, so show it. - if (pending_render_view_host_) - CancelRenderView(&pending_render_view_host_); - SwapToRenderView(&original_render_view_host_, true); - renderer_state_ = NORMAL; - } else if (render_view_host == pending_render_view_host_) { - // We navigated to something in the pending renderer. - CancelRenderView(&original_render_view_host_); - SwapToRenderView(&pending_render_view_host_, true); - renderer_state_ = NORMAL; - } else { - // No one else should be sending us DidNavigate in this state. - DCHECK(false); - return; - } - InterstitialPageGone(); + } + if (render_view_host == pending_render_view_host_) { + // The pending cross-site navigation completed, so show the renderer. + SwapToRenderView(&pending_render_view_host_, true); + cross_navigation_pending_ = false; + } else if (render_view_host == render_view_host_) { + // A navigation in the original page has taken place. Cancel the pending + // one. + CancelPendingRenderView(); + cross_navigation_pending_ = false; } else { - // No such state. + // No one else should be sending us DidNavigate in this state. DCHECK(false); - return; } } void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id, int new_request_id) { - // Should only see this while we have a pending renderer, possibly during an - // interstitial. Otherwise, we should ignore. - if (renderer_state_ != PENDING && renderer_state_ != LEAVING_INTERSTITIAL) + // Should only see this while we have a pending renderer. + if (!cross_navigation_pending_) return; DCHECK(pending_render_view_host_); @@ -298,14 +168,7 @@ void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id, // will send a ClosePage_ACK to the ResourceDispatcherHost with the given // IDs (of the pending RVH's request), allowing the pending RVH's response to // resume. - if (showing_interstitial_page()) { - DCHECK(original_render_view_host_); - original_render_view_host_->ClosePage(new_render_process_host_id, - new_request_id); - } else { - render_view_host_->ClosePage(new_render_process_host_id, - new_request_id); - } + render_view_host_->ClosePage(new_render_process_host_id, new_request_id); // ResourceDispatcherHost has told us to run the onunload handler, which // means it is not a download or unsafe page, and we are going to perform the @@ -327,50 +190,6 @@ void RenderViewHostManager::RendererAbortedProvisionalLoad( // navigation events. (That's necessary to support onunload anyway.) Once // we've made that change, we won't create a pending renderer until we know // the response is not a download. - - if (renderer_state_ == ENTERING_INTERSTITIAL) { - if ((pending_render_view_host_ && - (pending_render_view_host_ == render_view_host)) || - (!pending_render_view_host_ && - (render_view_host_ == render_view_host))) { - // The abort came from the RenderViewHost that triggered the - // interstitial. (e.g., User clicked stop after ShowInterstitial but - // before the interstitial was visible.) We should go back to NORMAL. - // Note that this is an uncommon case, because we are only in the - // ENTERING_INTERSTITIAL state in the small time window while the - // interstitial's RenderViewHost is being created. - if (pending_render_view_host_) - CancelRenderView(&pending_render_view_host_); - CancelRenderView(&interstitial_render_view_host_); - renderer_state_ = NORMAL; - } - - // We can get here, at least in the following case. - // We show an interstitial, then navigate to a URL that leads to another - // interstitial. Now there's a race. The new interstitial will be - // created and we will go to ENTERING_INTERSTITIAL, but the old one will - // meanwhile destroy itself and fire DidFailProvisionalLoad. That puts - // us here. Should be safe to ignore the DidFailProvisionalLoad, from - // the perspective of the renderer state. - } else if (renderer_state_ == LEAVING_INTERSTITIAL) { - // If we've left the interstitial by seeing a download (or otherwise - // aborting a load), we should get back to the original page, because - // interstitial page doesn't make sense anymore. (For example, we may - // have clicked Proceed on a download URL.) - - // TODO(creis): This causes problems in the old process model when - // visiting a new URL from an interstitial page. - // This is because we receive a DidFailProvisionalLoad from cancelling - // the first request, which is indistinguishable from a - // DidFailProvisionalLoad from the second request (if it is a download). - // We need to find a way to distinguish these cases, because it doesn't - // make sense to keep showing the interstitial after a download. - // if (pending_render_view_host_) - // CancelRenderView(&pending_render_view_host_); - // SwapToRenderView(&original_render_view_host_, true); - // renderer_state_ = NORMAL; - // delegate_->InterstitialPageGoneFromRenderManager(); - } } void RenderViewHostManager::ShouldClosePage(bool proceed) { @@ -388,226 +207,21 @@ void RenderViewHostManager::ShouldClosePage(bool proceed) { return; } - DCHECK(renderer_state_ != ENTERING_INTERSTITIAL); - DCHECK(renderer_state_ != INTERSTITIAL); if (proceed) { // Ok to unload the current page, so proceed with the cross-site navigate. pending_render_view_host_->SetNavigationsSuspended(false); } else { // Current page says to cancel. - CancelRenderView(&pending_render_view_host_); - renderer_state_ = NORMAL; + CancelPendingRenderView(); + cross_navigation_pending_ = false; } } -void RenderViewHostManager::ShowInterstitialPage( - InterstitialPage* interstitial_page) { - // Note that it is important that the interstitial page render view host is - // in the same process as the normal render view host for the tab, so they - // use page ids from the same pool. If they came from different processes, - // page ids may collide causing confusion in the controller (existing - // navigation entries in the controller history could get overridden with the - // interstitial entry). - SiteInstance* interstitial_instance = NULL; - - if (renderer_state_ == NORMAL) { - // 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. - interstitial_instance = render_view_host_->site_instance(); - - } else if (renderer_state_ == PENDING) { - // pending_render_view_host_ will not be deleted before the end of this - // method (when we are in this state), so we don't have to worry about this - // SiteInstance's ref count dropping to zero. - interstitial_instance = pending_render_view_host_->site_instance(); - - } else if (renderer_state_ == ENTERING_INTERSTITIAL) { - // We should never get here if we're in the process of showing an - // interstitial. - // However, until we intercept navigation events from JavaScript, it is - // possible to get here, if another tab tells render_view_host_ to - // navigate to a URL that causes an interstitial. To be safe, we'll cancel - // the first interstitial. - CancelRenderView(&interstitial_render_view_host_); - renderer_state_ = NORMAL; - - // We'd like to now show the new interstitial, but if there's a - // pending_render_view_host_, we can't tell if this JavaScript navigation - // occurred in the original or the pending renderer. That means we won't - // know where to proceed, so we can't show the interstitial. This is - // really just meant to avoid a crash until we can intercept JavaScript - // navigation events, so for now we'll kill the interstitial and go back - // to the last known good page. - if (pending_render_view_host_) { - CancelRenderView(&pending_render_view_host_); - return; - } - // Should be safe to show the interstitial for the new page. - // 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. - interstitial_instance = render_view_host_->site_instance(); - - } else if (renderer_state_ == INTERSTITIAL) { - // We should never get here if we're already showing an interstitial. - // However, until we intercept navigation events from JavaScript, it is - // possible to get here, if another tab tells render_view_host_ to - // navigate to a URL that causes an interstitial. To be safe, we'll go - // back to normal first. - if (pending_render_view_host_ != NULL) { - // There was a pending RVH. We don't know which RVH caused this call - // to ShowInterstitial, so we can't really proceed. We'll have to stay - // in the NORMAL state, showing the last good page. This is only a - // temporary fix anyway, to stave off a crash. - HideInterstitialPage(false, false); - return; - } - // Should be safe to show the interstitial for the new page. - // 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. - SwapToRenderView(&original_render_view_host_, true); - interstitial_instance = render_view_host_->site_instance(); - - } else if (renderer_state_ == LEAVING_INTERSTITIAL) { - SwapToRenderView(&original_render_view_host_, true); - interstitial_instance = NULL; - if (pending_render_view_host_) { - // We're now effectively in PENDING. - // pending_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. - interstitial_instance = pending_render_view_host_->site_instance(); - } else { - // We're now effectively in NORMAL. - // 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. - interstitial_instance = render_view_host_->site_instance(); - } - - } else { - // No such state. - DCHECK(false); - return; - } - - // Create a pending renderer and move to ENTERING_INTERSTITIAL. - interstitial_render_view_host_ = - CreateRenderViewHost(interstitial_instance, MSG_ROUTING_NONE, NULL); - interstitial_page_ = interstitial_page; - bool success = delegate_->CreateRenderViewForRenderManager( - interstitial_render_view_host_); - if (!success) { - // TODO(creis): If this fails, should we load the interstitial in - // render_view_host_? We shouldn't just skip the interstitial... - CancelRenderView(&interstitial_render_view_host_); - return; - } - - // Don't show the view yet. - interstitial_render_view_host_->view()->Hide(); - - renderer_state_ = ENTERING_INTERSTITIAL; - - // We allow the DOM bindings as a way to get the page to talk back to us. - interstitial_render_view_host_->AllowDomAutomationBindings(); - - interstitial_render_view_host_->LoadAlternateHTMLString( - interstitial_page->GetHTMLContents(), false, - GURL::EmptyGURL(), - std::string()); -} - -void RenderViewHostManager::HideInterstitialPage(bool wait_for_navigation, - bool proceed) { - if (renderer_state_ == NORMAL || renderer_state_ == PENDING) { - // Shouldn't get here, since there's no interstitial showing. - DCHECK(false); - return; - - } else if (renderer_state_ == ENTERING_INTERSTITIAL) { - // Unclear if it is possible to get here. (Can you hide the interstitial - // before it is shown?) If so, we should go back to NORMAL. - CancelRenderView(&interstitial_render_view_host_); - if (pending_render_view_host_) - CancelRenderView(&pending_render_view_host_); - renderer_state_ = NORMAL; - return; - } - - DCHECK(showing_interstitial_page()); - DCHECK(render_view_host_ && original_render_view_host_ && - !interstitial_render_view_host_); - - if (renderer_state_ == INTERSTITIAL) { - // Disable the Proceed button on the interstitial, because the destination - // renderer might get replaced. - DisableInterstitialProceed(false); - - } else if (renderer_state_ == LEAVING_INTERSTITIAL) { - // We have already given up the ability to proceed by starting a new - // navigation. If this is a request to proceed, we must ignore it. - // (Hopefully we will have disabled the Proceed button by now, but it's - // possible to get here before that happens.) - if (proceed) - return; - } - - if (wait_for_navigation) { - // We are resuming the loading. We need to set the state to loading again - // as it was set to false when the interstitial stopped loading (so the - // throbber runs). - delegate_->DidStartLoadingFromRenderManager(render_view_host_, NULL); - } - - if (proceed) { - // Now we will resume loading automatically, either in - // original_render_view_host_ or in pending_render_view_host_. When it - // completes, we will display the renderer in DidNavigate. - renderer_state_ = LEAVING_INTERSTITIAL; - - } else { - // Don't proceed. Go back to the previously showing page. - if (renderer_state_ == LEAVING_INTERSTITIAL) { - // We said DontProceed after starting to leave the interstitial. - // Abandon whatever we were in the process of doing. - original_render_view_host_->Stop(); - } - SwapToRenderView(&original_render_view_host_, true); - if (pending_render_view_host_) - CancelRenderView(&pending_render_view_host_); - renderer_state_ = NORMAL; - InterstitialPageGone(); - } -} - -bool RenderViewHostManager::IsRenderViewInterstitial( - const RenderViewHost* render_view_host) const { - if (showing_interstitial_page()) - return render_view_host_ == render_view_host; - if (renderer_state_ == ENTERING_INTERSTITIAL) - return interstitial_render_view_host_ == render_view_host; - return false; -} - void RenderViewHostManager::OnJavaScriptMessageBoxClosed( IPC::Message* reply_msg, bool success, const std::wstring& prompt) { - RenderViewHost* rvh = render_view_host_; - if (showing_interstitial_page()) { - // No JavaScript message boxes are ever shown by interstitial pages, but - // they can be shown by the original RVH while an interstitial page is - // showing (e.g., from an onunload event handler). We should send this to - // the original RVH and not the interstitial's RVH. - // TODO(creis): Perhaps the JavascriptMessageBoxHandler should store which - // RVH created it, so that it can tell this method which RVH to reply to. - DCHECK(original_render_view_host_); - rvh = original_render_view_host_; - } - rvh->JavaScriptMessageBoxClosed(reply_msg, success, prompt); + render_view_host_->JavaScriptMessageBoxClosed(reply_msg, success, prompt); } @@ -676,7 +290,7 @@ SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry( // compare the entry's URL to the last committed entry's URL. NavigationController* controller = delegate_->GetControllerForRenderManager(); NavigationEntry* curr_entry = controller->GetLastCommittedEntry(); - if (showing_interstitial_page()) { + if (interstitial_page_) { // The interstitial is currently the last committed entry, but we want to // compare against the last non-interstitial entry. curr_entry = controller->GetEntryAtOffset(-1); @@ -725,7 +339,7 @@ bool RenderViewHostManager::CreatePendingRenderView(SiteInstance* instance) { // Don't show the view until we get a DidNavigate from it. pending_render_view_host_->view()->Hide(); } else { - CancelRenderView(&pending_render_view_host_); + CancelPendingRenderView(); } return success; } @@ -794,37 +408,18 @@ void RenderViewHostManager::SwapToRenderView( RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate( const NavigationEntry& entry) { - // If we are in PENDING or ENTERING_INTERSTITIAL, then we want to get back - // to NORMAL and navigate as usual. - if (renderer_state_ == PENDING || renderer_state_ == ENTERING_INTERSTITIAL) { + // 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_) - CancelRenderView(&pending_render_view_host_); - if (interstitial_render_view_host_) - CancelRenderView(&interstitial_render_view_host_); - renderer_state_ = NORMAL; + CancelPendingRenderView(); + cross_navigation_pending_ = false; } // 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_->site_instance(); - if (showing_interstitial_page()) { - // Must disable any ability to proceed from the interstitial, because we're - // about to navigate somewhere else. - DisableInterstitialProceed(true); - - if (pending_render_view_host_) - CancelRenderView(&pending_render_view_host_); - - renderer_state_ = LEAVING_INTERSTITIAL; - - // We want to compare against where we were, because we just cancelled - // where we were going. The original_render_view_host_ won't be deleted - // before the end of this method, so we don't have to worry about this - // SiteInstance's ref count dropping to zero. - curr_instance = original_render_view_host_->site_instance(); - } - // 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. @@ -834,8 +429,7 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate( if (new_instance != curr_instance) { // New SiteInstance. - DCHECK(renderer_state_ == NORMAL || - renderer_state_ == LEAVING_INTERSTITIAL); + DCHECK(!cross_navigation_pending_); // Create a pending RVH and navigate it. bool success = CreatePendingRenderView(new_instance); @@ -844,36 +438,14 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate( // Check if our current RVH is live before we set up a transition. if (!render_view_host_->IsRenderViewLive()) { - if (renderer_state_ == NORMAL) { + if (!cross_navigation_pending_) { // The current RVH is not live. There's no reason to sit around with a // sad tab or a newly created RVH while we wait for the pending RVH to - // navigate. Just switch to the pending RVH now and go back to NORMAL, - // without requiring a cross-site transition. (Note that we don't care - // about on{before}unload handlers if the current RVH isn't live.) + // navigate. Just switch to the pending RVH now and go back to non + // cross-navigating (Note that we don't care about on{before}unload + // handlers if the current RVH isn't live.) SwapToRenderView(&pending_render_view_host_, true); return render_view_host_; - - } else if (renderer_state_ == LEAVING_INTERSTITIAL) { - // Cancel the interstitial, since it has died and we're navigating away - // anyway. - DCHECK(original_render_view_host_); - if (original_render_view_host_->IsRenderViewLive()) { - // Swap back to the original and act like a pending request (using - // the logic below). - SwapToRenderView(&original_render_view_host_, true); - renderer_state_ = NORMAL; - InterstitialPageGone(); - // Continue with the pending cross-site transition logic below. - } else { - // Both the interstitial and original are dead. Just like the NORMAL - // case, let's skip the cross-site transition entirely. We also have - // to clean up the interstitial state. - SwapToRenderView(&pending_render_view_host_, true); - CancelRenderView(&original_render_view_host_); - renderer_state_ = NORMAL; - InterstitialPageGone(); - return render_view_host_; - } } else { NOTREACHED(); return render_view_host_; @@ -895,12 +467,9 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate( // old page's onunload handler before it sends the response. pending_render_view_host_->SetHasPendingCrossSiteRequest(true, -1); - // We now have a pending RVH. If we were in NORMAL, we should now be in - // PENDING. If we were in LEAVING_INTERSTITIAL, we should stay there. - if (renderer_state_ == NORMAL) - renderer_state_ = PENDING; - else - DCHECK(renderer_state_ == LEAVING_INTERSTITIAL); + // We now have a pending RVH. + DCHECK(!cross_navigation_pending_); + cross_navigation_pending_ = true; // Tell the old render view to run its onbeforeunload handler, since it // doesn't otherwise know that the cross-site request is happening. This @@ -910,38 +479,14 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate( return pending_render_view_host_; } - // Same SiteInstance can be used. Navigate render_view_host_ if we are in - // the NORMAL state, and original_render_view_host_ if an interstitial is - // showing. - if (renderer_state_ == NORMAL) - return render_view_host_; - - DCHECK(renderer_state_ == LEAVING_INTERSTITIAL); - return original_render_view_host_; -} - -void RenderViewHostManager::DisableInterstitialProceed(bool stop_request) { - // TODO(creis): Make sure the interstitial page disables any ability to - // proceed at this point, because we're about to abort the original request. - // This can be done by adding a new event to the NotificationService. - // We should also disable the button on the page itself, but it's ok if that - // doesn't happen immediately. - - // Stopping the request is necessary if we are navigating away, because the - // user could be requesting the same URL again, causing the HttpCache to - // ignore it. (Fixes bug 1079784.) - if (stop_request) { - original_render_view_host_->Stop(); - if (pending_render_view_host_) - pending_render_view_host_->Stop(); - } + // Same SiteInstance can be used. Navigate render_view_host_ if we are not + // cross navigating. + DCHECK(!cross_navigation_pending_); + return render_view_host_; } -void RenderViewHostManager::InterstitialPageGone() { - DCHECK(!showing_interstitial_page()); - if (interstitial_page_) { - interstitial_page_->InterstitialClosed(); - interstitial_page_ = NULL; - } +void RenderViewHostManager::CancelPendingRenderView() { + pending_render_view_host_->Shutdown(); + pending_render_view_host_ = NULL; } |