diff options
author | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-22 21:15:13 +0000 |
---|---|---|
committer | jennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-22 21:15:13 +0000 |
commit | ed56a7a029ec8515ab30ba13ee1dcdb4721c32d4 (patch) | |
tree | 7715b5adfb7fe112484758d1fe8640b083b9ec39 | |
parent | 9fc1e6c183707ebde09cb0057f528646f309b32d (diff) | |
download | chromium_src-ed56a7a029ec8515ab30ba13ee1dcdb4721c32d4.zip chromium_src-ed56a7a029ec8515ab30ba13ee1dcdb4721c32d4.tar.gz chromium_src-ed56a7a029ec8515ab30ba13ee1dcdb4721c32d4.tar.bz2 |
Keep crashed extension info bar across page navigations and close all when extension is reloaded.
BUG=28759
TEST=Added new extension crash recovery tests.
Review URL: http://codereview.chromium.org/5909002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69980 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/crashed_extension_infobar.cc | 5 | ||||
-rw-r--r-- | chrome/browser/extensions/crashed_extension_infobar.h | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_crash_recovery_browsertest.cc | 127 | ||||
-rw-r--r-- | chrome/browser/ui/browser.cc | 23 |
4 files changed, 146 insertions, 11 deletions
diff --git a/chrome/browser/extensions/crashed_extension_infobar.cc b/chrome/browser/extensions/crashed_extension_infobar.cc index c3576fc..fbed6e6 100644 --- a/chrome/browser/extensions/crashed_extension_infobar.cc +++ b/chrome/browser/extensions/crashed_extension_infobar.cc @@ -30,6 +30,11 @@ AsCrashedExtensionInfoBarDelegate() { return this; } +bool CrashedExtensionInfoBarDelegate::ShouldExpire( + const NavigationController::LoadCommittedDetails& details) const { + return false; +} + string16 CrashedExtensionInfoBarDelegate::GetMessageText() const { return l10n_util::GetStringFUTF16(IDS_EXTENSION_CRASHED_INFOBAR_MESSAGE, UTF8ToUTF16(extension_name_)); diff --git a/chrome/browser/extensions/crashed_extension_infobar.h b/chrome/browser/extensions/crashed_extension_infobar.h index 619561c..201e606 100644 --- a/chrome/browser/extensions/crashed_extension_infobar.h +++ b/chrome/browser/extensions/crashed_extension_infobar.h @@ -30,6 +30,8 @@ class CrashedExtensionInfoBarDelegate : public ConfirmInfoBarDelegate { // InfoBarDelegate virtual CrashedExtensionInfoBarDelegate* AsCrashedExtensionInfoBarDelegate(); + virtual bool ShouldExpire( + const NavigationController::LoadCommittedDetails& details) const; // ConfirmInfoBarDelegate virtual string16 GetMessageText() const; diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc index 91c7c7f..cb489a1 100644 --- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc +++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc @@ -13,6 +13,7 @@ #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/result_codes.h" #include "chrome/test/ui_test_utils.h" @@ -150,6 +151,132 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, ReloadIndependently) { ASSERT_EQ(0, current_tab->infobar_delegate_count()); } +IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, + ReloadIndependentlyChangeTabs) { + const size_t size_before = GetExtensionService()->extensions()->size(); + LoadTestExtension(); + CrashExtension(size_before); + ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); + + TabContents* original_tab = browser()->GetSelectedTabContents(); + ASSERT_TRUE(original_tab); + ASSERT_EQ(1, original_tab->infobar_delegate_count()); + + // Open a new tab so the info bar will not be in the current tab. + browser()->NewTab(); + TabContents* new_current_tab = browser()->GetSelectedTabContents(); + ASSERT_TRUE(new_current_tab); + ASSERT_NE(new_current_tab, original_tab); + ASSERT_EQ(0, new_current_tab->infobar_delegate_count()); + + ReloadExtension(first_extension_id_); + + SCOPED_TRACE("after reloading"); + CheckExtensionConsistency(size_before); + + // The infobar should automatically hide after the extension is successfully + // reloaded. + ASSERT_EQ(0, original_tab->infobar_delegate_count()); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, + ReloadIndependentlyNavigatePage) { + const size_t size_before = GetExtensionService()->extensions()->size(); + LoadTestExtension(); + CrashExtension(size_before); + ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); + + TabContents* current_tab = browser()->GetSelectedTabContents(); + ASSERT_TRUE(current_tab); + ASSERT_EQ(1, current_tab->infobar_delegate_count()); + + // Navigate to another page. + ui_test_utils::NavigateToURL(browser(), + ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory), + FilePath(FILE_PATH_LITERAL("title1.html")))); + ASSERT_EQ(1, current_tab->infobar_delegate_count()); + + ReloadExtension(first_extension_id_); + + SCOPED_TRACE("after reloading"); + CheckExtensionConsistency(size_before); + + // The infobar should automatically hide after the extension is successfully + // reloaded. + ASSERT_EQ(0, current_tab->infobar_delegate_count()); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, + ReloadIndependentlyTwoInfoBars) { + const size_t size_before = GetExtensionService()->extensions()->size(); + LoadTestExtension(); + + // Open a new window so that there will be an info bar in each. + Browser* browser2 = CreateBrowser(browser()->profile()); + + CrashExtension(size_before); + ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); + + TabContents* current_tab = browser()->GetSelectedTabContents(); + ASSERT_TRUE(current_tab); + ASSERT_EQ(1, current_tab->infobar_delegate_count()); + + TabContents* current_tab2 = browser2->GetSelectedTabContents(); + ASSERT_TRUE(current_tab2); + ASSERT_EQ(1, current_tab2->infobar_delegate_count()); + + ReloadExtension(first_extension_id_); + + SCOPED_TRACE("after reloading"); + CheckExtensionConsistency(size_before); + + // Both infobars should automatically hide after the extension is successfully + // reloaded. + ASSERT_EQ(0, current_tab->infobar_delegate_count()); + ASSERT_EQ(0, current_tab2->infobar_delegate_count()); +} + +IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, + ReloadIndependentlyTwoInfoBarsSameBrowser) { + const size_t size_before = GetExtensionService()->extensions()->size(); + LoadTestExtension(); + + // Open a new window so that there will be an info bar in each. + Browser* browser2 = CreateBrowser(browser()->profile()); + + CrashExtension(size_before); + ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); + + TabContents* current_tab = browser()->GetSelectedTabContents(); + ASSERT_TRUE(current_tab); + ASSERT_EQ(1, current_tab->infobar_delegate_count()); + + TabContents* current_tab2 = browser2->GetSelectedTabContents(); + ASSERT_TRUE(current_tab2); + ASSERT_EQ(1, current_tab2->infobar_delegate_count()); + + // Move second window into first browser so there will be multiple tabs + // with the info bar for the same extension in one browser. + TabContentsWrapper* contents = + browser2->tabstrip_model()->DetachTabContentsAt(0); + browser()->tabstrip_model()->AppendTabContents(contents, true); + current_tab2 = browser()->GetSelectedTabContents(); + ASSERT_EQ(1, current_tab2->infobar_delegate_count()); + ASSERT_NE(current_tab2, current_tab); + + ReloadExtension(first_extension_id_); + + SCOPED_TRACE("after reloading"); + CheckExtensionConsistency(size_before); + + // Both infobars should automatically hide after the extension is successfully + // reloaded. + ASSERT_EQ(0, current_tab2->infobar_delegate_count()); + browser()->SelectPreviousTab(); + ASSERT_EQ(current_tab, browser()->GetSelectedTabContents()); + ASSERT_EQ(0, current_tab->infobar_delegate_count()); +} + // Make sure that when we don't do anything about the crashed extension // and close the browser, it doesn't crash. The browser is closed implicitly // at the end of each browser test. diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index d7adce2..44c28b6d 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -3250,20 +3250,21 @@ void Browser::Observe(NotificationType type, // If any "This extension has crashed" InfoBarDelegates are around for // this extension, it means that it has been reloaded in another window // so just remove the remaining CrashedExtensionInfoBarDelegate objects. - TabContents* tab_contents = GetSelectedTabContents(); - if (!tab_contents) - break; const Extension* extension = Details<const Extension>(details).ptr(); CrashedExtensionInfoBarDelegate* delegate = NULL; - for (int i = 0; i < tab_contents->infobar_delegate_count();) { - delegate = tab_contents->GetInfoBarDelegateAt(i)-> - AsCrashedExtensionInfoBarDelegate(); - if (delegate && delegate->extension_id() == extension->id()) { - tab_contents->RemoveInfoBar(delegate); - continue; + TabStripModel* model = tab_handler_->GetTabStripModel(); + for (int m = 0; m < model->count(); ++m) { + TabContents* tab_contents = model->GetTabContentsAt(m)->tab_contents(); + for (int i = 0; i < tab_contents->infobar_delegate_count();) { + delegate = tab_contents->GetInfoBarDelegateAt(i)-> + AsCrashedExtensionInfoBarDelegate(); + if (delegate && delegate->extension_id() == extension->id()) { + tab_contents->RemoveInfoBar(delegate); + continue; + } + // Only increment |i| if we didn't remove an entry. + ++i; } - // Only increment |i| if we didn't remove an entry. - ++i; } break; } |