summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/automation_provider.cc2
-rw-r--r--chrome/browser/browser.vcproj8
-rw-r--r--chrome/browser/browser_commands.cc4
-rw-r--r--chrome/browser/dom_ui/dom_ui_host.cc5
-rw-r--r--chrome/browser/dom_ui/dom_ui_host.h3
-rw-r--r--chrome/browser/render_view_host_manager.cc956
-rw-r--r--chrome/browser/render_view_host_manager.h339
-rw-r--r--chrome/browser/ssl_blocking_page.cc4
-rw-r--r--chrome/browser/tab_contents.h3
-rw-r--r--chrome/browser/tab_contents_container_view.cc12
-rw-r--r--chrome/browser/tabs/tab_strip_model.cc5
-rw-r--r--chrome/browser/web_contents.cc1117
-rw-r--r--chrome/browser/web_contents.h239
-rw-r--r--chrome/browser/web_contents_unittest.cc155
-rw-r--r--chrome/browser/web_drop_target.cc8
15 files changed, 1639 insertions, 1221 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 5c10d68..ae675bf 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -2011,7 +2011,7 @@ void AutomationProvider::GetPageType(const IPC::Message& message, int handle) {
// no navigation entry were created for it we need to ask the WebContents.
if (page_type == NavigationEntry::NORMAL_PAGE &&
tab->active_contents()->AsWebContents() &&
- tab->active_contents()->AsWebContents()->IsShowingInterstitialPage())
+ tab->active_contents()->AsWebContents()->showing_interstitial_page())
page_type = NavigationEntry::INTERSTITIAL_PAGE;
Send(new AutomationMsg_GetPageTypeResponse(message.routing_id(), true,
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index b7c955b..5598daf 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -894,6 +894,14 @@
>
</File>
<File
+ RelativePath=".\render_view_host_manager.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\render_view_host_manager.h"
+ >
+ </File>
+ <File
RelativePath=".\security_style.h"
>
</File>
diff --git a/chrome/browser/browser_commands.cc b/chrome/browser/browser_commands.cc
index 79e1f06..9492c71 100644
--- a/chrome/browser/browser_commands.cc
+++ b/chrome/browser/browser_commands.cc
@@ -780,7 +780,7 @@ void Browser::GoBack() {
// to the previous page as it is already available in a render view host
// of the WebContents. This makes the back more snappy and avoids potential
// reloading of POST pages.
- if (web_contents && web_contents->IsShowingInterstitialPage()) {
+ if (web_contents && web_contents->showing_interstitial_page()) {
// Let the delegate decide (if any) if it wants to handle the back
// navigation (it may have extra things to do).
if (web_contents->interstitial_page_delegate() &&
@@ -830,7 +830,7 @@ void Browser::Reload() {
TabContents* current_tab = GetSelectedTabContents();
if (current_tab) {
WebContents* web_contents = current_tab->AsWebContents();
- if (web_contents && web_contents->IsShowingInterstitialPage()) {
+ if (web_contents && web_contents->showing_interstitial_page()) {
NavigationEntry* entry = current_tab->controller()->GetActiveEntry();
DCHECK(entry); // Should exist if interstitial is showing.
OpenURL(entry->GetURL(), CURRENT_TAB, PageTransition::RELOAD);
diff --git a/chrome/browser/dom_ui/dom_ui_host.cc b/chrome/browser/dom_ui/dom_ui_host.cc
index b7d685f..f00c5a3 100644
--- a/chrome/browser/dom_ui/dom_ui_host.cc
+++ b/chrome/browser/dom_ui/dom_ui_host.cc
@@ -54,13 +54,14 @@ DOMUIHost::~DOMUIHost() {
STLDeleteContainerPointers(handlers_.begin(), handlers_.end());
}
-bool DOMUIHost::CreateRenderView(RenderViewHost* render_view_host) {
+bool DOMUIHost::CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host) {
// Be sure to enable DOM UI bindings on the RenderViewHost before
// CreateRenderView is called. Since a cross-site transition may be
// involved, this may or may not be the same RenderViewHost that we had when
// we were created.
render_view_host->AllowDOMUIBindings();
- return WebContents::CreateRenderView(render_view_host);
+ return WebContents::CreateRenderViewForRenderManager(render_view_host);
}
void DOMUIHost::AddMessageHandler(DOMMessageHandler* handler) {
diff --git a/chrome/browser/dom_ui/dom_ui_host.h b/chrome/browser/dom_ui/dom_ui_host.h
index 09d624f..a0a5970 100644
--- a/chrome/browser/dom_ui/dom_ui_host.h
+++ b/chrome/browser/dom_ui/dom_ui_host.h
@@ -60,7 +60,8 @@ class DOMUIHost : public WebContents {
RenderViewHostFactory* render_view_factory);
// Initializes the given renderer, after enabling DOM UI bindings on it.
- virtual bool CreateRenderView(RenderViewHost* render_view_host);
+ virtual bool CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host);
// Add type-specific javascript message handlers.
// TODO(timsteele): Any implementation of this method should really be done
diff --git a/chrome/browser/render_view_host_manager.cc b/chrome/browser/render_view_host_manager.cc
new file mode 100644
index 0000000..b046c8e
--- /dev/null
+++ b/chrome/browser/render_view_host_manager.cc
@@ -0,0 +1,956 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/browser/render_view_host_manager.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "chrome/browser/interstitial_page_delegate.h"
+#include "chrome/browser/navigation_controller.h"
+#include "chrome/browser/navigation_entry.h"
+#include "chrome/browser/render_widget_host_view.h"
+#include "chrome/browser/render_view_host.h"
+#include "chrome/browser/render_view_host_delegate.h"
+#include "chrome/browser/site_instance.h"
+#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),
+ 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_delegate_(NULL),
+ showing_repost_interstitial_(false) {
+}
+
+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,
+ SiteInstance* site_instance,
+ int routing_id,
+ HANDLE modal_dialog_event) {
+ // Create a RenderViewHost, once we have an instance. It is important to
+ // immediately give this SiteInstance to a RenderViewHost so that it is
+ // ref counted.
+ if (!site_instance)
+ site_instance = SiteInstance::CreateSiteInstance(profile);
+ render_view_host_ = CreateRenderViewHost(
+ site_instance, routing_id, modal_dialog_event);
+}
+
+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;
+ }
+
+ // We should always have a main RenderViewHost.
+ render_view_host_->Shutdown();
+ render_view_host_ = NULL;
+}
+
+RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) {
+ RenderViewHost* dest_render_view_host = UpdateRendererStateNavigate(entry);
+ if (!dest_render_view_host)
+ return NULL; // We weren't able to create a pending render view host.
+
+ // If the current render_view_host_ isn't live, we should create it so
+ // that we don't show a sad tab while the dest_render_view_host fetches
+ // its first page. (Bug 1145340)
+ if (dest_render_view_host != render_view_host_ &&
+ !render_view_host_->IsRenderViewLive()) {
+ delegate_->CreateRenderViewForRenderManager(render_view_host_);
+ }
+
+ // If the renderer crashed, then try to create a new one to satisfy this
+ // navigation request.
+ if (!dest_render_view_host->IsRenderViewLive()) {
+ if (!delegate_->CreateRenderViewForRenderManager(dest_render_view_host))
+ return NULL;
+
+ // 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()
+ // on it later.
+ if (dest_render_view_host != render_view_host_ &&
+ dest_render_view_host->view()) {
+ dest_render_view_host->view()->Hide();
+ } else {
+ // This is our primary renderer, notify here as we won't be calling
+ // SwapToRenderView (which does the notify).
+ RenderViewHostSwitchedDetails details;
+ details.new_host = render_view_host_;
+ details.old_host = NULL;
+ NotificationService::current()->Notify(
+ NOTIFY_RENDER_VIEW_HOST_CHANGED,
+ Source<NavigationController>(
+ delegate_->GetControllerForRenderManager()),
+ Details<RenderViewHostSwitchedDetails>(&details));
+ }
+ }
+
+ 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) {
+ 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();
+ }
+ }
+}
+
+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);
+}
+
+void RenderViewHostManager::DidNavigateMainFrame(
+ RenderViewHost* render_view_host) {
+ if (renderer_state_ == NORMAL) {
+ // 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();
+
+ } else {
+ // No such 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)
+ return;
+ DCHECK(pending_render_view_host_);
+
+ // Tell the old renderer to run its onunload handler. When it finishes, it
+ // 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);
+ }
+
+ // 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
+ // navigation. Thus, we no longer need to remember that the RenderViewHost
+ // is part of a pending cross-site request.
+ pending_render_view_host_->SetHasPendingCrossSiteRequest(false);
+}
+
+void RenderViewHostManager::RendererAbortedProvisionalLoad(
+ RenderViewHost* render_view_host) {
+ // We used to cancel the pending renderer here for cross-site downloads.
+ // However, it's not safe to do that because the download logic repeatedly
+ // looks for this TabContents based on a render view ID. Instead, we just
+ // leave the pending renderer around until the next navigation event
+ // (Navigate, DidNavigate, etc), which will clean it up properly.
+ // TODO(creis): All of this will go away when we move the cross-site logic
+ // to ResourceDispatcherHost, so that we intercept responses rather than
+ // 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) {
+ // Should only see this while we have a pending renderer. Otherwise, we
+ // should ignore.
+ if (!pending_render_view_host_) {
+ bool proceed_to_fire_unload;
+ delegate_->BeforeUnloadFiredFromRenderManager(proceed,
+ &proceed_to_fire_unload);
+
+ if (proceed_to_fire_unload) {
+ // This is not a cross-site navigation, the tab is being closed.
+ render_view_host_->FirePageUnload();
+ }
+ 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;
+ }
+}
+
+void RenderViewHostManager::ShowInterstitialPage(
+ const std::string& html_text,
+ InterstitialPageDelegate* delegate) {
+ // 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_delegate_ = delegate;
+ 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(html_text, 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);
+}
+
+
+bool RenderViewHostManager::ShouldTransitionCrossSite() {
+ // True if we are using process-per-site-instance (default) or
+ // process-per-site (kProcessPerSite).
+ return !CommandLine().HasSwitch(switches::kProcessPerTab);
+}
+
+SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
+ const NavigationEntry& entry,
+ SiteInstance* curr_instance) {
+ // NOTE: This is only called when ShouldTransitionCrossSite is true.
+
+ // 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().HasSwitch(switches::kProcessPerSite) &&
+ entry.GetTransitionType() == PageTransition::GENERATED)
+ return curr_instance;
+
+ const GURL& dest_url = entry.GetURL();
+
+ // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
+ // for this entry. We won't commit the SiteInstance to this site until the
+ // navigation commits (in DidNavigate), unless the navigation entry was
+ // restored. As session restore loads all the pages immediately we need to set
+ // the site first, otherwise after a restore none of the pages would share
+ // renderers.
+ if (!curr_instance->has_site()) {
+ // If we've already created a SiteInstance for our destination, we don't
+ // want to use this unused SiteInstance; use the existing one. (We don't
+ // do this check if the curr_instance has a site, because for now, we want
+ // to compare against the current URL and not the SiteInstance's site. In
+ // this case, there is no current URL, so comparing against the site is ok.
+ // See additional comments below.)
+ if (curr_instance->HasRelatedSiteInstance(dest_url)) {
+ return curr_instance->GetRelatedSiteInstance(dest_url);
+ } else {
+ if (entry.restored())
+ curr_instance->SetSite(dest_url);
+ return curr_instance;
+ }
+ }
+
+ // 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
+ // the same site, and it will be safe to compare the URL against the
+ // SiteInstance's site, as follows:
+ // const GURL& current_url = curr_instance->site();
+ // For now, though, we're in a hybrid model where you only switch
+ // SiteInstances if you type in a cross-site URL. This means we have to
+ // 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()) {
+ // The interstitial is currently the last committed entry, but we want to
+ // compare against the last non-interstitial entry.
+ curr_entry = controller->GetEntryAtOffset(-1);
+ }
+ // If there is no last non-interstitial entry (and curr_instance already
+ // has a site), then we must have been opened from another tab. We want
+ // to compare against the URL of the page that opened us, but we can't
+ // get to it directly. The best we can do is check against the site of
+ // the SiteInstance. This will be correct when we intercept links and
+ // script-based navigations, but for now, it could place some pages in a
+ // new process unnecessarily. We should only hit this case if a page tries
+ // to open a new tab to an interstitial-inducing URL, and then navigates
+ // the page to a different same-site URL. (This seems very unlikely in
+ // practice.)
+ const GURL& current_url = (curr_entry) ? curr_entry->GetURL() :
+ curr_instance->site();
+
+ if (SiteInstance::IsSameWebSite(current_url, dest_url)) {
+ return curr_instance;
+ } 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
+ // CreatePendingRenderView.
+ return curr_instance->GetRelatedSiteInstance(dest_url);
+ }
+}
+
+bool RenderViewHostManager::CreatePendingRenderView(SiteInstance* instance) {
+ NavigationEntry* curr_entry =
+ delegate_->GetControllerForRenderManager()->GetLastCommittedEntry();
+ if (curr_entry && curr_entry->GetType() == TAB_CONTENTS_WEB) {
+ DCHECK(!curr_entry->GetContentState().empty());
+
+ // TODO(creis): Should send a message to the RenderView to let it know
+ // we're about to switch away, so that it sends an UpdateState message.
+ }
+
+ pending_render_view_host_ =
+ CreateRenderViewHost(instance, MSG_ROUTING_NONE, NULL);
+
+ bool success = delegate_->CreateRenderViewForRenderManager(
+ pending_render_view_host_);
+ if (success) {
+ // Don't show the view until we get a DidNavigate from it.
+ pending_render_view_host_->view()->Hide();
+ } else {
+ CancelRenderView(&pending_render_view_host_);
+ }
+ return success;
+}
+
+RenderViewHost* RenderViewHostManager::CreateRenderViewHost(
+ SiteInstance* instance,
+ int routing_id,
+ HANDLE modal_dialog_event) {
+ if (render_view_factory_) {
+ return render_view_factory_->CreateRenderViewHost(
+ instance, render_view_delegate_, routing_id, modal_dialog_event);
+ } else {
+ return new RenderViewHost(instance, render_view_delegate_, routing_id,
+ modal_dialog_event);
+ }
+}
+
+void RenderViewHostManager::SwapToRenderView(
+ RenderViewHost** new_render_view_host,
+ bool destroy_after) {
+ // Remember if the page was focused so we can focus the new renderer in
+ // that case.
+ bool focus_render_view = render_view_host_->view() &&
+ render_view_host_->view()->HasFocus();
+
+ // Hide the current view and prepare to destroy it.
+ // TODO(creis): Get the old RenderViewHost to send us an UpdateState message
+ // before we destroy it.
+ if (render_view_host_->view())
+ render_view_host_->view()->Hide();
+ RenderViewHost* old_render_view_host = render_view_host_;
+
+ // Swap in the pending view and make it active.
+ render_view_host_ = (*new_render_view_host);
+ (*new_render_view_host) = NULL;
+
+ // If the view is gone, then this RenderViewHost died while it was hidden.
+ // We ignored the RendererGone call at the time, so we should send it now
+ // to make sure the sad tab shows up, etc.
+ if (render_view_host_->view())
+ render_view_host_->view()->Show();
+ else
+ delegate_->RendererGoneFromRenderManager(render_view_host_);
+
+ // Make sure the size is up to date. (Fix for bug 1079768.)
+ delegate_->UpdateRenderViewSizeForRenderManager();
+
+ if (focus_render_view && render_view_host_->view())
+ render_view_host_->view()->Focus();
+
+ RenderViewHostSwitchedDetails details;
+ details.new_host = render_view_host_;
+ details.old_host = old_render_view_host;
+ NotificationService::current()->Notify(
+ NOTIFY_RENDER_VIEW_HOST_CHANGED,
+ Source<NavigationController>(delegate_->GetControllerForRenderManager()),
+ Details<RenderViewHostSwitchedDetails>(&details));
+
+ if (destroy_after)
+ old_render_view_host->Shutdown();
+
+ // Let the task manager know that we've swapped RenderViewHosts, since it
+ // might need to update its process groupings.
+ delegate_->NotifySwappedFromRenderManager();
+}
+
+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 (pending_render_view_host_)
+ CancelRenderView(&pending_render_view_host_);
+ if (interstitial_render_view_host_)
+ CancelRenderView(&interstitial_render_view_host_);
+ 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.
+ 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.
+ SiteInstance* new_instance = curr_instance;
+ if (ShouldTransitionCrossSite())
+ new_instance = GetSiteInstanceForEntry(entry, curr_instance);
+
+ if (new_instance != curr_instance) {
+ // New SiteInstance.
+ DCHECK(renderer_state_ == NORMAL ||
+ renderer_state_ == LEAVING_INTERSTITIAL);
+
+ // Create a pending RVH and navigate it.
+ bool success = CreatePendingRenderView(new_instance);
+ if (!success)
+ return NULL;
+
+ // Check if our current RVH is live before we set up a transition.
+ if (!render_view_host_->IsRenderViewLive()) {
+ if (renderer_state_ == NORMAL) {
+ // 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.)
+ 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_;
+ }
+ }
+ // Otherwise, it's safe to treat this as a pending cross-site transition.
+
+ // Make sure the old render view stops, in case a load is in progress.
+ render_view_host_->Stop();
+
+ // Suspend the new render view (i.e., don't let it send the cross-site
+ // Navigate message) until we hear back from the old renderer's
+ // onbeforeunload handler. If it returns false, we'll have to cancel the
+ // request.
+ pending_render_view_host_->SetNavigationsSuspended(true);
+
+ // Tell the CrossSiteRequestManager that this RVH has a pending cross-site
+ // request, so that ResourceDispatcherHost will know to tell us to run the
+ // old page's onunload handler before it sends the response.
+ pending_render_view_host_->SetHasPendingCrossSiteRequest(true);
+
+ // 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);
+
+ // Tell the old render view to run its onbeforeunload handler, since it
+ // doesn't otherwise know that the cross-site request is happening. This
+ // will trigger a call to ShouldClosePage with the reply.
+ render_view_host_->FirePageBeforeUnload();
+
+ 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();
+ }
+}
+
+void RenderViewHostManager::InterstitialPageGone() {
+ DCHECK(!showing_interstitial_page());
+
+ NotificationService::current()->Notify(
+ NOTIFY_INTERSTITIAL_PAGE_CLOSED,
+ Source<NavigationController>(delegate_->GetControllerForRenderManager()),
+ NotificationService::NoDetails());
+ if (interstitial_delegate_) {
+ interstitial_delegate_->InterstitialClosed();
+ interstitial_delegate_ = NULL;
+ }
+}
diff --git a/chrome/browser/render_view_host_manager.h b/chrome/browser/render_view_host_manager.h
new file mode 100644
index 0000000..74c7798
--- /dev/null
+++ b/chrome/browser/render_view_host_manager.h
@@ -0,0 +1,339 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef CHROME_BROWSER_RENDER_VIEW_HOST_MANAGER_H_
+#define CHROME_BROWSER_RENDER_VIEW_HOST_MANAGER_H_
+
+#include <windows.h>
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "chrome/browser/render_view_host.h"
+
+class InterstitialPageDelegate;
+class NavigationController;
+class NavigationEntry;
+class Profile;
+class RenderViewHostDelegate;
+class RenderViewHostFactory;
+class RenderWidgetHostView;
+class SiteInstance;
+
+// Manages RenderViewHosts for a WebContents. Normally there is only one and
+// it is easy to do. But we can also have interstitial pages and transitions
+// of processes (and hence RenderViewHosts) that can get very complex.
+class RenderViewHostManager {
+ public:
+ // Functions implemented by our owner that we need.
+ //
+ // TODO(brettw) Clean this up! These are all the functions in WebContents that
+ // are required to run this class. The design should probably be better such
+ // that these are more clear.
+ //
+ // There is additional complexity that some of the functions we need in
+ // WebContents are inherited and non-virtual. These are named with
+ // "RenderManager" so that the duplicate implementation of them will be clear.
+ class Delegate {
+ public:
+ // See web_contents.h's implementation for more.
+ virtual bool CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host) = 0;
+ virtual void BeforeUnloadFiredFromRenderManager(
+ bool proceed, bool* proceed_to_fire_unload) = 0;
+ virtual void DidStartLoadingFromRenderManager(
+ RenderViewHost* render_view_host, int32 page_id) = 0;
+ virtual void RendererGoneFromRenderManager(
+ RenderViewHost* render_view_host) = 0;
+ virtual void UpdateRenderViewSizeForRenderManager() = 0;
+ virtual void NotifySwappedFromRenderManager() = 0;
+ virtual NavigationController* GetControllerForRenderManager() = 0;
+ };
+
+ // The factory is optional. It is used by unit tests to supply custom render
+ // view hosts. When NULL, the regular RenderViewHost will be created.
+ //
+ // Both delegate pointers must be non-NULL and are not owned by this class.
+ // They must outlive this class. The RenderViewHostDelegate is what will be
+ // installed into all RenderViewHosts that are created.
+ //
+ // You must call Init() before using this class and Shutdown() before
+ // deleting it.
+ RenderViewHostManager(RenderViewHostFactory* render_view_factory,
+ RenderViewHostDelegate* render_view_delegate,
+ Delegate* delegate);
+ ~RenderViewHostManager();
+
+ // For arguments, see WebContents constructor.
+ void Init(Profile* profile,
+ SiteInstance* site_instance,
+ int routing_id,
+ HANDLE modal_dialog_event);
+
+ // Schedules all RenderViewHosts for destruction.
+ void Shutdown();
+
+ // Returns the currently actuive RenderViewHost.
+ //
+ // This will be non-NULL between Init() and Shutdown(). You may want to NULL
+ // check it in many cases, however. Windows can send us messages during the
+ // destruction process after it has been shut down.
+ RenderViewHost* current_host() const {
+ return render_view_host_;
+ }
+
+ // Returns the view associated with the current RenderViewHost, or NULL if
+ // there is no current one.
+ RenderWidgetHostView* current_view() const {
+ if (!render_view_host_)
+ return NULL;
+ return render_view_host_->view();
+ }
+
+ // Called when we want to instruct the renderer to navigate to the given
+ // navigation entry. It may create a new RenderViewHost or re-use an existing
+ // one. The RenderViewHost to navigate will be returned. Returns NULL if one
+ // could not be created.
+ RenderViewHost* Navigate(const NavigationEntry& entry);
+
+ // Instructs the various live views to stop. Called when the user directed the
+ // page to stop loading.
+ void Stop();
+
+ // Notifies all RenderViewHosts (regular, interstitials, etc.) that a load is
+ // or is not happening. Even though the message is only for one of them, we
+ // don't know which one so we tell them all.
+ void SetIsLoading(bool is_loading);
+
+ // Called when a renderer's main frame navigates. This handles all the logic
+ // associated with interstitial management.
+ void DidNavigateMainFrame(RenderViewHost* render_view_host);
+
+ // Allows the WebContents to react when a cross-site response is ready to be
+ // delivered to a pending RenderViewHost. We must first run the onunload
+ // handler of the old RenderViewHost before we can allow it to proceed.
+ void OnCrossSiteResponse(int new_render_process_host_id,
+ int new_request_id);
+
+ // Called when a provisional load on the given renderer is aborted.
+ void RendererAbortedProvisionalLoad(RenderViewHost* render_view_host);
+
+ // Actually implements this RenderViewHostDelegate function for the
+ // WebContents.
+ void ShouldClosePage(bool proceed);
+
+ // Displays the specified html in the current page. This method can be used to
+ // show temporary pages (such as security error pages). It can be hidden by
+ // calling HideInterstitialPage, in which case the original page is restored.
+ // An optional delegate may be passed, it is owned by the caller and must
+ // remain valid while the interstitial does.
+ void ShowInterstitialPage(const std::string& html_text,
+ InterstitialPageDelegate* delegate);
+
+ // Reverts from the interstitial page to the original page.
+ // If |wait_for_navigation| is true, the interstitial page is removed when
+ // the original page has transitioned to the new contents. This is useful
+ // when you want to hide the interstitial page as you navigate to a new page.
+ // Hiding the interstitial page right away would show the previous displayed
+ // page. If |proceed| is true, the WebContents will expect the navigation
+ // to complete. If not, it will revert to the last shown page.
+ void HideInterstitialPage(bool wait_for_navigation,
+ bool proceed);
+
+ // Returns true if the given render view host is an interstitial.
+ bool IsRenderViewInterstitial(const RenderViewHost* render_view_host) const;
+
+ // Forwards the message to the RenderViewHost, which is the original one,
+ // not any interstitial that may be showing.
+ void OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg,
+ bool success,
+ const std::wstring& prompt);
+
+ // Are we showing the POST interstitial page?
+ //
+ // NOTE: the POST interstitial does NOT result in a separate RenderViewHost.
+ bool showing_repost_interstitial() const {
+ return showing_repost_interstitial_;
+ }
+ void set_showing_repost_interstitial(bool showing) {
+ showing_repost_interstitial_ = showing;
+ }
+
+ // Returns whether we are currently showing an interstitial page.
+ bool showing_interstitial_page() const {
+ return (renderer_state_ == INTERSTITIAL) ||
+ (renderer_state_ == LEAVING_INTERSTITIAL);
+ }
+
+ // Accessors to the the interstitial delegate, that is optionaly set when
+ // an interstitial page is shown.
+ InterstitialPageDelegate* interstitial_delegate() const {
+ return interstitial_delegate_;
+ }
+ void set_interstitial_delegate(InterstitialPageDelegate* delegate) {
+ interstitial_delegate_ = delegate;
+ }
+
+ private:
+ friend class TestWebContents;
+
+ // RenderViewHost states. These states represent whether a cross-site
+ // request is pending (in the new process model) and whether an interstitial
+ // page is being shown. These are public to give easy access to unit tests.
+ enum RendererState {
+ // NORMAL: just showing a page normally.
+ // render_view_host_ is showing a page.
+ // pending_render_view_host_ is NULL.
+ // original_render_view_host_ is NULL.
+ // interstitial_render_view_host_ is NULL.
+ NORMAL = 0,
+
+ // PENDING: creating a new RenderViewHost for a cross-site navigation.
+ // Never used when --process-per-tab is specified.
+ // render_view_host_ is showing a page.
+ // pending_render_view_host_ is loading a page in the background.
+ // original_render_view_host_ is NULL.
+ // interstitial_render_view_host_ is NULL.
+ PENDING,
+
+ // ENTERING_INTERSTITIAL: an interstitial RenderViewHost has been created.
+ // and will be shown as soon as it calls DidNavigate.
+ // render_view_host_ is showing a page.
+ // pending_render_view_host_ is either NULL or suspended in the background.
+ // original_render_view_host_ is NULL.
+ // interstitial_render_view_host_ is loading in the background.
+ ENTERING_INTERSTITIAL,
+
+ // INTERSTITIAL: Showing an interstitial page.
+ // render_view_host_ is showing the interstitial.
+ // pending_render_view_host_ is either NULL or suspended in the background.
+ // original_render_view_host_ is the hidden original page.
+ // interstitial_render_view_host_ is NULL.
+ INTERSTITIAL,
+
+ // LEAVING_INTERSTITIAL: interstitial is still showing, but we are
+ // navigating to a new page that will replace it.
+ // render_view_host_ is showing the interstitial.
+ // pending_render_view_host_ is either NULL or loading a page.
+ // original_render_view_host_ is hidden and possibly loading a page.
+ // interstitial_render_view_host_ is NULL.
+ LEAVING_INTERSTITIAL
+ };
+
+ // Returns whether this tab should transition to a new renderer for
+ // cross-site URLs. Enabled unless we see the --process-per-tab command line
+ // switch. Can be overridden in unit tests.
+ bool ShouldTransitionCrossSite();
+
+ // Returns an appropriate SiteInstance object for the given NavigationEntry,
+ // possibly reusing the current SiteInstance.
+ // Never called if --process-per-tab is used.
+ SiteInstance* GetSiteInstanceForEntry(const NavigationEntry& entry,
+ SiteInstance* curr_instance);
+
+ // Helper method to create a pending RenderViewHost for a cross-site
+ // navigation.
+ bool CreatePendingRenderView(SiteInstance* instance);
+
+ // Creates a RenderViewHost using render_view_factory_ (or directly, if the
+ // factory is NULL).
+ RenderViewHost* CreateRenderViewHost(SiteInstance* instance,
+ int routing_id,
+ HANDLE modal_dialog_event);
+
+ // Replaces the currently shown render_view_host_ with the RenderViewHost in
+ // the field pointed to by |new_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. If |destroy_after|, this method will call
+ // ScheduleDeferredDestroy on the previous render_view_host_.
+ void SwapToRenderView(RenderViewHost** new_render_view_host,
+ bool destroy_after);
+
+ RenderViewHost* UpdateRendererStateNavigate(const NavigationEntry& entry);
+
+ // Prevent the interstitial page from proceeding after we start navigating
+ // away from it. If |stop_request| is true, abort the pending requests
+ // immediately, because we are navigating away.
+ void DisableInterstitialProceed(bool stop_request);
+
+ // Cleans up after an interstitial page is hidden, including removing the
+ // interstitial's NavigationEntry.
+ void InterstitialPageGone();
+
+
+ // Our delegate, not owned by us. Guaranteed non-NULL.
+ Delegate* delegate_;
+
+ // See RendererState definition above.
+ RendererState renderer_state_;
+
+ // Allows tests to create their own render view host types.
+ RenderViewHostFactory* render_view_factory_;
+
+ // Implemented by the owner of this class, this delegate is installed into all
+ // the RenderViewHosts that we create.
+ RenderViewHostDelegate* render_view_delegate_;
+
+ // Our RenderView host. This object is responsible for all communication with
+ // a child RenderView instance. Note that this can be the page render view
+ // host or the interstitial RenderViewHost if the RendererState is
+ // INTERSTITIAL or LEAVING_INTERSTITIAL.
+ RenderViewHost* render_view_host_;
+
+ // This var holds the original RenderViewHost when the interstitial page is
+ // showing (the RendererState is INTERSTITIAL or LEAVING_INTERSTITIAL). It
+ // is NULL otherwise.
+ RenderViewHost* original_render_view_host_;
+
+ // The RenderViewHost of the interstitial page. This is non NULL when the
+ // the RendererState is ENTERING_INTERSTITIAL.
+ RenderViewHost* interstitial_render_view_host_;
+
+ // A RenderViewHost used to load a cross-site page. This remains hidden
+ // during the PENDING RendererState until it calls DidNavigate. It can also
+ // exist if an interstitial page is shown.
+ RenderViewHost* pending_render_view_host_;
+
+ InterstitialPageDelegate* interstitial_delegate_;
+
+ // See comment above showing_repost_interstitial().
+ bool showing_repost_interstitial_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderViewHostManager);
+};
+
+// The "details" for a NOTIFY_RENDER_VIEW_HOST_CHANGED notification. The old
+// host can be NULL when the first RenderViewHost is set.
+struct RenderViewHostSwitchedDetails {
+ RenderViewHost* old_host;
+ RenderViewHost* new_host;
+};
+
+#endif // CHROME_BROWSER_RENDER_VIEW_HOST_MANAGER_H_
diff --git a/chrome/browser/ssl_blocking_page.cc b/chrome/browser/ssl_blocking_page.cc
index cb5d3ac..220328a 100644
--- a/chrome/browser/ssl_blocking_page.cc
+++ b/chrome/browser/ssl_blocking_page.cc
@@ -87,7 +87,7 @@ SSLBlockingPage::SSLBlockingPage(SSLManager::CertError* error,
NotificationService::current()->AddObserver(this,
NOTIFY_INTERSTITIAL_PAGE_CLOSED,
- Source<TabContents>(tab_));
+ Source<NavigationController>(tab_->controller()));
// Register for DOM operations, this is how the blocking page notifies us of
// what the user chooses.
@@ -103,7 +103,7 @@ SSLBlockingPage::~SSLBlockingPage() {
NotificationService::current()->RemoveObserver(this,
NOTIFY_INTERSTITIAL_PAGE_CLOSED,
- Source<TabContents>(tab_));
+ Source<NavigationController>(tab_->controller()));
NotificationService::current()->RemoveObserver(this,
NOTIFY_DOM_OPERATION_RESPONSE,
diff --git a/chrome/browser/tab_contents.h b/chrome/browser/tab_contents.h
index 76061c1..e83cd72 100644
--- a/chrome/browser/tab_contents.h
+++ b/chrome/browser/tab_contents.h
@@ -191,6 +191,9 @@ class TabContents : public PageNavigator,
// Sets up a new NavigationController for this TabContents.
// |profile| is the user profile that should be associated with
// the new controller.
+ //
+ // TODO(brettw) this seems bogus and I couldn't find any legitimate need for
+ // it. I think it should be passed in the constructor.
void SetupController(Profile* profile);
// Returns the user profile associated with this TabContents (via the
diff --git a/chrome/browser/tab_contents_container_view.cc b/chrome/browser/tab_contents_container_view.cc
index 6a2a3d4..e0be427 100644
--- a/chrome/browser/tab_contents_container_view.cc
+++ b/chrome/browser/tab_contents_container_view.cc
@@ -33,6 +33,7 @@
#include "base/logging.h"
#include "chrome/browser/render_view_host.h"
+#include "chrome/browser/render_view_host_manager.h"
#include "chrome/browser/render_widget_host_view.h"
#include "chrome/browser/tab_contents.h"
#include "chrome/browser/view_ids.h"
@@ -204,9 +205,10 @@ void TabContentsContainerView::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
if (type == NOTIFY_RENDER_VIEW_HOST_CHANGED) {
- RenderViewHost* new_rvh = Source<WebContents>(source)->render_view_host();
- RenderViewHost* old_rvh = Details<RenderViewHost>(details).ptr();
- RenderViewHostChanged(old_rvh, new_rvh);
+ RenderViewHostSwitchedDetails* switched_details =
+ Details<RenderViewHostSwitchedDetails>(details).ptr();
+ RenderViewHostChanged(switched_details->old_host,
+ switched_details->new_host);
} else if (type == NOTIFY_TAB_CONTENTS_DESTROYED) {
TabContentsDestroyed(Source<TabContents>(source).ptr());
} else {
@@ -222,7 +224,7 @@ void TabContentsContainerView::AddObservers() {
// the focus subclass on the shown HWND so we intercept focus change events.
NotificationService::current()->AddObserver(
this, NOTIFY_RENDER_VIEW_HOST_CHANGED,
- Source<WebContents>(tab_contents_->AsWebContents()));
+ Source<NavigationController>(tab_contents_->controller()));
}
NotificationService::current()->AddObserver(
this, NOTIFY_TAB_CONTENTS_DESTROYED,
@@ -234,7 +236,7 @@ void TabContentsContainerView::RemoveObservers() {
if (tab_contents_->AsWebContents()) {
NotificationService::current()->RemoveObserver(
this, NOTIFY_RENDER_VIEW_HOST_CHANGED,
- Source<WebContents>(tab_contents_->AsWebContents()));
+ Source<NavigationController>(tab_contents_->controller()));
}
NotificationService::current()->RemoveObserver(
this, NOTIFY_TAB_CONTENTS_DESTROYED,
diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc
index c71c089d..2828d51 100644
--- a/chrome/browser/tabs/tab_strip_model.cc
+++ b/chrome/browser/tabs/tab_strip_model.cc
@@ -271,14 +271,15 @@ bool TabStripModel::TabHasUnloadListener(int index) {
// in testing and then provide better test coverage for features
// like "close other tabs".
WebContents* web_contents = GetContentsAt(index)->AsWebContents();
- if (web_contents)
+ if (web_contents) {
// If the WebContents is not connected yet, then there's no unload
// handler we can fire even if the WebContents has an unload listener.
// One case where we hit this is in a tab that has an infinite loop
// before load.
return web_contents->notify_disconnection() &&
- !web_contents->IsShowingInterstitialPage() &&
+ !web_contents->showing_interstitial_page() &&
web_contents->render_view_host()->HasUnloadListener();
+ }
return false;
}
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index 9ed7927..9108c7d 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -219,6 +219,9 @@ WebContents::WebContents(Profile* profile,
int routing_id,
HANDLE modal_dialog_event)
: TabContents(TAB_CONTENTS_WEB),
+#pragma warning(suppress: 4355) // Okay to pass "this" here.
+ render_manager_(render_view_factory, this, this),
+ render_view_factory_(render_view_factory),
is_profiling_(false),
has_page_title_(false),
info_bar_visible_(false),
@@ -226,31 +229,18 @@ WebContents::WebContents(Profile* profile,
printing_(*this),
notify_disconnection_(false),
message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)),
- render_view_factory_(render_view_factory),
- original_render_view_host_(NULL),
- interstitial_render_view_host_(NULL),
- pending_render_view_host_(NULL),
- renderer_state_(NORMAL),
capturing_contents_(false),
#pragma warning(suppress: 4355) // Okay to pass "this" here.
fav_icon_helper_(this),
crashed_plugin_info_bar_(NULL),
suppress_javascript_messages_(false),
- load_state_(net::LOAD_STATE_IDLE),
- showing_repost_interstitial_(false),
- interstitial_delegate_(NULL) {
+ load_state_(net::LOAD_STATE_IDLE) {
InitWebContentsClass();
pending_install_.page_id = 0;
pending_install_.callback_functor = NULL;
- // Create a RenderViewHost, once we have an instance. It is important to
- // immediately give this SiteInstance to a RenderViewHost so that it is
- // ref counted.
- if (!site_instance)
- site_instance = SiteInstance::CreateSiteInstance(profile);
- render_view_host_ = CreateRenderViewHost(
- site_instance, this, routing_id, modal_dialog_event);
+ render_manager_.Init(profile, site_instance, routing_id, modal_dialog_event);
// Register for notifications about all interested prefs change.
PrefService* prefs = profile->GetPrefs();
@@ -290,8 +280,8 @@ void WebContents::GetContainerBounds(gfx::Rect *out) const {
}
void WebContents::ShowContents() {
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->DidBecomeSelected();
+ if (view())
+ view()->DidBecomeSelected();
// Loop through children and send DidBecomeSelected to them, too.
int count = static_cast<int>(child_windows_.size());
@@ -317,8 +307,8 @@ void WebContents::HideContents() {
}
void WebContents::SizeContents(const gfx::Size& size) {
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->SetSize(size);
+ if (view())
+ view()->SetSize(size);
if (find_in_page_controller_.get())
find_in_page_controller_->RespondToResize(size);
RepositionSupressedPopupsToFit(size);
@@ -336,21 +326,15 @@ void WebContents::Destroy() {
// Destroy the print manager right now since a Print command may be pending.
printing_.Destroy();
-
// Unregister the notifications of all observed prefs change.
PrefService* prefs = profile()->GetPrefs();
- if (prefs)
+ if (prefs) {
for (int i = 0; i < kPrefsToObserveLength; ++i)
prefs->RemovePrefObserver(kPrefsToObserve[i], this);
+ }
cancelable_consumer_.CancelAllRequests();
- if (IsShowingInterstitialPage()) {
- // The tab is closed while the interstitial page is showing, hide and
- // destroy it.
- HideInterstitialPage(false, false);
- }
-
// Close the Find in page dialog.
if (find_in_page_controller_.get())
find_in_page_controller_->Close();
@@ -359,19 +343,9 @@ void WebContents::Destroy() {
// They will be cleaned up properly in plugin process.
DetachPluginWindows();
- if (pending_render_view_host_)
- pending_render_view_host_->Shutdown();
- if (original_render_view_host_)
- original_render_view_host_->Shutdown();
- if (interstitial_render_view_host_)
- interstitial_render_view_host_->Shutdown();
-
NotifyDisconnected();
HungRendererWarning::HideForWebContents(this);
-
- render_view_host_->Shutdown();
- render_view_host_ = NULL;
-
+ render_manager_.Shutdown();
TabContents::Destroy();
}
@@ -409,7 +383,7 @@ void WebContents::OnWindowPosChanged(WINDOWPOS* window_pos) {
}
void WebContents::OnPaint(HDC junk_dc) {
- if (render_view_host_ && !render_view_host_->IsRenderViewLive()) {
+ if (render_view_host() && !render_view_host()->IsRenderViewLive()) {
if (!sad_tab_.get())
sad_tab_.reset(new SadTabView);
CRect cr;
@@ -450,8 +424,7 @@ LRESULT WebContents::OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param) {
delegate()->ContentsMouseEvent(this, WM_MOUSEMOVE);
break;
case WM_MOUSEWHEEL:
- // This message is reflected from the render_view_host_->view()
- // to this window.
+ // This message is reflected from the view() to this window.
if (GET_KEYSTATE_WPARAM(w_param) & MK_CONTROL) {
WheelZoom(GET_WHEEL_DELTA_WPARAM(w_param));
return 1;
@@ -532,8 +505,8 @@ void WebContents::OnSetFocus(HWND window) {
// background from properly taking focus.
// We NULL-check the render_view_host_ here because Windows can send us
// messages during the destruction process after it has been destroyed.
- if (render_view_host_ && render_view_host_->view()) {
- HWND inner_hwnd = render_view_host_->view()->GetPluginHWND();
+ if (view()) {
+ HWND inner_hwnd = view()->GetPluginHWND();
if (::IsWindow(inner_hwnd))
::SetFocus(inner_hwnd);
}
@@ -554,7 +527,7 @@ void WebContents::SaveCurrentProfilingEntry() {
if (is_profiling()) {
NavigationProfiler* profiler = GetNavigationProfiler();
profiler->MoveActivePageToVisited(process()->host_id(),
- render_view_host_->routing_id());
+ render_view_host()->routing_id());
}
is_profiling_ = false;
}
@@ -568,7 +541,7 @@ void WebContents::CreateNewProfilingEntry(const GURL& url) {
TimeTicks current_time = TimeTicks::Now();
PageLoadTracker *page = new PageLoadTracker(
- url, process()->host_id(), render_view_host_->routing_id(),
+ url, process()->host_id(), render_view_host()->routing_id(),
current_time);
profiler->AddActivePage(page);
@@ -653,40 +626,7 @@ void WebContents::SavePage(const std::wstring& main_file,
// pending RVH and goes back to the NORMAL RendererState.
bool WebContents::Navigate(const NavigationEntry& entry, bool reload) {
- RenderViewHost* dest_render_view_host = UpdateRendererStateNavigate(entry);
- if (!dest_render_view_host) {
- // We weren't able to create a pending render view host.
- return false;
- }
-
- // If the current render_view_host_ isn't live, we should create it so
- // that we don't show a sad tab while the dest_render_view_host fetches
- // its first page. (Bug 1145340)
- if (dest_render_view_host != render_view_host_ &&
- !render_view_host_->IsRenderViewLive()) {
- CreateRenderView(render_view_host_);
- }
-
- // If the renderer crashed, then try to create a new one to satisfy this
- // navigation request.
- if (!dest_render_view_host->IsRenderViewLive()) {
- if (!CreateRenderView(dest_render_view_host))
- return false;
-
- // 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()
- // on it later.
- if (dest_render_view_host != render_view_host_ &&
- dest_render_view_host->view()) {
- dest_render_view_host->view()->Hide();
- } else {
- // This is our primary renderer, notify here as we won't be calling
- // SwapToRenderView (which does the notify).
- NotificationService::current()->Notify(
- NOTIFY_RENDER_VIEW_HOST_CHANGED,
- Source<WebContents>(this), NotificationService::NoDetails());
- }
- }
+ RenderViewHost* dest_render_view_host = render_manager_.Navigate(entry);
CreateNewProfilingEntry(entry.GetURL());
@@ -696,8 +636,6 @@ bool WebContents::Navigate(const NavigationEntry& entry, bool reload) {
// Navigate in the desired RenderViewHost
dest_render_view_host->NavigateToEntry(entry, reload);
- showing_repost_interstitial_ = false;
-
if (entry.GetPageID() == -1) {
// HACK!! This code suppresses javascript: URLs from being added to
// session history, which is what we want to do for javascript: URLs that
@@ -718,371 +656,29 @@ bool WebContents::Navigate(const NavigationEntry& entry, bool reload) {
return true;
}
-RenderViewHost* WebContents::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 (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- if (interstitial_render_view_host_)
- CancelRenderView(&interstitial_render_view_host_);
- 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.
- SiteInstance* curr_instance = render_view_host_->site_instance();
-
- if (IsShowingInterstitialPage()) {
- // 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.
- SiteInstance* new_instance = curr_instance;
- if (ShouldTransitionCrossSite()) {
- new_instance = GetSiteInstanceForEntry(entry, curr_instance);
- }
-
- if (new_instance != curr_instance) {
- // New SiteInstance.
- DCHECK(renderer_state_ == NORMAL ||
- renderer_state_ == LEAVING_INTERSTITIAL);
-
- // Create a pending RVH and navigate it.
- bool success = CreatePendingRenderView(new_instance);
- if (!success)
- return NULL;
-
- // Check if our current RVH is live before we set up a transition.
- if (!render_view_host_->IsRenderViewLive()) {
- if (renderer_state_ == NORMAL) {
- // 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.)
- 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_;
- }
- }
- // Otherwise, it's safe to treat this as a pending cross-site transition.
-
- // Make sure the old render view stops, in case a load is in progress.
- render_view_host_->Stop();
-
- // Suspend the new render view (i.e., don't let it send the cross-site
- // Navigate message) until we hear back from the old renderer's
- // onbeforeunload handler. If it returns false, we'll have to cancel the
- // request.
- pending_render_view_host_->SetNavigationsSuspended(true);
-
- // Tell the CrossSiteRequestManager that this RVH has a pending cross-site
- // request, so that ResourceDispatcherHost will know to tell us to run the
- // old page's onunload handler before it sends the response.
- pending_render_view_host_->SetHasPendingCrossSiteRequest(true);
-
- // 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);
-
- // Tell the old render view to run its onbeforeunload handler, since it
- // doesn't otherwise know that the cross-site request is happening. This
- // will trigger a call to ShouldClosePage with the reply.
- render_view_host_->FirePageBeforeUnload();
-
- 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_;
-}
-
-bool WebContents::ShouldTransitionCrossSite() {
- // True if we are using process-per-site-instance (default) or
- // process-per-site (kProcessPerSite).
- return !CommandLine().HasSwitch(switches::kProcessPerTab);
-}
-
-SiteInstance* WebContents::GetSiteInstanceForEntry(
- const NavigationEntry& entry, SiteInstance* curr_instance) {
- // NOTE: This is only called when ShouldTransitionCrossSite is true.
-
- // 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().HasSwitch(switches::kProcessPerSite) &&
- entry.GetTransitionType() == PageTransition::GENERATED)
- return curr_instance;
-
- const GURL& dest_url = entry.GetURL();
-
- // If we haven't used our SiteInstance (and thus RVH) yet, then we can use it
- // for this entry. We won't commit the SiteInstance to this site until the
- // navigation commits (in DidNavigate), unless the navigation entry was
- // restored. As session restore loads all the pages immediately we need to set
- // the site first, otherwise after a restore none of the pages would share
- // renderers.
- if (!curr_instance->has_site()) {
- // If we've already created a SiteInstance for our destination, we don't
- // want to use this unused SiteInstance; use the existing one. (We don't
- // do this check if the curr_instance has a site, because for now, we want
- // to compare against the current URL and not the SiteInstance's site. In
- // this case, there is no current URL, so comparing against the site is ok.
- // See additional comments below.)
- if (curr_instance->HasRelatedSiteInstance(dest_url)) {
- return curr_instance->GetRelatedSiteInstance(dest_url);
- } else {
- if (entry.restored())
- curr_instance->SetSite(dest_url);
- return curr_instance;
- }
- }
-
- // 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
- // the same site, and it will be safe to compare the URL against the
- // SiteInstance's site, as follows:
- // const GURL& current_url = curr_instance->site();
- // For now, though, we're in a hybrid model where you only switch
- // SiteInstances if you type in a cross-site URL. This means we have to
- // compare the entry's URL to the last committed entry's URL.
- NavigationEntry* curr_entry = controller()->GetLastCommittedEntry();
- if (IsShowingInterstitialPage()) {
- // The interstitial is currently the last committed entry, but we want to
- // compare against the last non-interstitial entry.
- curr_entry = controller()->GetEntryAtOffset(-1);
- }
- // If there is no last non-interstitial entry (and curr_instance already
- // has a site), then we must have been opened from another tab. We want
- // to compare against the URL of the page that opened us, but we can't
- // get to it directly. The best we can do is check against the site of
- // the SiteInstance. This will be correct when we intercept links and
- // script-based navigations, but for now, it could place some pages in a
- // new process unnecessarily. We should only hit this case if a page tries
- // to open a new tab to an interstitial-inducing URL, and then navigates
- // the page to a different same-site URL. (This seems very unlikely in
- // practice.)
- const GURL& current_url = (curr_entry) ? curr_entry->GetURL() :
- curr_instance->site();
-
- if (SiteInstance::IsSameWebSite(current_url, dest_url)) {
- return curr_instance;
- } 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
- // CreatePendingRenderView.
- return curr_instance->GetRelatedSiteInstance(dest_url);
- }
-}
-
-void WebContents::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();
- }
-}
-
-bool WebContents::CreatePendingRenderView(SiteInstance* instance) {
- NavigationEntry* curr_entry = controller()->GetLastCommittedEntry();
- if (curr_entry && curr_entry->GetType() == TAB_CONTENTS_WEB) {
- DCHECK(!curr_entry->GetContentState().empty());
-
- // TODO(creis): Should send a message to the RenderView to let it know
- // we're about to switch away, so that it sends an UpdateState message.
- }
-
- pending_render_view_host_ =
- CreateRenderViewHost(instance, this, MSG_ROUTING_NONE, NULL);
-
- bool success = CreateRenderView(pending_render_view_host_);
- if (success) {
- // Don't show the view until we get a DidNavigate from it.
- pending_render_view_host_->view()->Hide();
- } else {
- CancelRenderView(&pending_render_view_host_);
- }
- return success;
-}
-
-void WebContents::CancelRenderView(RenderViewHost** render_view_host) {
- DCHECK(*render_view_host != NULL);
-
- // Destroy the render view host
- (*render_view_host)->Shutdown();
- (*render_view_host) = NULL;
-}
-
-void WebContents::ShouldClosePage(bool proceed) {
- // Should only see this while we have a pending renderer. Otherwise, we
- // should ignore.
- if (!pending_render_view_host_) {
- bool proceed_to_fire_unload;
- delegate()->BeforeUnloadFired(this, proceed, &proceed_to_fire_unload);
-
- if (proceed_to_fire_unload) {
- // This is not a cross-site navigation, the tab is being closed.
- render_view_host_->FirePageUnload();
- }
- 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;
- }
-}
-
-void WebContents::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)
- return;
- DCHECK(pending_render_view_host_);
-
- // Tell the old renderer to run its onunload handler. When it finishes, it
- // 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 (IsShowingInterstitialPage()) {
- 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);
- }
-
- // 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
- // navigation. Thus, we no longer need to remember that the RenderViewHost
- // is part of a pending cross-site request.
- pending_render_view_host_->SetHasPendingCrossSiteRequest(false);
-}
-
void WebContents::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) {
- 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();
- }
- }
-
+ render_manager_.Stop();
printing_.Stop();
}
void WebContents::DidBecomeSelected() {
TabContents::DidBecomeSelected();
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->DidBecomeSelected();
+ if (render_view_host() && view())
+ view()->DidBecomeSelected();
CacheManagerHost::GetInstance()->ObserveActivity(process()->host_id());
}
void WebContents::WasHidden() {
if (!capturing_contents_) {
- // |render_view_host_| can be NULL if the user middle clicks a link to open
+ // |render_view_host()| can be NULL if the user middle clicks a link to open
// a tab in then background, then closes the tab before selecting it. This
// is because closing the tab calls WebContents::Destroy(), which removes
- // the |render_view_host_|; then when we actually destroy the window,
+ // the |render_view_host()|; then when we actually destroy the window,
// OnWindowPosChanged() notices and calls HideContents() (which calls us).
- if (render_view_host_ && render_view_host_->view())
- render_view_host_->view()->WasHidden();
+ if (render_view_host() && view())
+ view()->WasHidden();
// Loop through children and send WasHidden to them, too.
int count = static_cast<int>(child_windows_.size());
@@ -1104,16 +700,14 @@ void WebContents::StartFinding(int request_id,
bool forward,
bool match_case,
bool find_next) {
- if (search_string.empty()) {
+ if (search_string.empty())
return;
- }
-
- render_view_host_->StartFinding(request_id, search_string, forward,
- match_case, find_next);
+ render_view_host()->StartFinding(request_id, search_string, forward,
+ match_case, find_next);
}
void WebContents::StopFinding(bool clear_selection) {
- render_view_host_->StopFinding(clear_selection);
+ render_view_host()->StopFinding(clear_selection);
}
void WebContents::OpenFindInPageWindow(const Browser& browser) {
@@ -1156,29 +750,29 @@ bool WebContents::AdvanceFindSelection(bool forward_direction) {
}
void WebContents::AlterTextSize(text_zoom::TextSize size) {
- render_view_host_->AlterTextSize(size);
+ render_view_host()->AlterTextSize(size);
// TODO(creis): should this be propagated to other and future RVHs?
}
void WebContents::SetPageEncoding(const std::wstring& encoding_name) {
- render_view_host_->SetPageEncoding(encoding_name);
+ render_view_host()->SetPageEncoding(encoding_name);
// TODO(creis): should this be propagated to other and future RVHs?
}
void WebContents::CopyImageAt(int x, int y) {
- render_view_host_->CopyImageAt(x, y);
+ render_view_host()->CopyImageAt(x, y);
}
void WebContents::InspectElementAt(int x, int y) {
- render_view_host_->InspectElementAt(x, y);
+ render_view_host()->InspectElementAt(x, y);
}
void WebContents::ShowJavaScriptConsole() {
- render_view_host_->ShowJavaScriptConsole();
+ render_view_host()->ShowJavaScriptConsole();
}
void WebContents::AllowDomAutomationBindings() {
- render_view_host_->AllowDomAutomationBindings();
+ render_view_host()->AllowDomAutomationBindings();
// TODO(creis): should this be propagated to other and future RVHs?
}
@@ -1186,19 +780,7 @@ void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& prompt) {
last_javascript_message_dismissal_ = TimeTicks::Now();
-
- RenderViewHost* rvh = render_view_host_;
- if (IsShowingInterstitialPage()) {
- // 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_manager_.OnJavaScriptMessageBoxClosed(reply_msg, success, prompt);
}
// Generic NotificationObserver callback.
@@ -1360,33 +942,33 @@ InfoBarView* WebContents::GetInfoBarView() {
void WebContents::ExecuteJavascriptInWebFrame(
const std::wstring& frame_xpath, const std::wstring& jscript) {
- render_view_host_->ExecuteJavascriptInWebFrame(frame_xpath, jscript);
+ render_view_host()->ExecuteJavascriptInWebFrame(frame_xpath, jscript);
}
void WebContents::AddMessageToConsole(
const std::wstring& frame_xpath, const std::wstring& msg,
ConsoleMessageLevel level) {
- render_view_host_->AddMessageToConsole(frame_xpath, msg, level);
+ render_view_host()->AddMessageToConsole(frame_xpath, msg, level);
}
void WebContents::Undo() {
- render_view_host_->Undo();
+ render_view_host()->Undo();
}
void WebContents::Redo() {
- render_view_host_->Redo();
+ render_view_host()->Redo();
}
void WebContents::Replace(const std::wstring& text) {
- render_view_host_->Replace(text);
+ render_view_host()->Replace(text);
}
void WebContents::Delete() {
- render_view_host_->Delete();
+ render_view_host()->Delete();
}
void WebContents::SelectAll() {
- render_view_host_->SelectAll();
+ render_view_host()->SelectAll();
}
void WebContents::StartFileUpload(const std::wstring& file_path,
@@ -1394,7 +976,7 @@ void WebContents::StartFileUpload(const std::wstring& file_path,
const std::wstring& file,
const std::wstring& submit,
const std::wstring& other_values) {
- render_view_host_->UploadFile(file_path, form, file, submit, other_values);
+ render_view_host()->UploadFile(file_path, form, file, submit, other_values);
}
void WebContents::SetWebApp(WebApp* web_app) {
@@ -1435,35 +1017,35 @@ void WebContents::CreateShortcut() {
// Request the application info. When done OnDidGetApplicationInfo is invoked
// and we'll create the shortcut.
- render_view_host_->GetApplicationInfo(pending_install_.page_id);
+ render_view_host()->GetApplicationInfo(pending_install_.page_id);
}
void WebContents::FillForm(const FormData& form) {
- render_view_host_->FillForm(form);
+ render_view_host()->FillForm(form);
}
void WebContents::FillPasswordForm(
const PasswordFormDomManager::FillData& form_data) {
- render_view_host_->FillPasswordForm(form_data);
+ render_view_host()->FillPasswordForm(form_data);
}
void WebContents::DragTargetDragEnter(const WebDropData& drop_data,
const gfx::Point& client_pt, const gfx::Point& screen_pt) {
- render_view_host_->DragTargetDragEnter(drop_data, client_pt, screen_pt);
+ render_view_host()->DragTargetDragEnter(drop_data, client_pt, screen_pt);
}
void WebContents::DragTargetDragOver(
const gfx::Point& client_pt, const gfx::Point& screen_pt) {
- render_view_host_->DragTargetDragOver(client_pt, screen_pt);
+ render_view_host()->DragTargetDragOver(client_pt, screen_pt);
}
void WebContents::DragTargetDragLeave() {
- render_view_host_->DragTargetDragLeave();
+ render_view_host()->DragTargetDragLeave();
}
void WebContents::DragTargetDrop(
const gfx::Point& client_pt, const gfx::Point& screen_pt) {
- render_view_host_->DragTargetDrop(client_pt, screen_pt);
+ render_view_host()->DragTargetDrop(client_pt, screen_pt);
}
PasswordManager* WebContents::GetPasswordManager() {
@@ -1478,16 +1060,6 @@ PluginInstaller* WebContents::GetPluginInstaller() {
return plugin_installer_.get();
}
-RenderProcessHost* WebContents::process() const {
- return render_view_host_->process();
-}
-RenderViewHost* WebContents::render_view_host() const {
- return render_view_host_;
-}
-SiteInstance* WebContents::site_instance() const {
- return render_view_host_->site_instance();
-}
-
bool WebContents::IsActiveEntry(int32 page_id) {
NavigationEntry* active_entry = controller()->GetActiveEntry();
return (active_entry != NULL &&
@@ -1516,7 +1088,9 @@ void WebContents::CreateView(int route_id, HANDLE modal_dialog_event) {
// other issues. We should fix this.
HWND new_view_parent_window = ::GetAncestor(GetHWND(), GA_ROOT);
new_view->CreateView(new_view_parent_window, gfx::Rect());
- new_view->CreatePageView(new_view->render_view_host_);
+ // TODO(brettw) it seems bogus that we have to call this function on the
+ // newly created object and give it one of its own member variables.
+ new_view->CreatePageView(new_view->render_view_host());
// Don't show the view until we get enough context in ShowView.
pending_views_[route_id] = new_view;
@@ -1529,7 +1103,7 @@ void WebContents::CreateWidget(int route_id) {
// We set the parent HWDN explicitly as pop-up HWNDs are parented and owned by
// the first non-child HWND of the HWND that was specified to the CreateWindow
// call.
- widget_view->set_parent_hwnd(render_view_host_->view()->GetPluginHWND());
+ widget_view->set_parent_hwnd(view()->GetPluginHWND());
widget_view->set_close_on_deactivate(true);
// Don't show the widget until we get its position in ShowWidget.
@@ -1549,13 +1123,14 @@ void WebContents::ShowView(int route_id,
WebContents* new_view = iter->second;
pending_views_.erase(route_id);
- if (!new_view->render_view_host_->view() ||
- !new_view->render_view_host_->process()->channel()) {
+ if (!new_view->view() ||
+ !new_view->process()->channel()) {
// The view has gone away or the renderer crashed. Nothing to do.
return;
}
- new_view->render_view_host_->Init();
+ // TODO(brettw) this seems bogus to reach into here and initialize the host.
+ new_view->render_view_host()->Init();
AddNewContents(new_view, disposition, initial_pos, user_gesture);
}
@@ -1586,11 +1161,12 @@ void WebContents::ShowWidget(int route_id, const gfx::Rect& initial_pos) {
widget_host->Init();
}
-void WebContents::RendererReady(RenderViewHost* render_view_host) {
- if (IsShowingInterstitialPage() && (render_view_host == render_view_host_)) {
+void WebContents::RendererReady(RenderViewHost* rvh) {
+ if (render_manager_.showing_interstitial_page() &&
+ rvh == render_view_host()) {
// We are showing an interstitial page, don't notify the world.
return;
- } else if (render_view_host != render_view_host_) {
+ } else if (rvh != render_view_host()) {
// Don't notify the world, since this came from a renderer in the
// background.
return;
@@ -1600,11 +1176,11 @@ void WebContents::RendererReady(RenderViewHost* render_view_host) {
SetIsCrashed(false);
}
-void WebContents::RendererGone(RenderViewHost* render_view_host) {
+void WebContents::RendererGone(RenderViewHost* rvh) {
// Ask the print preview if this renderer was valuable.
- if (!printing_.OnRendererGone(render_view_host))
+ if (!printing_.OnRendererGone(rvh))
return;
- if (render_view_host != render_view_host_) {
+ if (rvh != render_view_host()) {
// The pending or interstitial page's RenderViewHost is gone. If we are
// showing an interstitial, this may mean that the original RenderViewHost
// is gone. If so, we will call RendererGone again if we try to swap that
@@ -1634,16 +1210,14 @@ void WebContents::RendererGone(RenderViewHost* render_view_host) {
HungRendererWarning::HideForWebContents(this);
}
-void WebContents::DidNavigate(RenderViewHost* render_view_host,
+void WebContents::DidNavigate(RenderViewHost* rvh,
const ViewHostMsg_FrameNavigate_Params& params) {
if (PageTransition::IsMainFrame(params.transition))
- UpdateRendererStateDidNavigate(render_view_host);
+ render_manager_.DidNavigateMainFrame(rvh);
// In the case of interstitial, we don't mess with the navigation entries.
- if (IsShowingInterstitialPage()) {
- DCHECK(renderer_state_ != LEAVING_INTERSTITIAL);
+ if (render_manager_.showing_interstitial_page())
return;
- }
// Check for navigations we don't expect.
if (!controller() || !is_active_ || params.page_id == -1) {
@@ -1653,7 +1227,7 @@ void WebContents::DidNavigate(RenderViewHost* render_view_host,
"invalid |page_id| if, and only if, this is the initial blank "
"page for a main frame.";
}
- BroadcastProvisionalLoadCommit(render_view_host, params);
+ BroadcastProvisionalLoadCommit(rvh, params);
return;
}
@@ -1688,7 +1262,7 @@ void WebContents::DidNavigate(RenderViewHost* render_view_host,
// Run post-commit tasks.
if (PageTransition::IsMainFrame(params.transition))
DidNavigateMainFramePostCommit(params);
- DidNavigateAnyFramePostCommit(render_view_host, params);
+ DidNavigateAnyFramePostCommit(rvh, params);
}
NavigationEntry* WebContents::CreateNavigationEntryForCommit(
@@ -1710,7 +1284,12 @@ NavigationEntry* WebContents::CreateNavigationEntryForCommit(
// Update the site of the SiteInstance if it doesn't have one yet, unless we
// are showing an interstitial page. If we are, we should wait until the
// real page commits.
- if (!site_instance()->has_site() && renderer_state_ != INTERSTITIAL)
+ //
+ // TODO(brettw) the old code only checked for INTERSTIAL, this new code also
+ // checks for LEAVING_INTERSTITIAL mode in the manager. Is this difference
+ // important?
+ if (!site_instance()->has_site() &&
+ !render_manager_.showing_interstitial_page())
site_instance()->SetSite(params.url);
// When the navigation is just a change in ref or a sub-frame navigation, the
@@ -1973,117 +1552,8 @@ void WebContents::HandleProfilingForDidNavigate(
params.page_id);
profiler->AddFrameMetrics(process()->host_id(),
- render_view_host_->routing_id(), frame);
- }
-}
-
-void WebContents::UpdateRendererStateDidNavigate(
- RenderViewHost* render_view_host) {
- if (renderer_state_ == NORMAL) {
- // 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();
-
- } else {
- // No such state.
- DCHECK(false);
- return;
+ render_view_host()->routing_id(),
+ frame);
}
}
@@ -2092,7 +1562,7 @@ void WebContents::BroadcastProvisionalLoadCommit(
const ViewHostMsg_FrameNavigate_Params& params) {
ProvisionalLoadDetails details(
PageTransition::IsMainFrame(params.transition),
- IsInterstitialRenderViewHost(render_view_host),
+ render_manager_.IsRenderViewInterstitial(render_view_host),
IsInPageNavigation(params.url),
params.url, params.security_info);
NotificationService::current()->
@@ -2119,51 +1589,6 @@ void WebContents::UpdateWebPreferences() {
render_view_host()->UpdateWebPreferences(GetWebkitPrefs());
}
-void WebContents::SwapToRenderView(RenderViewHost** new_render_view_host,
- bool destroy_after) {
- // Remember if the page was focused so we can focus the new renderer in
- // that case.
- bool focus_render_view = render_view_host_->view() &&
- render_view_host_->view()->HasFocus();
-
- // Hide the current view and prepare to destroy it.
- // TODO(creis): Get the old RenderViewHost to send us an UpdateState message
- // before we destroy it.
- if (render_view_host_->view())
- render_view_host_->view()->Hide();
- RenderViewHost* old_render_view_host = render_view_host_;
-
- // Swap in the pending view and make it active.
- render_view_host_ = (*new_render_view_host);
- (*new_render_view_host) = NULL;
-
- // If the view is gone, then this RenderViewHost died while it was hidden.
- // We ignored the RendererGone call at the time, so we should send it now
- // to make sure the sad tab shows up, etc.
- if (render_view_host_->view())
- render_view_host_->view()->Show();
- else
- RendererGone(render_view_host_);
-
- // Make sure the size is up to date. (Fix for bug 1079768.)
- UpdateRenderViewSize();
-
- if (focus_render_view && render_view_host_->view())
- render_view_host_->view()->Focus();
-
- NotificationService::current()->Notify(
- NOTIFY_RENDER_VIEW_HOST_CHANGED,
- Source<WebContents>(this),
- Details<RenderViewHost>(old_render_view_host));
-
- if (destroy_after)
- old_render_view_host->Shutdown();
-
- // Let the task manager know that we've swapped RenderViewHosts, since it
- // might need to update its process groupings.
- NotifySwapped();
-}
-
void WebContents::UpdateRenderViewSize() {
// Using same technique as OnPaint, which sets size of SadTab.
CRect cr;
@@ -2172,12 +1597,13 @@ void WebContents::UpdateRenderViewSize() {
SizeContents(new_size);
}
-void WebContents::UpdateState(RenderViewHost* render_view_host,
+void WebContents::UpdateState(RenderViewHost* rvh,
int32 page_id,
const GURL& url,
const std::wstring& title,
const std::string& state) {
- if (render_view_host != render_view_host_ || IsShowingInterstitialPage()) {
+ if (rvh != render_view_host() ||
+ render_manager_.showing_interstitial_page()) {
// This UpdateState is either:
// - targeted not at the current RenderViewHost. This could be that we are
// showing the interstitial page and getting an update for the regular page,
@@ -2234,7 +1660,7 @@ void WebContents::UpdateState(RenderViewHost* render_view_host,
if (GetHWND()) {
// It's possible to get this after the hwnd has been destroyed.
::SetWindowText(GetHWND(), title.c_str());
- ::SetWindowText(render_view_host_->view()->GetPluginHWND(), title.c_str());
+ ::SetWindowText(view()->GetPluginHWND(), title.c_str());
}
// Update the state (forms, etc.).
@@ -2249,7 +1675,7 @@ void WebContents::UpdateState(RenderViewHost* render_view_host,
controller()->SyncSessionWithEntryByPageID(type(), site_instance(), page_id);
}
-void WebContents::UpdateTitle(RenderViewHost* render_view_host,
+void WebContents::UpdateTitle(RenderViewHost* rvh,
int32 page_id, const std::wstring& title) {
if (!controller())
return;
@@ -2259,7 +1685,8 @@ void WebContents::UpdateTitle(RenderViewHost* render_view_host,
response_started_ = false;
NavigationEntry* entry;
- if (IsShowingInterstitialPage() && (render_view_host == render_view_host_)) {
+ if (render_manager_.showing_interstitial_page() &&
+ (rvh == render_view_host())) {
// We are showing an interstitial page in a different RenderViewHost, so
// the page_id is not sufficient to find the entry from the controller.
// (both RenderViewHost page_ids overlap). We know it is the last entry,
@@ -2316,9 +1743,9 @@ void WebContents::UpdateThumbnail(const GURL& url,
}
}
-void WebContents::Close(RenderViewHost* render_view_host) {
+void WebContents::Close(RenderViewHost* rvh) {
// Ignore this if it comes from a RenderViewHost that we aren't showing.
- if (delegate() && render_view_host == render_view_host_)
+ if (delegate() && rvh == render_view_host())
delegate()->CloseContents(this);
}
@@ -2339,7 +1766,7 @@ void WebContents::DidStopLoading(RenderViewHost* rvh, int32 page_id) {
NavigationProfiler* profiler = GetNavigationProfiler();
profiler->SetLoadingEndTime(process()->host_id(),
- render_view_host_->routing_id(), page_id,
+ render_view_host()->routing_id(), page_id,
current_time);
SaveCurrentProfilingEntry();
}
@@ -2380,10 +1807,11 @@ void WebContents::DidStartProvisionalLoadForFrame(
RenderViewHost* render_view_host,
bool is_main_frame,
const GURL& url) {
- ProvisionalLoadDetails details(is_main_frame,
- IsInterstitialRenderViewHost(render_view_host),
- IsInPageNavigation(url),
- url, std::string());
+ ProvisionalLoadDetails details(
+ is_main_frame,
+ render_manager_.IsRenderViewInterstitial(render_view_host),
+ IsInPageNavigation(url),
+ url, std::string());
NotificationService::current()->
Notify(NOTIFY_FRAME_PROVISIONAL_LOAD_START,
Source<NavigationController>(controller()),
@@ -2431,78 +1859,27 @@ void WebContents::DidFailProvisionalLoadWithError(
if (!controller())
return;
- // This will discard our pending entry if we cancelled the load (e.g., if we
- // decided to download the file instead of load it). Only discard the pending
- // entry if the URLs match, otherwise the user initiated a navigate before
- // the page loaded so that the discard would discard the wrong entry.
if (net::ERR_ABORTED == error_code) {
+ // This will discard our pending entry if we cancelled the load (e.g., if we
+ // decided to download the file instead of load it). Only discard the
+ // pending entry if the URLs match, otherwise the user initiated a navigate
+ // before the page loaded so that the discard would discard the wrong entry.
NavigationEntry* pending_entry = controller()->GetPendingEntry();
if (pending_entry && pending_entry->GetURL() == url)
controller()->DiscardPendingEntry();
- // We used to cancel the pending renderer here for cross-site downloads.
- // However, it's not safe to do that because the download logic repeatedly
- // looks for this TabContents based on a render view ID. Instead, we just
- // leave the pending renderer around until the next navigation event
- // (Navigate, DidNavigate, etc), which will clean it up properly.
- // TODO(creis): All of this will go away when we move the cross-site logic
- // to ResourceDispatcherHost, so that we intercept responses rather than
- // 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;
- // InterstitialPageGone();
- }
+ render_manager_.RendererAbortedProvisionalLoad(render_view_host);
}
// Send out a notification that we failed a provisional load with an error.
- ProvisionalLoadDetails details(is_main_frame,
- IsInterstitialRenderViewHost(render_view_host),
- IsInPageNavigation(url),
- url, std::string());
+ ProvisionalLoadDetails details(
+ is_main_frame,
+ render_manager_.IsRenderViewInterstitial(render_view_host),
+ IsInPageNavigation(url),
+ url, std::string());
details.set_error_code(error_code);
- showing_repost_interstitial_ = showing_repost_interstitial;
+ render_manager_.set_showing_repost_interstitial(showing_repost_interstitial);
NotificationService::current()->
Notify(NOTIFY_FAIL_PROVISIONAL_LOAD_WITH_ERROR,
@@ -2590,7 +1967,7 @@ void WebContents::StartDragging(const WebDropData& drop_data) {
data->SetString(drop_data.plain_text);
scoped_refptr<WebDragSource> drag_source(
- new WebDragSource(GetHWND(), render_view_host_));
+ new WebDragSource(GetHWND(), render_view_host()));
DWORD effects;
@@ -2601,7 +1978,8 @@ void WebContents::StartDragging(const WebDropData& drop_data) {
DoDragDrop(data, drag_source, DROPEFFECT_COPY | DROPEFFECT_LINK, &effects);
MessageLoop::current()->SetNestableTasksAllowed(old_state);
- render_view_host_->DragSourceSystemDragEnded();
+ if (render_view_host())
+ render_view_host()->DragSourceSystemDragEnded();
}
void WebContents::UpdateDragCursor(bool is_drop_target) {
@@ -2969,11 +2347,17 @@ void WebContents::UpdateMaxPageIDIfNecessary(SiteInstance* site_instance,
}
}
+void WebContents::BeforeUnloadFiredFromRenderManager(
+ bool proceed,
+ bool* proceed_to_fire_unload) {
+ delegate()->BeforeUnloadFired(this, proceed, proceed_to_fire_unload);
+}
+
+
HWND WebContents::GetContentHWND() {
- if (!render_view_host_ || !render_view_host_->view())
+ if (!view())
return NULL;
-
- return render_view_host_->view()->GetPluginHWND();
+ return view()->GetPluginHWND();
}
bool WebContents::CanDisplayFile(const std::wstring& full_path) {
@@ -2989,7 +2373,7 @@ bool WebContents::CanDisplayFile(const std::wstring& full_path) {
void WebContents::PrintPreview() {
// We can't print interstitial page for now.
- if (IsShowingInterstitialPage())
+ if (render_manager_.showing_interstitial_page())
return;
// If we have a FindInPage dialog, notify it that its tab was hidden.
@@ -3002,7 +2386,7 @@ void WebContents::PrintPreview() {
bool WebContents::PrintNow() {
// We can't print interstitial page for now.
- if (IsShowingInterstitialPage())
+ if (render_manager_.showing_interstitial_page())
return false;
// If we have a FindInPage dialog, notify it that its tab was hidden.
@@ -3021,19 +2405,19 @@ void WebContents::DidCaptureContents() {
}
void WebContents::Cut() {
- render_view_host_->Cut();
+ render_view_host()->Cut();
}
void WebContents::Copy() {
- render_view_host_->Copy();
+ render_view_host()->Copy();
}
void WebContents::Paste() {
- render_view_host_->Paste();
+ render_view_host()->Paste();
}
void WebContents::SetInitialFocus(bool reverse) {
- render_view_host_->SetInitialFocus(reverse);
+ render_view_host()->SetInitialFocus(reverse);
}
void WebContents::GenerateKeywordIfNecessary(
@@ -3148,21 +2532,8 @@ void WebContents::HandleKeyboardEvent(const WebKeyboardEvent& event) {
event.actual_message.lParam);
}
-RenderViewHost* WebContents::CreateRenderViewHost(
- SiteInstance* instance,
- RenderViewHostDelegate* delegate,
- int routing_id,
- HANDLE modal_dialog_event) {
- if (render_view_factory_) {
- return render_view_factory_->CreateRenderViewHost(
- instance, delegate, routing_id, modal_dialog_event);
- } else {
- return new RenderViewHost(instance, delegate, routing_id,
- modal_dialog_event);
- }
-}
-
-bool WebContents::CreateRenderView(RenderViewHost* render_view_host) {
+bool WebContents::CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host) {
RenderWidgetHostHWND* view = CreatePageView(render_view_host);
bool ok = render_view_host->CreateRenderView();
@@ -3199,239 +2570,25 @@ void WebContents::SetIsLoading(bool is_loading,
LoadNotificationDetails* details) {
if (!is_loading) {
load_state_ = net::LOAD_STATE_IDLE;
- load_state_host_ = std::wstring();
+ load_state_host_.clear();
}
TabContents::SetIsLoading(is_loading, details);
- // We don't know which render_view_host this is for, so let's tell them all
- 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);
+ render_manager_.SetIsLoading(is_loading);
}
void WebContents::FileSelected(const std::wstring& path, void* params) {
- render_view_host_->FileSelected(path);
+ render_view_host()->FileSelected(path);
}
void WebContents::FileSelectionCanceled(void* params) {
// If the user cancels choosing a file to upload we need to pass back the
// empty string.
- render_view_host_->FileSelected(L"");
+ render_view_host()->FileSelected(std::wstring());
}
///////////////////////////////////////////////////////////////////////////////
-bool WebContents::IsShowingInterstitialPage() const {
- return (renderer_state_ == INTERSTITIAL) ||
- (renderer_state_ == LEAVING_INTERSTITIAL);
-}
-
-void WebContents::ShowInterstitialPage(const std::string& html_text,
- InterstitialPageDelegate* delegate) {
- // 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, this, MSG_ROUTING_NONE, NULL);
- interstitial_delegate_ = delegate;
- bool success = CreateRenderView(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(html_text, false,
- GURL::EmptyGURL(),
- std::string());
-}
-
-void WebContents::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(IsShowingInterstitialPage());
- 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).
- DidStartLoading(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();
- }
-}
-
-void WebContents::InterstitialPageGone() {
- DCHECK(!IsShowingInterstitialPage());
-
- NotificationService::current()->Notify(
- NOTIFY_INTERSTITIAL_PAGE_CLOSED,
- Source<WebContents>(this), NotificationService::NoDetails());
- if (interstitial_delegate_) {
- interstitial_delegate_->InterstitialClosed();
- interstitial_delegate_ = NULL;
- }
-}
-
-bool WebContents::IsInterstitialRenderViewHost(
- RenderViewHost* render_view_host) const {
- if (IsShowingInterstitialPage()) {
- return render_view_host_ == render_view_host;
- }
- if (renderer_state_ == ENTERING_INTERSTITIAL) {
- return interstitial_render_view_host_ == render_view_host;
- }
- return false;
-}
-
bool WebContents::IsInPageNavigation(const GURL& url) const {
// We compare to the last committed entry and not the active entry as the
// active entry is the current pending entry (if any).
@@ -3484,7 +2641,8 @@ void WebContents::InstallMissingPlugin() {
void WebContents::GetAllSavableResourceLinksForCurrentPage(
const GURL& page_url) {
- render_view_host_->GetAllSavableResourceLinksForCurrentPage(page_url);
+ render_view_host()->GetAllSavableResourceLinksForCurrentPage(
+ page_url);
}
void WebContents::OnReceivedSavableResourceLinksForCurrentPage(
@@ -3492,10 +2650,11 @@ void WebContents::OnReceivedSavableResourceLinksForCurrentPage(
const std::vector<GURL>& referrers_list,
const std::vector<GURL>& frames_list) {
SavePackage* save_package = get_save_package();
- if (save_package)
+ if (save_package) {
save_package->ProcessCurrentPageAllSavableResourceLinks(resources_list,
referrers_list,
frames_list);
+ }
}
void WebContents::GetSerializedHtmlDataForCurrentPageWithLocalLinks(
@@ -3521,8 +2680,8 @@ bool WebContents::CanBlur() const {
return delegate() ? delegate()->CanBlur() : true;
}
-void WebContents::RendererUnresponsive(RenderViewHost* render_view_host) {
- if (render_view_host_ && render_view_host_->IsRenderViewLive())
+void WebContents::RendererUnresponsive(RenderViewHost* rvh) {
+ if (render_view_host() && render_view_host()->IsRenderViewLive())
HungRendererWarning::ShowForWebContents(this);
}
@@ -3533,7 +2692,7 @@ void WebContents::RendererResponsive(RenderViewHost* render_view_host) {
void WebContents::LoadStateChanged(const GURL& url,
net::LoadState load_state) {
load_state_ = load_state;
- load_state_host_ = UTF8ToWide(url.host().c_str());
+ load_state_host_ = UTF8ToWide(url.host());
if (load_state_ == net::LOAD_STATE_READING_RESPONSE)
response_started_ = false;
if (is_loading())
diff --git a/chrome/browser/web_contents.h b/chrome/browser/web_contents.h
index a48d117..2f3a7bd 100644
--- a/chrome/browser/web_contents.h
+++ b/chrome/browser/web_contents.h
@@ -37,6 +37,7 @@
#include "chrome/browser/fav_icon_helper.h"
#include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/render_view_host_delegate.h"
+#include "chrome/browser/render_view_host_manager.h"
#include "chrome/browser/save_package.h"
#include "chrome/browser/shell_dialogs.h"
#include "chrome/browser/tab_contents.h"
@@ -58,6 +59,7 @@ class WebDropTarget;
class WebContents : public TabContents,
public RenderViewHostDelegate,
+ public RenderViewHostManager::Delegate,
public ChromeViews::HWNDViewContainer,
public SelectFileDialog::Listener,
public WebApp::Observer {
@@ -119,6 +121,14 @@ class WebContents : public TabContents,
// Return true if the WebContents is doing performance profiling
bool is_profiling() const { return is_profiling_; }
+ // Various other systems need to know about our interstitials.
+ bool showing_interstitial_page() const {
+ return render_manager_.showing_interstitial_page();
+ }
+ bool showing_repost_interstitial() const {
+ return render_manager_.showing_repost_interstitial();
+ }
+
// Check with the global navigation profiler on whether to enable
// profiling. Return true if profiling needs to be enabled, return
// false otherwise.
@@ -254,9 +264,18 @@ class WebContents : public TabContents,
// should be aware that the SiteInstance could be deleted if its ref count
// drops to zero (i.e., if all RenderViewHosts and NavigationEntries that
// use it are deleted).
- RenderProcessHost* process() const;
- RenderViewHost* render_view_host() const;
- SiteInstance* site_instance() const;
+ RenderProcessHost* process() const {
+ return render_manager_.current_host()->process();
+ }
+ RenderViewHost* render_view_host() const {
+ return render_manager_.current_host();
+ }
+ SiteInstance* site_instance() const {
+ return render_manager_.current_host()->site_instance();
+ }
+ RenderWidgetHostView* view() const {
+ return render_manager_.current_view();
+ }
// Overridden from TabContents to return the window of the
// RenderWidgetHostView.
@@ -284,15 +303,23 @@ class WebContents : public TabContents,
virtual void Copy();
virtual void Paste();
- // Returns whether we are currently showing an interstitial page.
- bool IsShowingInterstitialPage() const;
+ // The rest of the system wants to interact with the delegate our render view
+ // host manager has. See those setters for more.
+ InterstitialPageDelegate* interstitial_page_delegate() const {
+ return render_manager_.interstitial_delegate();
+ }
+ void set_interstitial_delegate(InterstitialPageDelegate* delegate) {
+ render_manager_.set_interstitial_delegate(delegate);
+ }
// Displays the specified html in the current page. This method can be used to
// show temporary pages (such as security error pages). It can be hidden by
// calling HideInterstitialPage, in which case the original page is restored.
// An optional delegate may be passed, it is not owned by the WebContents.
void ShowInterstitialPage(const std::string& html_text,
- InterstitialPageDelegate* delegate);
+ InterstitialPageDelegate* delegate) {
+ render_manager_.ShowInterstitialPage(html_text, delegate);
+ }
// Reverts from the interstitial page to the original page.
// If |wait_for_navigation| is true, the interstitial page is removed when
@@ -301,56 +328,22 @@ class WebContents : public TabContents,
// Hiding the interstitial page right away would show the previous displayed
// page. If |proceed| is true, the WebContents will expect the navigation
// to complete. If not, it will revert to the last shown page.
- void HideInterstitialPage(bool wait_for_navigation, bool proceed);
+ void HideInterstitialPage(bool wait_for_navigation, bool proceed) {
+ render_manager_.HideInterstitialPage(wait_for_navigation, proceed);
+ }
// Allows the WebContents to react when a cross-site response is ready to be
// delivered to a pending RenderViewHost. We must first run the onunload
// handler of the old RenderViewHost before we can allow it to proceed.
void OnCrossSiteResponse(int new_render_process_host_id,
- int new_request_id);
+ int new_request_id) {
+ render_manager_.OnCrossSiteResponse(new_render_process_host_id,
+ new_request_id);
+ }
// Returns true if the active NavigationEntry's page_id equals page_id.
bool IsActiveEntry(int32 page_id);
- // RenderViewHost states. These states represent whether a cross-site
- // request is pending (in the new process model) and whether an interstitial
- // page is being shown. These are public to give easy access to unit tests.
- enum RendererState {
- // NORMAL: just showing a page normally.
- // render_view_host_ is showing a page.
- // pending_render_view_host_ is NULL.
- // original_render_view_host_ is NULL.
- // interstitial_render_view_host_ is NULL.
- NORMAL = 0,
- // PENDING: creating a new RenderViewHost for a cross-site navigation.
- // Never used when --process-per-tab is specified.
- // render_view_host_ is showing a page.
- // pending_render_view_host_ is loading a page in the background.
- // original_render_view_host_ is NULL.
- // interstitial_render_view_host_ is NULL.
- PENDING,
- // ENTERING_INTERSTITIAL: an interstitial RenderViewHost has been created.
- // and will be shown as soon as it calls DidNavigate.
- // render_view_host_ is showing a page.
- // pending_render_view_host_ is either NULL or suspended in the background.
- // original_render_view_host_ is NULL.
- // interstitial_render_view_host_ is loading in the background.
- ENTERING_INTERSTITIAL,
- // INTERSTITIAL: Showing an interstitial page.
- // render_view_host_ is showing the interstitial.
- // pending_render_view_host_ is either NULL or suspended in the background.
- // original_render_view_host_ is the hidden original page.
- // interstitial_render_view_host_ is NULL.
- INTERSTITIAL,
- // LEAVING_INTERSTITIAL: interstitial is still showing, but we are
- // navigating to a new page that will replace it.
- // render_view_host_ is showing the interstitial.
- // pending_render_view_host_ is either NULL or loading a page.
- // original_render_view_host_ is hidden and possibly loading a page.
- // interstitial_render_view_host_ is NULL.
- LEAVING_INTERSTITIAL
- };
-
const std::string& contents_mime_type() const {
return contents_mime_type_;
}
@@ -358,20 +351,6 @@ class WebContents : public TabContents,
// Returns true if this WebContents will notify about disconnection.
bool notify_disconnection() const { return notify_disconnection_; }
- // Are we showing the POST interstitial page?
- //
- // NOTE: the POST interstitial does NOT result in a separate RenderViewHost.
- bool showing_repost_interstitial() { return showing_repost_interstitial_; }
-
- // Accessors to the the interstitial delegate, that is optionaly set when
- // an interstitial page is shown.
- InterstitialPageDelegate* interstitial_page_delegate() const {
- return interstitial_delegate_;
- }
- void set_interstitial_delegate(InterstitialPageDelegate* delegate) {
- interstitial_delegate_ = delegate;
- }
-
protected:
FRIEND_TEST(WebContentsTest, OnMessageReceived);
@@ -473,7 +452,9 @@ class WebContents : public TabContents,
virtual void OnReceivedSerializedHtmlData(const GURL& frame_url,
const std::string& data,
int32 status);
- virtual void ShouldClosePage(bool proceed);
+ virtual void ShouldClosePage(bool proceed) {
+ render_manager_.ShouldClosePage(proceed);
+ }
virtual bool CanBlur() const;
virtual void RendererUnresponsive(RenderViewHost* render_view_host);
virtual void RendererResponsive(RenderViewHost* render_view_host);
@@ -507,15 +488,22 @@ class WebContents : public TabContents,
virtual void FileSelected(const std::wstring& path, void* params);
virtual void FileSelectionCanceled(void* params);
- // This method initializes the given renderer if necessary and creates the
- // view ID corresponding to this view host. If this method is not called and
- // the process is not shared, then the WebContents will act as though the
- // renderer is not running (i.e., it will render "sad tab").
- // This method is automatically called from LoadURL.
+ // Another part of RenderViewHostManager::Delegate.
+ //
+ // Initializes the given renderer if necessary and creates the view ID
+ // corresponding to this view host. If this method is not called and the
+ // process is not shared, then the WebContents will act as though the renderer
+ // is not running (i.e., it will render "sad tab"). This method is
+ // automatically called from LoadURL.
//
// If you are attaching to an already-existing RenderView, you should call
// InitWithExistingID.
- virtual bool CreateRenderView(RenderViewHost* render_view_host);
+ //
+ // TODO(brettw) clean this up! This logic seems out of place. This is called
+ // by the RenderViewHostManager, but also overridden by the DOMUIHost. Any
+ // logic that has to be here should have a more clear name.
+ virtual bool CreateRenderViewForRenderManager(
+ RenderViewHost* render_view_host);
private:
friend class TestWebContents;
@@ -536,52 +524,9 @@ class WebContents : public TabContents,
GearsCreateShortcutCallbackFunctor* callback_functor;
};
-
bool ScrollZoom(int scroll_type);
void WheelZoom(int distance);
- // Creates a RenderViewHost using render_view_factory_ (or directly, if the
- // factory is NULL).
- RenderViewHost* CreateRenderViewHost(SiteInstance* instance,
- RenderViewHostDelegate* delegate,
- int routing_id,
- HANDLE modal_dialog_event);
-
- // Returns whether this tab should transition to a new renderer for
- // cross-site URLs. Enabled unless we see the --process-per-tab command line
- // switch. Can be overridden in unit tests.
- virtual bool ShouldTransitionCrossSite();
-
- // Returns an appropriate SiteInstance object for the given NavigationEntry,
- // possibly reusing the current SiteInstance.
- // Never called if --process-per-tab is used.
- SiteInstance* GetSiteInstanceForEntry(const NavigationEntry& entry,
- SiteInstance* curr_instance);
-
- // Prevent the interstitial page from proceeding after we start navigating
- // away from it. If |stop_request| is true, abort the pending requests
- // immediately, because we are navigating away.
- void DisableInterstitialProceed(bool stop_request);
-
- // Helper method to create a pending RenderViewHost for a cross-site
- // navigation. Used in the new process model.
- bool CreatePendingRenderView(SiteInstance* instance);
-
- // Replaces the currently shown render_view_host_ with the RenderViewHost in
- // the field pointed to by |new_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. If |destroy_after|, this method will call
- // ScheduleDeferredDestroy on the previous render_view_host_.
- void SwapToRenderView(RenderViewHost** new_render_view_host,
- bool destroy_after);
-
- // Destroys the RenderViewHost in the field pointed to by |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.
- void CancelRenderView(RenderViewHost** render_view_host);
-
// Backend for LoadURL that optionally creates a history entry. The
// transition type will be ignored if a history entry is not created.
void LoadURL(const std::wstring& url, bool create_history_entry,
@@ -626,14 +571,6 @@ class WebContents : public TabContents,
// it and contains page plugins.
RenderWidgetHostHWND* CreatePageView(RenderViewHost* render_view_host);
- // Cleans up after an interstitial page is hidden, including removing the
- // interstitial's NavigationEntry.
- void InterstitialPageGone();
-
- // Convenience method that returns true if the specified RenderViewHost is
- // this WebContents' interstitial page RenderViewHost.
- bool IsInterstitialRenderViewHost(RenderViewHost* render_view_host) const;
-
// Navigation helpers --------------------------------------------------------
//
// These functions are helpers for Navigate() and DidNavigate().
@@ -673,10 +610,6 @@ class WebContents : public TabContents,
RenderViewHost* render_view_host,
const ViewHostMsg_FrameNavigate_Params& params);
- // Helper method to update the RendererState on a call to [Did]Navigate.
- RenderViewHost* UpdateRendererStateNavigate(const NavigationEntry& entry);
- void UpdateRendererStateDidNavigate(RenderViewHost* render_view_host);
-
// Called when navigating the main frame to close all child windows if the
// domain is changing.
void MaybeCloseChildWindows(const ViewHostMsg_FrameNavigate_Params& params);
@@ -725,6 +658,28 @@ class WebContents : public TabContents,
void UpdateMaxPageIDIfNecessary(SiteInstance* site_instance,
RenderViewHost* rvh);
+ // RenderViewHostManager::Delegate pass-throughs -----------------------------
+
+ virtual void BeforeUnloadFiredFromRenderManager(
+ bool proceed,
+ bool* proceed_to_fire_unload);
+ virtual void DidStartLoadingFromRenderManager(
+ RenderViewHost* render_view_host, int32 page_id) {
+ DidStartLoading(render_view_host, page_id);
+ }
+ virtual void RendererGoneFromRenderManager(RenderViewHost* render_view_host) {
+ RendererGone(render_view_host);
+ }
+ virtual void UpdateRenderViewSizeForRenderManager() {
+ UpdateRenderViewSize();
+ }
+ virtual void NotifySwappedFromRenderManager() {
+ NotifySwapped();
+ }
+ virtual NavigationController* GetControllerForRenderManager() {
+ return controller();
+ }
+
// Profiling -----------------------------------------------------------------
// Logs the commit of the load for profiling purposes. Used by DidNavigate.
@@ -746,35 +701,11 @@ class WebContents : public TabContents,
// Data ----------------------------------------------------------------------
- // Factory for creating RenderViewHosts. This is useful for unit tests. If
- // this is NULL, just create a RenderViewHost directly.
- RenderViewHostFactory* render_view_factory_;
-
- // Our RenderView host. This object is responsible for all communication with
- // a child RenderView instance. Note that this can be the page render view
- // host or the interstitial RenderViewHost if the RendererState is
- // INTERSTITIAL or LEAVING_INTERSTITIAL.
- RenderViewHost* render_view_host_;
+ // Manages creation and swapping of render views.
+ RenderViewHostManager render_manager_;
- // This var holds the original RenderViewHost when the interstitial page is
- // showing (the RendererState is INTERSTITIAL or LEAVING_INTERSTITIAL). It
- // is NULL otherwise.
- RenderViewHost* original_render_view_host_;
-
- // The RenderViewHost of the interstitial page. This is non NULL when the
- // the RendererState is ENTERING_INTERSTITIAL.
- RenderViewHost* interstitial_render_view_host_;
-
- // A RenderViewHost used to load a cross-site page. This remains hidden
- // during the PENDING RendererState until it calls DidNavigate. It can also
- // exist if an interstitial page is shown.
- RenderViewHost* pending_render_view_host_;
-
- // Indicates if we are in the process of swapping our RenderViewHost. This
- // allows us to switch to interstitial pages in different RenderViewHosts.
- // In the new process model, this also allows us to render pages from
- // different SiteInstances in different processes, all within the same tab.
- RendererState renderer_state_;
+ // For testing, passed to new RenderViewHost managers.
+ RenderViewHostFactory* render_view_factory_;
// Handles print preview and print job for this contents.
printing::PrintViewManager printing_;
@@ -885,12 +816,6 @@ class WebContents : public TabContents,
// Non-null if we're displaying content for a web app.
scoped_refptr<WebApp> web_app_;
- // See comment above showing_repost_interstitial().
- bool showing_repost_interstitial_;
-
- // An optional delegate used when an interstitial page is shown that gets
- // notified when the state of the interstitial changes.
- InterstitialPageDelegate* interstitial_delegate_;
DISALLOW_EVIL_CONSTRUCTORS(WebContents);
};
diff --git a/chrome/browser/web_contents_unittest.cc b/chrome/browser/web_contents_unittest.cc
index a4995fa..3b7450c 100644
--- a/chrome/browser/web_contents_unittest.cc
+++ b/chrome/browser/web_contents_unittest.cc
@@ -197,18 +197,41 @@ class TestWebContents : public WebContents {
transition_cross_site(false) {}
// Accessors for interesting fields
- RendererState renderer_state() { return renderer_state_; }
TestRenderViewHost* rvh() {
- return static_cast<TestRenderViewHost*>(render_view_host_);
+ return static_cast<TestRenderViewHost*>(
+ render_manager_.render_view_host_);
}
TestRenderViewHost* pending_rvh() {
- return static_cast<TestRenderViewHost*>(pending_render_view_host_);
+ return static_cast<TestRenderViewHost*>(
+ render_manager_.pending_render_view_host_);
}
TestRenderViewHost* interstitial_rvh() {
- return static_cast<TestRenderViewHost*>(interstitial_render_view_host_);
+ return static_cast<TestRenderViewHost*>(
+ render_manager_.interstitial_render_view_host_);
}
TestRenderViewHost* original_rvh() {
- return static_cast<TestRenderViewHost*>(original_render_view_host_);
+ return static_cast<TestRenderViewHost*>(
+ render_manager_.original_render_view_host_);
+ }
+
+ // State accessors.
+ bool state_is_normal() const {
+ return render_manager_.renderer_state_ == RenderViewHostManager::NORMAL;
+ }
+ bool state_is_pending() const {
+ return render_manager_.renderer_state_ == RenderViewHostManager::PENDING;
+ }
+ bool state_is_entering_interstitial() const {
+ return render_manager_.renderer_state_ ==
+ RenderViewHostManager::ENTERING_INTERSTITIAL;
+ }
+ bool state_is_interstitial() const {
+ return render_manager_.renderer_state_ ==
+ RenderViewHostManager::INTERSTITIAL;
+ }
+ bool state_is_leaving_interstitial() const {
+ return render_manager_.renderer_state_ ==
+ RenderViewHostManager::LEAVING_INTERSTITIAL;
}
// Ensure we create TestRenderViewHosts that don't spawn processes.
@@ -242,7 +265,7 @@ class TestWebContents : public WebContents {
}
// Prevent interaction with views.
- bool CreateRenderView(RenderViewHost* render_view_host) {
+ bool CreateRenderViewForRenderManager(RenderViewHost* render_view_host) {
// This will go to a TestRenderViewHost.
render_view_host->CreateRenderView();
return true;
@@ -323,7 +346,7 @@ TEST_F(WebContentsTest, SimpleNavigation) {
// Navigate to URL
const GURL url("http://www.google.com");
contents->controller()->LoadURL(url, PageTransition::TYPED);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_TRUE(orig_rvh->is_loading);
EXPECT_EQ(instance1, orig_rvh->site_instance());
// Controller's pending entry will have a NULL site instance until we assign
@@ -335,7 +358,7 @@ TEST_F(WebContentsTest, SimpleNavigation) {
ViewHostMsg_FrameNavigate_Params params;
InitNavigateParams(&params, 1, url);
contents->TestDidNavigate(orig_rvh, params);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_EQ(instance1, orig_rvh->site_instance());
// Controller's entry should now have the SiteInstance, or else we won't be
@@ -356,12 +379,12 @@ TEST_F(WebContentsTest, ShowInterstitialDontProceed) {
// Navigate to URL
const GURL url("http://www.google.com");
contents->controller()->LoadURL(url, PageTransition::TYPED);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_TRUE(orig_rvh->is_loading);
// Show interstitial
contents->ShowInterstitialPage(std::string("Blocked"), NULL);
- EXPECT_EQ(WebContents::ENTERING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_entering_interstitial());
TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
EXPECT_TRUE(orig_rvh->is_loading); // Still loading in the background
EXPECT_TRUE(interstitial_rvh->is_loading);
@@ -370,14 +393,14 @@ TEST_F(WebContentsTest, ShowInterstitialDontProceed) {
ViewHostMsg_FrameNavigate_Params params;
InitNavigateParams(&params, 1, url);
contents->TestDidNavigate(interstitial_rvh, params);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_FALSE(interstitial_rvh->is_loading);
// Hide interstitial (don't proceed)
contents->HideInterstitialPage(false, false);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->interstitial_rvh() == NULL);
@@ -388,7 +411,7 @@ TEST_F(WebContentsTest, ShowInterstitialProceed) {
TestRenderViewHost* orig_rvh = contents->rvh();
// The RenderViewHost's SiteInstance should not yet have a site.
- EXPECT_EQ(GURL(""), contents->rvh()->site_instance()->site());
+ EXPECT_EQ(GURL(), contents->rvh()->site_instance()->site());
// Navigate to URL
const GURL url("http://www.google.com");
@@ -405,17 +428,17 @@ TEST_F(WebContentsTest, ShowInterstitialProceed) {
// Ensure this DidNavigate hasn't changed the SiteInstance's site.
// Prevents regression for bug 1163298.
- EXPECT_EQ(GURL(""), contents->rvh()->site_instance()->site());
+ EXPECT_EQ(GURL(), contents->rvh()->site_instance()->site());
// Hide interstitial (proceed and wait)
contents->HideInterstitialPage(true, true);
- EXPECT_EQ(WebContents::LEAVING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_leaving_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
// DidNavigate from the destination page
contents->TestDidNavigate(orig_rvh, params);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->interstitial_rvh() == NULL);
@@ -448,7 +471,7 @@ TEST_F(WebContentsTest, ShowInterstitialThenNavigate) {
// While interstitial showing, navigate to a new URL.
const GURL url2("http://www.yahoo.com");
contents->controller()->LoadURL(url2, PageTransition::TYPED);
- EXPECT_EQ(WebContents::LEAVING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_leaving_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_TRUE(orig_rvh->is_loading);
EXPECT_FALSE(interstitial_rvh->is_loading);
@@ -458,7 +481,7 @@ TEST_F(WebContentsTest, ShowInterstitialThenNavigate) {
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
contents->TestDidNavigate(orig_rvh, params2);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_FALSE(orig_rvh->is_loading);
}
@@ -476,7 +499,7 @@ TEST_F(WebContentsTest, ShowInterstitialIFrameNavigate) {
// Navigate to URL.
const GURL url("http://www.google.com");
contents->controller()->LoadURL(url, PageTransition::TYPED);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_TRUE(orig_rvh->is_loading);
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
@@ -485,7 +508,7 @@ TEST_F(WebContentsTest, ShowInterstitialIFrameNavigate) {
// Show interstitial (in real world would probably be triggered by a resource
// in the page).
contents->ShowInterstitialPage(std::string("Blocked"), NULL);
- EXPECT_EQ(WebContents::ENTERING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_entering_interstitial());
TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
EXPECT_TRUE(interstitial_rvh->is_loading);
@@ -499,7 +522,7 @@ TEST_F(WebContentsTest, ShowInterstitialIFrameNavigate) {
ViewHostMsg_FrameNavigate_Params params3;
InitNavigateParams(&params3, 1, url);
contents->TestDidNavigate(interstitial_rvh, params3);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_FALSE(interstitial_rvh->is_loading);
@@ -522,7 +545,7 @@ TEST_F(WebContentsTest, VisitInterstitialURLTwice) {
const GURL url2("https://www.google.com");
contents->controller()->LoadURL(url2, PageTransition::TYPED);
contents->ShowInterstitialPage(std::string("Blocked"), NULL);
- EXPECT_EQ(WebContents::ENTERING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_entering_interstitial());
int interstitial_delete_counter = 0;
TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
interstitial_rvh->set_delete_counter(&interstitial_delete_counter);
@@ -531,17 +554,17 @@ TEST_F(WebContentsTest, VisitInterstitialURLTwice) {
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
// While interstitial showing, navigate to the same URL.
contents->controller()->LoadURL(url2, PageTransition::TYPED);
- EXPECT_EQ(WebContents::LEAVING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_leaving_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
// Interstitial shown a second time in a different RenderViewHost.
contents->ShowInterstitialPage(std::string("Blocked"), NULL);
- EXPECT_EQ(WebContents::ENTERING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_entering_interstitial());
// We expect the original interstitial has been deleted.
EXPECT_EQ(interstitial_delete_counter, 1);
TestRenderViewHost* interstitial_rvh2 = contents->interstitial_rvh();
@@ -551,27 +574,27 @@ TEST_F(WebContentsTest, VisitInterstitialURLTwice) {
ViewHostMsg_FrameNavigate_Params params3;
InitNavigateParams(&params3, 3, url2);
contents->TestDidNavigate(interstitial_rvh2, params3);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh2, contents->render_view_host());
// Proceed. In the old process model, we'll still have the same
// RenderViewHost.
contents->HideInterstitialPage(true, true);
- EXPECT_EQ(WebContents::LEAVING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_leaving_interstitial());
ViewHostMsg_FrameNavigate_Params params4;
InitNavigateParams(&params4, 3, url2);
contents->TestDidNavigate(orig_rvh, params4);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
// We expect the second interstitial has been deleted.
EXPECT_EQ(interstitial_delete_counter, 2);
// Now go back. Should take us back to the original page.
contents->controller()->GoBack();
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
// DidNavigate from going back.
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->interstitial_rvh() == NULL);
@@ -593,7 +616,7 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->interstitial_rvh() == NULL);
@@ -601,7 +624,7 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
// Navigate to new site
const GURL url2("http://www.yahoo.com");
contents->controller()->LoadURL(url2, PageTransition::TYPED);
- EXPECT_EQ(WebContents::PENDING, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_pending());
TestRenderViewHost* pending_rvh = contents->pending_rvh();
int pending_rvh_delete_count = 0;
pending_rvh->set_delete_counter(&pending_rvh_delete_count);
@@ -612,7 +635,7 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
contents->TestDidNavigate(pending_rvh, params2);
SiteInstance* instance2 = contents->site_instance();
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(pending_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
@@ -624,11 +647,11 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
// stored in the NavigationEntry, so it should be the same as at the start.
contents->controller()->GoBack();
TestRenderViewHost* goback_rvh = contents->pending_rvh();
- EXPECT_EQ(WebContents::PENDING, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_pending());
// DidNavigate from the back action
contents->TestDidNavigate(goback_rvh, params1);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(goback_rvh, contents->render_view_host());
EXPECT_EQ(pending_rvh_delete_count, 1);
EXPECT_EQ(instance1, contents->site_instance());
@@ -650,7 +673,7 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->interstitial_rvh() == NULL);
@@ -662,7 +685,7 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
const GURL url2("http://www.yahoo.com");
contents->controller()->LoadURL(url2, PageTransition::TYPED);
TestRenderViewHost* new_rvh = contents->rvh();
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_TRUE(contents->pending_rvh() == NULL);
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->interstitial_rvh() == NULL);
@@ -675,7 +698,7 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
contents->TestDidNavigate(new_rvh, params2);
SiteInstance* instance2 = contents->site_instance();
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(new_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
@@ -697,18 +720,18 @@ TEST_F(WebContentsTest, CrossSiteInterstitialDontProceed) {
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
// Navigate to new site
const GURL url2("https://www.google.com");
contents->controller()->LoadURL(url2, PageTransition::TYPED);
- EXPECT_EQ(WebContents::PENDING, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_pending());
TestRenderViewHost* pending_rvh = contents->pending_rvh();
// Show an interstitial
contents->ShowInterstitialPage(std::string("Blocked"), NULL);
- EXPECT_EQ(WebContents::ENTERING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_entering_interstitial());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_EQ(pending_rvh, contents->pending_rvh());
TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
@@ -717,7 +740,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialDontProceed) {
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_EQ(pending_rvh, contents->pending_rvh());
@@ -725,7 +748,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialDontProceed) {
// Hide interstitial (don't proceed)
contents->HideInterstitialPage(false, false);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->pending_rvh() == NULL);
@@ -763,7 +786,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialProceed) {
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 1, url2);
contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_EQ(pending_rvh, contents->pending_rvh());
@@ -771,7 +794,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialProceed) {
// Hide interstitial (proceed and wait)
contents->HideInterstitialPage(true, true);
- EXPECT_EQ(WebContents::LEAVING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_leaving_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_EQ(pending_rvh, contents->pending_rvh());
@@ -782,7 +805,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialProceed) {
InitNavigateParams(&params3, 2, url2);
contents->TestDidNavigate(pending_rvh, params3);
SiteInstance* instance2 = contents->site_instance();
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(pending_rvh, contents->render_view_host());
EXPECT_TRUE(contents->original_rvh() == NULL);
EXPECT_TRUE(contents->pending_rvh() == NULL);
@@ -797,11 +820,11 @@ TEST_F(WebContentsTest, CrossSiteInterstitialProceed) {
// stored in the NavigationEntry, so it should be the same as at the start.
contents->controller()->GoBack();
TestRenderViewHost* goback_rvh = contents->pending_rvh();
- EXPECT_EQ(WebContents::PENDING, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_pending());
// DidNavigate from the back action
contents->TestDidNavigate(goback_rvh, params1);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(goback_rvh, contents->render_view_host());
EXPECT_EQ(instance1, contents->site_instance());
EXPECT_EQ(pending_rvh_delete_count, 1); // The second page's rvh should die.
@@ -829,7 +852,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialThenNavigate) {
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 1, url);
contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_TRUE(contents->interstitial_rvh() == NULL);
@@ -842,14 +865,14 @@ TEST_F(WebContentsTest, CrossSiteInterstitialThenNavigate) {
ASSERT_TRUE(new_rvh != NULL);
// Make sure the RVH is not suspended (bug #1236441).
EXPECT_FALSE(new_rvh->IsNavigationSuspended());
- EXPECT_EQ(WebContents::LEAVING_INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_leaving_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
// DidNavigate from the new page
ViewHostMsg_FrameNavigate_Params params3;
InitNavigateParams(&params3, 1, url2);
contents->TestDidNavigate(new_rvh, params3);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(new_rvh, contents->render_view_host());
EXPECT_TRUE(contents->pending_rvh() == NULL);
EXPECT_EQ(orig_rvh_delete_count, 1);
@@ -885,7 +908,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialCrashThenNavigate) {
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 1, url2);
contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_EQ(pending_rvh, contents->pending_rvh());
@@ -901,7 +924,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialCrashThenNavigate) {
contents->controller()->LoadURL(url3, PageTransition::TYPED);
TestRenderViewHost* new_rvh = contents->pending_rvh();
ASSERT_TRUE(new_rvh != NULL);
- EXPECT_EQ(WebContents::PENDING, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
EXPECT_EQ(pending_rvh_delete_count, 1);
EXPECT_NE(interstitial_rvh, new_rvh);
@@ -912,7 +935,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialCrashThenNavigate) {
ViewHostMsg_FrameNavigate_Params params3;
InitNavigateParams(&params3, 1, url3);
contents->TestDidNavigate(new_rvh, params3);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(new_rvh, contents->render_view_host());
EXPECT_TRUE(contents->pending_rvh() == NULL);
EXPECT_EQ(orig_rvh_delete_count, 1);
@@ -948,7 +971,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialCrashesThenNavigate) {
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 1, url2);
contents->TestDidNavigate(interstitial_rvh, params2);
- EXPECT_EQ(WebContents::INTERSTITIAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_interstitial());
EXPECT_EQ(interstitial_rvh, contents->render_view_host());
EXPECT_EQ(orig_rvh, contents->original_rvh());
EXPECT_EQ(pending_rvh, contents->pending_rvh());
@@ -965,7 +988,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialCrashesThenNavigate) {
contents->controller()->LoadURL(url3, PageTransition::TYPED);
TestRenderViewHost* new_rvh = contents->rvh();
ASSERT_TRUE(new_rvh != NULL);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh_delete_count, 1);
EXPECT_EQ(pending_rvh_delete_count, 1);
EXPECT_NE(interstitial_rvh, new_rvh);
@@ -977,7 +1000,7 @@ TEST_F(WebContentsTest, CrossSiteInterstitialCrashesThenNavigate) {
ViewHostMsg_FrameNavigate_Params params3;
InitNavigateParams(&params3, 1, url3);
contents->TestDidNavigate(new_rvh, params3);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(new_rvh, contents->render_view_host());
}
@@ -1017,7 +1040,7 @@ TEST_F(WebContentsTest, NavigateTwoTabsCrossSite) {
contents2->controller()->LoadURL(url2b, PageTransition::TYPED);
TestRenderViewHost* pending_rvh_b = contents2->pending_rvh();
EXPECT_TRUE(pending_rvh_b != NULL);
- EXPECT_EQ(WebContents::PENDING, contents2->renderer_state());
+ EXPECT_TRUE(contents2->state_is_pending());
// NOTE(creis): We used to be in danger of showing a sad tab page here if the
// second tab hadn't navigated somewhere first (bug 1145430). That case is
@@ -1058,13 +1081,13 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
// The first RVH in contents2 isn't live yet, so we shortcut the PENDING
// state and go straight to NORMAL.
TestRenderViewHost* rvh2 = contents2->rvh();
- EXPECT_EQ(WebContents::NORMAL, contents2->renderer_state());
+ EXPECT_TRUE(contents2->state_is_normal());
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
contents2->TestDidNavigate(rvh2, params2);
SiteInstance* instance2 = contents2->site_instance();
EXPECT_NE(instance1, instance2);
- EXPECT_EQ(WebContents::NORMAL, contents2->renderer_state());
+ EXPECT_TRUE(contents2->state_is_normal());
// Simulate a link click in first tab to second site. Doesn't switch
// SiteInstances, because we don't intercept WebKit navigations.
@@ -1073,13 +1096,13 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
contents->TestDidNavigate(orig_rvh, params3);
SiteInstance* instance3 = contents->site_instance();
EXPECT_EQ(instance1, instance3);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
// Navigate to the new site. Doesn't switch SiteInstancees, because we
// compare against the current URL, not the SiteInstance's site.
const GURL url3("http://mail.yahoo.com");
contents->controller()->LoadURL(url3, PageTransition::TYPED);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
ViewHostMsg_FrameNavigate_Params params4;
InitNavigateParams(&params4, 3, url3);
contents->TestDidNavigate(orig_rvh, params4);
@@ -1102,7 +1125,7 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
// Navigate to new site, but simulate an onbeforeunload denial.
@@ -1110,13 +1133,13 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
orig_rvh->immediate_before_unload = false;
contents->controller()->LoadURL(url2, PageTransition::TYPED);
orig_rvh->TestOnMsgShouldClose(false);
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(orig_rvh, contents->render_view_host());
// Navigate again, but simulate an onbeforeunload approval.
contents->controller()->LoadURL(url2, PageTransition::TYPED);
orig_rvh->TestOnMsgShouldClose(true);
- EXPECT_EQ(WebContents::PENDING, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_pending());
TestRenderViewHost* pending_rvh = contents->pending_rvh();
// We won't hear DidNavigate until the onunload handler has finished running.
@@ -1128,7 +1151,7 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
InitNavigateParams(&params2, 1, url2);
contents->TestDidNavigate(pending_rvh, params2);
SiteInstance* instance2 = contents->site_instance();
- EXPECT_EQ(WebContents::NORMAL, contents->renderer_state());
+ EXPECT_TRUE(contents->state_is_normal());
EXPECT_EQ(pending_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
diff --git a/chrome/browser/web_drop_target.cc b/chrome/browser/web_drop_target.cc
index f107d95..aa4dd10 100644
--- a/chrome/browser/web_drop_target.cc
+++ b/chrome/browser/web_drop_target.cc
@@ -116,7 +116,7 @@ DWORD WebDropTarget::OnDragEnter(IDataObject* data_object,
// Don't pass messages to the renderer if an interstitial page is showing
// because we don't want the interstitial page to navigate. Instead,
// pass the messages on to a separate interstitial DropTarget handler.
- if (web_contents_->IsShowingInterstitialPage())
+ if (web_contents_->showing_interstitial_page())
return interstitial_drop_target_->OnDragEnter(data_object, effect);
// TODO(tc): PopulateWebDropData is kind of slow, maybe we can do this in a
@@ -144,7 +144,7 @@ DWORD WebDropTarget::OnDragOver(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect) {
- if (web_contents_->IsShowingInterstitialPage())
+ if (web_contents_->showing_interstitial_page())
return interstitial_drop_target_->OnDragOver(data_object, effect);
POINT client_pt = cursor_position;
@@ -160,7 +160,7 @@ DWORD WebDropTarget::OnDragOver(IDataObject* data_object,
}
void WebDropTarget::OnDragLeave(IDataObject* data_object) {
- if (web_contents_->IsShowingInterstitialPage()) {
+ if (web_contents_->showing_interstitial_page()) {
interstitial_drop_target_->OnDragLeave(data_object);
} else {
web_contents_->DragTargetDragLeave();
@@ -172,7 +172,7 @@ DWORD WebDropTarget::OnDrop(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect) {
- if (web_contents_->IsShowingInterstitialPage())
+ if (web_contents_->showing_interstitial_page())
return interstitial_drop_target_->OnDrop(data_object, effect);
POINT client_pt = cursor_position;