diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-19 00:42:30 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-19 00:42:30 +0000 |
commit | a3a1d14240d6e41a0b6732ebcd3600399c64b26a (patch) | |
tree | a38ced2761bdf4447bf180470fd5dade857ef11b /chrome | |
parent | 5b62083c99317965244123c031c707d53f0a03f1 (diff) | |
download | chromium_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')
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(¶ms, 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(¶ms, page_id, url); + contents->TestDidNavigate(contents->rvh(), params); + } + scoped_ptr<WebContentsTestingProfile> profile; TestWebContents* contents; @@ -306,9 +370,9 @@ TEST_F(WebContentsTest, UpdateTitle) { InitNavigateParams(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms, 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(¶ms2, 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(¶ms1, 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(¶ms2, 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(¶ms3, 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(¶ms1, 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(¶ms2, 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(¶ms3, 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(¶ms4, 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(¶ms1, 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(¶ms1, 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(¶ms1, 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(¶ms2, 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(¶ms1, 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(¶ms2, 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(¶ms3, 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(¶ms1, 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(¶ms2, 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(¶ms3, 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(¶ms1, 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(¶ms2, 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(¶ms3, 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(¶ms1, 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(¶ms2, 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(¶ms3, 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(¶ms2, 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(¶ms4, 3, url3); contents->TestDidNavigate(orig_rvh, params4); @@ -1147,7 +627,7 @@ TEST_F(WebContentsTest, CrossSiteUnloadHandlers) { ViewHostMsg_FrameNavigate_Params params1; InitNavigateParams(¶ms1, 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(¶ms2, 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); } |