summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-19 00:42:30 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-19 00:42:30 +0000
commita3a1d14240d6e41a0b6732ebcd3600399c64b26a (patch)
treea38ced2761bdf4447bf180470fd5dade857ef11b /chrome
parent5b62083c99317965244123c031c707d53f0a03f1 (diff)
downloadchromium_src-a3a1d14240d6e41a0b6732ebcd3600399c64b26a.zip
chromium_src-a3a1d14240d6e41a0b6732ebcd3600399c64b26a.tar.gz
chromium_src-a3a1d14240d6e41a0b6732ebcd3600399c64b26a.tar.bz2
Review URL: http://codereview.chromium.org/14809
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7281 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/automation_provider.cc10
-rw-r--r--chrome/browser/browser.cc7
-rw-r--r--chrome/browser/browser.scons2
-rw-r--r--chrome/browser/download/download_file.cc6
-rw-r--r--chrome/browser/download/download_manager.cc4
-rw-r--r--chrome/browser/download/download_request_manager.cc6
-rw-r--r--chrome/browser/download/save_file_manager.cc10
-rw-r--r--chrome/browser/interstitial_page.cc211
-rw-r--r--chrome/browser/interstitial_page.h107
-rw-r--r--chrome/browser/login_prompt.cc10
-rw-r--r--chrome/browser/navigation_controller.cc13
-rw-r--r--chrome/browser/navigation_controller.h8
-rw-r--r--chrome/browser/navigation_controller_unittest.cc37
-rw-r--r--chrome/browser/provisional_load_details.cc2
-rw-r--r--chrome/browser/provisional_load_details.h12
-rw-r--r--chrome/browser/render_view_host_manager.cc551
-rw-r--r--chrome/browser/render_view_host_manager.h139
-rw-r--r--chrome/browser/render_widget_host_view_win.h4
-rw-r--r--chrome/browser/resource_dispatcher_host.cc10
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page.cc47
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_blocking_page.h6
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.cc15
-rw-r--r--chrome/browser/ssl_blocking_page.cc13
-rw-r--r--chrome/browser/ssl_manager.cc21
-rw-r--r--chrome/browser/ssl_manager.h6
-rw-r--r--chrome/browser/ssl_policy.cc8
-rw-r--r--chrome/browser/tab_util.cc2
-rw-r--r--chrome/browser/tab_util.h6
-rw-r--r--chrome/browser/task_manager_resource_providers.cc9
-rw-r--r--chrome/browser/views/dom_view.cc4
-rw-r--r--chrome/browser/views/external_protocol_dialog.cc6
-rw-r--r--chrome/browser/views/external_protocol_dialog.h2
-rw-r--r--chrome/browser/web_contents.cc93
-rw-r--r--chrome/browser/web_contents.h45
-rw-r--r--chrome/browser/web_contents_unittest.cc1261
-rw-r--r--chrome/browser/web_contents_view_win.cc3
-rw-r--r--chrome/chrome.xcodeproj/project.pbxproj2
-rw-r--r--chrome/test/test_tab_contents.cc2
38 files changed, 1099 insertions, 1601 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 2f2b6b5..3a36b52 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -588,7 +588,7 @@ class DocumentPrintedNotificationObserver : public NotificationObserver {
class AutomationInterstitialPage : public InterstitialPage {
public:
- AutomationInterstitialPage(TabContents* tab,
+ AutomationInterstitialPage(WebContents* tab,
const GURL& url,
const std::string& contents)
: InterstitialPage(tab, true, url),
@@ -1990,7 +1990,7 @@ void AutomationProvider::ShowInterstitialPage(const IPC::Message& message,
new AutomationInterstitialPage(web_contents,
GURL("about:interstitial"),
html_text);
- web_contents->ShowInterstitialPage(interstitial);
+ interstitial->Show();
return;
}
}
@@ -2001,8 +2001,8 @@ void AutomationProvider::ShowInterstitialPage(const IPC::Message& message,
void AutomationProvider::HideInterstitialPage(const IPC::Message& message,
int tab_handle) {
WebContents* web_contents = GetWebContentsForHandle(tab_handle, NULL);
- if (web_contents) {
- web_contents->HideInterstitialPage(false, false);
+ if (web_contents && web_contents->interstitial_page()) {
+ web_contents->interstitial_page()->DontProceed();
Send(new AutomationMsg_HideInterstitialPageResponse(message.routing_id(),
true));
return;
@@ -2161,7 +2161,7 @@ void AutomationProvider::ActionOnSSLBlockingPage(const IPC::Message& message,
if (entry->page_type() == NavigationEntry::INTERSTITIAL_PAGE) {
TabContents* tab_contents = tab->GetTabContents(TAB_CONTENTS_WEB);
InterstitialPage* ssl_blocking_page =
- InterstitialPage::GetInterstitialPage(tab_contents);
+ InterstitialPage::GetInterstitialPage(tab_contents->AsWebContents());
if (ssl_blocking_page) {
if (proceed) {
AddNavigationStatusListener(tab,
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 2fcaa53..310103f 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -561,8 +561,11 @@ void Browser::GoBack() {
// If we are showing an interstitial, just hide it.
TabContents* current_tab = GetSelectedTabContents();
WebContents* web_contents = current_tab->AsWebContents();
- if (web_contents && web_contents->showing_interstitial_page()) {
- // Pressing back on an interstitial page means "don't proceed".
+ if (web_contents && web_contents->interstitial_page()) {
+ // The GoBack() case is a special case when an interstitial is shown because
+ // the "previous" page is still available, just hidden by the interstitial.
+ // We treat the back as a "Don't proceed", this hides the interstitial and
+ // reveals the previous page.
web_contents->interstitial_page()->DontProceed();
return;
}
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index 587da3c..feee5e8 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -102,7 +102,6 @@ if not env.Bit('mac'):
'safe_browsing/safe_browsing_database.cc',
'safe_browsing/safe_browsing_database_bloom.cc',
'safe_browsing/safe_browsing_database_impl.cc',
- 'safe_browsing/safe_browsing_service.cc',
'safe_browsing/safe_browsing_util.cc',
'session_startup_pref.cc',
'spellcheck_worditerator.cc',
@@ -251,6 +250,7 @@ if env.Bit('windows'):
'rlz/rlz.cc',
'safe_browsing/protocol_manager.cc',
'safe_browsing/safe_browsing_blocking_page.cc',
+ 'safe_browsing/safe_browsing_service.cc',
'sandbox_policy.cc',
'sessions/base_session_service.cc',
'sessions/session_backend.cc',
diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc
index f921661..2a5e612 100644
--- a/chrome/browser/download/download_file.cc
+++ b/chrome/browser/download/download_file.cc
@@ -16,8 +16,8 @@
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/resource_dispatcher_host.h"
-#include "chrome/browser/tab_contents.h"
#include "chrome/browser/tab_util.h"
+#include "chrome/browser/web_contents.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/stl_util-inl.h"
#include "chrome/common/win_util.h"
@@ -458,9 +458,9 @@ void DownloadFileManager::RemoveDownload(int id, DownloadManager* manager) {
// static
DownloadManager* DownloadFileManager::DownloadManagerFromRenderIds(
int render_process_id, int render_view_id) {
- TabContents* contents = tab_util::GetTabContentsByID(render_process_id,
+ WebContents* contents = tab_util::GetWebContentsByID(render_process_id,
render_view_id);
- if (contents && contents->type() == TAB_CONTENTS_WEB) {
+ if (contents) {
Profile* profile = contents->profile();
if (profile)
return profile->GetDownloadManager();
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index 5328807..adf62d3 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -618,7 +618,7 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
if (!select_file_dialog_.get())
select_file_dialog_ = SelectFileDialog::Create(this);
- TabContents* contents = tab_util::GetTabContentsByID(
+ WebContents* contents = tab_util::GetWebContentsByID(
info->render_process_id, info->render_view_id);
std::wstring filter = win_util::GetFileFilterFromPath(info->suggested_path);
HWND owning_hwnd =
@@ -1308,7 +1308,7 @@ void DownloadManager::OnCreateDownloadEntryComplete(DownloadCreateInfo info,
// this start completion event. If it does, tell the origin WebContents to
// display its download shelf.
TabContents* contents =
- tab_util::GetTabContentsByID(info.render_process_id, info.render_view_id);
+ tab_util::GetWebContentsByID(info.render_process_id, info.render_view_id);
// If the contents no longer exists or is no longer active, we start the
// download in the last active browser. This is not ideal but better than
diff --git a/chrome/browser/download/download_request_manager.cc b/chrome/browser/download/download_request_manager.cc
index 6869d6e..ac4cdb5 100644
--- a/chrome/browser/download/download_request_manager.cc
+++ b/chrome/browser/download/download_request_manager.cc
@@ -9,9 +9,9 @@
#include "chrome/browser/navigation_controller.h"
#include "chrome/browser/navigation_entry.h"
#include "chrome/browser/constrained_window.h"
-#include "chrome/browser/tab_contents.h"
#include "chrome/browser/tab_contents_delegate.h"
#include "chrome/browser/tab_util.h"
+#include "chrome/browser/web_contents.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
@@ -409,8 +409,8 @@ void DownloadRequestManager::CanDownload(int render_process_host_id,
Callback* callback) {
DCHECK(!ui_loop_ || MessageLoop::current() == ui_loop_);
- TabContents* originating_tab =
- tab_util::GetTabContentsByID(render_process_host_id, render_view_id);
+ WebContents* originating_tab =
+ tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
if (!originating_tab) {
// The tab was closed, don't allow the download.
ScheduleNotification(callback, false);
diff --git a/chrome/browser/download/save_file_manager.cc b/chrome/browser/download/save_file_manager.cc
index 940e878..631b55d 100644
--- a/chrome/browser/download/save_file_manager.cc
+++ b/chrome/browser/download/save_file_manager.cc
@@ -215,14 +215,10 @@ void SaveFileManager::RemoveSaveFile(int save_id, const std::wstring& save_url,
// only on the UI thread.
SavePackage* SaveFileManager::GetSavePackageFromRenderIds(
int render_process_id, int render_view_id) {
- TabContents* contents = tab_util::GetTabContentsByID(render_process_id,
+ WebContents* contents = tab_util::GetWebContentsByID(render_process_id,
render_view_id);
- if (contents && contents->type() == TAB_CONTENTS_WEB) {
- // Convert const pointer of WebContents to pointer of WebContents.
- const WebContents* web_contents = contents->AsWebContents();
- if (web_contents)
- return web_contents->save_package();
- }
+ if (contents)
+ return contents->save_package();
return NULL;
}
diff --git a/chrome/browser/interstitial_page.cc b/chrome/browser/interstitial_page.cc
index e400730..514e822 100644
--- a/chrome/browser/interstitial_page.cc
+++ b/chrome/browser/interstitial_page.cc
@@ -5,54 +5,59 @@
#include "chrome/browser/interstitial_page.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_resources.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/navigation_controller.h"
#include "chrome/browser/navigation_entry.h"
-#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/render_widget_host_view_win.h"
#include "chrome/browser/web_contents.h"
+#include "chrome/browser/web_contents_view_win.h"
+#include "chrome/views/window.h"
+#include "chrome/views/window_delegate.h"
+#include "net/base/escape.h"
// static
InterstitialPage::InterstitialPageMap*
InterstitialPage::tab_to_interstitial_page_ = NULL;
-InterstitialPage::InterstitialPage(TabContents* tab,
- bool create_navigation_entry,
+InterstitialPage::InterstitialPage(WebContents* tab,
+ bool new_navigation,
const GURL& url)
: tab_(tab),
url_(url),
- delegate_has_been_notified_(false),
- create_navigation_entry_(create_navigation_entry) {
+ action_taken_(false),
+ enabled_(true),
+ new_navigation_(new_navigation),
+ render_view_host_(NULL),
+ should_revert_tab_title_(false) {
InitInterstitialPageMap();
-
- // If there's already an interstitial in this tab, then we're about to
- // replace it. We should be ok with just deleting the previous
- // InterstitialPage (not hiding it first), since we're about to be shown.
- InterstitialPageMap::const_iterator iter =
- tab_to_interstitial_page_->find(tab_);
- if (iter != tab_to_interstitial_page_->end()) {
- // Deleting the InterstitialPage will also remove it from the map.
- delete iter->second;
- }
- (*tab_to_interstitial_page_)[tab_] = this;
-
- // Register for DOM operations, this is how the page notifies us of the user
- // selection.
- notification_registrar_.Add(this, NOTIFY_DOM_OPERATION_RESPONSE,
- Source<TabContents>(tab_));
+ // It would be inconsistent to create an interstitial with no new navigation
+ // (which is the case when the interstitial was triggered by a sub-resource on
+ // a page) when we have a pending entry (in the process of loading a new top
+ // frame).
+ DCHECK(new_navigation || !tab->controller()->GetPendingEntry());
}
InterstitialPage::~InterstitialPage() {
InterstitialPageMap::iterator iter = tab_to_interstitial_page_->find(tab_);
DCHECK(iter != tab_to_interstitial_page_->end());
tab_to_interstitial_page_->erase(iter);
+ DCHECK(!render_view_host_);
}
void InterstitialPage::Show() {
- DCHECK(tab_->type() == TAB_CONTENTS_WEB);
- WebContents* tab = tab_->AsWebContents();
+ // If an interstitial is already showing, close it before showing the new one.
+ if (tab_->interstitial_page())
+ tab_->interstitial_page()->DontProceed();
+
+ // Update the tab_to_interstitial_page_ map.
+ InterstitialPageMap::const_iterator iter =
+ tab_to_interstitial_page_->find(tab_);
+ DCHECK(iter == tab_to_interstitial_page_->end());
+ (*tab_to_interstitial_page_)[tab_] = this;
- if (create_navigation_entry_) {
+ if (new_navigation_) {
NavigationEntry* entry = new NavigationEntry(TAB_CONTENTS_WEB);
entry->set_url(url_);
entry->set_display_url(url_);
@@ -64,39 +69,173 @@ void InterstitialPage::Show() {
tab_->controller()->AddTransientEntry(entry);
}
- tab->ShowInterstitialPage(this);
+ DCHECK(!render_view_host_);
+ render_view_host_ = CreateRenderViewHost();
+
+ std::string data_url = "data:text/html;charset=utf-8," +
+ EscapePath(GetHTMLContents());
+ render_view_host_->NavigateToURL(GURL(data_url));
+
+ notification_registrar_.Add(this, NOTIFY_TAB_CONTENTS_DESTROYED,
+ Source<TabContents>(tab_));
+ notification_registrar_.Add(this, NOTIFY_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(tab_->controller()));
+ notification_registrar_.Add(this, NOTIFY_NAV_ENTRY_PENDING,
+ Source<NavigationController>(tab_->controller()));
+}
+
+void InterstitialPage::Hide() {
+ render_view_host_->Shutdown();
+ render_view_host_ = NULL;
+ if (tab_->interstitial_page())
+ tab_->remove_interstitial_page();
+ // Let's revert to the original title if necessary.
+ NavigationEntry* entry = tab_->controller()->GetActiveEntry();
+ if (!new_navigation_ && should_revert_tab_title_) {
+ entry->set_title(original_tab_title_);
+ tab_->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE);
+ }
+ delete this;
}
void InterstitialPage::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- DCHECK(type == NOTIFY_DOM_OPERATION_RESPONSE);
- std::string json = Details<DomOperationNotificationDetails>(details)->json();
- CommandReceived(json);
+ if (type == NOTIFY_NAV_ENTRY_PENDING) {
+ // We are navigating away from the interstitial. Make sure clicking on the
+ // interstitial will have no effect.
+ Disable();
+ return;
+ }
+ DCHECK(type == NOTIFY_TAB_CONTENTS_DESTROYED ||
+ type == NOTIFY_NAV_ENTRY_COMMITTED);
+ if (!action_taken_) {
+ // We are navigating away from the interstitial or closing a tab with an
+ // interstitial. Default to DontProceed(). We don't just call Hide as
+ // subclasses will almost certainly override DontProceed to do some work
+ // (ex: close pending connections).
+ DontProceed();
+ } else {
+ // User decided to proceed and either the navigation was committed or the
+ // tab was closed before that.
+ Hide();
+ // WARNING: we are now deleted!
+ }
}
-void InterstitialPage::InterstitialClosed() {
- delete this;
+RenderViewHost* InterstitialPage::CreateRenderViewHost() {
+ RenderViewHost* render_view_host = new RenderViewHost(
+ SiteInstance::CreateSiteInstance(tab()->profile()),
+ this, MSG_ROUTING_NONE, NULL);
+ RenderWidgetHostViewWin* view =
+ new RenderWidgetHostViewWin(render_view_host);
+ render_view_host->set_view(view);
+ view->Create(tab_->GetContentHWND());
+ view->set_parent_hwnd(tab_->GetContentHWND());
+ WebContentsViewWin* web_contents_view =
+ static_cast<WebContentsViewWin*>(tab_->view());
+ render_view_host->CreateRenderView();
+ // SetSize must be called after CreateRenderView or the HWND won't show.
+ view->SetSize(web_contents_view->GetContainerSize());
+
+ render_view_host->AllowDomAutomationBindings();
+ return render_view_host;
}
void InterstitialPage::Proceed() {
- DCHECK(tab_->type() == TAB_CONTENTS_WEB);
- tab_->AsWebContents()->HideInterstitialPage(true, true);
+ DCHECK(!action_taken_);
+ Disable();
+ action_taken_ = true;
+
+ // Resumes the throbber.
+ tab_->SetIsLoading(true, NULL);
+
+ // No need to hide if we are a new navigation, we'll get hidden when the
+ // navigation is committed.
+ if (!new_navigation_) {
+ Hide();
+ // WARNING: we are now deleted!
+ }
}
void InterstitialPage::DontProceed() {
- if (create_navigation_entry_) {
+ DCHECK(!action_taken_);
+ Disable();
+ action_taken_ = true;
+
+ if (new_navigation_) {
// Since no navigation happens we have to discard the transient entry
// explicitely. Note that by calling DiscardNonCommittedEntries() we also
// discard the pending entry, which is what we want, since the navigation is
// cancelled.
tab_->controller()->DiscardNonCommittedEntries();
}
- tab_->AsWebContents()->HideInterstitialPage(false, false);
+ Hide();
// WARNING: we are now deleted!
}
+void InterstitialPage::SetSize(const gfx::Size& size) {
+ render_view_host_->view()->SetSize(size);
+}
+
+Profile* InterstitialPage::GetProfile() const {
+ return tab_->profile();
+}
+
+void InterstitialPage::DidNavigate(
+ RenderViewHost* render_view_host,
+ const ViewHostMsg_FrameNavigate_Params& params) {
+ // A fast user could have navigated away from the page that triggered the
+ // interstitial while the interstitial was loading, that would have disabled
+ // us. In that case we can dismiss ourselves.
+ if (!enabled_){
+ DontProceed();
+ return;
+ }
+
+ // The RenderViewHost has loaded its contents, we can show it now.
+ render_view_host_->view()->Show();
+ tab_->set_interstitial_page(this);
+
+ // Notify the tab we are not loading so the throbber is stopped. It also
+ // causes a NOTIFY_LOAD_STOP notification, that the AutomationProvider (used
+ // by the UI tests) expects to consider a navigation as complete. Without this,
+ // navigating in a UI test to a URL that triggers an interstitial would hang.
+ tab_->SetIsLoading(false, NULL);
+}
+
+void InterstitialPage::RendererGone(RenderViewHost* render_view_host) {
+ // Our renderer died. This should not happen in normal cases.
+ // Just dismiss the interstitial.
+ DontProceed();
+}
+
+void InterstitialPage::DomOperationResponse(const std::string& json_string,
+ int automation_id) {
+ if (enabled_)
+ CommandReceived(json_string);
+}
+
+void InterstitialPage::UpdateTitle(RenderViewHost* render_view_host,
+ int32 page_id,
+ const std::wstring& title) {
+ DCHECK(render_view_host == render_view_host_);
+ NavigationEntry* entry = tab_->controller()->GetActiveEntry();
+ // If this interstitial is shown on an existing navigation entry, we'll need
+ // to remember its title so we can revert to it when hidden.
+ if (!new_navigation_ && !should_revert_tab_title_) {
+ original_tab_title_ = entry->title();
+ should_revert_tab_title_ = true;
+ }
+ entry->set_title(title);
+ tab_->NotifyNavigationStateChanged(TabContents::INVALIDATE_TITLE);
+}
+
+void InterstitialPage::Disable() {
+ enabled_ = false;
+}
+
// static
void InterstitialPage::InitInterstitialPageMap() {
if (!tab_to_interstitial_page_)
@@ -105,10 +244,10 @@ void InterstitialPage::InitInterstitialPageMap() {
// static
InterstitialPage* InterstitialPage::GetInterstitialPage(
- TabContents* tab_contents) {
+ WebContents* web_contents) {
InitInterstitialPageMap();
InterstitialPageMap::const_iterator iter =
- tab_to_interstitial_page_->find(tab_contents);
+ tab_to_interstitial_page_->find(web_contents);
if (iter == tab_to_interstitial_page_->end())
return NULL;
diff --git a/chrome/browser/interstitial_page.h b/chrome/browser/interstitial_page.h
index fae6723..92674c1 100644
--- a/chrome/browser/interstitial_page.h
+++ b/chrome/browser/interstitial_page.h
@@ -7,16 +7,16 @@
#include <string>
+#include "chrome/browser/render_view_host_delegate.h"
#include "chrome/common/notification_registrar.h"
-#include "chrome/common/notification_service.h"
#include "googleurl/src/gurl.h"
class NavigationEntry;
-class TabContents;
+class WebContents;
// This class is a base class for interstitial pages, pages that show some
// informative message asking for user validation before reaching the target
-// page. (Navigating to a page served over bad HTTPS or a page contining
+// page. (Navigating to a page served over bad HTTPS or a page containing
// malware are typical cases where an interstitial is required.)
//
// If specified in its constructor, this class creates a navigation entry so
@@ -26,27 +26,27 @@ class TabContents;
// through a navigation, the WebContents closing them or the tab containing them
// being closed.
-class InterstitialPage : public NotificationObserver {
+class InterstitialPage : public NotificationObserver,
+ public RenderViewHostDelegate {
public:
- // Creates an interstitial page to show in |tab|. If |create_navigation_entry|
- // is true, a temporary navigation entry is created with the URL |url| and
+ // Creates an interstitial page to show in |tab|. |new_navigation| should be
+ // set to true when the interstitial is caused by loading a new page, in which
+ // case a temporary navigation entry is created with the URL |url| and
// added to the navigation controller (so the interstitial page appears as a
- // new navigation entry).
- InterstitialPage(TabContents* tab,
- bool create_navigation_entry,
- const GURL& url);
+ // new navigation entry). |new_navigation| should be false when the
+ // interstitial was triggered by a loading a sub-resource in a page.
+ InterstitialPage(WebContents* tab, bool new_navigation, const GURL& url);
virtual ~InterstitialPage();
// Shows the interstitial page in the tab.
- void Show();
+ virtual void Show();
- // Invoked by the tab showing the interstitial to notify that the interstitial
- // page was closed.
- virtual void InterstitialClosed();
+ // Hides the interstitial page. Warning: this deletes the InterstitialPage.
+ void Hide();
// Retrieves the InterstitialPage if any associated with the specified
// |tab_contents| (used by ui tests).
- static InterstitialPage* GetInterstitialPage(TabContents* tab_contents);
+ static InterstitialPage* GetInterstitialPage(WebContents* web_contents);
// Sub-classes should return the HTML that should be displayed in the page.
virtual std::string GetHTMLContents() { return std::string(); }
@@ -57,7 +57,34 @@ class InterstitialPage : public NotificationObserver {
// Warning: 'this' has been deleted when this method returns.
virtual void DontProceed();
+ // Sub-classes should call this method when the user has chosen to proceed to
+ // the target URL.
+ // Warning: 'this' has been deleted when this method returns.
+ virtual void Proceed();
+
+ // Sizes the RenderViewHost showing the actual interstitial page contents.
+ void SetSize(const gfx::Size& size);
+
protected:
+ // NotificationObserver method:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // RenderViewHostDelegate implementation:
+ virtual Profile* GetProfile() const;
+ virtual WebPreferences GetWebkitPrefs() {
+ return WebPreferences();
+ }
+ virtual void DidNavigate(RenderViewHost* render_view_host,
+ const ViewHostMsg_FrameNavigate_Params& params);
+ virtual void RendererGone(RenderViewHost* render_view_host);
+ virtual void DomOperationResponse(const std::string& json_string,
+ int automation_id);
+ virtual void UpdateTitle(RenderViewHost* render_view_host,
+ int32 page_id,
+ const std::wstring& title);
+
// Invoked when the page sent a command through DOMAutomation.
virtual void CommandReceived(const std::string& command) { }
@@ -68,47 +95,61 @@ class InterstitialPage : public NotificationObserver {
// |create_navigation_entry| set to true.
virtual void UpdateEntry(NavigationEntry* entry) { }
- // Sub-classes should call this method when the user has chosen to proceed to
- // the target URL.
- // Warning: 'this' has been deleted when this method returns.
- virtual void Proceed();
-
- TabContents* tab() const { return tab_; }
+ WebContents* tab() const { return tab_; }
const GURL& url() const { return url_; }
+ RenderViewHost* render_view_host() const { return render_view_host_; }
+
+ // Creates and shows the RenderViewHost containing the interstitial content.
+ // Overriden in unit tests.
+ virtual RenderViewHost* CreateRenderViewHost();
private:
// AutomationProvider needs access to Proceed and DontProceed to simulate
// user actions.
friend class AutomationProvider;
- // NotificationObserver method.
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
// Initializes tab_to_interstitial_page_ in a thread-safe manner.
// Should be called before accessing tab_to_interstitial_page_.
static void InitInterstitialPageMap();
- // A flag to indicate if we've notified |delegate_| of the user's decision.
- bool delegate_has_been_notified_;
+ // Disable the interstitial:
+ // - if it is not yet showing, then it won't be shown.
+ // - any command sent by the RenderViewHost will be ignored.
+ void Disable();
// The tab in which we are displayed.
- TabContents* tab_;
+ WebContents* tab_;
// The URL that is shown when the interstitial is showing.
GURL url_;
- // Whether a transient navigation entry should be created when the page is
- // shown.
- bool create_navigation_entry_;
+ // Whether this interstitial is shown as a result of a new navigation (in
+ // which case a transient navigation entry is created).
+ bool new_navigation_;
+
+ // Whether this interstitial is enabled. See Disable() for more info.
+ bool enabled_;
+
+ // Whether the Proceed or DontProceed have been called yet.
+ bool action_taken_;
// Notification magic.
NotificationRegistrar notification_registrar_;
+ // The RenderViewHost displaying the interstitial contents.
+ RenderViewHost* render_view_host_;
+
+ // Whether or not we should change the title of the tab when hidden (to revert
+ // it to its original value).
+ bool should_revert_tab_title_;
+
+ // The original title of the tab that should be reverted to when the
+ // interstitial is hidden.
+ std::wstring original_tab_title_;
+
// We keep a map of the various blocking pages shown as the UI tests need to
// be able to retrieve them.
- typedef std::map<TabContents*,InterstitialPage*> InterstitialPageMap;
+ typedef std::map<WebContents*,InterstitialPage*> InterstitialPageMap;
static InterstitialPageMap* tab_to_interstitial_page_;
DISALLOW_COPY_AND_ASSIGN(InterstitialPage);
diff --git a/chrome/browser/login_prompt.cc b/chrome/browser/login_prompt.cc
index 1e95b0c..db9d775 100644
--- a/chrome/browser/login_prompt.cc
+++ b/chrome/browser/login_prompt.cc
@@ -84,11 +84,11 @@ class LoginHandlerImpl : public LoginHandler,
SendNotifications();
}
- // Returns the TabContents that needs authentication.
- TabContents* GetTabContentsForLogin() {
+ // Returns the WebContents that needs authentication.
+ WebContents* GetWebContentsForLogin() {
DCHECK(MessageLoop::current() == ui_loop_);
- return tab_util::GetTabContentsByID(render_process_host_id_,
+ return tab_util::GetWebContentsByID(render_process_host_id_,
tab_contents_id_);
}
@@ -238,7 +238,7 @@ class LoginHandlerImpl : public LoginHandler,
DCHECK(MessageLoop::current() == ui_loop_);
NotificationService* service = NotificationService::current();
- TabContents* requesting_contents = GetTabContentsForLogin();
+ WebContents* requesting_contents = GetWebContentsForLogin();
if (!requesting_contents)
return;
@@ -311,7 +311,7 @@ class LoginDialogTask : public Task {
}
void Run() {
- TabContents* parent_contents = handler_->GetTabContentsForLogin();
+ WebContents* parent_contents = handler_->GetWebContentsForLogin();
if (!parent_contents) {
// The request was probably cancelled.
return;
diff --git a/chrome/browser/navigation_controller.cc b/chrome/browser/navigation_controller.cc
index deee023..e1ccbb1 100644
--- a/chrome/browser/navigation_controller.cc
+++ b/chrome/browser/navigation_controller.cc
@@ -212,13 +212,10 @@ void NavigationController::Reload(bool check_for_repost) {
DiscardNonCommittedEntriesInternal();
int current_index = GetCurrentEntryIndex();
if (check_for_repost_ && check_for_repost && current_index != -1 &&
- GetEntryAtIndex(current_index)->has_post_data() &&
- active_contents_->AsWebContents() &&
- !active_contents_->AsWebContents()->showing_repost_interstitial()) {
- // The user is asking to reload a page with POST data and we're not showing
- // the POST interstitial. Prompt to make sure they really want to do this.
- // If they do, RepostFormWarningDialog calls us back with
- // ReloadDontCheckForRepost.
+ GetEntryAtIndex(current_index)->has_post_data()) {
+ // The user is asking to reload a page with POST data. Prompt to make sure
+ // they really want to do this. If they do, RepostFormWarningDialog calls us
+ // back with ReloadDontCheckForRepost.
active_contents_->Activate();
RepostFormWarningDialog::RunRepostFormWarningDialog(this);
} else {
@@ -538,7 +535,6 @@ const SkBitmap& NavigationController::GetLazyFavIcon() const {
bool NavigationController::RendererDidNavigate(
const ViewHostMsg_FrameNavigate_Params& params,
- bool is_interstitial,
LoadCommittedDetails* details) {
// Save the previous state before we clobber it.
if (GetLastCommittedEntry()) {
@@ -613,7 +609,6 @@ bool NavigationController::RendererDidNavigate(
details->entry = GetActiveEntry();
details->is_in_page = IsURLInPageNavigation(params.url);
details->is_main_frame = PageTransition::IsMainFrame(params.transition);
- details->is_interstitial = is_interstitial;
details->serialized_security_info = params.security_info;
details->is_content_filtered = params.is_content_filtered;
NotifyNavigationEntryCommitted(details);
diff --git a/chrome/browser/navigation_controller.h b/chrome/browser/navigation_controller.h
index bd1d2aa..ce5a20f 100644
--- a/chrome/browser/navigation_controller.h
+++ b/chrome/browser/navigation_controller.h
@@ -51,8 +51,7 @@ class NavigationController {
: entry(NULL),
is_auto(false),
is_in_page(false),
- is_main_frame(true),
- is_interstitial(false) {
+ is_main_frame(true) {
}
// The committed entry. This will be the active entry in the controller.
@@ -85,10 +84,6 @@ class NavigationController {
// sub-frame.
bool is_main_frame;
- // True when this navigation is for an interstitial page. Many consumers
- // won't care about interstitial loads.
- bool is_interstitial;
-
// Whether the content of this frame has been altered/blocked because it was
// unsafe.
bool is_content_filtered;
@@ -325,7 +320,6 @@ class NavigationController {
// In the case that nothing has changed, the details structure is undefined
// and it will return false.
bool RendererDidNavigate(const ViewHostMsg_FrameNavigate_Params& params,
- bool is_interstitial,
LoadCommittedDetails* details);
// Notifies us that we just became active. This is used by the TabContents
diff --git a/chrome/browser/navigation_controller_unittest.cc b/chrome/browser/navigation_controller_unittest.cc
index 7938877..b2e21cf 100644
--- a/chrome/browser/navigation_controller_unittest.cc
+++ b/chrome/browser/navigation_controller_unittest.cc
@@ -794,8 +794,7 @@ TEST_F(NavigationControllerTest, NewSubframe) {
params.is_post = false;
NavigationController::LoadCommittedDetails details;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(url1, details.previous_url);
EXPECT_FALSE(details.is_auto);
@@ -829,8 +828,7 @@ TEST_F(NavigationControllerTest, SubframeOnEmptyPage) {
params.is_post = false;
NavigationController::LoadCommittedDetails details;
- EXPECT_FALSE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_FALSE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_EQ(0, notifications.size());
}
@@ -855,8 +853,7 @@ TEST_F(NavigationControllerTest, AutoSubframe) {
// Navigating should do nothing.
NavigationController::LoadCommittedDetails details;
- EXPECT_FALSE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_FALSE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_EQ(0, notifications.size());
// There should still be only one entry.
@@ -885,8 +882,7 @@ TEST_F(NavigationControllerTest, BackSubframe) {
// This should generate a new entry.
NavigationController::LoadCommittedDetails details;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(2, contents->controller()->GetEntryCount());
@@ -894,8 +890,7 @@ TEST_F(NavigationControllerTest, BackSubframe) {
const GURL url3(scheme1() + ":foo3");
params.page_id = 2;
params.url = url3;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(3, contents->controller()->GetEntryCount());
EXPECT_EQ(2, contents->controller()->GetCurrentEntryIndex());
@@ -904,8 +899,7 @@ TEST_F(NavigationControllerTest, BackSubframe) {
contents->controller()->GoBack();
params.url = url2;
params.page_id = 1;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(3, contents->controller()->GetEntryCount());
EXPECT_EQ(1, contents->controller()->GetCurrentEntryIndex());
@@ -914,8 +908,7 @@ TEST_F(NavigationControllerTest, BackSubframe) {
contents->controller()->GoBack();
params.url = url1;
params.page_id = 0;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(3, contents->controller()->GetEntryCount());
EXPECT_EQ(0, contents->controller()->GetCurrentEntryIndex());
@@ -966,8 +959,7 @@ TEST_F(NavigationControllerTest, InPage) {
// This should generate a new entry.
NavigationController::LoadCommittedDetails details;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(params, &details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(2, contents->controller()->GetEntryCount());
@@ -976,7 +968,7 @@ TEST_F(NavigationControllerTest, InPage) {
contents->controller()->GoBack();
back_params.url = url1;
back_params.page_id = 0;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(back_params, false,
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(back_params,
&details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(2, contents->controller()->GetEntryCount());
@@ -988,7 +980,7 @@ TEST_F(NavigationControllerTest, InPage) {
contents->controller()->GoForward();
forward_params.url = url2;
forward_params.page_id = 1;
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(forward_params, false,
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(forward_params,
&details));
EXPECT_TRUE(notifications.Check1AndReset(NOTIFY_NAV_ENTRY_COMMITTED));
EXPECT_EQ(2, contents->controller()->GetEntryCount());
@@ -1001,10 +993,10 @@ TEST_F(NavigationControllerTest, InPage) {
// one identified by an existing page ID. This would result in the second URL
// losing the reference fragment when you navigate away from it and then back.
contents->controller()->GoBack();
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(back_params, false,
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(back_params,
&details));
contents->controller()->GoForward();
- EXPECT_TRUE(contents->controller()->RendererDidNavigate(forward_params, false,
+ EXPECT_TRUE(contents->controller()->RendererDidNavigate(forward_params,
&details));
EXPECT_EQ(forward_params.url,
contents->controller()->GetActiveEntry()->url());
@@ -1250,7 +1242,7 @@ TEST_F(NavigationControllerTest, RestoreNavigate) {
params.gesture = NavigationGestureUser;
params.is_post = false;
NavigationController::LoadCommittedDetails details;
- controller->RendererDidNavigate(params, false, &details);
+ controller->RendererDidNavigate(params, &details);
// There should be no longer any pending entry and one committed one. This
// means that we were able to locate the entry, assign its site instance, and
@@ -1520,8 +1512,7 @@ TEST_F(NavigationControllerTest, SameSubframe) {
params.gesture = NavigationGestureAuto;
params.is_post = false;
NavigationController::LoadCommittedDetails details;
- EXPECT_FALSE(contents->controller()->RendererDidNavigate(params, false,
- &details));
+ EXPECT_FALSE(contents->controller()->RendererDidNavigate(params, &details));
// Nothing should have changed.
EXPECT_EQ(contents->controller()->GetEntryCount(), 1);
diff --git a/chrome/browser/provisional_load_details.cc b/chrome/browser/provisional_load_details.cc
index f7a9f89..ffc85a0 100644
--- a/chrome/browser/provisional_load_details.cc
+++ b/chrome/browser/provisional_load_details.cc
@@ -8,13 +8,11 @@
#include "chrome/browser/ssl_manager.h"
ProvisionalLoadDetails::ProvisionalLoadDetails(bool is_main_frame,
- bool is_interstitial_page,
bool is_in_page_navigation,
const GURL& url,
const std::string& security_info,
bool is_content_filtered)
: is_main_frame_(is_main_frame),
- is_interstitial_page_(is_interstitial_page),
is_in_page_navigation_(is_in_page_navigation),
url_(url),
error_code_(net::OK),
diff --git a/chrome/browser/provisional_load_details.h b/chrome/browser/provisional_load_details.h
index 9f63acb..5cb9501 100644
--- a/chrome/browser/provisional_load_details.h
+++ b/chrome/browser/provisional_load_details.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_PROVISIONAL_LOAD_DETAILS_H__
-#define CHROME_BROWSER_PROVISIONAL_LOAD_DETAILS_H__
+#ifndef CHROME_BROWSER_PROVISIONAL_LOAD_DETAILS_H_
+#define CHROME_BROWSER_PROVISIONAL_LOAD_DETAILS_H_
#include "base/basictypes.h"
#include "googleurl/src/gurl.h"
@@ -20,7 +20,6 @@
class ProvisionalLoadDetails {
public:
ProvisionalLoadDetails(bool main_frame,
- bool interstitial_page,
bool in_page_navigation,
const GURL& url,
const std::string& security_info,
@@ -34,8 +33,6 @@ class ProvisionalLoadDetails {
bool main_frame() const { return is_main_frame_; }
- bool interstitial_page() const { return is_interstitial_page_; }
-
bool in_page_navigation() const { return is_in_page_navigation_; }
int ssl_cert_id() const { return ssl_cert_id_; }
@@ -50,15 +47,14 @@ class ProvisionalLoadDetails {
int error_code_;
GURL url_;
bool is_main_frame_;
- bool is_interstitial_page_;
bool is_in_page_navigation_;
int ssl_cert_id_;
int ssl_cert_status_;
int ssl_security_bits_;
bool is_content_filtered_;
- DISALLOW_EVIL_CONSTRUCTORS(ProvisionalLoadDetails);
+ DISALLOW_COPY_AND_ASSIGN(ProvisionalLoadDetails);
};
-#endif // CHROME_BROWSER_PROVISIONAL_LOAD_DETAILS_H__
+#endif // CHROME_BROWSER_PROVISIONAL_LOAD_DETAILS_H_
diff --git a/chrome/browser/render_view_host_manager.cc b/chrome/browser/render_view_host_manager.cc
index 81e95aa..5ad576b 100644
--- a/chrome/browser/render_view_host_manager.cc
+++ b/chrome/browser/render_view_host_manager.cc
@@ -6,7 +6,6 @@
#include "base/command_line.h"
#include "base/logging.h"
-#include "chrome/browser/interstitial_page.h"
#include "chrome/browser/navigation_controller.h"
#include "chrome/browser/navigation_entry.h"
#include "chrome/browser/render_widget_host_view.h"
@@ -16,37 +15,23 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
-// Destroys the given |**render_view_host| and NULLs out |*render_view_host|
-// and then NULLs the field. Callers should only pass pointers to the
-// pending_render_view_host_, interstitial_render_view_host_, or
-// original_render_view_host_ fields of this object.
-static void CancelRenderView(RenderViewHost** render_view_host) {
- (*render_view_host)->Shutdown();
- (*render_view_host) = NULL;
-}
-
RenderViewHostManager::RenderViewHostManager(
RenderViewHostFactory* render_view_factory,
RenderViewHostDelegate* render_view_delegate,
Delegate* delegate)
: delegate_(delegate),
- renderer_state_(NORMAL),
+ cross_navigation_pending_(false),
render_view_factory_(render_view_factory),
render_view_delegate_(render_view_delegate),
render_view_host_(NULL),
- original_render_view_host_(NULL),
- interstitial_render_view_host_(NULL),
pending_render_view_host_(NULL),
- interstitial_page_(NULL),
- showing_repost_interstitial_(false) {
+ interstitial_page_(NULL) {
}
RenderViewHostManager::~RenderViewHostManager() {
// Shutdown should have been called which should have cleaned these up.
DCHECK(!render_view_host_);
DCHECK(!pending_render_view_host_);
- DCHECK(!original_render_view_host_);
- DCHECK(!interstitial_render_view_host_);
}
void RenderViewHostManager::Init(Profile* profile,
@@ -63,21 +48,8 @@ void RenderViewHostManager::Init(Profile* profile,
}
void RenderViewHostManager::Shutdown() {
- if (showing_interstitial_page()) {
- // The tab is closed while the interstitial page is showing, hide and
- // destroy it.
- HideInterstitialPage(false, false);
- }
- DCHECK(!interstitial_render_view_host_) << "Should have been deleted by Hide";
-
- if (pending_render_view_host_) {
- pending_render_view_host_->Shutdown();
- pending_render_view_host_ = NULL;
- }
- if (original_render_view_host_) {
- original_render_view_host_->Shutdown();
- original_render_view_host_ = NULL;
- }
+ if (pending_render_view_host_)
+ CancelPendingRenderView();
// We should always have a main RenderViewHost.
render_view_host_->Shutdown();
@@ -123,29 +95,17 @@ RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) {
}
}
- showing_repost_interstitial_ = false;
return dest_render_view_host;
}
void RenderViewHostManager::Stop() {
render_view_host_->Stop();
- // If we aren't in the NORMAL renderer state, we should stop the pending
- // renderers. This will lead to a DidFailProvisionalLoad, which will
- // properly destroy them.
- if (renderer_state_ == PENDING) {
+ // If we are cross-navigating, we should stop the pending renderers. This
+ // will lead to a DidFailProvisionalLoad, which will properly destroy them.
+ if (cross_navigation_pending_) {
pending_render_view_host_->Stop();
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- interstitial_render_view_host_->Stop();
- if (pending_render_view_host_) {
- pending_render_view_host_->Stop();
- }
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- if (pending_render_view_host_) {
- pending_render_view_host_->Stop();
- }
}
}
@@ -153,12 +113,10 @@ void RenderViewHostManager::SetIsLoading(bool is_loading) {
render_view_host_->SetIsLoading(is_loading);
if (pending_render_view_host_)
pending_render_view_host_->SetIsLoading(is_loading);
- if (original_render_view_host_)
- original_render_view_host_->SetIsLoading(is_loading);
}
bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() {
- if (renderer_state_ != PENDING)
+ if (!cross_navigation_pending_)
return true;
// If the tab becomes unresponsive during unload while doing a
@@ -178,119 +136,31 @@ bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() {
void RenderViewHostManager::DidNavigateMainFrame(
RenderViewHost* render_view_host) {
- if (renderer_state_ == NORMAL) {
+ if (!cross_navigation_pending_) {
// We should only hear this from our current renderer.
DCHECK(render_view_host == render_view_host_);
return;
- } else if (renderer_state_ == PENDING) {
- if (render_view_host == pending_render_view_host_) {
- // The pending cross-site navigation completed, so show the renderer.
- SwapToRenderView(&pending_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else if (render_view_host == render_view_host_) {
- // A navigation in the original page has taken place. Cancel the pending
- // one.
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
-
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- if (render_view_host == interstitial_render_view_host_) {
- // The interstitial renderer is ready, so show it, and keep the old
- // RenderViewHost around.
- original_render_view_host_ = render_view_host_;
- SwapToRenderView(&interstitial_render_view_host_, false);
- renderer_state_ = INTERSTITIAL;
- } else if (render_view_host == render_view_host_) {
- // We shouldn't get here, because the original render view was the one
- // that caused the ShowInterstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- CancelRenderView(&interstitial_render_view_host_);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- } else if (render_view_host == pending_render_view_host_) {
- // We shouldn't get here, because the original render view was the one
- // that caused the ShowInterstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells pending_render_view_host_
- // to navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- CancelRenderView(&interstitial_render_view_host_);
- SwapToRenderView(&pending_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
-
- } else if (renderer_state_ == INTERSTITIAL) {
- if (render_view_host == original_render_view_host_) {
- // We shouldn't get here, because the original render view was the one
- // that caused the ShowInterstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- SwapToRenderView(&original_render_view_host_, true);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- } else if (render_view_host == pending_render_view_host_) {
- // No one else should be sending us DidNavigate in this state.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells pending_render_view_host_
- // to navigate. To be safe, we'll cancel the interstitial and show the
- // page that caused the DidNavigate.
- SwapToRenderView(&pending_render_view_host_, true);
- CancelRenderView(&original_render_view_host_);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
- InterstitialPageGone();
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- if (render_view_host == original_render_view_host_) {
- // We navigated to something in the original renderer, so show it.
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- SwapToRenderView(&original_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else if (render_view_host == pending_render_view_host_) {
- // We navigated to something in the pending renderer.
- CancelRenderView(&original_render_view_host_);
- SwapToRenderView(&pending_render_view_host_, true);
- renderer_state_ = NORMAL;
- } else {
- // No one else should be sending us DidNavigate in this state.
- DCHECK(false);
- return;
- }
- InterstitialPageGone();
+ }
+ if (render_view_host == pending_render_view_host_) {
+ // The pending cross-site navigation completed, so show the renderer.
+ SwapToRenderView(&pending_render_view_host_, true);
+ cross_navigation_pending_ = false;
+ } else if (render_view_host == render_view_host_) {
+ // A navigation in the original page has taken place. Cancel the pending
+ // one.
+ CancelPendingRenderView();
+ cross_navigation_pending_ = false;
} else {
- // No such state.
+ // No one else should be sending us DidNavigate in this state.
DCHECK(false);
- return;
}
}
void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id,
int new_request_id) {
- // Should only see this while we have a pending renderer, possibly during an
- // interstitial. Otherwise, we should ignore.
- if (renderer_state_ != PENDING && renderer_state_ != LEAVING_INTERSTITIAL)
+ // Should only see this while we have a pending renderer.
+ if (!cross_navigation_pending_)
return;
DCHECK(pending_render_view_host_);
@@ -298,14 +168,7 @@ void RenderViewHostManager::OnCrossSiteResponse(int new_render_process_host_id,
// will send a ClosePage_ACK to the ResourceDispatcherHost with the given
// IDs (of the pending RVH's request), allowing the pending RVH's response to
// resume.
- if (showing_interstitial_page()) {
- DCHECK(original_render_view_host_);
- original_render_view_host_->ClosePage(new_render_process_host_id,
- new_request_id);
- } else {
- render_view_host_->ClosePage(new_render_process_host_id,
- new_request_id);
- }
+ render_view_host_->ClosePage(new_render_process_host_id, new_request_id);
// ResourceDispatcherHost has told us to run the onunload handler, which
// means it is not a download or unsafe page, and we are going to perform the
@@ -327,50 +190,6 @@ void RenderViewHostManager::RendererAbortedProvisionalLoad(
// navigation events. (That's necessary to support onunload anyway.) Once
// we've made that change, we won't create a pending renderer until we know
// the response is not a download.
-
- if (renderer_state_ == ENTERING_INTERSTITIAL) {
- if ((pending_render_view_host_ &&
- (pending_render_view_host_ == render_view_host)) ||
- (!pending_render_view_host_ &&
- (render_view_host_ == render_view_host))) {
- // The abort came from the RenderViewHost that triggered the
- // interstitial. (e.g., User clicked stop after ShowInterstitial but
- // before the interstitial was visible.) We should go back to NORMAL.
- // Note that this is an uncommon case, because we are only in the
- // ENTERING_INTERSTITIAL state in the small time window while the
- // interstitial's RenderViewHost is being created.
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- CancelRenderView(&interstitial_render_view_host_);
- renderer_state_ = NORMAL;
- }
-
- // We can get here, at least in the following case.
- // We show an interstitial, then navigate to a URL that leads to another
- // interstitial. Now there's a race. The new interstitial will be
- // created and we will go to ENTERING_INTERSTITIAL, but the old one will
- // meanwhile destroy itself and fire DidFailProvisionalLoad. That puts
- // us here. Should be safe to ignore the DidFailProvisionalLoad, from
- // the perspective of the renderer state.
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // If we've left the interstitial by seeing a download (or otherwise
- // aborting a load), we should get back to the original page, because
- // interstitial page doesn't make sense anymore. (For example, we may
- // have clicked Proceed on a download URL.)
-
- // TODO(creis): This causes problems in the old process model when
- // visiting a new URL from an interstitial page.
- // This is because we receive a DidFailProvisionalLoad from cancelling
- // the first request, which is indistinguishable from a
- // DidFailProvisionalLoad from the second request (if it is a download).
- // We need to find a way to distinguish these cases, because it doesn't
- // make sense to keep showing the interstitial after a download.
- // if (pending_render_view_host_)
- // CancelRenderView(&pending_render_view_host_);
- // SwapToRenderView(&original_render_view_host_, true);
- // renderer_state_ = NORMAL;
- // delegate_->InterstitialPageGoneFromRenderManager();
- }
}
void RenderViewHostManager::ShouldClosePage(bool proceed) {
@@ -388,226 +207,21 @@ void RenderViewHostManager::ShouldClosePage(bool proceed) {
return;
}
- DCHECK(renderer_state_ != ENTERING_INTERSTITIAL);
- DCHECK(renderer_state_ != INTERSTITIAL);
if (proceed) {
// Ok to unload the current page, so proceed with the cross-site navigate.
pending_render_view_host_->SetNavigationsSuspended(false);
} else {
// Current page says to cancel.
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
+ CancelPendingRenderView();
+ cross_navigation_pending_ = false;
}
}
-void RenderViewHostManager::ShowInterstitialPage(
- InterstitialPage* interstitial_page) {
- // Note that it is important that the interstitial page render view host is
- // in the same process as the normal render view host for the tab, so they
- // use page ids from the same pool. If they came from different processes,
- // page ids may collide causing confusion in the controller (existing
- // navigation entries in the controller history could get overridden with the
- // interstitial entry).
- SiteInstance* interstitial_instance = NULL;
-
- if (renderer_state_ == NORMAL) {
- // render_view_host_ will not be deleted before the end of this method, so
- // we don't have to worry about this SiteInstance's ref count dropping to
- // zero.
- interstitial_instance = render_view_host_->site_instance();
-
- } else if (renderer_state_ == PENDING) {
- // pending_render_view_host_ will not be deleted before the end of this
- // method (when we are in this state), so we don't have to worry about this
- // SiteInstance's ref count dropping to zero.
- interstitial_instance = pending_render_view_host_->site_instance();
-
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- // We should never get here if we're in the process of showing an
- // interstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate to a URL that causes an interstitial. To be safe, we'll cancel
- // the first interstitial.
- CancelRenderView(&interstitial_render_view_host_);
- renderer_state_ = NORMAL;
-
- // We'd like to now show the new interstitial, but if there's a
- // pending_render_view_host_, we can't tell if this JavaScript navigation
- // occurred in the original or the pending renderer. That means we won't
- // know where to proceed, so we can't show the interstitial. This is
- // really just meant to avoid a crash until we can intercept JavaScript
- // navigation events, so for now we'll kill the interstitial and go back
- // to the last known good page.
- if (pending_render_view_host_) {
- CancelRenderView(&pending_render_view_host_);
- return;
- }
- // Should be safe to show the interstitial for the new page.
- // render_view_host_ will not be deleted before the end of this method, so
- // we don't have to worry about this SiteInstance's ref count dropping to
- // zero.
- interstitial_instance = render_view_host_->site_instance();
-
- } else if (renderer_state_ == INTERSTITIAL) {
- // We should never get here if we're already showing an interstitial.
- // However, until we intercept navigation events from JavaScript, it is
- // possible to get here, if another tab tells render_view_host_ to
- // navigate to a URL that causes an interstitial. To be safe, we'll go
- // back to normal first.
- if (pending_render_view_host_ != NULL) {
- // There was a pending RVH. We don't know which RVH caused this call
- // to ShowInterstitial, so we can't really proceed. We'll have to stay
- // in the NORMAL state, showing the last good page. This is only a
- // temporary fix anyway, to stave off a crash.
- HideInterstitialPage(false, false);
- return;
- }
- // Should be safe to show the interstitial for the new page.
- // render_view_host_ will not be deleted before the end of this method, so
- // we don't have to worry about this SiteInstance's ref count dropping to
- // zero.
- SwapToRenderView(&original_render_view_host_, true);
- interstitial_instance = render_view_host_->site_instance();
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- SwapToRenderView(&original_render_view_host_, true);
- interstitial_instance = NULL;
- if (pending_render_view_host_) {
- // We're now effectively in PENDING.
- // pending_render_view_host_ will not be deleted before the end of this
- // method, so we don't have to worry about this SiteInstance's ref count
- // dropping to zero.
- interstitial_instance = pending_render_view_host_->site_instance();
- } else {
- // We're now effectively in NORMAL.
- // render_view_host_ will not be deleted before the end of this method,
- // so we don't have to worry about this SiteInstance's ref count dropping
- // to zero.
- interstitial_instance = render_view_host_->site_instance();
- }
-
- } else {
- // No such state.
- DCHECK(false);
- return;
- }
-
- // Create a pending renderer and move to ENTERING_INTERSTITIAL.
- interstitial_render_view_host_ =
- CreateRenderViewHost(interstitial_instance, MSG_ROUTING_NONE, NULL);
- interstitial_page_ = interstitial_page;
- bool success = delegate_->CreateRenderViewForRenderManager(
- interstitial_render_view_host_);
- if (!success) {
- // TODO(creis): If this fails, should we load the interstitial in
- // render_view_host_? We shouldn't just skip the interstitial...
- CancelRenderView(&interstitial_render_view_host_);
- return;
- }
-
- // Don't show the view yet.
- interstitial_render_view_host_->view()->Hide();
-
- renderer_state_ = ENTERING_INTERSTITIAL;
-
- // We allow the DOM bindings as a way to get the page to talk back to us.
- interstitial_render_view_host_->AllowDomAutomationBindings();
-
- interstitial_render_view_host_->LoadAlternateHTMLString(
- interstitial_page->GetHTMLContents(), false,
- GURL::EmptyGURL(),
- std::string());
-}
-
-void RenderViewHostManager::HideInterstitialPage(bool wait_for_navigation,
- bool proceed) {
- if (renderer_state_ == NORMAL || renderer_state_ == PENDING) {
- // Shouldn't get here, since there's no interstitial showing.
- DCHECK(false);
- return;
-
- } else if (renderer_state_ == ENTERING_INTERSTITIAL) {
- // Unclear if it is possible to get here. (Can you hide the interstitial
- // before it is shown?) If so, we should go back to NORMAL.
- CancelRenderView(&interstitial_render_view_host_);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- return;
- }
-
- DCHECK(showing_interstitial_page());
- DCHECK(render_view_host_ && original_render_view_host_ &&
- !interstitial_render_view_host_);
-
- if (renderer_state_ == INTERSTITIAL) {
- // Disable the Proceed button on the interstitial, because the destination
- // renderer might get replaced.
- DisableInterstitialProceed(false);
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // We have already given up the ability to proceed by starting a new
- // navigation. If this is a request to proceed, we must ignore it.
- // (Hopefully we will have disabled the Proceed button by now, but it's
- // possible to get here before that happens.)
- if (proceed)
- return;
- }
-
- if (wait_for_navigation) {
- // We are resuming the loading. We need to set the state to loading again
- // as it was set to false when the interstitial stopped loading (so the
- // throbber runs).
- delegate_->DidStartLoadingFromRenderManager(render_view_host_, NULL);
- }
-
- if (proceed) {
- // Now we will resume loading automatically, either in
- // original_render_view_host_ or in pending_render_view_host_. When it
- // completes, we will display the renderer in DidNavigate.
- renderer_state_ = LEAVING_INTERSTITIAL;
-
- } else {
- // Don't proceed. Go back to the previously showing page.
- if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // We said DontProceed after starting to leave the interstitial.
- // Abandon whatever we were in the process of doing.
- original_render_view_host_->Stop();
- }
- SwapToRenderView(&original_render_view_host_, true);
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- renderer_state_ = NORMAL;
- InterstitialPageGone();
- }
-}
-
-bool RenderViewHostManager::IsRenderViewInterstitial(
- const RenderViewHost* render_view_host) const {
- if (showing_interstitial_page())
- return render_view_host_ == render_view_host;
- if (renderer_state_ == ENTERING_INTERSTITIAL)
- return interstitial_render_view_host_ == render_view_host;
- return false;
-}
-
void RenderViewHostManager::OnJavaScriptMessageBoxClosed(
IPC::Message* reply_msg,
bool success,
const std::wstring& prompt) {
- RenderViewHost* rvh = render_view_host_;
- if (showing_interstitial_page()) {
- // No JavaScript message boxes are ever shown by interstitial pages, but
- // they can be shown by the original RVH while an interstitial page is
- // showing (e.g., from an onunload event handler). We should send this to
- // the original RVH and not the interstitial's RVH.
- // TODO(creis): Perhaps the JavascriptMessageBoxHandler should store which
- // RVH created it, so that it can tell this method which RVH to reply to.
- DCHECK(original_render_view_host_);
- rvh = original_render_view_host_;
- }
- rvh->JavaScriptMessageBoxClosed(reply_msg, success, prompt);
+ render_view_host_->JavaScriptMessageBoxClosed(reply_msg, success, prompt);
}
@@ -676,7 +290,7 @@ SiteInstance* RenderViewHostManager::GetSiteInstanceForEntry(
// compare the entry's URL to the last committed entry's URL.
NavigationController* controller = delegate_->GetControllerForRenderManager();
NavigationEntry* curr_entry = controller->GetLastCommittedEntry();
- if (showing_interstitial_page()) {
+ if (interstitial_page_) {
// The interstitial is currently the last committed entry, but we want to
// compare against the last non-interstitial entry.
curr_entry = controller->GetEntryAtOffset(-1);
@@ -725,7 +339,7 @@ bool RenderViewHostManager::CreatePendingRenderView(SiteInstance* instance) {
// Don't show the view until we get a DidNavigate from it.
pending_render_view_host_->view()->Hide();
} else {
- CancelRenderView(&pending_render_view_host_);
+ CancelPendingRenderView();
}
return success;
}
@@ -794,37 +408,18 @@ void RenderViewHostManager::SwapToRenderView(
RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate(
const NavigationEntry& entry) {
- // If we are in PENDING or ENTERING_INTERSTITIAL, then we want to get back
- // to NORMAL and navigate as usual.
- if (renderer_state_ == PENDING || renderer_state_ == ENTERING_INTERSTITIAL) {
+ // If we are cross-navigating, then we want to get back to normal and navigate
+ // as usual.
+ if (cross_navigation_pending_) {
if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
- if (interstitial_render_view_host_)
- CancelRenderView(&interstitial_render_view_host_);
- renderer_state_ = NORMAL;
+ CancelPendingRenderView();
+ cross_navigation_pending_ = false;
}
// render_view_host_ will not be deleted before the end of this method, so we
// don't have to worry about this SiteInstance's ref count dropping to zero.
SiteInstance* curr_instance = render_view_host_->site_instance();
- if (showing_interstitial_page()) {
- // Must disable any ability to proceed from the interstitial, because we're
- // about to navigate somewhere else.
- DisableInterstitialProceed(true);
-
- if (pending_render_view_host_)
- CancelRenderView(&pending_render_view_host_);
-
- renderer_state_ = LEAVING_INTERSTITIAL;
-
- // We want to compare against where we were, because we just cancelled
- // where we were going. The original_render_view_host_ won't be deleted
- // before the end of this method, so we don't have to worry about this
- // SiteInstance's ref count dropping to zero.
- curr_instance = original_render_view_host_->site_instance();
- }
-
// Determine if we need a new SiteInstance for this entry.
// Again, new_instance won't be deleted before the end of this method, so it
// is safe to use a normal pointer here.
@@ -834,8 +429,7 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate(
if (new_instance != curr_instance) {
// New SiteInstance.
- DCHECK(renderer_state_ == NORMAL ||
- renderer_state_ == LEAVING_INTERSTITIAL);
+ DCHECK(!cross_navigation_pending_);
// Create a pending RVH and navigate it.
bool success = CreatePendingRenderView(new_instance);
@@ -844,36 +438,14 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate(
// Check if our current RVH is live before we set up a transition.
if (!render_view_host_->IsRenderViewLive()) {
- if (renderer_state_ == NORMAL) {
+ if (!cross_navigation_pending_) {
// The current RVH is not live. There's no reason to sit around with a
// sad tab or a newly created RVH while we wait for the pending RVH to
- // navigate. Just switch to the pending RVH now and go back to NORMAL,
- // without requiring a cross-site transition. (Note that we don't care
- // about on{before}unload handlers if the current RVH isn't live.)
+ // navigate. Just switch to the pending RVH now and go back to non
+ // cross-navigating (Note that we don't care about on{before}unload
+ // handlers if the current RVH isn't live.)
SwapToRenderView(&pending_render_view_host_, true);
return render_view_host_;
-
- } else if (renderer_state_ == LEAVING_INTERSTITIAL) {
- // Cancel the interstitial, since it has died and we're navigating away
- // anyway.
- DCHECK(original_render_view_host_);
- if (original_render_view_host_->IsRenderViewLive()) {
- // Swap back to the original and act like a pending request (using
- // the logic below).
- SwapToRenderView(&original_render_view_host_, true);
- renderer_state_ = NORMAL;
- InterstitialPageGone();
- // Continue with the pending cross-site transition logic below.
- } else {
- // Both the interstitial and original are dead. Just like the NORMAL
- // case, let's skip the cross-site transition entirely. We also have
- // to clean up the interstitial state.
- SwapToRenderView(&pending_render_view_host_, true);
- CancelRenderView(&original_render_view_host_);
- renderer_state_ = NORMAL;
- InterstitialPageGone();
- return render_view_host_;
- }
} else {
NOTREACHED();
return render_view_host_;
@@ -895,12 +467,9 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate(
// old page's onunload handler before it sends the response.
pending_render_view_host_->SetHasPendingCrossSiteRequest(true, -1);
- // We now have a pending RVH. If we were in NORMAL, we should now be in
- // PENDING. If we were in LEAVING_INTERSTITIAL, we should stay there.
- if (renderer_state_ == NORMAL)
- renderer_state_ = PENDING;
- else
- DCHECK(renderer_state_ == LEAVING_INTERSTITIAL);
+ // We now have a pending RVH.
+ DCHECK(!cross_navigation_pending_);
+ cross_navigation_pending_ = true;
// Tell the old render view to run its onbeforeunload handler, since it
// doesn't otherwise know that the cross-site request is happening. This
@@ -910,38 +479,14 @@ RenderViewHost* RenderViewHostManager::UpdateRendererStateNavigate(
return pending_render_view_host_;
}
- // Same SiteInstance can be used. Navigate render_view_host_ if we are in
- // the NORMAL state, and original_render_view_host_ if an interstitial is
- // showing.
- if (renderer_state_ == NORMAL)
- return render_view_host_;
-
- DCHECK(renderer_state_ == LEAVING_INTERSTITIAL);
- return original_render_view_host_;
-}
-
-void RenderViewHostManager::DisableInterstitialProceed(bool stop_request) {
- // TODO(creis): Make sure the interstitial page disables any ability to
- // proceed at this point, because we're about to abort the original request.
- // This can be done by adding a new event to the NotificationService.
- // We should also disable the button on the page itself, but it's ok if that
- // doesn't happen immediately.
-
- // Stopping the request is necessary if we are navigating away, because the
- // user could be requesting the same URL again, causing the HttpCache to
- // ignore it. (Fixes bug 1079784.)
- if (stop_request) {
- original_render_view_host_->Stop();
- if (pending_render_view_host_)
- pending_render_view_host_->Stop();
- }
+ // Same SiteInstance can be used. Navigate render_view_host_ if we are not
+ // cross navigating.
+ DCHECK(!cross_navigation_pending_);
+ return render_view_host_;
}
-void RenderViewHostManager::InterstitialPageGone() {
- DCHECK(!showing_interstitial_page());
- if (interstitial_page_) {
- interstitial_page_->InterstitialClosed();
- interstitial_page_ = NULL;
- }
+void RenderViewHostManager::CancelPendingRenderView() {
+ pending_render_view_host_->Shutdown();
+ pending_render_view_host_ = NULL;
}
diff --git a/chrome/browser/render_view_host_manager.h b/chrome/browser/render_view_host_manager.h
index 371c398..40eabce 100644
--- a/chrome/browser/render_view_host_manager.h
+++ b/chrome/browser/render_view_host_manager.h
@@ -22,8 +22,8 @@ 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.
+// it is easy to do. But we can also have transitions of processes (and hence
+// RenderViewHosts) that can get complex.
class RenderViewHostManager {
public:
// Functions implemented by our owner that we need.
@@ -101,9 +101,9 @@ class RenderViewHostManager {
// 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.
+ // Notifies the regular and pending RenderViewHosts 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 both.
void SetIsLoading(bool is_loading);
// Whether to close the tab or not when there is a hang during an unload
@@ -111,8 +111,7 @@ class RenderViewHostManager {
// with the navigation instead of closing the tab.
bool ShouldCloseTabOnUnresponsiveRenderer();
- // Called when a renderer's main frame navigates. This handles all the logic
- // associated with interstitial management.
+ // Called when a renderer's main frame navigates.
void DidNavigateMainFrame(RenderViewHost* render_view_host);
// Allows the WebContents to react when a cross-site response is ready to be
@@ -128,49 +127,28 @@ class RenderViewHostManager {
// WebContents.
void ShouldClosePage(bool proceed);
- // Displays an interstitial page 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. The passed InterstitialPage is owned by the caller and must
- // remain valid while the interstitial page is shown.
- void ShowInterstitialPage(InterstitialPage* interstitial_page);
-
- // 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.
+ // Forwards the message to the RenderViewHost, which is the original one.
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;
+ // Sets the passed passed interstitial as the currently showing interstitial.
+ // |interstitial_page| should be non NULL (use the remove_interstitial_page
+ // method to unset the interstitial) and no interstitial page should be set
+ // when there is already a non NULL interstitial page set.
+ void set_interstitial_page(InterstitialPage* interstitial_page) {
+ DCHECK(!interstitial_page_ && interstitial_page);
+ interstitial_page_ = interstitial_page;
}
- // Returns whether we are currently showing an interstitial page.
- bool showing_interstitial_page() const {
- return (renderer_state_ == INTERSTITIAL) ||
- (renderer_state_ == LEAVING_INTERSTITIAL);
+ // Unsets the currently showing interstitial.
+ void remove_interstitial_page() {
+ DCHECK(interstitial_page_);
+ interstitial_page_ = NULL;
}
- // Accessors to the the interstitial page.
+ // Returns the currently showing interstitial, NULL if no interstitial is
+ // showing.
InterstitialPage* interstitial_page() const {
return interstitial_page_;
}
@@ -178,49 +156,6 @@ class RenderViewHostManager {
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.
@@ -251,22 +186,14 @@ class RenderViewHostManager {
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);
+ // Helper method to terminate the pending RenderViewHost.
+ void CancelPendingRenderView();
- // Cleans up after an interstitial page is hidden.
- void InterstitialPageGone();
+ RenderViewHost* UpdateRendererStateNavigate(const NavigationEntry& entry);
// 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_;
@@ -275,31 +202,19 @@ class RenderViewHostManager {
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.
+ // a child RenderView instance.
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.
+ // while a cross-site request is pending until it calls DidNavigate.
RenderViewHost* pending_render_view_host_;
// The intersitial page currently shown if any, not own by this class
// (the InterstitialPage is self-owned, it deletes itself when hidden).
InterstitialPage* interstitial_page_;
- // See comment above showing_repost_interstitial().
- bool showing_repost_interstitial_;
+ // Whether a cross-site request is pending (in the new process model).
+ bool cross_navigation_pending_;
DISALLOW_COPY_AND_ASSIGN(RenderViewHostManager);
};
diff --git a/chrome/browser/render_widget_host_view_win.h b/chrome/browser/render_widget_host_view_win.h
index 064c7a0..be3c6b5 100644
--- a/chrome/browser/render_widget_host_view_win.h
+++ b/chrome/browser/render_widget_host_view_win.h
@@ -37,7 +37,7 @@ static const wchar_t* const kRenderWidgetHostHWNDClass =
L"Chrome_RenderWidgetHostHWND";
///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostHWND
+// RenderWidgetHostViewWin
//
// An object representing the "View" of a rendered web page. This object is
// responsible for displaying the content of the web page, receiving windows
@@ -274,7 +274,7 @@ class RenderWidgetHostViewWin :
// until that bug is fixed.
bool renderer_accessible_;
- DISALLOW_EVIL_CONSTRUCTORS(RenderWidgetHostViewWin);
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin);
};
#endif // #ifndef CHROME_BROWSER_RENDER_WIDGET_HOST_VIEW_WIN_H_
diff --git a/chrome/browser/resource_dispatcher_host.cc b/chrome/browser/resource_dispatcher_host.cc
index 1d1aa18..042f178 100644
--- a/chrome/browser/resource_dispatcher_host.cc
+++ b/chrome/browser/resource_dispatcher_host.cc
@@ -25,8 +25,8 @@
#include "chrome/browser/render_view_host_delegate.h"
#include "chrome/browser/resource_request_details.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
-#include "chrome/browser/tab_contents.h"
#include "chrome/browser/tab_util.h"
+#include "chrome/browser/web_contents.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_types.h"
#include "chrome/common/render_messages.h"
@@ -2319,14 +2319,14 @@ class NotificationTask : public Task {
void Run() {
// Find the tab associated with this request.
- TabContents* tab_contents =
- tab_util::GetTabContentsByID(render_process_host_id_, tab_contents_id_);
+ WebContents* web_contents =
+ tab_util::GetWebContentsByID(render_process_host_id_, tab_contents_id_);
- if (tab_contents) {
+ if (web_contents) {
// Issue the notification.
NotificationService::current()->
Notify(type_,
- Source<NavigationController>(tab_contents->controller()),
+ Source<NavigationController>(web_contents->controller()),
Details<ResourceRequestDetails>(details_.get()));
}
}
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
index 6c6433a..265e4c7 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -43,7 +43,7 @@ static const wchar_t* const kSbDiagnosticHtml =
SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
SafeBrowsingService* sb_service,
const SafeBrowsingService::BlockingPageParam& param)
- : InterstitialPage(tab_util::GetTabContentsByID(
+ : InterstitialPage(tab_util::GetWebContentsByID(
param.render_process_host_id, param.render_view_id),
param.resource_type == ResourceType::MAIN_FRAME,
param.url),
@@ -55,6 +55,12 @@ SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
proceed_(false),
did_notify_(false),
is_main_frame_(param.resource_type == ResourceType::MAIN_FRAME) {
+ if (!is_main_frame_) {
+ navigation_entry_index_to_remove_ =
+ tab()->controller()->GetLastCommittedEntryIndex();
+ } else {
+ navigation_entry_index_to_remove_ = -1;
+ }
}
SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() {
@@ -138,8 +144,6 @@ std::string SafeBrowsingBlockingPage::GetHTMLContents() {
}
void SafeBrowsingBlockingPage::CommandReceived(const std::string& command) {
- DCHECK(tab()->type() == TAB_CONTENTS_WEB);
- WebContents* web = tab()->AsWebContents();
if (command == "2") {
// User pressed "Learn more".
GURL url;
@@ -150,7 +154,7 @@ void SafeBrowsingBlockingPage::CommandReceived(const std::string& command) {
} else {
NOTREACHED();
}
- web->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::LINK);
+ tab()->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::LINK);
return;
}
if (command == "3") {
@@ -161,8 +165,8 @@ void SafeBrowsingBlockingPage::CommandReceived(const std::string& command) {
GURL report_url =
safe_browsing_util::GeneratePhishingReportUrl(kSbReportPhishingUrl,
url().spec());
- web->HideInterstitialPage(false, false);
- web->OpenURL(report_url, GURL(), CURRENT_TAB, PageTransition::LINK);
+ Hide();
+ tab()->OpenURL(report_url, GURL(), CURRENT_TAB, PageTransition::LINK);
return;
}
if (command == "4") {
@@ -173,33 +177,26 @@ void SafeBrowsingBlockingPage::CommandReceived(const std::string& command) {
GURL diagnostic_url(diagnostic);
diagnostic_url = google_util::AppendGoogleLocaleParam(diagnostic_url);
DCHECK(result_ == SafeBrowsingService::URL_MALWARE);
- web->HideInterstitialPage(false, false);
- web->OpenURL(diagnostic_url, GURL(), CURRENT_TAB, PageTransition::LINK);
+ tab()->OpenURL(diagnostic_url, GURL(), CURRENT_TAB, PageTransition::LINK);
return;
}
proceed_ = command == "1";
- if (proceed_) {
- if (is_main_frame_)
- web->HideInterstitialPage(true, true);
- else
- web->HideInterstitialPage(false, false);
- } else {
- if (is_main_frame_) {
- DontProceed();
- } else {
- NavigationController* controller = web->controller();
- controller->RemoveEntryAtIndex(controller->GetLastCommittedEntryIndex(),
- NewTabUIURL());
- }
- }
+ if (proceed_)
+ Proceed();
+ else
+ DontProceed();
+
NotifyDone();
}
-void SafeBrowsingBlockingPage::InterstitialClosed() {
- NotifyDone();
- InterstitialPage::InterstitialClosed();
+void SafeBrowsingBlockingPage::DontProceed() {
+ if (navigation_entry_index_to_remove_ != -1) {
+ tab()->controller()->RemoveEntryAtIndex(navigation_entry_index_to_remove_,
+ NewTabUIURL());
+ }
+ InterstitialPage::DontProceed();
// We are now deleted.
}
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
index 056d9ae..b0fa2ea 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.h
@@ -38,7 +38,7 @@ class SafeBrowsingBlockingPage : public InterstitialPage {
// InterstitialPage method:
virtual std::string GetHTMLContents();
- virtual void InterstitialClosed();
+ virtual void DontProceed();
protected:
// InterstitialPage method:
@@ -77,6 +77,10 @@ class SafeBrowsingBlockingPage : public InterstitialPage {
// Whether the flagged resource is the main page (or a sub-resource is false).
bool is_main_frame_;
+ // The index of a navigation entry that should be removed when DontProceed()
+ // is invoked, -1 if not entry should be removed.
+ int navigation_entry_index_to_remove_;
+
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPage);
};
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index 837c11f..5a7a617 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/safe_browsing/protocol_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
#include "chrome/browser/safe_browsing/safe_browsing_database.h"
+#include "chrome/browser/tab_util.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -281,6 +282,20 @@ void SafeBrowsingService::DisplayBlockingPage(const GURL& url,
// Invoked on the UI thread.
void SafeBrowsingService::DoDisplayBlockingPage(
const BlockingPageParam& param) {
+ // The tab might have been closed.
+ if (!tab_util::GetWebContentsByID(param.render_process_host_id,
+ param.render_view_id)) {
+ // The tab is gone and we did not have a chance at showing the interstitial.
+ // Just act as "Don't Proceed" was chosen.
+ base::Thread* io_thread = g_browser_process->io_thread();
+ if (!io_thread)
+ return;
+ BlockingPageParam response_param = param;
+ response_param.proceed = false;
+ io_thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &SafeBrowsingService::OnBlockingPageDone, response_param));
+ return;
+ }
SafeBrowsingBlockingPage* blocking_page = new SafeBrowsingBlockingPage(this,
param);
blocking_page->Show();
diff --git a/chrome/browser/ssl_blocking_page.cc b/chrome/browser/ssl_blocking_page.cc
index c92ddc2..88b402c 100644
--- a/chrome/browser/ssl_blocking_page.cc
+++ b/chrome/browser/ssl_blocking_page.cc
@@ -12,7 +12,6 @@
#include "chrome/browser/navigation_controller.h"
#include "chrome/browser/navigation_entry.h"
#include "chrome/browser/ssl_error_info.h"
-#include "chrome/browser/tab_contents.h"
#include "chrome/browser/web_contents.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/l10n_util.h"
@@ -26,7 +25,7 @@
// No error happening loading a sub-resource triggers an interstitial so far.
SSLBlockingPage::SSLBlockingPage(SSLManager::CertError* error,
Delegate* delegate)
- : InterstitialPage(error->GetTabContents(), true, error->request_url()),
+ : InterstitialPage(error->GetWebContents(), true, error->request_url()),
error_(error),
delegate_(delegate),
delegate_has_been_notified_(false) {
@@ -95,15 +94,11 @@ void SSLBlockingPage::CommandReceived(const std::string& command) {
}
void SSLBlockingPage::Proceed() {
- // We hide the interstitial page first (by calling Proceed()) as allowing the
- // certificate will resume the request and we want the WebContents back to
- // showing the non interstitial page (otherwise the request completion
- // messages may confuse the WebContents if it is still showing the
- // interstitial page).
- InterstitialPage::Proceed();
-
// Accepting the certificate resumes the loading of the page.
NotifyAllowCertificate();
+
+ // This call hides and deletes the interstitial.
+ InterstitialPage::Proceed();
}
void SSLBlockingPage::DontProceed() {
diff --git a/chrome/browser/ssl_manager.cc b/chrome/browser/ssl_manager.cc
index f76774a0..2a875d4 100644
--- a/chrome/browser/ssl_manager.cc
+++ b/chrome/browser/ssl_manager.cc
@@ -259,10 +259,10 @@ SSLManager::ErrorHandler::ErrorHandler(ResourceDispatcherHost* rdh,
void SSLManager::ErrorHandler::Dispatch() {
DCHECK(MessageLoop::current() == ui_loop_);
- TabContents* tab_contents =
- tab_util::GetTabContentsByID(render_process_host_id_, tab_contents_id_);
+ TabContents* web_contents =
+ tab_util::GetWebContentsByID(render_process_host_id_, tab_contents_id_);
- if (!tab_contents) {
+ if (!web_contents) {
// We arrived on the UI thread, but the tab we're looking for is no longer
// here.
OnDispatchFailed();
@@ -270,12 +270,12 @@ void SSLManager::ErrorHandler::Dispatch() {
}
// Hand ourselves off to the SSLManager.
- manager_ = tab_contents->controller()->ssl_manager();
+ manager_ = web_contents->controller()->ssl_manager();
OnDispatched();
}
-TabContents* SSLManager::ErrorHandler::GetTabContents() {
- return tab_util::GetTabContentsByID(render_process_host_id_,
+WebContents* SSLManager::ErrorHandler::GetWebContents() {
+ return tab_util::GetWebContentsByID(render_process_host_id_,
tab_contents_id_);
}
@@ -570,11 +570,6 @@ void SSLManager::DidCommitProvisionalLoad(
changed = true;
}
- if (details->is_interstitial) {
- // We should not have any errors when loading an interstitial page, and as
- // a consequence no messages.
- DCHECK(pending_messages_.empty());
- }
ShowPendingMessages();
}
@@ -615,14 +610,12 @@ void SSLManager::DidCommitProvisionalLoad(
void SSLManager::DidFailProvisionalLoadWithError(
ProvisionalLoadDetails* details) {
DCHECK(details);
- // A transitional page is not expected to fail.
- DCHECK(!details->interstitial_page());
// Ignore in-page navigations.
if (details->in_page_navigation())
return;
- if (details->main_frame() && !details->interstitial_page())
+ if (details->main_frame())
ClearPendingMessages();
}
diff --git a/chrome/browser/ssl_manager.h b/chrome/browser/ssl_manager.h
index 29c01f3..43b71c2 100644
--- a/chrome/browser/ssl_manager.h
+++ b/chrome/browser/ssl_manager.h
@@ -34,9 +34,9 @@ class PrefService;
class ResourceRedirectDetails;
class ResourceRequestDetails;
class SSLErrorInfo;
-class TabContents;
class Task;
class URLRequest;
+class WebContents;
// The SSLManager SSLManager controls the SSL UI elements in a TabContents. It
// listens for various events that influence when these elements should or
@@ -75,9 +75,9 @@ class SSLManager : public NotificationObserver {
// Call on the UI thread.
SSLManager* manager() const { return manager_; };
- // Returns the TabContents this object is associated with. Should be
+ // Returns the WebContents this object is associated with. Should be
// called from the UI thread.
- TabContents* GetTabContents();
+ WebContents* GetWebContents();
// Cancels the associated URLRequest.
// This method can be called from OnDispatchFailed and OnDispatched.
diff --git a/chrome/browser/ssl_policy.cc b/chrome/browser/ssl_policy.cc
index 8ed4486..f89cdcd 100644
--- a/chrome/browser/ssl_policy.cc
+++ b/chrome/browser/ssl_policy.cc
@@ -61,9 +61,7 @@ ShowUnsafeContentTask::~ShowUnsafeContentTask() {
void ShowUnsafeContentTask::Run() {
error_handler_->manager()->AllowShowInsecureContentForURL(main_frame_url_);
// Reload the page.
- DCHECK(error_handler_->GetTabContents()->type() == TAB_CONTENTS_WEB);
- WebContents* tab = error_handler_->GetTabContents()->AsWebContents();
- tab->controller()->Reload(true);
+ error_handler_->GetWebContents()->controller()->Reload(true);
}
static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) {
@@ -91,8 +89,7 @@ static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) {
std::string html_text(jstemplate_builder::GetTemplateHtml(html, &strings,
"template_root"));
- DCHECK(error->GetTabContents()->type() == TAB_CONTENTS_WEB);
- WebContents* tab = error->GetTabContents()->AsWebContents();
+ WebContents* tab = error->GetWebContents();
int cert_id = CertStore::GetSharedInstance()->StoreCert(
error->ssl_info().cert, tab->render_view_host()->process()->host_id());
std::string security_info =
@@ -481,7 +478,6 @@ void SSLPolicy::OnFatalCertError(const GURL& main_frame_url,
return;
}
error->CancelRequest();
- DCHECK(error->GetTabContents()->type() == TAB_CONTENTS_WEB);
ShowErrorPage(this, error);
// No need to degrade our security indicators because we didn't continue.
}
diff --git a/chrome/browser/tab_util.cc b/chrome/browser/tab_util.cc
index 815abfe..863b38d4 100644
--- a/chrome/browser/tab_util.cc
+++ b/chrome/browser/tab_util.cc
@@ -27,7 +27,7 @@ bool tab_util::GetTabContentsID(URLRequest* request,
return true;
}
-TabContents* tab_util::GetTabContentsByID(int render_process_id,
+WebContents* tab_util::GetWebContentsByID(int render_process_id,
int render_view_id) {
RenderViewHost* render_view_host =
RenderViewHost::FromID(render_process_id, render_view_id);
diff --git a/chrome/browser/tab_util.h b/chrome/browser/tab_util.h
index 9b576e5..6aa96f3 100644
--- a/chrome/browser/tab_util.h
+++ b/chrome/browser/tab_util.h
@@ -5,8 +5,8 @@
#ifndef CHROME_BROWSER_TAB_UTIL_H__
#define CHROME_BROWSER_TAB_UTIL_H__
-class TabContents;
class URLRequest;
+class WebContents;
namespace tab_util {
@@ -15,10 +15,10 @@ namespace tab_util {
bool GetTabContentsID(URLRequest* request, int* render_process_host_id,
int* routing_id);
-// Helper to find the TabContents that originated the given request. Can be
+// Helper to find the WebContents that originated the given request. Can be
// NULL if the tab has been closed or some other error occurs.
// Should only be called from the UI thread, since it accesses TabContent.
-TabContents* GetTabContentsByID(int render_process_host_id, int routing_id);
+WebContents* GetWebContentsByID(int render_process_host_id, int routing_id);
} // namespace tab_util
diff --git a/chrome/browser/task_manager_resource_providers.cc b/chrome/browser/task_manager_resource_providers.cc
index ceca70c..6e62e7a 100644
--- a/chrome/browser/task_manager_resource_providers.cc
+++ b/chrome/browser/task_manager_resource_providers.cc
@@ -85,12 +85,9 @@ TaskManager::Resource* TaskManagerWebContentsResourceProvider::GetResource(
int render_process_host_id,
int routing_id) {
- TabContents* tab_contents =
- tab_util::GetTabContentsByID(render_process_host_id, routing_id);
- if (!tab_contents) // Not one of our resource.
- return NULL;
- WebContents* web_contents = tab_contents->AsWebContents();
- if (!web_contents)
+ WebContents* web_contents =
+ tab_util::GetWebContentsByID(render_process_host_id, routing_id);
+ if (!web_contents) // Not one of our resource.
return NULL;
if (!web_contents->process()->process().handle()) {
diff --git a/chrome/browser/views/dom_view.cc b/chrome/browser/views/dom_view.cc
index ed8fa95..f6c92a8 100644
--- a/chrome/browser/views/dom_view.cc
+++ b/chrome/browser/views/dom_view.cc
@@ -27,8 +27,8 @@ bool DOMView::Init(Profile* profile, SiteInstance* instance) {
// a DOMUIHostFactory rather than TabContentsFactory, because DOMView's
// should only be associated with instances of DOMUIHost.
TabContentsType type = TabContents::TypeForURL(&contents_);
- TabContents* tab_contents = TabContents::CreateWithType(type, profile,
- instance);
+ TabContents* tab_contents = TabContents::CreateWithType(type, profile,
+ instance);
host_ = tab_contents->AsDOMUIHost();
DCHECK(host_);
diff --git a/chrome/browser/views/external_protocol_dialog.cc b/chrome/browser/views/external_protocol_dialog.cc
index aa9308d..f4aafcb 100644
--- a/chrome/browser/views/external_protocol_dialog.cc
+++ b/chrome/browser/views/external_protocol_dialog.cc
@@ -10,7 +10,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/external_protocol_handler.h"
#include "chrome/browser/tab_util.h"
-#include "chrome/browser/tab_contents.h"
+#include "chrome/browser/web_contents.h"
#include "chrome/common/l10n_util.h"
#include "chrome/views/message_box_view.h"
#include "chrome/views/window.h"
@@ -31,10 +31,10 @@ const int kMessageWidth = 400;
void ExternalProtocolDialog::RunExternalProtocolDialog(
const GURL& url, const std::wstring& command, int render_process_host_id,
int routing_id) {
- TabContents* tab_contents = tab_util::GetTabContentsByID(
+ WebContents* web_contents = tab_util::GetWebContentsByID(
render_process_host_id, routing_id);
ExternalProtocolDialog* handler =
- new ExternalProtocolDialog(tab_contents, url, command);
+ new ExternalProtocolDialog(web_contents, url, command);
}
ExternalProtocolDialog::~ExternalProtocolDialog() {
diff --git a/chrome/browser/views/external_protocol_dialog.h b/chrome/browser/views/external_protocol_dialog.h
index db23116..720ebae 100644
--- a/chrome/browser/views/external_protocol_dialog.h
+++ b/chrome/browser/views/external_protocol_dialog.h
@@ -17,7 +17,7 @@ class ExternalProtocolDialog : public views::DialogDelegate {
// |url| - The url of the request.
// |command| - the command that ShellExecute will run.
// |render_process_host_id| and |routing_id| are used by
- // tab_util::GetTabContentsByID to aquire the tab contents associated with
+ // tab_util::GetWebContentsByID to aquire the tab contents associated with
// this dialog.
// NOTE: There is a race between the Time of Check and the Time Of Use for
// the command line. Since the caller (web page) does not have access
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index 7bee9a5..5f1c124 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -19,7 +19,6 @@
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/find_notification_details.h"
#include "chrome/browser/google_util.h"
-#include "chrome/browser/interstitial_page.h"
#include "chrome/browser/js_before_unload_handler.h"
#include "chrome/browser/jsmessage_box_handler.h"
#include "chrome/browser/load_from_memory_cache_details.h"
@@ -590,7 +589,7 @@ void WebContents::SavePage(const std::wstring& main_file,
void WebContents::PrintPreview() {
// We can't print interstitial page for now.
- if (render_manager_.showing_interstitial_page())
+ if (showing_interstitial_page())
return;
// If we have a find bar it needs to hide as well.
@@ -602,7 +601,7 @@ void WebContents::PrintPreview() {
bool WebContents::PrintNow() {
// We can't print interstitial page for now.
- if (render_manager_.showing_interstitial_page())
+ if (showing_interstitial_page())
return false;
// If we have a find bar it needs to hide as well.
@@ -648,11 +647,7 @@ Profile* WebContents::GetProfile() const {
}
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 (rvh != render_view_host()) {
+ if (rvh != render_view_host()) {
// Don't notify the world, since this came from a renderer in the
// background.
return;
@@ -667,10 +662,7 @@ void WebContents::RendererGone(RenderViewHost* rvh) {
if (!printing_.OnRendererGone(rvh))
return;
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
- // RenderViewHost back in, in SwapToRenderView.
+ // The pending page's RenderViewHost is gone.
return;
}
@@ -691,27 +683,12 @@ void WebContents::DidNavigate(RenderViewHost* rvh,
if (PageTransition::IsMainFrame(params.transition))
render_manager_.DidNavigateMainFrame(rvh);
- // In the case of interstitial, we don't mess with the navigation entries.
- // TODO(brettw) this seems like a bug. What happens if the page goes and
- // does something on its own (or something that just got delayed), then
- // we won't have a navigation entry for that stuff when the interstitial
- // is hidden.
- if (render_manager_.showing_interstitial_page())
- return;
-
// We can't do anything about navigations when we're inactive.
if (!controller() || !is_active())
return;
- // 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.
- //
- // 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 (!GetSiteInstance()->has_site() &&
- !render_manager_.showing_interstitial_page())
+ // Update the site of the SiteInstance if it doesn't have one yet.
+ if (!GetSiteInstance()->has_site())
GetSiteInstance()->SetSite(params.url);
// Need to update MIME type here because it's referred to in
@@ -726,10 +703,7 @@ void WebContents::DidNavigate(RenderViewHost* rvh,
contents_mime_type_ = params.contents_mime_type;
NavigationController::LoadCommittedDetails details;
- if (!controller()->RendererDidNavigate(
- params,
- render_manager_.IsRenderViewInterstitial(rvh),
- &details))
+ if (!controller()->RendererDidNavigate(params, &details))
return; // No navigation happened.
// DO NOT ADD MORE STUFF TO THIS FUNCTION! Your component should either listen
@@ -746,18 +720,7 @@ void WebContents::DidNavigate(RenderViewHost* rvh,
void WebContents::UpdateState(RenderViewHost* rvh,
int32 page_id,
const std::string& state) {
- 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,
- // or that we are navigating from the interstitial and getting an update
- // for it.
- // - targeted at the interstitial page. Ignore it as we don't want to update
- // the fake navigation entry.
- return;
- }
-
+ DCHECK(rvh == render_view_host());
if (!controller())
return;
@@ -788,19 +751,10 @@ void WebContents::UpdateTitle(RenderViewHost* rvh,
// getting useful data.
SetNotWaitingForResponse();
- NavigationEntry* entry;
- 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 active entry,
- // so just use that.
- entry = controller()->GetActiveEntry();
- } else {
- entry = controller()->GetEntryWithPageID(type(), GetSiteInstance(),
- page_id);
- }
-
+ DCHECK(rvh == render_view_host());
+ NavigationEntry* entry = controller()->GetEntryWithPageID(type(),
+ GetSiteInstance(),
+ page_id);
if (!entry || !UpdateTitleForEntry(entry, title))
return;
@@ -879,11 +833,9 @@ void WebContents::DidStartProvisionalLoadForFrame(
RenderViewHost* render_view_host,
bool is_main_frame,
const GURL& url) {
- ProvisionalLoadDetails details(
- is_main_frame,
- render_manager_.IsRenderViewInterstitial(render_view_host),
- controller()->IsURLInPageNavigation(url),
- url, std::string(), false);
+ ProvisionalLoadDetails details(is_main_frame,
+ controller()->IsURLInPageNavigation(url),
+ url, std::string(), false);
NotificationService::current()->
Notify(NOTIFY_FRAME_PROVISIONAL_LOAD_START,
Source<NavigationController>(controller()),
@@ -928,8 +880,7 @@ void WebContents::DidFailProvisionalLoadWithError(
RenderViewHost* render_view_host,
bool is_main_frame,
int error_code,
- const GURL& url,
- bool showing_repost_interstitial) {
+ const GURL& url) {
if (!controller())
return;
@@ -952,7 +903,7 @@ void WebContents::DidFailProvisionalLoadWithError(
// in the previous tab type. If you navigate somewhere that activates the
// tab with the interstitial again, you'll see a flash before the new load
// commits of the interstitial page.
- if (render_manager_.showing_interstitial_page()) {
+ if (showing_interstitial_page()) {
LOG(WARNING) << "Discarding message during interstitial.";
return;
}
@@ -969,15 +920,11 @@ void WebContents::DidFailProvisionalLoadWithError(
}
// Send out a notification that we failed a provisional load with an error.
- ProvisionalLoadDetails details(
- is_main_frame,
- render_manager_.IsRenderViewInterstitial(render_view_host),
- controller()->IsURLInPageNavigation(url),
- url, std::string(), false);
+ ProvisionalLoadDetails details(is_main_frame,
+ controller()->IsURLInPageNavigation(url),
+ url, std::string(), false);
details.set_error_code(error_code);
- render_manager_.set_showing_repost_interstitial(showing_repost_interstitial);
-
NotificationService::current()->
Notify(NOTIFY_FAIL_PROVISIONAL_LOAD_WITH_ERROR,
Source<NavigationController>(controller()),
diff --git a/chrome/browser/web_contents.h b/chrome/browser/web_contents.h
index f7ed61e..359a294 100644
--- a/chrome/browser/web_contents.h
+++ b/chrome/browser/web_contents.h
@@ -124,32 +124,24 @@ class WebContents : public TabContents,
// 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();
+ return render_manager_.interstitial_page() != NULL;
}
- // Displays the specified interstitial 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.
- // |interstitial_page| is not owned by the WebContents.
- void ShowInterstitialPage(InterstitialPage* interstitial_page) {
- render_manager_.ShowInterstitialPage(interstitial_page);
+ // Sets the passed passed interstitial as the currently showing interstitial.
+ // |interstitial_page| should be non NULL (use the remove_interstitial_page
+ // method to unset the interstitial) and no interstitial page should be set
+ // when there is already a non NULL interstitial page set.
+ void set_interstitial_page(InterstitialPage* interstitial_page) {
+ render_manager_.set_interstitial_page(interstitial_page);
}
- // 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) {
- render_manager_.HideInterstitialPage(wait_for_navigation, proceed);
+ // Unsets the currently showing interstitial.
+ void remove_interstitial_page() {
+ render_manager_.remove_interstitial_page();
}
- // Returns the interstitial page currently shown if any, NULL otherwise.
+ // Returns the currently showing interstitial, NULL if no interstitial is
+ // showing.
InterstitialPage* interstitial_page() const {
return render_manager_.interstitial_page();
}
@@ -253,12 +245,10 @@ class WebContents : public TabContents,
const GURL& target_url);
virtual void DidLoadResourceFromMemoryCache(const GURL& url,
const std::string& security_info);
- virtual void DidFailProvisionalLoadWithError(
- RenderViewHost* render_view_host,
- bool is_main_frame,
- int error_code,
- const GURL& url,
- bool showing_repost_interstitial);
+ virtual void DidFailProvisionalLoadWithError(RenderViewHost* render_view_host,
+ bool is_main_frame,
+ int error_code,
+ const GURL& url);
virtual void UpdateFavIconURL(RenderViewHost* render_view_host,
int32 page_id, const GURL& icon_url);
virtual void DidDownloadImage(RenderViewHost* render_view_host,
@@ -368,6 +358,9 @@ class WebContents : public TabContents,
// Temporary until the view/contents separation is complete.
friend class WebContentsViewWin;
+ // So InterstitialPage can access SetIsLoading.
+ friend class InterstitialPage;
+
// When CreateShortcut is invoked RenderViewHost::GetApplicationInfo is
// invoked. CreateShortcut caches the state of the page needed to create the
// shortcut in PendingInstall. When OnDidGetApplicationInfo is invoked, it
diff --git a/chrome/browser/web_contents_unittest.cc b/chrome/browser/web_contents_unittest.cc
index 4811350..8f9ed31 100644
--- a/chrome/browser/web_contents_unittest.cc
+++ b/chrome/browser/web_contents_unittest.cc
@@ -16,11 +16,29 @@
#include "chrome/test/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
+static void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
+ int page_id,
+ const GURL& url) {
+ params->page_id = page_id;
+ params->url = url;
+ params->referrer = GURL::EmptyGURL();
+ params->transition = PageTransition::TYPED;
+ params->redirects = std::vector<GURL>();
+ params->should_update_history = false;
+ params->searchable_form_url = GURL::EmptyGURL();
+ params->searchable_form_element_name = std::wstring();
+ params->searchable_form_encoding = std::string();
+ params->password_form = PasswordForm();
+ params->security_info = std::string();
+ params->gesture = NavigationGestureUser;
+ params->is_post = false;
+}
+
// Subclass the RenderViewHost's view so that we can call Show(), etc.,
// without having side-effects.
class TestRenderWidgetHostView : public RenderWidgetHostView {
public:
- TestRenderWidgetHostView() {}
+ TestRenderWidgetHostView() : is_showing_(false) {}
virtual RenderWidgetHost* GetRenderWidgetHost() const { return NULL; }
virtual void DidBecomeSelected() {}
@@ -35,8 +53,8 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual void Blur() {}
virtual bool HasFocus() { return true; }
virtual void AdvanceFocus(bool reverse) {}
- virtual void Show() {}
- virtual void Hide() {}
+ virtual void Show() { is_showing_ = true; }
+ virtual void Hide() { is_showing_ = false; }
virtual gfx::Rect GetViewBounds() const { return gfx::Rect(); }
virtual void UpdateCursor(const WebCursor& cursor) {}
virtual void UpdateCursorIfOverSelf() {}
@@ -50,6 +68,11 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual void Destroy() {}
virtual void PrepareToDestroy() {}
virtual void SetTooltipText(const std::wstring& tooltip_text) {}
+
+ bool is_showing() const { return is_showing_; }
+
+ private:
+ bool is_showing_;
};
// Subclass RenderViewHost so that it does not create a process.
@@ -184,33 +207,10 @@ class TestWebContents : public WebContents {
return static_cast<TestRenderViewHost*>(
render_manager_.pending_render_view_host_);
}
- TestRenderViewHost* interstitial_rvh() {
- return static_cast<TestRenderViewHost*>(
- render_manager_.interstitial_render_view_host_);
- }
- TestRenderViewHost* original_rvh() {
- 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;
+
+ // State accessor.
+ bool cross_navigation_pending() {
+ return render_manager_.cross_navigation_pending_;
}
// Ensure we create TestRenderViewHosts that don't spawn processes.
@@ -250,28 +250,84 @@ class TestWebContents : public WebContents {
bool transition_cross_site;
};
-class WebContentsTest : public testing::Test {
+class TestInterstitialPage : public InterstitialPage {
public:
- WebContentsTest() : contents(NULL) {}
+ enum InterstitialState {
+ UNDECIDED = 0, // No decision taken yet.
+ OKED, // Proceed was called.
+ CANCELED // DontProceed was called.
+ };
+
+ TestInterstitialPage(WebContents* tab,
+ bool new_navigation,
+ const GURL& url,
+ InterstitialState* state,
+ bool* deleted)
+ : InterstitialPage(tab, new_navigation, url),
+ state_(state),
+ deleted_(deleted),
+ command_received_count_(0) {
+ *state_ = UNDECIDED;
+ *deleted_ = false;
+ }
+
+ virtual ~TestInterstitialPage() {
+ *deleted_ = true;
+ }
+
+ virtual void DontProceed() {
+ *state_ = CANCELED;
+ InterstitialPage::DontProceed();
+ }
+ virtual void Proceed() {
+ *state_ = OKED;
+ InterstitialPage::Proceed();
+ }
+
+ int command_received_count() const {
+ return command_received_count_;
+ }
- void InitNavigateParams(ViewHostMsg_FrameNavigate_Params* params,
- int pageID,
- const GURL& url) {
- params->page_id = pageID;
- params->url = url;
- params->referrer = GURL::EmptyGURL();
- params->transition = PageTransition::TYPED;
- params->redirects = std::vector<GURL>();
- params->should_update_history = false;
- params->searchable_form_url = GURL::EmptyGURL();
- params->searchable_form_element_name = std::wstring();
- params->searchable_form_encoding = std::string();
- params->password_form = PasswordForm();
- params->security_info = std::string();
- params->gesture = NavigationGestureUser;
- params->is_post = false;
+ void TestDomOperationResponse(const std::string& json_string) {
+ DomOperationResponse(json_string, 1);
}
+ void TestDidNavigate(int page_id, const GURL& url) {
+ ViewHostMsg_FrameNavigate_Params params;
+ InitNavigateParams(&params, page_id, url);
+ DidNavigate(render_view_host(), params);
+ }
+
+ void TestRendererGone() {
+ RendererGone(render_view_host());
+ }
+
+ bool is_showing() const {
+ return static_cast<TestRenderWidgetHostView*>(render_view_host()->view())->
+ is_showing();
+ }
+
+ protected:
+ virtual RenderViewHost* CreateRenderViewHost() {
+ return new TestRenderViewHost(
+ SiteInstance::CreateSiteInstance(tab()->profile()),
+ this, MSG_ROUTING_NONE, NULL);
+ }
+
+ virtual void CommandReceived(const std::string& command) {
+ command_received_count_++;
+ }
+
+ private:
+ InterstitialState* state_;
+ bool* deleted_;
+ int command_received_count_;
+};
+
+class WebContentsTest : public testing::Test {
+ public:
+ WebContentsTest() : contents(NULL) {}
+
// testing::Test methods:
virtual void SetUp() {
@@ -286,6 +342,7 @@ class WebContentsTest : public testing::Test {
virtual void TearDown() {
// This will delete the contents.
+ if (contents)
contents->CloseContents();
// Make sure that we flush any messages related to WebContents destruction
@@ -293,6 +350,13 @@ class WebContentsTest : public testing::Test {
MessageLoop::current()->RunAllPending();
}
+ void Navigate(int page_id, const GURL& url) {
+ DCHECK(contents);
+ ViewHostMsg_FrameNavigate_Params params;
+ InitNavigateParams(&params, page_id, url);
+ contents->TestDidNavigate(contents->rvh(), params);
+ }
+
scoped_ptr<WebContentsTestingProfile> profile;
TestWebContents* contents;
@@ -306,9 +370,9 @@ TEST_F(WebContentsTest, UpdateTitle) {
InitNavigateParams(&params, 0, GURL("about:blank"));
NavigationController::LoadCommittedDetails details;
- contents->controller()->RendererDidNavigate(params, false, &details);
+ contents->controller()->RendererDidNavigate(params, &details);
- contents->UpdateTitle(NULL, 0, L" Lots O' Whitespace\n");
+ contents->UpdateTitle(contents->rvh(), 0, L" Lots O' Whitespace\n");
EXPECT_EQ(std::wstring(L"Lots O' Whitespace"), contents->GetTitle());
}
@@ -317,14 +381,12 @@ TEST_F(WebContentsTest, SimpleNavigation) {
TestRenderViewHost* orig_rvh = contents->rvh();
SiteInstance* instance1 = contents->GetSiteInstance();
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
EXPECT_FALSE(orig_rvh->is_loading);
// Navigate to URL
const GURL url("http://www.google.com");
contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
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
@@ -336,7 +398,7 @@ TEST_F(WebContentsTest, SimpleNavigation) {
ViewHostMsg_FrameNavigate_Params params;
InitNavigateParams(&params, 1, url);
contents->TestDidNavigate(orig_rvh, params);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
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
@@ -345,260 +407,6 @@ TEST_F(WebContentsTest, SimpleNavigation) {
contents->controller()->GetActiveEntry()->site_instance());
}
-// Test navigating to a page that shows an interstitial, then hiding it
-// without proceeding.
-TEST_F(WebContentsTest, ShowInterstitialDontProceed) {
- TestRenderViewHost* orig_rvh = contents->rvh();
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
- EXPECT_FALSE(orig_rvh->is_loading);
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_TRUE(orig_rvh->is_loading);
-
- // Show interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- 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);
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params;
- InitNavigateParams(&params, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params);
- 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_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);
-}
-
-// Test navigating to a page that shows an interstitial, then proceeding.
-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());
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
-
- // Show interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params;
- InitNavigateParams(&params, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params);
-
- // Ensure this DidNavigate hasn't changed the SiteInstance's site.
- // Prevents regression for bug 1163298.
- EXPECT_EQ(GURL(), contents->rvh()->site_instance()->site());
-
- // Hide interstitial (proceed and wait)
- contents->HideInterstitialPage(true, true);
- 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_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);
-
- // The SiteInstance's site should now be updated.
- EXPECT_EQ(GURL("http://google.com"),
- contents->rvh()->site_instance()->site());
-
- // Since we weren't viewing a page before, we shouldn't be able to go back.
- EXPECT_FALSE(contents->controller()->CanGoBack());
-}
-
-// Test navigating to a page that shows an interstitial, then navigating away.
-TEST_F(WebContentsTest, ShowInterstitialThenNavigate) {
- TestRenderViewHost* orig_rvh = contents->rvh();
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
-
- // Show interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params;
- InitNavigateParams(&params, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params);
-
- // While interstitial showing, navigate to a new URL.
- const GURL url2("http://www.yahoo.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- 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);
-
- // DidNavigate from the new URL. In the old process model, we'll still have
- // the same RenderViewHost.
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 2, url2);
- contents->TestDidNavigate(orig_rvh, params2);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_FALSE(orig_rvh->is_loading);
-}
-
-// Ensures that an interstitial cannot be cancelled if a notification for a
-// navigation from an IFrame from the previous page is received while the
-// interstitial is being shown (bug #1182394).
-TEST_F(WebContentsTest, ShowInterstitialIFrameNavigate) {
- TestRenderViewHost* orig_rvh = contents->rvh();
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
- EXPECT_FALSE(orig_rvh->is_loading);
-
- // Navigate to URL.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_TRUE(orig_rvh->is_loading);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Show interstitial (in real world would probably be triggered by a resource
- // in the page).
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- EXPECT_TRUE(contents->state_is_entering_interstitial());
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
- EXPECT_TRUE(interstitial_rvh->is_loading);
-
- // DidNavigate from an IFrame in the initial page.
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, GURL("http://www.iframe.com"));
- params2.transition = PageTransition::AUTO_SUBFRAME;
- contents->TestDidNavigate(orig_rvh, params2);
-
- // Now we get the DidNavigate from the interstitial.
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params3);
- 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);
-}
-
-// Test navigating to an interstitial page from a normal page. Also test
-// visiting the interstitial-inducing URL twice (bug 1079784), and test
-// that going back shows the first page and not the interstitial.
-TEST_F(WebContentsTest, VisitInterstitialURLTwice) {
- TestRenderViewHost* orig_rvh = contents->rvh();
-
- // Navigate to URL
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Now navigate to an interstitial-inducing URL
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- 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);
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 2, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- 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, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_leaving_interstitial());
- EXPECT_EQ(interstitial_rvh, contents->render_view_host());
-
- // Interstitial shown a second time in a different RenderViewHost.
- interstitial = new InterstitialPage(contents, true, interstitial_url);
- interstitial->Show();
- 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();
- interstitial_rvh2->set_delete_counter(&interstitial_delete_counter);
-
- // DidNavigate from the interstitial.
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 3, url2);
- contents->TestDidNavigate(interstitial_rvh2, params3);
- 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_TRUE(contents->state_is_leaving_interstitial());
- ViewHostMsg_FrameNavigate_Params params4;
- InitNavigateParams(&params4, 3, url2);
- contents->TestDidNavigate(orig_rvh, params4);
- 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_TRUE(contents->state_is_normal());
-
- // DidNavigate from going back.
- contents->TestDidNavigate(orig_rvh, params1);
- 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);
-}
-
// Test that navigating across a site boundary creates a new RenderViewHost
// with a new SiteInstance. Going back should do the same.
TEST_F(WebContentsTest, CrossSiteBoundaries) {
@@ -615,15 +423,13 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
// Navigate to new site
const GURL url2("http://www.yahoo.com");
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_pending());
+ EXPECT_TRUE(contents->cross_navigation_pending());
TestRenderViewHost* pending_rvh = contents->pending_rvh();
int pending_rvh_delete_count = 0;
pending_rvh->set_delete_counter(&pending_rvh_delete_count);
@@ -634,23 +440,21 @@ TEST_F(WebContentsTest, CrossSiteBoundaries) {
contents->TestDidNavigate(pending_rvh, params2);
SiteInstance* instance2 = contents->GetSiteInstance();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(pending_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
EXPECT_EQ(orig_rvh_delete_count, 1);
// Going back should switch SiteInstances again. The first SiteInstance is
// stored in the NavigationEntry, so it should be the same as at the start.
contents->controller()->GoBack();
TestRenderViewHost* goback_rvh = contents->pending_rvh();
- EXPECT_TRUE(contents->state_is_pending());
+ EXPECT_TRUE(contents->cross_navigation_pending());
// DidNavigate from the back action
contents->TestDidNavigate(goback_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(goback_rvh, contents->render_view_host());
EXPECT_EQ(pending_rvh_delete_count, 1);
EXPECT_EQ(instance1, contents->GetSiteInstance());
@@ -672,10 +476,8 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
// Crash the renderer.
orig_rvh->is_created = false;
@@ -684,10 +486,8 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
const GURL url2("http://www.yahoo.com");
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
TestRenderViewHost* new_rvh = contents->rvh();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
EXPECT_NE(orig_rvh, new_rvh);
EXPECT_EQ(orig_rvh_delete_count, 1);
@@ -697,330 +497,10 @@ TEST_F(WebContentsTest, CrossSiteBoundariesAfterCrash) {
contents->TestDidNavigate(new_rvh, params2);
SiteInstance* instance2 = contents->GetSiteInstance();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(new_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-}
-
-// Test state transitions when showing an interstitial in the new process
-// model, and then choosing DontProceed.
-TEST_F(WebContentsTest, CrossSiteInterstitialDontProceed) {
- contents->transition_cross_site = true;
- TestRenderViewHost* orig_rvh = contents->rvh();
- SiteInstance* instance1 = contents->GetSiteInstance();
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- 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, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_pending());
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- 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();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 2, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- 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());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Hide interstitial (don't proceed)
- contents->HideInterstitialPage(false, false);
- 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);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-}
-
-// Test state transitions when showing an interstitial in the new process
-// model, and then choosing Proceed.
-TEST_F(WebContentsTest, CrossSiteInterstitialProceed) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
- SiteInstance* instance1 = contents->GetSiteInstance();
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Navigate to new site
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
- int pending_rvh_delete_count = 0;
- pending_rvh->set_delete_counter(&pending_rvh_delete_count);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- 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());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Hide interstitial (proceed and wait)
- contents->HideInterstitialPage(true, true);
- 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());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // DidNavigate from the destination page should transition to new renderer
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 2, url2);
- contents->TestDidNavigate(pending_rvh, params3);
- SiteInstance* instance2 = contents->GetSiteInstance();
- 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);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
- EXPECT_NE(instance1, instance2);
- EXPECT_EQ(orig_rvh_delete_count, 1); // The original should be gone.
-
- // Since we were viewing a page before, we should be able to go back.
- EXPECT_TRUE(contents->controller()->CanGoBack());
-
- // Going back should switch SiteInstances again. The first SiteInstance is
- // stored in the NavigationEntry, so it should be the same as at the start.
- contents->controller()->GoBack();
- TestRenderViewHost* goback_rvh = contents->pending_rvh();
- EXPECT_TRUE(contents->state_is_pending());
-
- // DidNavigate from the back action
- contents->TestDidNavigate(goback_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(goback_rvh, contents->render_view_host());
- EXPECT_EQ(instance1, contents->GetSiteInstance());
- EXPECT_EQ(pending_rvh_delete_count, 1); // The second page's rvh should die.
-}
-
-// Tests that we can transition away from an interstitial page.
-TEST_F(WebContentsTest, CrossSiteInterstitialThenNavigate) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- false,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url);
- contents->TestDidNavigate(interstitial_rvh, params2);
- 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);
-
- // Navigate to a new page.
- const GURL url2("http://www.yahoo.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
-
- TestRenderViewHost* new_rvh = contents->pending_rvh();
- ASSERT_TRUE(new_rvh != NULL);
- // Make sure the RVH is not suspended (bug #1236441).
- EXPECT_FALSE(new_rvh->IsNavigationSuspended());
- 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_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);
-}
-
-// Tests that we can transition away from an interstitial page even if the
-// interstitial renderer has crashed.
-TEST_F(WebContentsTest, CrossSiteInterstitialCrashThenNavigate) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Navigate to new site
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
- int pending_rvh_delete_count = 0;
- pending_rvh->set_delete_counter(&pending_rvh_delete_count);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- 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());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Crash the interstitial RVH
- // (by making IsRenderViewLive() == false)
- interstitial_rvh->is_created = false;
-
- // Navigate to a new page. Since interstitial RVH is dead, we should clean
- // it up and go to a new PENDING state, showing the orig_rvh.
- const GURL url3("http://www.yahoo.com");
- contents->controller()->LoadURL(url3, GURL(), PageTransition::TYPED);
- TestRenderViewHost* new_rvh = contents->pending_rvh();
- ASSERT_TRUE(new_rvh != NULL);
- 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);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // DidNavigate from the new page
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 1, url3);
- contents->TestDidNavigate(new_rvh, params3);
- 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);
-}
-
-// Tests that we can transition away from an interstitial page even if both the
-// original and interstitial renderers have crashed.
-TEST_F(WebContentsTest, CrossSiteInterstitialCrashesThenNavigate) {
- contents->transition_cross_site = true;
- int orig_rvh_delete_count = 0;
- TestRenderViewHost* orig_rvh = contents->rvh();
- orig_rvh->set_delete_counter(&orig_rvh_delete_count);
-
- // Navigate to URL. First URL should use first RenderViewHost.
- const GURL url("http://www.google.com");
- contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
- ViewHostMsg_FrameNavigate_Params params1;
- InitNavigateParams(&params1, 1, url);
- contents->TestDidNavigate(orig_rvh, params1);
-
- // Navigate to new site
- const GURL url2("https://www.google.com");
- contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- TestRenderViewHost* pending_rvh = contents->pending_rvh();
- int pending_rvh_delete_count = 0;
- pending_rvh->set_delete_counter(&pending_rvh_delete_count);
-
- // Show an interstitial
- const GURL interstitial_url("http://interstitial");
- InterstitialPage* interstitial = new InterstitialPage(contents,
- true,
- interstitial_url);
- interstitial->Show();
- TestRenderViewHost* interstitial_rvh = contents->interstitial_rvh();
-
- // DidNavigate from the interstitial
- ViewHostMsg_FrameNavigate_Params params2;
- InitNavigateParams(&params2, 1, url2);
- contents->TestDidNavigate(interstitial_rvh, params2);
- 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());
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // Crash both the original and interstitial RVHs
- // (by making IsRenderViewLive() == false)
- orig_rvh->is_created = false;
- interstitial_rvh->is_created = false;
-
- // Navigate to a new page. Since both the interstitial and original RVHs are
- // dead, we should create a new RVH, jump back to NORMAL, and navigate.
- const GURL url3("http://www.yahoo.com");
- contents->controller()->LoadURL(url3, GURL(), PageTransition::TYPED);
- TestRenderViewHost* new_rvh = contents->rvh();
- ASSERT_TRUE(new_rvh != NULL);
- 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);
- EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
-
- // DidNavigate from the new page
- ViewHostMsg_FrameNavigate_Params params3;
- InitNavigateParams(&params3, 1, url3);
- contents->TestDidNavigate(new_rvh, params3);
- EXPECT_TRUE(contents->state_is_normal());
- EXPECT_EQ(new_rvh, contents->render_view_host());
}
// Test that opening a new tab in the same SiteInstance and then navigating
@@ -1062,7 +542,7 @@ TEST_F(WebContentsTest, NavigateTwoTabsCrossSite) {
contents2->controller()->LoadURL(url2b, GURL(), PageTransition::TYPED);
TestRenderViewHost* pending_rvh_b = contents2->pending_rvh();
EXPECT_TRUE(pending_rvh_b != NULL);
- EXPECT_TRUE(contents2->state_is_pending());
+ EXPECT_TRUE(contents2->cross_navigation_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
@@ -1100,16 +580,16 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
contents2->SetupController(profile.get());
const GURL url2("http://www.yahoo.com");
contents2->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
- // The first RVH in contents2 isn't live yet, so we shortcut the PENDING
- // state and go straight to NORMAL.
+ // The first RVH in contents2 isn't live yet, so we shortcut the cross site
+ // pending.
TestRenderViewHost* rvh2 = contents2->rvh();
- EXPECT_TRUE(contents2->state_is_normal());
+ EXPECT_FALSE(contents2->cross_navigation_pending());
ViewHostMsg_FrameNavigate_Params params2;
InitNavigateParams(&params2, 2, url2);
contents2->TestDidNavigate(rvh2, params2);
SiteInstance* instance2 = contents2->GetSiteInstance();
EXPECT_NE(instance1, instance2);
- EXPECT_TRUE(contents2->state_is_normal());
+ EXPECT_FALSE(contents2->cross_navigation_pending());
// Simulate a link click in first tab to second site. Doesn't switch
// SiteInstances, because we don't intercept WebKit navigations.
@@ -1118,13 +598,13 @@ TEST_F(WebContentsTest, CrossSiteComparesAgainstCurrentPage) {
contents->TestDidNavigate(orig_rvh, params3);
SiteInstance* instance3 = contents->GetSiteInstance();
EXPECT_EQ(instance1, instance3);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
// 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, GURL(), PageTransition::TYPED);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
ViewHostMsg_FrameNavigate_Params params4;
InitNavigateParams(&params4, 3, url3);
contents->TestDidNavigate(orig_rvh, params4);
@@ -1147,7 +627,7 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
ViewHostMsg_FrameNavigate_Params params1;
InitNavigateParams(&params1, 1, url);
contents->TestDidNavigate(orig_rvh, params1);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
// Navigate to new site, but simulate an onbeforeunload denial.
@@ -1155,13 +635,13 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
orig_rvh->immediate_before_unload = false;
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
orig_rvh->TestOnMsgShouldClose(false);
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(orig_rvh, contents->render_view_host());
// Navigate again, but simulate an onbeforeunload approval.
contents->controller()->LoadURL(url2, GURL(), PageTransition::TYPED);
orig_rvh->TestOnMsgShouldClose(true);
- EXPECT_TRUE(contents->state_is_pending());
+ EXPECT_TRUE(contents->cross_navigation_pending());
TestRenderViewHost* pending_rvh = contents->pending_rvh();
// We won't hear DidNavigate until the onunload handler has finished running.
@@ -1173,12 +653,10 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) {
InitNavigateParams(&params2, 1, url2);
contents->TestDidNavigate(pending_rvh, params2);
SiteInstance* instance2 = contents->GetSiteInstance();
- EXPECT_TRUE(contents->state_is_normal());
+ EXPECT_FALSE(contents->cross_navigation_pending());
EXPECT_EQ(pending_rvh, contents->render_view_host());
EXPECT_NE(instance1, instance2);
EXPECT_TRUE(contents->pending_rvh() == NULL);
- EXPECT_TRUE(contents->original_rvh() == NULL);
- EXPECT_TRUE(contents->interstitial_rvh() == NULL);
}
// Test that NavigationEntries have the correct content state after going
@@ -1253,3 +731,472 @@ TEST_F(WebContentsTest, WebKitPrefs) {
EXPECT_EQ(true, webkit_prefs.javascript_enabled);
}
+////////////////////////////////////////////////////////////////////////////////
+// Interstitial Tests
+////////////////////////////////////////////////////////////////////////////////
+
+// Test navigating to a page (with the navigation initiated from the browser,
+// as when a URL is typed in the location bar) that shows an interstitial and
+// creates a new navigation entry, then hiding it without proceeding.
+TEST_F(WebContentsTest,
+ ShowInterstitialFromBrowserWithNewNavigationDontProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Initiate a browser navigation that will trigger the interstitial
+ contents->controller()->LoadURL(GURL("http://www.evil.com"), GURL(),
+ PageTransition::TYPED);
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Now don't proceed.
+ interstitial->DontProceed();
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page (with the navigation initiated from the renderer,
+// as when clicking on a link in the page) that shows an interstitial and
+// creates a new navigation entry, then hiding it without proceeding.
+TEST_F(WebContentsTest,
+ ShowInterstitiaFromRendererlWithNewNavigationDontProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial (no pending entry, the interstitial would have been
+ // triggered by clicking on a link).
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Now don't proceed.
+ interstitial->DontProceed();
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page that shows an interstitial without creating a new
+// navigation entry (this happens when the interstitial is triggered by a
+// sub-resource in the page), then hiding it without proceeding.
+TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationDontProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, false, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ // The URL specified to the interstitial should have been ignored.
+ EXPECT_TRUE(entry->url() == url1);
+
+ // Now don't proceed.
+ interstitial->DontProceed();
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page (with the navigation initiated from the browser,
+// as when a URL is typed in the location bar) that shows an interstitial and
+// creates a new navigation entry, then proceeding.
+TEST_F(WebContentsTest, ShowInterstitialFromBrowserNewNavigationProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Initiate a browser navigation that will trigger the interstitial
+ contents->controller()->LoadURL(GURL("http://www.evil.com"), GURL(),
+ PageTransition::TYPED);
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Then proceed.
+ interstitial->Proceed();
+ // The interstitial should show until the new navigation commits.
+ ASSERT_FALSE(deleted);
+ EXPECT_EQ(TestInterstitialPage::OKED, state);
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+
+ // Simulate the navigation to the page, that's when the interstitial gets
+ // hidden.
+ GURL url3("http://www.thepage.com");
+ Navigate(2, url3);
+
+ EXPECT_TRUE(deleted);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url3);
+
+ EXPECT_EQ(2, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page (with the navigation initiated from the renderer,
+// as when clicking on a link in the page) that shows an interstitial and
+// creates a new navigation entry, then proceeding.
+TEST_F(WebContentsTest, ShowInterstitialFromRendererNewNavigationProceed) {
+ // Navigate to a page.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url2);
+
+ // Then proceed.
+ interstitial->Proceed();
+ // The interstitial should show until the new navigation commits.
+ ASSERT_FALSE(deleted);
+ EXPECT_EQ(TestInterstitialPage::OKED, state);
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+
+ // Simulate the navigation to the page, that's when the interstitial gets
+ // hidden.
+ GURL url3("http://www.thepage.com");
+ Navigate(2, url3);
+
+ EXPECT_TRUE(deleted);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url3);
+
+ EXPECT_EQ(2, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page that shows an interstitial without creating a new
+// navigation entry (this happens when the interstitial is triggered by a
+// sub-resource in the page), then proceeding.
+TEST_F(WebContentsTest, ShowInterstitialNoNewNavigationProceed) {
+ // Navigate to a page so we have a navigation entry in the controller.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, false, url2, &state, &deleted);
+ interstitial->Show();
+ // The interstitial should not show until its navigation has committed.
+ EXPECT_FALSE(interstitial->is_showing());
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ // Let's commit the interstitial navigation.
+ interstitial->TestDidNavigate(1, url2);
+ EXPECT_TRUE(interstitial->is_showing());
+ EXPECT_TRUE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == interstitial);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ // The URL specified to the interstitial should have been ignored.
+ EXPECT_TRUE(entry->url() == url1);
+
+ // Then proceed.
+ interstitial->Proceed();
+ // Since this is not a new navigation, the previous page is dismissed right
+ // away and shows the original page.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::OKED, state);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == url1);
+
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+}
+
+// Test navigating to a page that shows an interstitial, then navigating away.
+TEST_F(WebContentsTest, ShowInterstitialThenNavigate) {
+ // Show interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url);
+
+ // While interstitial showing, navigate to a new URL.
+ const GURL url2("http://www.yahoo.com");
+ Navigate(1, url2);
+
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}
+
+// Test navigating to a page that shows an interstitial, then close the tab.
+TEST_F(WebContentsTest, ShowInterstitialThenCloseTab) {
+ // Show interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url);
+
+ // Now close the tab.
+ contents->CloseContents();
+ contents = NULL; // So we don't detroy it again on TearDown.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}
+
+// Test that after Proceed is called and an interstitial is still shown, no more
+// commands get executed.
+TEST_F(WebContentsTest, ShowInterstitialProceedMultipleCommands) {
+ // Navigate to a page so we have a navigation entry in the controller.
+ GURL url1("http://www.google.com");
+ Navigate(1, url1);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url2("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url2, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url2);
+
+ // Run a command.
+ EXPECT_EQ(0, interstitial->command_received_count());
+ interstitial->TestDomOperationResponse("toto");
+ EXPECT_EQ(1, interstitial->command_received_count());
+
+ // Then proceed.
+ interstitial->Proceed();
+ ASSERT_FALSE(deleted);
+
+ // While the navigation to the new page is pending, send other commands, they
+ // should be ignored.
+ interstitial->TestDomOperationResponse("hello");
+ interstitial->TestDomOperationResponse("hi");
+ EXPECT_EQ(1, interstitial->command_received_count());
+}
+
+// Test showing an interstitial while another interstitial is already showing.
+TEST_F(WebContentsTest, ShowInterstitialOnInterstitial) {
+ // Navigate to a page so we have a navigation entry in the controller.
+ GURL start_url("http://www.google.com");
+ Navigate(1, start_url);
+ EXPECT_EQ(1, contents->controller()->GetEntryCount());
+
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state1 =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted1 = false;
+ GURL url1("http://interstitial1");
+ TestInterstitialPage* interstitial1 =
+ new TestInterstitialPage(contents, true, url1, &state1, &deleted1);
+ interstitial1->Show();
+ interstitial1->TestDidNavigate(1, url1);
+
+ // Now show another interstitial.
+ TestInterstitialPage::InterstitialState state2 =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted2 = false;
+ GURL url2("http://interstitial2");
+ TestInterstitialPage* interstitial2 =
+ new TestInterstitialPage(contents, true, url2, &state2, &deleted2);
+ interstitial2->Show();
+ interstitial2->TestDidNavigate(1, url2);
+
+ // Showing interstitial2 should have caused interstitial1 to go away.
+ EXPECT_TRUE(deleted1);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state1);
+
+ // Let's make sure interstitial2 is working as intended.
+ ASSERT_FALSE(deleted2);
+ EXPECT_EQ(TestInterstitialPage::UNDECIDED, state2);
+ interstitial2->Proceed();
+ GURL landing_url("http://www.thepage.com");
+ Navigate(2, landing_url);
+
+ EXPECT_TRUE(deleted2);
+ EXPECT_FALSE(contents->showing_interstitial_page());
+ EXPECT_TRUE(contents->interstitial_page() == NULL);
+ NavigationEntry* entry = contents->controller()->GetActiveEntry();
+ ASSERT_TRUE(entry != NULL);
+ EXPECT_TRUE(entry->url() == landing_url);
+ EXPECT_EQ(2, contents->controller()->GetEntryCount());
+}
+
+// Test that navigating away from an interstitial while it's loading cause it
+// not to show.
+TEST_F(WebContentsTest, NavigateBeforeInterstitialShows) {
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL interstitial_url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, interstitial_url,
+ &state, &deleted);
+ interstitial->Show();
+
+ // Let's simulate a navigation initiated from the browser before the
+ // interstitial finishes loading.
+ const GURL url("http://www.google.com");
+ contents->controller()->LoadURL(url, GURL(), PageTransition::TYPED);
+ ASSERT_FALSE(deleted);
+ EXPECT_FALSE(interstitial->is_showing());
+
+ // Now let's make the interstitial navigation commit.
+ interstitial->TestDidNavigate(1, interstitial_url);
+
+ // After it loaded the interstitial should be gone.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}
+
+// Test showing an interstitial and have its renderer crash.
+TEST_F(WebContentsTest, InterstitialCrasher) {
+ // Show an interstitial.
+ TestInterstitialPage::InterstitialState state =
+ TestInterstitialPage::UNDECIDED;
+ bool deleted = false;
+ GURL url("http://interstitial");
+ TestInterstitialPage* interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ // Simulate a renderer crash before the interstitial is shown.
+ interstitial->TestRendererGone();
+ // The interstitial should have been dismissed.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+
+ // Now try again but this time crash the intersitial after it was shown.
+ interstitial =
+ new TestInterstitialPage(contents, true, url, &state, &deleted);
+ interstitial->Show();
+ interstitial->TestDidNavigate(1, url);
+ // Simulate a renderer crash.
+ interstitial->TestRendererGone();
+ // The interstitial should have been dismissed.
+ EXPECT_TRUE(deleted);
+ EXPECT_EQ(TestInterstitialPage::CANCELED, state);
+}
diff --git a/chrome/browser/web_contents_view_win.cc b/chrome/browser/web_contents_view_win.cc
index e97f6ac..dda346c 100644
--- a/chrome/browser/web_contents_view_win.cc
+++ b/chrome/browser/web_contents_view_win.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_request_manager.h"
+#include "chrome/browser/interstitial_page.h"
#include "chrome/browser/render_view_context_menu.h"
#include "chrome/browser/render_view_context_menu_controller.h"
#include "chrome/browser/render_view_host.h"
@@ -595,6 +596,8 @@ void WebContentsViewWin::WasShown() {
}
void WebContentsViewWin::WasSized(const gfx::Size& size) {
+ if (web_contents_->interstitial_page())
+ web_contents_->interstitial_page()->SetSize(size);
if (web_contents_->render_widget_host_view())
web_contents_->render_widget_host_view()->SetSize(size);
if (find_bar_.get())
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj
index 68a9a81..5302d98 100644
--- a/chrome/chrome.xcodeproj/project.pbxproj
+++ b/chrome/chrome.xcodeproj/project.pbxproj
@@ -93,7 +93,6 @@
4D7BFAEF0E9D49E7009A6919 /* chunk_range.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFAD10E9D49DE009A6919 /* chunk_range.cc */; };
4D7BFAF10E9D49EB009A6919 /* protocol_parser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFAD80E9D49DE009A6919 /* protocol_parser.cc */; };
4D7BFAF30E9D49EF009A6919 /* safe_browsing_database.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFADD0E9D49DE009A6919 /* safe_browsing_database.cc */; };
- 4D7BFAF40E9D49F3009A6919 /* safe_browsing_service.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFAE50E9D49DE009A6919 /* safe_browsing_service.cc */; };
4D7BFAF60E9D49F6009A6919 /* safe_browsing_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFAE70E9D49DE009A6919 /* safe_browsing_util.cc */; };
4D7BFB350E9D4C18009A6919 /* chrome_thread_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF8610E9D4839009A6919 /* chrome_thread_unittest.cc */; };
4D7BFB3C0E9D4C25009A6919 /* history_types_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF9F80E9D48F7009A6919 /* history_types_unittest.cc */; };
@@ -3173,7 +3172,6 @@
4D7BFAF30E9D49EF009A6919 /* safe_browsing_database.cc in Sources */,
E48FB9590EC4E9C10052B72B /* safe_browsing_database_bloom.cc in Sources */,
E48FB95C0EC4E9DD0052B72B /* safe_browsing_database_impl.cc in Sources */,
- 4D7BFAF40E9D49F3009A6919 /* safe_browsing_service.cc in Sources */,
4D7BFAF60E9D49F6009A6919 /* safe_browsing_util.cc in Sources */,
4D7BF9E10E9D48D6009A6919 /* save_file.cc in Sources */,
E4F324650EE5D082002533CE /* sdch_dictionary_fetcher.cc in Sources */,
diff --git a/chrome/test/test_tab_contents.cc b/chrome/test/test_tab_contents.cc
index 7b43b76..0cb8f54 100644
--- a/chrome/test/test_tab_contents.cc
+++ b/chrome/test/test_tab_contents.cc
@@ -34,5 +34,5 @@ void TestTabContents::CompleteNavigationAsRenderer(int page_id,
params.is_post = false;
NavigationController::LoadCommittedDetails details;
- controller()->RendererDidNavigate(params, false, &details);
+ controller()->RendererDidNavigate(params, &details);
}