summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-22 21:15:13 +0000
committerjennb@chromium.org <jennb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-22 21:15:13 +0000
commited56a7a029ec8515ab30ba13ee1dcdb4721c32d4 (patch)
tree7715b5adfb7fe112484758d1fe8640b083b9ec39
parent9fc1e6c183707ebde09cb0057f528646f309b32d (diff)
downloadchromium_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.cc5
-rw-r--r--chrome/browser/extensions/crashed_extension_infobar.h2
-rw-r--r--chrome/browser/extensions/extension_crash_recovery_browsertest.cc127
-rw-r--r--chrome/browser/ui/browser.cc23
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;
}