summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-25 04:25:45 +0000
committersail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-25 04:25:45 +0000
commitc6b207c6c4290a06000fabd9b09a96614d3ae118 (patch)
tree6c3f284de26c7a88415bba43f465e32282700d01
parent02eb89fb03a303cb2b745063e6d852feb3bc5c5e (diff)
downloadchromium_src-c6b207c6c4290a06000fabd9b09a96614d3ae118.zip
chromium_src-c6b207c6c4290a06000fabd9b09a96614d3ae118.tar.gz
chromium_src-c6b207c6c4290a06000fabd9b09a96614d3ae118.tar.bz2
Cocoa: Close bubble if its GlobalError object is removed
This is the Cocoa version of this change: https://chromiumcodereview.appspot.com/9190009 BUG=109728 TEST= Review URL: http://codereview.chromium.org/9254019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118994 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc4
-rw-r--r--chrome/browser/extensions/extension_global_error.cc20
-rw-r--r--chrome/browser/extensions/extension_global_error.h10
-rw-r--r--chrome/browser/extensions/extension_global_error_badge.cc10
-rw-r--r--chrome/browser/extensions/extension_global_error_badge.h8
-rw-r--r--chrome/browser/protector/base_setting_change.cc4
-rw-r--r--chrome/browser/protector/base_setting_change.h11
-rw-r--r--chrome/browser/protector/default_search_provider_change.cc18
-rw-r--r--chrome/browser/protector/default_search_provider_change_browsertest.cc26
-rw-r--r--chrome/browser/protector/mock_protector_service.h10
-rw-r--r--chrome/browser/protector/mock_setting_change.h4
-rw-r--r--chrome/browser/protector/protector_service.cc25
-rw-r--r--chrome/browser/protector/protector_service.h12
-rw-r--r--chrome/browser/protector/protector_service_browsertest.cc33
-rw-r--r--chrome/browser/protector/settings_change_global_error.cc27
-rw-r--r--chrome/browser/protector/settings_change_global_error.h14
-rw-r--r--chrome/browser/protector/settings_change_global_error_delegate.h8
-rw-r--r--chrome/browser/sync/sync_global_error.cc8
-rw-r--r--chrome/browser/sync/sync_global_error.h8
-rw-r--r--chrome/browser/sync/sync_global_error_unittest.cc28
-rw-r--r--chrome/browser/ui/cocoa/global_error_bubble_controller.h16
-rw-r--r--chrome/browser/ui/cocoa/global_error_bubble_controller.mm50
-rw-r--r--chrome/browser/ui/global_error.cc20
-rw-r--r--chrome/browser/ui/global_error.h30
-rw-r--r--chrome/browser/ui/global_error_bubble_view_base.h27
-rw-r--r--chrome/browser/ui/global_error_service.cc4
-rw-r--r--chrome/browser/ui/global_error_service_browsertest.cc42
-rw-r--r--chrome/browser/ui/global_error_service_unittest.cc15
-rw-r--r--chrome/browser/ui/gtk/global_error_bubble.cc58
-rw-r--r--chrome/browser/ui/gtk/global_error_bubble.h22
-rw-r--r--chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc15
-rw-r--r--chrome/browser/ui/views/global_error_bubble_view.cc82
-rw-r--r--chrome/browser/ui/views/global_error_bubble_view.h20
-rw-r--r--chrome/chrome_browser.gypi1
-rw-r--r--chrome/chrome_tests.gypi2
35 files changed, 385 insertions, 307 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index eb93b6c..e1e8e46 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -3440,9 +3440,9 @@ void TestingAutomationProvider::PerformProtectorAction(
return;
}
if (action == "apply_change")
- protector_service->ApplyChange();
+ protector_service->ApplyChange(browser);
else if (action == "discard_change")
- protector_service->DiscardChange();
+ protector_service->DiscardChange(browser);
else
return reply.SendError("Invalid 'action' value");
reply.SendSuccess(NULL);
diff --git a/chrome/browser/extensions/extension_global_error.cc b/chrome/browser/extensions/extension_global_error.cc
index f499317..dfcb016 100644
--- a/chrome/browser/extensions/extension_global_error.cc
+++ b/chrome/browser/extensions/extension_global_error.cc
@@ -15,8 +15,7 @@
ExtensionGlobalError::ExtensionGlobalError(
base::WeakPtr<ExtensionService> extension_service)
- : current_browser_(NULL),
- should_delete_self_on_close_(true),
+ : should_delete_self_on_close_(true),
extension_service_(extension_service),
external_extension_ids_(new ExtensionIdSet),
blacklisted_extension_ids_(new ExtensionIdSet),
@@ -79,11 +78,6 @@ bool ExtensionGlobalError::HasBubbleView() {
return true;
}
-void ExtensionGlobalError::ShowBubbleView(Browser* browser) {
- current_browser_ = browser;
- GlobalError::ShowBubbleView(browser);
-}
-
string16 ExtensionGlobalError::GetBubbleViewTitle() {
return l10n_util::GetStringUTF16(IDS_EXTENSION_ALERT_TITLE);
}
@@ -133,23 +127,23 @@ string16 ExtensionGlobalError::GetBubbleViewCancelButtonLabel() {
return l10n_util::GetStringUTF16(IDS_EXTENSION_ALERT_ITEM_DETAILS);
}
-void ExtensionGlobalError::BubbleViewDidClose() {
+void ExtensionGlobalError::OnBubbleViewDidClose(Browser* browser) {
if (!closed_callback_.is_null()) {
- closed_callback_.Run(*this, current_browser_);
+ closed_callback_.Run(*this, browser);
}
if (should_delete_self_on_close_) {
delete this;
}
}
-void ExtensionGlobalError::BubbleViewAcceptButtonPressed() {
+void ExtensionGlobalError::BubbleViewAcceptButtonPressed(Browser* browser) {
if (!accept_callback_.is_null()) {
- accept_callback_.Run(*this, current_browser_);
+ accept_callback_.Run(*this, browser);
}
}
-void ExtensionGlobalError::BubbleViewCancelButtonPressed() {
+void ExtensionGlobalError::BubbleViewCancelButtonPressed(Browser* browser) {
if (!cancel_callback_.is_null()) {
- cancel_callback_.Run(*this, current_browser_);
+ cancel_callback_.Run(*this, browser);
}
}
diff --git a/chrome/browser/extensions/extension_global_error.h b/chrome/browser/extensions/extension_global_error.h
index 7730125..6d8423f 100644
--- a/chrome/browser/extensions/extension_global_error.h
+++ b/chrome/browser/extensions/extension_global_error.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -81,17 +81,15 @@ class ExtensionGlobalError : public GlobalError {
virtual string16 MenuItemLabel() OVERRIDE;
virtual void ExecuteMenuItem(Browser* browser) OVERRIDE;
virtual bool HasBubbleView() OVERRIDE;
- virtual void ShowBubbleView(Browser* browser) OVERRIDE;
virtual string16 GetBubbleViewTitle() OVERRIDE;
virtual string16 GetBubbleViewMessage() OVERRIDE;
virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
- virtual void BubbleViewDidClose() OVERRIDE;
- virtual void BubbleViewAcceptButtonPressed() OVERRIDE;
- virtual void BubbleViewCancelButtonPressed() OVERRIDE;
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
private:
- Browser* current_browser_; // The browser passed to ShowBubbleView().
bool should_delete_self_on_close_;
base::WeakPtr<ExtensionService> extension_service_;
scoped_ptr<ExtensionIdSet> external_extension_ids_;
diff --git a/chrome/browser/extensions/extension_global_error_badge.cc b/chrome/browser/extensions/extension_global_error_badge.cc
index 8124dc8..6efd04b 100644
--- a/chrome/browser/extensions/extension_global_error_badge.cc
+++ b/chrome/browser/extensions/extension_global_error_badge.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -63,13 +63,15 @@ string16 ExtensionGlobalErrorBadge::GetBubbleViewCancelButtonLabel() {
return string16();
}
-void ExtensionGlobalErrorBadge::BubbleViewDidClose() {
+void ExtensionGlobalErrorBadge::OnBubbleViewDidClose(Browser* browser) {
}
-void ExtensionGlobalErrorBadge::BubbleViewAcceptButtonPressed() {
+void ExtensionGlobalErrorBadge::BubbleViewAcceptButtonPressed(
+ Browser* browser) {
NOTREACHED();
}
-void ExtensionGlobalErrorBadge::BubbleViewCancelButtonPressed() {
+void ExtensionGlobalErrorBadge::BubbleViewCancelButtonPressed(
+ Browser* browser) {
NOTREACHED();
}
diff --git a/chrome/browser/extensions/extension_global_error_badge.h b/chrome/browser/extensions/extension_global_error_badge.h
index f49ce4b..613fc93 100644
--- a/chrome/browser/extensions/extension_global_error_badge.h
+++ b/chrome/browser/extensions/extension_global_error_badge.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -34,9 +34,9 @@ class ExtensionGlobalErrorBadge : public GlobalError {
virtual string16 GetBubbleViewMessage() OVERRIDE;
virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
- virtual void BubbleViewDidClose() OVERRIDE;
- virtual void BubbleViewAcceptButtonPressed() OVERRIDE;
- virtual void BubbleViewCancelButtonPressed() OVERRIDE;
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(ExtensionGlobalErrorBadge);
diff --git a/chrome/browser/protector/base_setting_change.cc b/chrome/browser/protector/base_setting_change.cc
index 3ee61d4..805d48b 100644
--- a/chrome/browser/protector/base_setting_change.cc
+++ b/chrome/browser/protector/base_setting_change.cc
@@ -21,10 +21,10 @@ bool BaseSettingChange::Init(Profile* profile) {
return true;
}
-void BaseSettingChange::Apply() {
+void BaseSettingChange::Apply(Browser* browser) {
}
-void BaseSettingChange::Discard() {
+void BaseSettingChange::Discard(Browser* browser) {
}
void BaseSettingChange::Timeout() {
diff --git a/chrome/browser/protector/base_setting_change.h b/chrome/browser/protector/base_setting_change.h
index 0d1cdff..098d6f1 100644
--- a/chrome/browser/protector/base_setting_change.h
+++ b/chrome/browser/protector/base_setting_change.h
@@ -12,6 +12,7 @@
#include "base/basictypes.h"
#include "base/string16.h"
+class Browser;
class Profile;
class TemplateURL;
@@ -30,11 +31,13 @@ class BaseSettingChange {
// base method.
virtual bool Init(Profile* profile);
- // Persists new setting if needed.
- virtual void Apply();
+ // Persists new setting if needed. |browser| is the Browser instance from
+ // which the user action originates.
+ virtual void Apply(Browser* browser);
- // Restores old setting if needed.
- virtual void Discard();
+ // Restores old setting if needed. |browser| is the Browser instance from
+ // which the user action originates.
+ virtual void Discard(Browser* browser);
// Indicates that user has ignored this change and timeout has passed.
virtual void Timeout();
diff --git a/chrome/browser/protector/default_search_provider_change.cc b/chrome/browser/protector/default_search_provider_change.cc
index d7b29a8..6818f49 100644
--- a/chrome/browser/protector/default_search_provider_change.cc
+++ b/chrome/browser/protector/default_search_provider_change.cc
@@ -89,8 +89,8 @@ class DefaultSearchProviderChange : public BaseSettingChange,
// BaseSettingChange overrides:
virtual bool Init(Profile* profile) OVERRIDE;
- virtual void Apply() OVERRIDE;
- virtual void Discard() OVERRIDE;
+ virtual void Apply(Browser* browser) OVERRIDE;
+ virtual void Discard(Browser* browser) OVERRIDE;
virtual void Timeout() OVERRIDE;
virtual int GetBadgeIconID() const OVERRIDE;
virtual int GetMenuItemIconID() const OVERRIDE;
@@ -121,7 +121,7 @@ class DefaultSearchProviderChange : public BaseSettingChange,
scoped_ptr<TemplateURL>* search_provider);
// Opens the Search engine settings page in a new tab.
- void OpenSearchEngineSettings();
+ void OpenSearchEngineSettings(Browser* browser);
// Returns the TemplateURLService instance for the Profile this change is
// related to.
@@ -232,7 +232,7 @@ bool DefaultSearchProviderChange::Init(Profile* profile) {
return true;
}
-void DefaultSearchProviderChange::Apply() {
+void DefaultSearchProviderChange::Apply(Browser* browser) {
UMA_HISTOGRAM_ENUMERATION(
kProtectorHistogramSearchProviderApplied,
new_histogram_id_,
@@ -243,11 +243,11 @@ void DefaultSearchProviderChange::Apply() {
GetTemplateURLService()->SetDefaultSearchProvider(new_search_provider_);
} else {
// Open settings page in case the new setting is invalid.
- OpenSearchEngineSettings();
+ OpenSearchEngineSettings(browser);
}
}
-void DefaultSearchProviderChange::Discard() {
+void DefaultSearchProviderChange::Discard(Browser* browser) {
UMA_HISTOGRAM_ENUMERATION(
kProtectorHistogramSearchProviderDiscarded,
new_histogram_id_,
@@ -256,7 +256,7 @@ void DefaultSearchProviderChange::Discard() {
GetTemplateURLService()->RemoveObserver(this);
if (is_fallback_) {
// Open settings page in case the old setting is invalid.
- OpenSearchEngineSettings();
+ OpenSearchEngineSettings(browser);
}
// Nothing to do otherwise since we have already set the search engine
// to |old_id_| in |Init|.
@@ -385,10 +385,10 @@ const TemplateURL* DefaultSearchProviderChange::SetDefaultSearchProvider(
return new_default_provider;
}
-void DefaultSearchProviderChange::OpenSearchEngineSettings() {
+void DefaultSearchProviderChange::OpenSearchEngineSettings(Browser* browser) {
ProtectorServiceFactory::GetForProfile(profile())->OpenTab(
GURL(std::string(chrome::kChromeUISettingsURL) +
- chrome::kSearchEnginesSubPage));
+ chrome::kSearchEnginesSubPage), browser);
}
TemplateURLService* DefaultSearchProviderChange::GetTemplateURLService() {
diff --git a/chrome/browser/protector/default_search_provider_change_browsertest.cc b/chrome/browser/protector/default_search_provider_change_browsertest.cc
index 1bb7e50..7a87af7 100644
--- a/chrome/browser/protector/default_search_provider_change_browsertest.cc
+++ b/chrome/browser/protector/default_search_provider_change_browsertest.cc
@@ -121,7 +121,7 @@ class DefaultSearchProviderChangeTest : public InProcessBrowserTest {
void ExpectSettingsOpened(const std::string& subpage) {
GURL settings_url(chrome::kChromeUISettingsURL + subpage);
- EXPECT_CALL(*mock_protector_service_, OpenTab(settings_url));
+ EXPECT_CALL(*mock_protector_service_, OpenTab(settings_url, browser()));
}
void ExpectHistogramCount(const std::string& name,
@@ -181,14 +181,14 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchProviderChangeTest, BackupValid) {
change->GetDiscardButtonText());
// Discard does nothing - backup was already active.
- change->Discard();
+ change->Discard(browser());
EXPECT_EQ(FindTemplateURL(http_example_info),
turl_service_->GetDefaultSearchProvider());
ExpectHistogramCount(kProtectorHistogramSearchProviderDiscarded,
SEARCH_ENGINE_OTHER, 1);
// Verify that Apply switches back to |current_url|.
- change->Apply();
+ change->Apply(browser());
EXPECT_EQ(FindTemplateURL(http_example_com),
turl_service_->GetDefaultSearchProvider());
ExpectHistogramCount(kProtectorHistogramSearchProviderApplied,
@@ -278,12 +278,12 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchProviderChangeTest, BackupInvalid) {
// Verify that search engine settings are opened by Discard.
ExpectSettingsOpened(chrome::kSearchEnginesSubPage);
- change->Discard();
+ change->Discard(browser());
EXPECT_EQ(FindTemplateURL(prepopulated_url_->url()->url()),
turl_service_->GetDefaultSearchProvider());
// Verify that Apply switches back to |current_url|.
- change->Apply();
+ change->Apply(browser());
EXPECT_EQ(FindTemplateURL(http_example_com),
turl_service_->GetDefaultSearchProvider());
}
@@ -332,12 +332,12 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchProviderChangeTest,
// Verify that search engine settings are opened by Discard.
ExpectSettingsOpened(chrome::kSearchEnginesSubPage);
- change->Discard();
+ change->Discard(browser());
EXPECT_EQ(FindTemplateURL(prepopulated_url_->url()->url()),
turl_service_->GetDefaultSearchProvider());
// Verify that Apply switches back to |current_url|.
- change->Apply();
+ change->Apply(browser());
EXPECT_EQ(FindTemplateURL(http_example_com),
turl_service_->GetDefaultSearchProvider());
}
@@ -373,13 +373,13 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchProviderChangeTest,
change->GetDiscardButtonText());
// Discard does nothing - backup was already active.
- change->Discard();
+ change->Discard(browser());
EXPECT_EQ(FindTemplateURL(http_example_info),
turl_service_->GetDefaultSearchProvider());
// Verify that search engine settings are opened by Apply (no other changes).
ExpectSettingsOpened(chrome::kSearchEnginesSubPage);
- change->Apply();
+ change->Apply(browser());
EXPECT_EQ(FindTemplateURL(http_example_info),
turl_service_->GetDefaultSearchProvider());
}
@@ -415,7 +415,7 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchProviderChangeTest,
// Verify that search engine settings are opened by Discard.
ExpectSettingsOpened(chrome::kSearchEnginesSubPage);
- change->Discard();
+ change->Discard(browser());
EXPECT_EQ(FindTemplateURL(prepopulated_url_->url()->url()),
turl_service_->GetDefaultSearchProvider());
}
@@ -454,7 +454,7 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchProviderChangeTest,
// Verify that search engine settings are opened by Discard.
ExpectSettingsOpened(chrome::kSearchEnginesSubPage);
- change->Discard();
+ change->Discard(browser());
EXPECT_EQ(current_url, turl_service_->GetDefaultSearchProvider());
}
@@ -518,12 +518,12 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchProviderChangeTest,
// Verify that search engine settings are opened by Apply.
ExpectSettingsOpened(chrome::kSearchEnginesSubPage);
- change->Apply();
+ change->Apply(browser());
EXPECT_EQ(FindTemplateURL(http_example_info),
turl_service_->GetDefaultSearchProvider());
// Discard does nothing - backup was already active.
- change->Discard();
+ change->Discard(browser());
EXPECT_EQ(FindTemplateURL(http_example_info),
turl_service_->GetDefaultSearchProvider());
}
diff --git a/chrome/browser/protector/mock_protector_service.h b/chrome/browser/protector/mock_protector_service.h
index a32bb92..bc2c36f 100644
--- a/chrome/browser/protector/mock_protector_service.h
+++ b/chrome/browser/protector/mock_protector_service.h
@@ -26,13 +26,13 @@ class MockProtectorService : public ProtectorService {
MOCK_CONST_METHOD0(IsShowingChange, bool());
MOCK_METHOD0(DismissChange, void());
- MOCK_METHOD0(ApplyChange, void());
- MOCK_METHOD0(DiscardChange, void());
+ MOCK_METHOD1(ApplyChange, void(Browser*));
+ MOCK_METHOD1(DiscardChange, void(Browser*));
- MOCK_METHOD1(OpenTab, void(const GURL&));
+ MOCK_METHOD2(OpenTab, void(const GURL&, Browser*));
- MOCK_METHOD0(OnApplyChange, void());
- MOCK_METHOD0(OnDiscardChange, void());
+ MOCK_METHOD1(OnApplyChange, void(Browser*));
+ MOCK_METHOD1(OnDiscardChange, void(Browser*));
MOCK_METHOD0(OnDecisionTimeout, void());
MOCK_METHOD0(OnRemovedFromProfile, void());
diff --git a/chrome/browser/protector/mock_setting_change.h b/chrome/browser/protector/mock_setting_change.h
index 3f151ea..c665ced 100644
--- a/chrome/browser/protector/mock_setting_change.h
+++ b/chrome/browser/protector/mock_setting_change.h
@@ -20,8 +20,8 @@ class MockSettingChange : public BaseSettingChange {
virtual bool Init(Profile* profile) OVERRIDE;
MOCK_METHOD1(MockInit, bool(Profile* profile));
- MOCK_METHOD0(Apply, void());
- MOCK_METHOD0(Discard, void());
+ MOCK_METHOD1(Apply, void(Browser*));
+ MOCK_METHOD1(Discard, void(Browser*));
MOCK_METHOD0(Timeout, void());
MOCK_CONST_METHOD0(GetBadgeIconID, int());
diff --git a/chrome/browser/protector/protector_service.cc b/chrome/browser/protector/protector_service.cc
index 2464c0e..214be7db 100644
--- a/chrome/browser/protector/protector_service.cc
+++ b/chrome/browser/protector/protector_service.cc
@@ -44,15 +44,15 @@ bool ProtectorService::IsShowingChange() const {
return change_.get() != NULL;
}
-void ProtectorService::ApplyChange() {
+void ProtectorService::ApplyChange(Browser* browser) {
DCHECK(IsShowingChange());
- change_->Apply();
+ change_->Apply(browser);
DismissChange();
}
-void ProtectorService::DiscardChange() {
+void ProtectorService::DiscardChange(Browser* browser) {
DCHECK(IsShowingChange());
- change_->Discard();
+ change_->Discard(browser);
DismissChange();
}
@@ -62,12 +62,9 @@ void ProtectorService::DismissChange() {
DCHECK(!IsShowingChange());
}
-void ProtectorService::OpenTab(const GURL& url) {
- if (!error_.get() || !error_->browser()) {
- LOG(WARNING) << "Don't have browser to show tab in.";
- return;
- }
- error_->browser()->ShowSingletonTab(url);
+void ProtectorService::OpenTab(const GURL& url, Browser* browser) {
+ DCHECK(browser);
+ browser->ShowSingletonTab(url);
}
void ProtectorService::Shutdown() {
@@ -75,16 +72,16 @@ void ProtectorService::Shutdown() {
DismissChange();
}
-void ProtectorService::OnApplyChange() {
+void ProtectorService::OnApplyChange(Browser* browser) {
DVLOG(1) << "Apply change";
DCHECK(IsShowingChange());
- change_->Apply();
+ change_->Apply(browser);
}
-void ProtectorService::OnDiscardChange() {
+void ProtectorService::OnDiscardChange(Browser* browser) {
DVLOG(1) << "Discard change";
DCHECK(IsShowingChange());
- change_->Discard();
+ change_->Discard(browser);
}
void ProtectorService::OnDecisionTimeout() {
diff --git a/chrome/browser/protector/protector_service.h b/chrome/browser/protector/protector_service.h
index 28e1b6f..aae385c 100644
--- a/chrome/browser/protector/protector_service.h
+++ b/chrome/browser/protector/protector_service.h
@@ -43,14 +43,16 @@ class ProtectorService : public ProfileKeyedService,
virtual void DismissChange();
// Persists the change that is currently active and removes global error.
- virtual void ApplyChange();
+ // |browser| is the Browser instance from which the user action originates.
+ virtual void ApplyChange(Browser* browser);
// Discards the change that is currently active and removes global error.
- virtual void DiscardChange();
+ // |browser| is the Browser instance from which the user action originates.
+ virtual void DiscardChange(Browser* browser);
// Opens a tab with specified URL in the browser window we've shown error
// bubble for.
- virtual void OpenTab(const GURL& url);
+ virtual void OpenTab(const GURL& url, Browser* browser);
// Returns the Profile instance we've shown error bubble for.
Profile* profile() { return profile_; }
@@ -62,8 +64,8 @@ class ProtectorService : public ProfileKeyedService,
virtual void Shutdown() OVERRIDE;
// SettingsChangeGlobalErrorDelegate implementation.
- virtual void OnApplyChange() OVERRIDE;
- virtual void OnDiscardChange() OVERRIDE;
+ virtual void OnApplyChange(Browser* browser) OVERRIDE;
+ virtual void OnDiscardChange(Browser* browser) OVERRIDE;
virtual void OnDecisionTimeout() OVERRIDE;
virtual void OnRemovedFromProfile() OVERRIDE;
diff --git a/chrome/browser/protector/protector_service_browsertest.cc b/chrome/browser/protector/protector_service_browsertest.cc
index 951dabb..610af7e 100644
--- a/chrome/browser/protector/protector_service_browsertest.cc
+++ b/chrome/browser/protector/protector_service_browsertest.cc
@@ -11,12 +11,13 @@
#include "chrome/browser/protector/settings_change_global_error.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/global_error.h"
+#include "chrome/browser/ui/global_error_bubble_view_base.h"
#include "chrome/browser/ui/global_error_service.h"
#include "chrome/browser/ui/global_error_service_factory.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
-using ::testing::Invoke;
+using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock;
using ::testing::Return;
@@ -78,8 +79,8 @@ IN_PROC_BROWSER_TEST_F(ProtectorServiceTest, ShowAndApply) {
protector_service_->ShowChange(mock_change_);
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(true);
- EXPECT_CALL(*mock_change_, Apply());
- protector_service_->ApplyChange();
+ EXPECT_CALL(*mock_change_, Apply(browser()));
+ protector_service_->ApplyChange(browser());
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(false);
}
@@ -91,11 +92,11 @@ IN_PROC_BROWSER_TEST_F(ProtectorServiceTest, ShowAndApplyManually) {
protector_service_->ShowChange(mock_change_);
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(true);
- EXPECT_CALL(*mock_change_, Apply());
+ EXPECT_CALL(*mock_change_, Apply(browser()));
// Pressing Cancel applies the change.
GlobalError* error = GetGlobalError();
- error->BubbleViewCancelButtonPressed();
- error->BubbleViewDidClose();
+ error->BubbleViewCancelButtonPressed(browser());
+ error->GetBubbleView()->CloseBubbleView();
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(false);
}
@@ -107,8 +108,8 @@ IN_PROC_BROWSER_TEST_F(ProtectorServiceTest, ShowAndDiscard) {
protector_service_->ShowChange(mock_change_);
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(true);
- EXPECT_CALL(*mock_change_, Discard());
- protector_service_->DiscardChange();
+ EXPECT_CALL(*mock_change_, Discard(browser()));
+ protector_service_->DiscardChange(browser());
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(false);
}
@@ -120,11 +121,11 @@ IN_PROC_BROWSER_TEST_F(ProtectorServiceTest, ShowAndDiscardManually) {
protector_service_->ShowChange(mock_change_);
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(true);
- EXPECT_CALL(*mock_change_, Discard());
+ EXPECT_CALL(*mock_change_, Discard(browser()));
// Pressing Apply discards the change.
GlobalError* error = GetGlobalError();
- error->BubbleViewAcceptButtonPressed();
- error->BubbleViewDidClose();
+ error->BubbleViewAcceptButtonPressed(browser());
+ error->GetBubbleView()->CloseBubbleView();
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(false);
}
@@ -135,11 +136,15 @@ IN_PROC_BROWSER_TEST_F(ProtectorServiceTest, BubbleClosedInsideApply) {
protector_service_->ShowChange(mock_change_);
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(true);
+
GlobalError* error = GetGlobalError();
- EXPECT_CALL(*mock_change_, Apply()).
- WillOnce(Invoke(error, &GlobalError::BubbleViewDidClose));
+ GlobalErrorBubbleViewBase* bubble_view = error->GetBubbleView();
+ EXPECT_TRUE(bubble_view);
+ EXPECT_CALL(*mock_change_, Apply(browser())).WillOnce(InvokeWithoutArgs(
+ bubble_view, &GlobalErrorBubbleViewBase::CloseBubbleView));
+
// Pressing Cancel applies the change.
- error->BubbleViewCancelButtonPressed();
+ error->BubbleViewCancelButtonPressed(browser());
ui_test_utils::RunAllPendingInMessageLoop();
ExpectGlobalErrorActive(false);
}
diff --git a/chrome/browser/protector/settings_change_global_error.cc b/chrome/browser/protector/settings_change_global_error.cc
index 4d22142..e9b2194 100644
--- a/chrome/browser/protector/settings_change_global_error.cc
+++ b/chrome/browser/protector/settings_change_global_error.cc
@@ -34,7 +34,6 @@ SettingsChangeGlobalError::SettingsChangeGlobalError(
: change_(change),
delegate_(delegate),
profile_(NULL),
- browser_(NULL),
closed_by_button_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
DCHECK(delegate_);
@@ -70,8 +69,7 @@ int SettingsChangeGlobalError::MenuItemIconResourceID() {
void SettingsChangeGlobalError::ExecuteMenuItem(Browser* browser) {
// Cancel previously posted tasks.
weak_factory_.InvalidateWeakPtrs();
- browser_ = browser;
- ShowBubbleView(browser_);
+ ShowBubbleView(browser);
}
bool SettingsChangeGlobalError::HasBubbleView() {
@@ -103,14 +101,16 @@ string16 SettingsChangeGlobalError::GetBubbleViewCancelButtonLabel() {
return change_->GetApplyButtonText();
}
-void SettingsChangeGlobalError::BubbleViewAcceptButtonPressed() {
+void SettingsChangeGlobalError::BubbleViewAcceptButtonPressed(
+ Browser* browser) {
closed_by_button_ = true;
- delegate_->OnDiscardChange();
+ delegate_->OnDiscardChange(browser);
}
-void SettingsChangeGlobalError::BubbleViewCancelButtonPressed() {
+void SettingsChangeGlobalError::BubbleViewCancelButtonPressed(
+ Browser* browser) {
closed_by_button_ = true;
- delegate_->OnApplyChange();
+ delegate_->OnApplyChange(browser);
}
void SettingsChangeGlobalError::RemoveFromProfile() {
@@ -120,8 +120,7 @@ void SettingsChangeGlobalError::RemoveFromProfile() {
delegate_->OnRemovedFromProfile();
}
-void SettingsChangeGlobalError::BubbleViewDidClose() {
- browser_ = NULL;
+void SettingsChangeGlobalError::OnBubbleViewDidClose(Browser* browser) {
if (!closed_by_button_) {
BrowserThread::PostDelayedTask(
BrowserThread::UI, FROM_HERE,
@@ -155,13 +154,13 @@ void SettingsChangeGlobalError::AddToProfile(Profile* profile) {
void SettingsChangeGlobalError::Show() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(profile_);
- browser_ = BrowserList::GetLastActiveWithProfile(profile_);
- if (!browser_ && profile_->HasOffTheRecordProfile()) {
- browser_ = BrowserList::GetLastActiveWithProfile(
+ Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
+ if (!browser && profile_->HasOffTheRecordProfile()) {
+ browser = BrowserList::GetLastActiveWithProfile(
profile_->GetOffTheRecordProfile());
}
- if (browser_)
- ShowBubbleView(browser_);
+ if (browser)
+ ShowBubbleView(browser);
}
void SettingsChangeGlobalError::OnInactiveTimeout() {
diff --git a/chrome/browser/protector/settings_change_global_error.h b/chrome/browser/protector/settings_change_global_error.h
index 2065e52..1542443 100644
--- a/chrome/browser/protector/settings_change_global_error.h
+++ b/chrome/browser/protector/settings_change_global_error.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -38,9 +38,6 @@ class SettingsChangeGlobalError : public GlobalError {
// Removes global error from its profile.
void RemoveFromProfile();
- // Browser that the bubble has been last time shown for.
- Browser* browser() const { return browser_; }
-
// GlobalError implementation.
virtual bool HasBadge() OVERRIDE;
virtual int GetBadgeResourceID() OVERRIDE;
@@ -55,9 +52,9 @@ class SettingsChangeGlobalError : public GlobalError {
virtual string16 GetBubbleViewMessage() OVERRIDE;
virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
- virtual void BubbleViewDidClose() OVERRIDE;
- virtual void BubbleViewAcceptButtonPressed() OVERRIDE;
- virtual void BubbleViewCancelButtonPressed() OVERRIDE;
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
private:
// Helper called on the UI thread to add this global error to the default
@@ -80,9 +77,6 @@ class SettingsChangeGlobalError : public GlobalError {
// Profile that we have been added to.
Profile* profile_;
- // Browser that we have been shown for.
- Browser* browser_;
-
// True if user has dismissed the bubble by clicking on one of the buttons.
bool closed_by_button_;
diff --git a/chrome/browser/protector/settings_change_global_error_delegate.h b/chrome/browser/protector/settings_change_global_error_delegate.h
index cf21d2a..34cc9a8 100644
--- a/chrome/browser/protector/settings_change_global_error_delegate.h
+++ b/chrome/browser/protector/settings_change_global_error_delegate.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,6 +8,8 @@
#include "base/basictypes.h"
+class Browser;
+
namespace protector {
// Interface for notifications about settings change error bubble closing.
@@ -16,10 +18,10 @@ class SettingsChangeGlobalErrorDelegate {
virtual ~SettingsChangeGlobalErrorDelegate() {}
// Called if user clicks "Apply change" button.
- virtual void OnApplyChange() = 0;
+ virtual void OnApplyChange(Browser* browser) = 0;
// Called if user clicks "Discard change" button.
- virtual void OnDiscardChange() = 0;
+ virtual void OnDiscardChange(Browser* browser) = 0;
// Called if user clicked outside the bubble and timeout for its reshow
// has passed.
diff --git a/chrome/browser/sync/sync_global_error.cc b/chrome/browser/sync/sync_global_error.cc
index c55e05b..1dba4c5 100644
--- a/chrome/browser/sync/sync_global_error.cc
+++ b/chrome/browser/sync/sync_global_error.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -72,14 +72,14 @@ string16 SyncGlobalError::GetBubbleViewCancelButtonLabel() {
return string16();
}
-void SyncGlobalError::BubbleViewDidClose() {
+void SyncGlobalError::OnBubbleViewDidClose(Browser* browser) {
}
-void SyncGlobalError::BubbleViewAcceptButtonPressed() {
+void SyncGlobalError::BubbleViewAcceptButtonPressed(Browser* browser) {
service_->ShowErrorUI();
}
-void SyncGlobalError::BubbleViewCancelButtonPressed() {
+void SyncGlobalError::BubbleViewCancelButtonPressed(Browser* browser) {
NOTREACHED();
}
diff --git a/chrome/browser/sync/sync_global_error.h b/chrome/browser/sync/sync_global_error.h
index 27c6d63..c58dc99 100644
--- a/chrome/browser/sync/sync_global_error.h
+++ b/chrome/browser/sync/sync_global_error.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -33,9 +33,9 @@ class SyncGlobalError : public GlobalError,
virtual string16 GetBubbleViewMessage() OVERRIDE;
virtual string16 GetBubbleViewAcceptButtonLabel() OVERRIDE;
virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE;
- virtual void BubbleViewDidClose() OVERRIDE;
- virtual void BubbleViewAcceptButtonPressed() OVERRIDE;
- virtual void BubbleViewCancelButtonPressed() OVERRIDE;
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE;
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE;
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE;
// ProfileSyncServiceObserver implementation.
virtual void OnStateChanged() OVERRIDE;
diff --git a/chrome/browser/sync/sync_global_error_unittest.cc b/chrome/browser/sync/sync_global_error_unittest.cc
index e795dc5..683fe59 100644
--- a/chrome/browser/sync/sync_global_error_unittest.cc
+++ b/chrome/browser/sync/sync_global_error_unittest.cc
@@ -9,6 +9,7 @@
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/browser_with_test_window_test.h"
#include "content/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock-actions.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -24,6 +25,7 @@ namespace {
// Utility function to test that SyncGlobalError behaves correct for the given
// error condition.
void VerifySyncGlobalErrorResult(NiceMock<ProfileSyncServiceMock>* service,
+ Browser* browser,
SyncGlobalError* error,
GoogleServiceAuthError::State error_state,
bool is_signed_in,
@@ -56,19 +58,19 @@ void VerifySyncGlobalErrorResult(NiceMock<ProfileSyncServiceMock>* service,
// Test message handler.
if (is_error) {
EXPECT_CALL(*service, ShowErrorUI());
- error->ExecuteMenuItem(NULL);
+ error->ExecuteMenuItem(browser);
EXPECT_CALL(*service, ShowErrorUI());
- error->BubbleViewAcceptButtonPressed();
- error->BubbleViewDidClose();
+ error->BubbleViewAcceptButtonPressed(browser);
+ error->BubbleViewDidClose(browser);
}
}
} // namespace
+typedef BrowserWithTestWindowTest SyncGlobalErrorTest;
+
// Test that SyncGlobalError shows an error if a passphrase is required.
-TEST(SyncGlobalErrorTest, PassphraseGlobalError) {
- MessageLoopForUI message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
+TEST_F(SyncGlobalErrorTest, PassphraseGlobalError) {
scoped_ptr<Profile> profile(
ProfileSyncServiceMock::MakeSignedInTestingProfile());
NiceMock<ProfileSyncServiceMock> service(profile.get());
@@ -79,15 +81,13 @@ TEST(SyncGlobalErrorTest, PassphraseGlobalError) {
EXPECT_CALL(service, IsPassphraseRequiredForDecryption())
.WillRepeatedly(Return(true));
VerifySyncGlobalErrorResult(
- &service, &error, GoogleServiceAuthError::NONE, true, true);
+ &service, browser(), &error, GoogleServiceAuthError::NONE, true, true);
}
// Test that SyncGlobalError shows an error for conditions that can be resolved
// by the user and suppresses errors for conditions that cannot be resolved by
// the user.
-TEST(SyncGlobalErrorTest, AuthStateGlobalError) {
- MessageLoopForUI message_loop;
- content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop);
+TEST_F(SyncGlobalErrorTest, AuthStateGlobalError) {
scoped_ptr<Profile> profile(
ProfileSyncServiceMock::MakeSignedInTestingProfile());
NiceMock<ProfileSyncServiceMock> service(profile.get());
@@ -115,9 +115,9 @@ TEST(SyncGlobalErrorTest, AuthStateGlobalError) {
};
for (size_t i = 0; i < sizeof(table)/sizeof(*table); ++i) {
- VerifySyncGlobalErrorResult(
- &service, &error, table[i].error_state, true, table[i].is_error);
- VerifySyncGlobalErrorResult(
- &service, &error, table[i].error_state, false, false);
+ VerifySyncGlobalErrorResult(&service, browser(), &error,
+ table[i].error_state, true, table[i].is_error);
+ VerifySyncGlobalErrorResult(&service, browser(), &error,
+ table[i].error_state, false, false);
}
}
diff --git a/chrome/browser/ui/cocoa/global_error_bubble_controller.h b/chrome/browser/ui/cocoa/global_error_bubble_controller.h
index 9c61c8b..75a2ef5 100644
--- a/chrome/browser/ui/cocoa/global_error_bubble_controller.h
+++ b/chrome/browser/ui/cocoa/global_error_bubble_controller.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,18 +8,26 @@
#import <Cocoa/Cocoa.h>
+#include "base/memory/weak_ptr.h"
#import "chrome/browser/ui/cocoa/base_bubble_controller.h"
+class Browser;
class GlobalError;
@class GTMUILocalizerAndLayoutTweaker;
@class GTMWidthBasedTweaker;
+class Profile;
+
+namespace GlobalErrorBubbleControllerInternal {
+class Bridge;
+}
// This is a bubble view shown from the wrench menu to display information
// about a global error.
@interface GlobalErrorBubbleController : BaseBubbleController {
@private
- // |error_| can be NULL after -close is called.
- GlobalError* error_;
+ base::WeakPtr<GlobalError> error_;
+ scoped_ptr<GlobalErrorBubbleControllerInternal::Bridge> bridge_;
+ Browser* browser_;
IBOutlet NSImageView* iconView_;
IBOutlet NSTextField* title_;
@@ -33,6 +41,8 @@ class GlobalError;
- (IBAction)onAccept:(id)sender;
- (IBAction)onCancel:(id)sender;
+- (void)close;
+
@end
#endif // CHROME_BROWSER_UI_COCOA_GLOBAL_ERROR_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/global_error_bubble_controller.mm b/chrome/browser/ui/cocoa/global_error_bubble_controller.mm
index 1315e08..1d1c4d4 100644
--- a/chrome/browser/ui/cocoa/global_error_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/global_error_bubble_controller.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,7 +14,10 @@
#import "chrome/browser/ui/cocoa/l10n_util.h"
#import "chrome/browser/ui/cocoa/info_bubble_view.h"
#import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
-#import "chrome/browser/ui/global_error.h"
+#include "chrome/browser/ui/global_error.h"
+#include "chrome/browser/ui/global_error_bubble_view_base.h"
+#include "chrome/browser/ui/global_error_service.h"
+#include "chrome/browser/ui/global_error_service_factory.h"
#include "grit/generated_resources.h"
#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
#include "ui/base/l10n/l10n_util.h"
@@ -28,10 +31,28 @@ const CGFloat kWrenchBubblePointOffsetY = 6;
} // namespace
+namespace GlobalErrorBubbleControllerInternal {
+
+// This is the bridge to the C++ GlobalErrorBubbleViewBase object.
+class Bridge : public GlobalErrorBubbleViewBase {
+ public:
+ Bridge(GlobalErrorBubbleController* controller) : controller_(controller) {
+ }
+
+ private:
+ virtual void CloseBubbleView() OVERRIDE {
+ [controller_ close];
+ }
+
+ GlobalErrorBubbleController* controller_; // Weak, owns this.
+};
+
+} // namespace GlobalErrorBubbleControllerInternal
+
@implementation GlobalErrorBubbleController
-+ (void)showForBrowser:(Browser*)browser
- error:(GlobalError*)error {
++ (GlobalErrorBubbleViewBase*)showForBrowser:(Browser*)browser
+ error:(const base::WeakPtr<GlobalError>&)error {
NSWindow* parentWindow = browser->window()->GetNativeHandle();
BrowserWindowController* bwc = [BrowserWindowController
browserWindowControllerForWindow:parentWindow];
@@ -45,7 +66,12 @@ const CGFloat kWrenchBubblePointOffsetY = 6;
relativeToView:wrenchButton
offset:offset];
bubble->error_ = error;
+ bubble->bridge_.reset(new GlobalErrorBubbleControllerInternal::Bridge(
+ bubble));
+ bubble->browser_ = browser;
[bubble showWindow:nil];
+
+ return bubble->bridge_.get();
}
- (void)awakeFromNib {
@@ -96,8 +122,8 @@ const CGFloat kWrenchBubblePointOffsetY = 6;
- (void)close {
if (error_)
- error_->BubbleViewDidClose();
- error_ = NULL;
+ error_->BubbleViewDidClose(browser_);
+ bridge_.reset();
BrowserWindowController* bwc = [BrowserWindowController
browserWindowControllerForWindow:[self parentWindow]];
[bwc releaseBarVisibilityForOwner:self withAnimation:YES delay:NO];
@@ -105,17 +131,21 @@ const CGFloat kWrenchBubblePointOffsetY = 6;
}
- (IBAction)onAccept:(id)sender {
- error_->BubbleViewAcceptButtonPressed();
+ if (error_)
+ error_->BubbleViewAcceptButtonPressed(browser_);
[self close];
}
- (IBAction)onCancel:(id)sender {
- error_->BubbleViewCancelButtonPressed();
+ if (error_)
+ error_->BubbleViewCancelButtonPressed(browser_);
[self close];
}
@end
-void GlobalError::ShowBubbleView(Browser* browser, GlobalError* error) {
- [GlobalErrorBubbleController showForBrowser:browser error:error];
+GlobalErrorBubbleViewBase* GlobalErrorBubbleViewBase::ShowBubbleView(
+ Browser* browser,
+ const base::WeakPtr<GlobalError>& error) {
+ return [GlobalErrorBubbleController showForBrowser:browser error:error];
}
diff --git a/chrome/browser/ui/global_error.cc b/chrome/browser/ui/global_error.cc
index f2cf17c..a282df7 100644
--- a/chrome/browser/ui/global_error.cc
+++ b/chrome/browser/ui/global_error.cc
@@ -1,14 +1,17 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/global_error.h"
#include "base/logging.h"
+#include "chrome/browser/ui/global_error_bubble_view_base.h"
#include "grit/theme_resources.h"
#include "grit/theme_resources_standard.h"
-GlobalError::GlobalError() : has_shown_bubble_view_(false) {
+GlobalError::GlobalError()
+ : has_shown_bubble_view_(false),
+ bubble_view_(NULL) {
}
GlobalError::~GlobalError() {
@@ -28,9 +31,20 @@ bool GlobalError::HasShownBubbleView() {
void GlobalError::ShowBubbleView(Browser* browser) {
has_shown_bubble_view_ = true;
- ShowBubbleView(browser, this);
+ bubble_view_ =
+ GlobalErrorBubbleViewBase::ShowBubbleView(browser, AsWeakPtr());
+}
+
+GlobalErrorBubbleViewBase* GlobalError::GetBubbleView() {
+ return bubble_view_;
}
int GlobalError::GetBubbleViewIconResourceID() {
return IDR_INPUT_ALERT;
}
+
+void GlobalError::BubbleViewDidClose(Browser* browser) {
+ DCHECK(browser);
+ bubble_view_ = NULL;
+ OnBubbleViewDidClose(browser);
+}
diff --git a/chrome/browser/ui/global_error.h b/chrome/browser/ui/global_error.h
index 6352037..fb579f8 100644
--- a/chrome/browser/ui/global_error.h
+++ b/chrome/browser/ui/global_error.h
@@ -7,12 +7,14 @@
#pragma once
#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
#include "base/string16.h"
class Browser;
+class GlobalErrorBubbleViewBase;
// This object describes a single global error.
-class GlobalError {
+class GlobalError : public base::SupportsWeakPtr<GlobalError> {
public:
GlobalError();
virtual ~GlobalError();
@@ -38,7 +40,9 @@ class GlobalError {
// Returns true if the bubble view has been shown.
virtual bool HasShownBubbleView();
// Called to show the bubble view.
- virtual void ShowBubbleView(Browser* browser);
+ void ShowBubbleView(Browser* browser);
+ // Returns the bubble view.
+ virtual GlobalErrorBubbleViewBase* GetBubbleView();
// Returns the resource ID for bubble view icon.
virtual int GetBubbleViewIconResourceID();
// Returns the title for the bubble view.
@@ -50,19 +54,23 @@ class GlobalError {
// Returns the cancel button label for the bubble view. To hide the cancel
// button return an empty string.
virtual string16 GetBubbleViewCancelButtonLabel() = 0;
- // Called when the bubble view is closed unless the bubble is closed as the
- // result of |this| being removed from GlobalErrorService.
- virtual void BubbleViewDidClose() = 0;
- // Called when the user clicks on the accept button.
- virtual void BubbleViewAcceptButtonPressed() = 0;
- // Called when teh user clicks the cancel button.
- virtual void BubbleViewCancelButtonPressed() = 0;
+ // Called when the bubble view is closed. |browser| is the Browser that the
+ // bubble view was shown on.
+ void BubbleViewDidClose(Browser* browser);
+ // Notifies subclasses that the bubble view is closed. |browser| is the
+ // Browser that the bubble view was shown on.
+ virtual void OnBubbleViewDidClose(Browser* browser) = 0;
+ // Called when the user clicks on the accept button. |browser| is the
+ // Browser that the bubble view was shown on.
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) = 0;
+ // Called when the user clicks the cancel button. |browser| is the
+ // Browser that the bubble view was shown on.
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) = 0;
private:
- static void ShowBubbleView(Browser* browser, GlobalError* error);
-
bool has_shown_bubble_view_;
+ GlobalErrorBubbleViewBase* bubble_view_;
DISALLOW_COPY_AND_ASSIGN(GlobalError);
};
diff --git a/chrome/browser/ui/global_error_bubble_view_base.h b/chrome/browser/ui/global_error_bubble_view_base.h
new file mode 100644
index 0000000..ce7cfbb
--- /dev/null
+++ b/chrome/browser/ui/global_error_bubble_view_base.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_GLOBAL_ERROR_BUBBLE_VIEW_BASE_H_
+#define CHROME_BROWSER_UI_GLOBAL_ERROR_BUBBLE_VIEW_BASE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+
+class Browser;
+class GlobalError;
+
+class GlobalErrorBubbleViewBase {
+ public:
+ static GlobalErrorBubbleViewBase* ShowBubbleView(
+ Browser* browser,
+ const base::WeakPtr<GlobalError>& error);
+
+ virtual ~GlobalErrorBubbleViewBase() {}
+
+ // Close the bubble view.
+ virtual void CloseBubbleView() = 0;
+};
+
+#endif // CHROME_BROWSER_UI_GLOBAL_ERROR_BUBBLE_VIEW_BASE_H_
diff --git a/chrome/browser/ui/global_error_service.cc b/chrome/browser/ui/global_error_service.cc
index ed24f47..491ba51 100644
--- a/chrome/browser/ui/global_error_service.cc
+++ b/chrome/browser/ui/global_error_service.cc
@@ -9,6 +9,7 @@
#include "base/stl_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/global_error.h"
+#include "chrome/browser/ui/global_error_bubble_view_base.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/notification_service.h"
@@ -26,6 +27,9 @@ void GlobalErrorService::AddGlobalError(GlobalError* error) {
void GlobalErrorService::RemoveGlobalError(GlobalError* error) {
errors_.erase(std::find(errors_.begin(), errors_.end(), error));
+ GlobalErrorBubbleViewBase* bubble = error->GetBubbleView();
+ if (bubble)
+ bubble->CloseBubbleView();
NotifyErrorsChanged(error);
}
diff --git a/chrome/browser/ui/global_error_service_browsertest.cc b/chrome/browser/ui/global_error_service_browsertest.cc
index 37932cb..63197f2 100644
--- a/chrome/browser/ui/global_error_service_browsertest.cc
+++ b/chrome/browser/ui/global_error_service_browsertest.cc
@@ -7,6 +7,7 @@
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/global_error.h"
+#include "chrome/browser/ui/global_error_bubble_view_base.h"
#include "chrome/browser/ui/global_error_service_factory.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
@@ -54,12 +55,12 @@ class BubbleViewError : public GlobalError {
virtual string16 GetBubbleViewCancelButtonLabel() OVERRIDE {
return string16();
}
- virtual void BubbleViewDidClose() OVERRIDE {
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE {
+ EXPECT_TRUE(browser);
++bubble_view_close_count_;
}
-
- virtual void BubbleViewAcceptButtonPressed() OVERRIDE {}
- virtual void BubbleViewCancelButtonPressed() OVERRIDE {}
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE {}
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE {}
private:
int bubble_view_close_count_;
@@ -92,8 +93,33 @@ IN_PROC_BROWSER_TEST_F(GlobalErrorServiceBrowserTest, ShowBubbleView) {
EXPECT_EQ(0, error->bubble_view_close_count());
}
-// TODO(sail): enable on Mac once http://crbug.com/109728 is fixed.
-#if !defined(OS_MACOSX)
+// Test that GlobalErrorBubbleViewBase::CloseBubbleView correctly closes the
+// bubble view.
+IN_PROC_BROWSER_TEST_F(GlobalErrorServiceBrowserTest, CloseBubbleView) {
+ // This will be deleted by the GlobalErrorService.
+ BubbleViewError* error = new BubbleViewError;
+
+ GlobalErrorService* service =
+ GlobalErrorServiceFactory::GetForProfile(browser()->profile());
+ service->AddGlobalError(error);
+
+ EXPECT_EQ(error, service->GetFirstGlobalErrorWithBubbleView());
+ EXPECT_FALSE(error->HasShownBubbleView());
+ EXPECT_EQ(0, error->bubble_view_close_count());
+
+ // Creating a second browser window should show the bubble view.
+ CreateBrowser(browser()->profile());
+ EXPECT_EQ(NULL, service->GetFirstGlobalErrorWithBubbleView());
+ EXPECT_TRUE(error->HasShownBubbleView());
+ EXPECT_EQ(0, error->bubble_view_close_count());
+
+ // Explicitly close the bubble view.
+ EXPECT_TRUE(error->GetBubbleView());
+ error->GetBubbleView()->CloseBubbleView();
+ ui_test_utils::RunAllPendingInMessageLoop();
+ EXPECT_EQ(1, error->bubble_view_close_count());
+}
+
// Test that bubble is silently dismissed if it is showing when the GlobalError
// instance is removed from the profile.
IN_PROC_BROWSER_TEST_F(GlobalErrorServiceBrowserTest,
@@ -113,7 +139,7 @@ IN_PROC_BROWSER_TEST_F(GlobalErrorServiceBrowserTest,
// Removing |error| from profile should dismiss the bubble view without
// calling |error->BubbleViewDidClose|.
service->RemoveGlobalError(error.get());
- EXPECT_EQ(0, error->bubble_view_close_count());
+ ui_test_utils::RunAllPendingInMessageLoop();
+ EXPECT_EQ(1, error->bubble_view_close_count());
// |error| is no longer owned by service and will be deleted.
}
-#endif
diff --git a/chrome/browser/ui/global_error_service_unittest.cc b/chrome/browser/ui/global_error_service_unittest.cc
index 2c16bc2..4613506 100644
--- a/chrome/browser/ui/global_error_service_unittest.cc
+++ b/chrome/browser/ui/global_error_service_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -41,7 +41,6 @@ class BaseError : public GlobalError {
virtual void ExecuteMenuItem(Browser* browser) OVERRIDE { ADD_FAILURE(); }
virtual bool HasBubbleView() OVERRIDE { return false; }
- virtual void ShowBubbleView(Browser* browser) OVERRIDE { ADD_FAILURE(); }
virtual int GetBubbleViewIconResourceID() OVERRIDE {
ADD_FAILURE();
return 0;
@@ -62,9 +61,15 @@ class BaseError : public GlobalError {
ADD_FAILURE();
return string16();
}
- virtual void BubbleViewDidClose() OVERRIDE { ADD_FAILURE(); }
- virtual void BubbleViewAcceptButtonPressed() OVERRIDE { ADD_FAILURE(); }
- virtual void BubbleViewCancelButtonPressed() OVERRIDE { ADD_FAILURE(); }
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE {
+ ADD_FAILURE();
+ }
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE {
+ ADD_FAILURE();
+ }
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE {
+ ADD_FAILURE();
+ }
private:
// This tracks the number BaseError objects that are currently instantiated.
diff --git a/chrome/browser/ui/gtk/global_error_bubble.cc b/chrome/browser/ui/gtk/global_error_bubble.cc
index 2e64fa0..2294437 100644
--- a/chrome/browser/ui/gtk/global_error_bubble.cc
+++ b/chrome/browser/ui/gtk/global_error_bubble.cc
@@ -16,8 +16,6 @@
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "content/public/browser/notification_service.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/gtk_util.h"
@@ -42,16 +40,20 @@ const int kMessageLabelWidth = 250;
} // namespace
-GlobalErrorBubble::GlobalErrorBubble(Profile* profile,
- GlobalError* error,
+GlobalErrorBubble::GlobalErrorBubble(Browser* browser,
+ const base::WeakPtr<GlobalError>& error,
GtkWidget* anchor)
- : bubble_(NULL),
+ : browser_(browser),
+ bubble_(NULL),
error_(error) {
+ DCHECK(browser_);
+ DCHECK(error_);
GtkWidget* content = gtk_vbox_new(FALSE, kInterLineSpacing);
gtk_container_set_border_width(GTK_CONTAINER(content), kContentBorder);
g_signal_connect(content, "destroy", G_CALLBACK(OnDestroyThunk), this);
- GtkThemeService* theme_service = GtkThemeService::GetFrom(profile);
+ GtkThemeService* theme_service =
+ GtkThemeService::GetFrom(browser_->profile());
int resource_id = error_->GetBubbleViewIconResourceID();
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
@@ -104,9 +106,6 @@ GlobalErrorBubble::GlobalErrorBubble(Profile* profile,
G_CALLBACK(OnCancelButtonThunk), this);
}
- registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
- content::Source<Profile>(profile));
-
BubbleGtk::ArrowLocationGtk arrow_location =
base::i18n::IsRTL() ?
BubbleGtk::ARROW_LOCATION_TOP_LEFT :
@@ -126,12 +125,8 @@ GlobalErrorBubble::~GlobalErrorBubble() {
void GlobalErrorBubble::BubbleClosing(BubbleGtk* bubble,
bool closed_by_escape) {
- // We unsubscribe from removal notifications here and below because any of
- // GlobalError callbacks may remove it from the profile. Here it is needed
- // also because |this| will be deleted later asynchronously in OnDestroy.
- registrar_.RemoveAll();
if (error_)
- error_->BubbleViewDidClose();
+ error_->BubbleViewDidClose(browser_);
}
void GlobalErrorBubble::OnDestroy(GtkWidget* sender) {
@@ -139,44 +134,29 @@ void GlobalErrorBubble::OnDestroy(GtkWidget* sender) {
}
void GlobalErrorBubble::OnAcceptButton(GtkWidget* sender) {
- registrar_.RemoveAll();
- error_->BubbleViewAcceptButtonPressed();
+ if (error_)
+ error_->BubbleViewAcceptButtonPressed(browser_);
bubble_->Close();
}
void GlobalErrorBubble::OnCancelButton(GtkWidget* sender) {
- registrar_.RemoveAll();
- error_->BubbleViewCancelButtonPressed();
+ if (error_)
+ error_->BubbleViewCancelButtonPressed(browser_);
bubble_->Close();
}
-void GlobalErrorBubble::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK(type == chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED);
- DCHECK(error_);
- if (content::Details<GlobalError>(details).ptr() == error_) {
- Profile* profile = content::Source<Profile>(source).ptr();
- const std::vector<GlobalError*>& errors =
- GlobalErrorServiceFactory::GetForProfile(profile)->errors();
- // This handles the case when a GlobalError instance is removed from profile
- // not as a part of normal flow (i.e., after the bubble has been closed)
- // but while the bubble is still showing. |error_| is no longer guaranteed
- // to exist so we set it to |NULL| and dismiss the bubble.
- if (std::find(errors.begin(), errors.end(), error_) == errors.end()) {
- error_ = NULL;
- registrar_.RemoveAll();
- bubble_->Close();
- }
- }
+void GlobalErrorBubble::CloseBubbleView() {
+ bubble_->Close();
}
-void GlobalError::ShowBubbleView(Browser* browser, GlobalError* error) {
+GlobalErrorBubbleViewBase* GlobalErrorBubbleViewBase::ShowBubbleView(
+ Browser* browser,
+ const base::WeakPtr<GlobalError>& error) {
BrowserWindowGtk* browser_window =
BrowserWindowGtk::GetBrowserWindowForNativeWindow(
browser->window()->GetNativeHandle());
GtkWidget* anchor = browser_window->GetToolbar()->GetAppMenuButton();
// The bubble will be automatically deleted when it's closed.
- new GlobalErrorBubble(browser->profile(), error, anchor);
+ return new GlobalErrorBubble(browser, error, anchor);
}
diff --git a/chrome/browser/ui/gtk/global_error_bubble.h b/chrome/browser/ui/gtk/global_error_bubble.h
index 424dbc4..c306e9a9 100644
--- a/chrome/browser/ui/gtk/global_error_bubble.h
+++ b/chrome/browser/ui/gtk/global_error_bubble.h
@@ -8,9 +8,9 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/global_error_bubble_view_base.h"
#include "chrome/browser/ui/gtk/bubble/bubble_gtk.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
#include "ui/base/gtk/gtk_signal.h"
typedef struct _GtkWidget GtkWidget;
@@ -19,9 +19,11 @@ class GlobalError;
class Profile;
class GlobalErrorBubble : public BubbleDelegateGtk,
- public content::NotificationObserver {
+ public GlobalErrorBubbleViewBase {
public:
- GlobalErrorBubble(Profile* profile, GlobalError* error, GtkWidget* anchor);
+ GlobalErrorBubble(Browser* browser,
+ const base::WeakPtr<GlobalError>& error,
+ GtkWidget* anchor);
virtual ~GlobalErrorBubble();
// BubbleDelegateGtk implementation.
@@ -32,17 +34,11 @@ class GlobalErrorBubble : public BubbleDelegateGtk,
CHROMEGTK_CALLBACK_0(GlobalErrorBubble, void, OnAcceptButton);
CHROMEGTK_CALLBACK_0(GlobalErrorBubble, void, OnCancelButton);
- // content::NotificationObserver overrides:
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
+ virtual void CloseBubbleView() OVERRIDE;
+ Browser* browser_;
BubbleGtk* bubble_;
- // Weak reference to the GlobalError instance the bubble is shown for. Is
- // reset to |NULL| if instance is removed from GlobalErrorService while
- // the bubble is still showing.
- GlobalError* error_;
- content::NotificationRegistrar registrar_;
+ base::WeakPtr<GlobalError> error_;
DISALLOW_COPY_AND_ASSIGN(GlobalErrorBubble);
};
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc b/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
index e6047e46..56a7df8 100644
--- a/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/wrench_menu_model_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -39,7 +39,6 @@ class MenuError : public GlobalError {
virtual void ExecuteMenuItem(Browser* browser) OVERRIDE { execute_count_++; }
virtual bool HasBubbleView() OVERRIDE { return false; }
- virtual void ShowBubbleView(Browser* browser) OVERRIDE { ADD_FAILURE(); }
virtual int GetBubbleViewIconResourceID() OVERRIDE {
ADD_FAILURE();
return 0;
@@ -60,9 +59,15 @@ class MenuError : public GlobalError {
ADD_FAILURE();
return string16();
}
- virtual void BubbleViewDidClose() OVERRIDE { ADD_FAILURE(); }
- virtual void BubbleViewAcceptButtonPressed() OVERRIDE { ADD_FAILURE(); }
- virtual void BubbleViewCancelButtonPressed() OVERRIDE { ADD_FAILURE(); }
+ virtual void OnBubbleViewDidClose(Browser* browser) OVERRIDE {
+ ADD_FAILURE();
+ }
+ virtual void BubbleViewAcceptButtonPressed(Browser* browser) OVERRIDE {
+ ADD_FAILURE();
+ }
+ virtual void BubbleViewCancelButtonPressed(Browser* browser) OVERRIDE {
+ ADD_FAILURE();
+ }
private:
int command_id_;
diff --git a/chrome/browser/ui/views/global_error_bubble_view.cc b/chrome/browser/ui/views/global_error_bubble_view.cc
index 9c368da..a801b0f 100644
--- a/chrome/browser/ui/views/global_error_bubble_view.cc
+++ b/chrome/browser/ui/views/global_error_bubble_view.cc
@@ -11,8 +11,6 @@
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar_view.h"
#include "chrome/browser/ui/views/window.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "content/public/browser/notification_service.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/button/text_button.h"
@@ -40,14 +38,35 @@ const int kLayoutBottomPadding = 2;
} // namespace
+// GlobalErrorBubbleViewBase ---------------------------------------------------
+
+// static
+GlobalErrorBubbleViewBase* GlobalErrorBubbleViewBase::ShowBubbleView(
+ Browser* browser,
+ const base::WeakPtr<GlobalError>& error) {
+ BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
+ views::View* wrench_button = browser_view->toolbar()->app_menu();
+ GlobalErrorBubbleView* bubble_view =
+ new GlobalErrorBubbleView(wrench_button,
+ views::BubbleBorder::TOP_RIGHT,
+ browser,
+ error);
+ browser::CreateViewsBubble(bubble_view);
+ bubble_view->StartFade(true);
+ return bubble_view;
+}
+
+// GlobalErrorBubbleView -------------------------------------------------------
+
GlobalErrorBubbleView::GlobalErrorBubbleView(
views::View* anchor_view,
views::BubbleBorder::ArrowLocation location,
Browser* browser,
- GlobalError* error)
+ const base::WeakPtr<GlobalError>& error)
: BubbleDelegateView(anchor_view, location),
browser_(browser),
error_(error) {
+ DCHECK(error_);
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
int resource_id = error_->GetBubbleViewIconResourceID();
scoped_ptr<views::ImageView> image_view(new views::ImageView());
@@ -122,9 +141,6 @@ GlobalErrorBubbleView::GlobalErrorBubbleView(
// Adjust the message label size in case buttons are too long.
message_label->SizeToFit(layout->GetPreferredSize(this).width());
-
- registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
- content::Source<Profile>(browser->profile()));
}
GlobalErrorBubbleView::~GlobalErrorBubbleView() {
@@ -138,54 +154,22 @@ gfx::Rect GlobalErrorBubbleView::GetAnchorRect() {
void GlobalErrorBubbleView::ButtonPressed(views::Button* sender,
const views::Event& event) {
- // We unsubscribe from removal notifications here and below because any of
- // GlobalError callbacks may remove it from the profile.
- registrar_.RemoveAll();
- if (sender->tag() == TAG_ACCEPT_BUTTON)
- error_->BubbleViewAcceptButtonPressed();
- else if (sender->tag() == TAG_CANCEL_BUTTON)
- error_->BubbleViewCancelButtonPressed();
- else
- NOTREACHED();
+ if (error_) {
+ if (sender->tag() == TAG_ACCEPT_BUTTON)
+ error_->BubbleViewAcceptButtonPressed(browser_);
+ else if (sender->tag() == TAG_CANCEL_BUTTON)
+ error_->BubbleViewCancelButtonPressed(browser_);
+ else
+ NOTREACHED();
+ }
GetWidget()->Close();
}
void GlobalErrorBubbleView::WindowClosing() {
- registrar_.RemoveAll();
if (error_)
- error_->BubbleViewDidClose();
-}
-
-void GlobalErrorBubbleView::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- DCHECK(type == chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED);
- DCHECK(error_);
- if (content::Details<GlobalError>(details).ptr() == error_) {
- Profile* profile = content::Source<Profile>(source).ptr();
- const std::vector<GlobalError*>& errors =
- GlobalErrorServiceFactory::GetForProfile(profile)->errors();
- // This handles the case when a GlobalError instance is removed from profile
- // not as a part of normal flow (i.e., after the bubble has been closed)
- // but while the bubble is still showing. |error_| is no longer guaranteed
- // to exist so we set it to |NULL| and dismiss the bubble.
- if (std::find(errors.begin(), errors.end(), error_) == errors.end()) {
- error_ = NULL;
- registrar_.RemoveAll();
- GetWidget()->Close();
- }
- }
+ error_->BubbleViewDidClose(browser_);
}
-void GlobalError::ShowBubbleView(Browser* browser, GlobalError* error) {
- BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
- views::View* wrench_button = browser_view->toolbar()->app_menu();
- GlobalErrorBubbleView* bubble_view =
- new GlobalErrorBubbleView(wrench_button,
- views::BubbleBorder::TOP_RIGHT,
- browser,
- error);
- browser::CreateViewsBubble(bubble_view);
- bubble_view->StartFade(true);
+void GlobalErrorBubbleView::CloseBubbleView() {
+ GetWidget()->Close();
}
diff --git a/chrome/browser/ui/views/global_error_bubble_view.h b/chrome/browser/ui/views/global_error_bubble_view.h
index 666cd67..116e5be 100644
--- a/chrome/browser/ui/views/global_error_bubble_view.h
+++ b/chrome/browser/ui/views/global_error_bubble_view.h
@@ -6,8 +6,8 @@
#define CHROME_BROWSER_UI_VIEWS_GLOBAL_ERROR_BUBBLE_VIEW_H_
#pragma once
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/global_error_bubble_view_base.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/controls/button/button.h"
@@ -16,12 +16,12 @@ class GlobalError;
class GlobalErrorBubbleView : public views::ButtonListener,
public views::BubbleDelegateView,
- public content::NotificationObserver {
+ public GlobalErrorBubbleViewBase {
public:
GlobalErrorBubbleView(views::View* anchor_view,
views::BubbleBorder::ArrowLocation location,
Browser* browser,
- GlobalError* error);
+ const base::WeakPtr<GlobalError>& error);
virtual ~GlobalErrorBubbleView();
// views::BubbleDelegateView implementation.
@@ -34,18 +34,12 @@ class GlobalErrorBubbleView : public views::ButtonListener,
// views::WidgetDelegate implementation.
virtual void WindowClosing() OVERRIDE;
- // content::NotificationObserver overrides:
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
+ // GlobalErrorBubbleViewBase implementation.
+ virtual void CloseBubbleView() OVERRIDE;
private:
Browser* browser_;
- // Weak reference to the GlobalError instance the bubble is shown for. Is
- // reset to |NULL| if instance is removed from GlobalErrorService while
- // the bubble is still showing.
- GlobalError* error_;
- content::NotificationRegistrar registrar_;
+ base::WeakPtr<GlobalError> error_;
DISALLOW_COPY_AND_ASSIGN(GlobalErrorBubbleView);
};
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 26b155f..c7e58f6 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2983,6 +2983,7 @@
'browser/ui/fullscreen_exit_bubble_type.h',
'browser/ui/global_error.cc',
'browser/ui/global_error.h',
+ 'browser/ui/global_error_bubble_view_base.h',
'browser/ui/global_error_service.cc',
'browser/ui/global_error_service.h',
'browser/ui/global_error_service_factory.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index e2ca1975..bdb4146 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -3055,8 +3055,6 @@
'../content/renderer/external_popup_menu_browsertest.cc',
],
'sources!': [
- # TODO(ivankr): enable this once http://crbug.com/109728 is fixed.
- 'browser/protector/protector_service_browsertest.cc',
# TODO(hbono): This test depends on hunspell and we cannot run it on
# Mac, which does not use hunspell by default.
'browser/spellchecker/spellcheck_host_browsertest.cc',