diff options
author | ivankr@chromium.org <ivankr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-21 16:05:37 +0000 |
---|---|---|
committer | ivankr@chromium.org <ivankr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-21 16:05:37 +0000 |
commit | 629918536d3620cb264f53bfb2992b8baca407a5 (patch) | |
tree | fa897c1af9630b238ec514f0334c3357acac7497 /chrome/browser/protector | |
parent | dc8532ac514bdda1baa24c0047bf17ac1296730a (diff) | |
download | chromium_src-629918536d3620cb264f53bfb2992b8baca407a5.zip chromium_src-629918536d3620cb264f53bfb2992b8baca407a5.tar.gz chromium_src-629918536d3620cb264f53bfb2992b8baca407a5.tar.bz2 |
Protector bubble cancels itself if user changes default search engine manually.
BUG=None
TEST=Manual: trigger protector bubble, change search engine manually; bubble should vanish.
Review URL: http://codereview.chromium.org/8612002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110933 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/protector')
-rw-r--r-- | chrome/browser/protector/base_setting_change.cc | 14 | ||||
-rw-r--r-- | chrome/browser/protector/base_setting_change.h | 19 | ||||
-rw-r--r-- | chrome/browser/protector/default_search_provider_change.cc | 83 | ||||
-rw-r--r-- | chrome/browser/protector/protector.cc | 39 | ||||
-rw-r--r-- | chrome/browser/protector/protector.h | 18 | ||||
-rw-r--r-- | chrome/browser/protector/settings_change_global_error.cc | 10 | ||||
-rw-r--r-- | chrome/browser/protector/settings_change_global_error.h | 18 |
7 files changed, 136 insertions, 65 deletions
diff --git a/chrome/browser/protector/base_setting_change.cc b/chrome/browser/protector/base_setting_change.cc index 255185a..80fe257 100644 --- a/chrome/browser/protector/base_setting_change.cc +++ b/chrome/browser/protector/base_setting_change.cc @@ -4,22 +4,30 @@ #include "chrome/browser/protector/base_setting_change.h" +#include "base/logging.h" + namespace protector { -BaseSettingChange::BaseSettingChange() { +BaseSettingChange::BaseSettingChange() + : protector_(NULL) { } BaseSettingChange::~BaseSettingChange() { } bool BaseSettingChange::Init(Protector* protector) { + DCHECK(protector); + protector_ = protector; return true; } -void BaseSettingChange::Apply(Protector* protector) { +void BaseSettingChange::Apply() { +} + +void BaseSettingChange::Discard() { } -void BaseSettingChange::Discard(Protector* protector) { +void BaseSettingChange::OnBeforeRemoved() { } } // namespace protector diff --git a/chrome/browser/protector/base_setting_change.h b/chrome/browser/protector/base_setting_change.h index e53f7eb..53f2518f 100644 --- a/chrome/browser/protector/base_setting_change.h +++ b/chrome/browser/protector/base_setting_change.h @@ -25,15 +25,21 @@ class BaseSettingChange { virtual ~BaseSettingChange(); // Applies initial actions to the setting if needed. Must be called before - // any other calls are made, including text getters. Returns true if - // initialization was successful. + // any other calls are made, including text getters. + // Returns true if initialization was successful. Otherwise, no other + // calls should be made. + // Associates this change with |protector_| instance so overrides must + // call the base method. virtual bool Init(Protector* protector); // Persists new setting if needed. - virtual void Apply(Protector* protector); + virtual void Apply(); // Restores old setting if needed. - virtual void Discard(Protector* protector); + virtual void Discard(); + + // Called before the change is removed from the protector instance. + virtual void OnBeforeRemoved() = 0; // Returns the wrench menu item and bubble title. virtual string16 GetBubbleTitle() const = 0; @@ -48,7 +54,12 @@ class BaseSettingChange { // Returns text for the button to discard the change with |Discard|. virtual string16 GetDiscardButtonText() const = 0; + // Protector instance we've been associated with by an |Init| call. + Protector* protector() { return protector_; } + private: + Protector* protector_; + DISALLOW_COPY_AND_ASSIGN(BaseSettingChange); }; diff --git a/chrome/browser/protector/default_search_provider_change.cc b/chrome/browser/protector/default_search_provider_change.cc index db37e27..026788d 100644 --- a/chrome/browser/protector/default_search_provider_change.cc +++ b/chrome/browser/protector/default_search_provider_change.cc @@ -9,6 +9,7 @@ #include "chrome/browser/protector/protector.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_service.h" +#include "chrome/browser/search_engines/template_url_service_observer.h" #include "chrome/browser/webdata/keyword_table.h" #include "chrome/common/url_constants.h" #include "grit/chromium_strings.h" @@ -25,33 +26,37 @@ const size_t kMaxDisplayedNameLength = 10; } // namespace -class DefaultSearchProviderChange : public BaseSettingChange { +class DefaultSearchProviderChange : public BaseSettingChange, + public TemplateURLServiceObserver { public: DefaultSearchProviderChange(const TemplateURL* old_url, const TemplateURL* new_url); // BaseSettingChange overrides: virtual bool Init(Protector* protector) OVERRIDE; - virtual void Apply(Protector* protector) OVERRIDE; - virtual void Discard(Protector* protector) OVERRIDE; + virtual void Apply() OVERRIDE; + virtual void Discard() OVERRIDE; + virtual void OnBeforeRemoved() OVERRIDE; virtual string16 GetBubbleTitle() const OVERRIDE; virtual string16 GetBubbleMessage() const OVERRIDE; virtual string16 GetApplyButtonText() const OVERRIDE; virtual string16 GetDiscardButtonText() const OVERRIDE; + // TemplateURLServiceObserver overrides: + virtual void OnTemplateURLServiceChanged() OVERRIDE; + private: virtual ~DefaultSearchProviderChange(); - // Sets the given default search provider to profile that |protector| is - // guarding. Returns the |TemplateURL| instance the default search provider - // has been set to. If no search provider with |id| exists and - // |allow_fallback| is true, sets one of the prepoluated search providers. - const TemplateURL* SetDefaultSearchProvider(Protector* protector, - int64 id, + // Sets the given default search provider to profile that this change is + // related to. Returns the |TemplateURL| instance of the new default search + // provider. If no search provider with |id| exists and |allow_fallback| is + // true, sets one of the prepopulated search providers. + const TemplateURL* SetDefaultSearchProvider(int64 id, bool allow_fallback); // Opens the Search engine settings page in a new tab. - void OpenSearchEngineSettings(Protector* protector); + void OpenSearchEngineSettings(); int64 old_id_; int64 new_id_; @@ -62,6 +67,12 @@ class DefaultSearchProviderChange : public BaseSettingChange { // Name of the search engine that we fall back to if the backup is lost. string16 fallback_name_; string16 product_name_; + // Default search provider set by |Init| for the period until user makes a + // choice and either |Apply| or |Discard| is performed. Should only be used + // for comparison with the current default search provider and never + // dereferenced other than in |Init| because it may be deallocated by + // TemplateURLService at any time. + const TemplateURL* default_search_provider_; DISALLOW_COPY_AND_ASSIGN(DefaultSearchProviderChange); }; @@ -72,7 +83,8 @@ DefaultSearchProviderChange::DefaultSearchProviderChange( : old_id_(0), new_id_(0), fallback_id_(0), - product_name_(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)) { + product_name_(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)), + default_search_provider_(NULL) { if (new_url) { new_id_ = new_url->id(); new_name_ = new_url->short_name(); @@ -87,41 +99,50 @@ DefaultSearchProviderChange::~DefaultSearchProviderChange() { } bool DefaultSearchProviderChange::Init(Protector* protector) { + BaseSettingChange::Init(protector); + // Initially reset the search engine to its previous setting. - const TemplateURL* current_url = - SetDefaultSearchProvider(protector, old_id_, true); - if (!current_url) + default_search_provider_ = SetDefaultSearchProvider(old_id_, true); + if (!default_search_provider_) return false; - if (!old_id_ || current_url->id() != old_id_) { + + if (!old_id_ || default_search_provider_->id() != old_id_) { // Old settings is lost or invalid, so we had to fall back to one of the // prepopulated search engines. - fallback_id_ = current_url->id(); - fallback_name_ = current_url->short_name(); + fallback_id_ = default_search_provider_->id(); + fallback_name_ = default_search_provider_->short_name(); VLOG(1) << "Fallback to " << fallback_name_; } + + protector->GetTemplateURLService()->AddObserver(this); + return true; } -void DefaultSearchProviderChange::Apply(Protector* protector) { +void DefaultSearchProviderChange::Apply() { // TODO(avayvod): Add histrogram. if (!new_id_) { // Open settings page in case the new setting is invalid. - OpenSearchEngineSettings(protector); + OpenSearchEngineSettings(); } else { - SetDefaultSearchProvider(protector, new_id_, false); + SetDefaultSearchProvider(new_id_, false); } } -void DefaultSearchProviderChange::Discard(Protector* protector) { +void DefaultSearchProviderChange::Discard() { // TODO(avayvod): Add histrogram. if (!old_id_) { // Open settings page in case the old setting is invalid. - OpenSearchEngineSettings(protector); + OpenSearchEngineSettings(); } // Nothing to do otherwise since we have already set the search engine // to |old_id_| in |Init|. } +void DefaultSearchProviderChange::OnBeforeRemoved() { + protector()->GetTemplateURLService()->RemoveObserver(this); +} + string16 DefaultSearchProviderChange::GetBubbleTitle() const { return l10n_util::GetStringUTF16(IDS_SEARCH_ENGINE_CHANGE_TITLE); } @@ -168,11 +189,20 @@ string16 DefaultSearchProviderChange::GetDiscardButtonText() const { } } +void DefaultSearchProviderChange::OnTemplateURLServiceChanged() { + if (protector()->GetTemplateURLService()->GetDefaultSearchProvider() != + default_search_provider_) { + default_search_provider_ = NULL; + VLOG(1) << "Default search provider has been changed by user"; + // This will delete the Protector instance and |this|. + protector()->DismissChange(); + } +} + const TemplateURL* DefaultSearchProviderChange::SetDefaultSearchProvider( - Protector* protector, int64 id, bool allow_fallback) { - TemplateURLService* url_service = protector->GetTemplateURLService(); + TemplateURLService* url_service = protector()->GetTemplateURLService(); if (!url_service) { NOTREACHED() << "Can't get TemplateURLService object."; return NULL; @@ -199,9 +229,8 @@ const TemplateURL* DefaultSearchProviderChange::SetDefaultSearchProvider( return url; } -void DefaultSearchProviderChange::OpenSearchEngineSettings( - Protector* protector) { - protector->OpenTab( +void DefaultSearchProviderChange::OpenSearchEngineSettings() { + protector()->OpenTab( GURL(std::string(chrome::kChromeUISettingsURL) + chrome::kSearchEnginesSubPage)); } diff --git a/chrome/browser/protector/protector.cc b/chrome/browser/protector/protector.cc index 606302c..9b2d417 100644 --- a/chrome/browser/protector/protector.cc +++ b/chrome/browser/protector/protector.cc @@ -26,6 +26,8 @@ Protector::Protector(Profile* profile) } Protector::~Protector() { + if (change_.get()) + change_->OnBeforeRemoved(); } void Protector::OpenTab(const GURL& url) { @@ -48,37 +50,44 @@ void Protector::ShowChange(BaseSettingChange* change) { base::Unretained(this), change)); } -void Protector::InitAndShowChange(BaseSettingChange* change) { - VLOG(1) << "Init change"; - if (!change->Init(this)) { - VLOG(1) << "Error while initializing, removing ourselves"; - delete change; - OnRemovedFromProfile(); - return; - } - error_.reset(new SettingsChangeGlobalError(change, this)); - error_->ShowForProfile(profile_); +void Protector::DismissChange() { + DCHECK(error_.get()); + error_->RemoveFromProfile(); } void Protector::OnApplyChange() { - VLOG(1) << "Apply change"; - error_->mutable_change()->Apply(this); + DVLOG(1) << "Apply change"; + change_->Apply(); } void Protector::OnDiscardChange() { - VLOG(1) << "Discard change"; - error_->mutable_change()->Discard(this); + DVLOG(1) << "Discard change"; + change_->Discard(); } void Protector::OnDecisionTimeout() { // TODO(ivankr): Add histogram. - VLOG(1) << "Timeout"; + DVLOG(1) << "Timeout"; } void Protector::OnRemovedFromProfile() { BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this); } +void Protector::InitAndShowChange(BaseSettingChange* change) { + DVLOG(1) << "Init change"; + if (!change->Init(this)) { + LOG(WARNING) << "Error while initializing, removing ourselves"; + delete change; + delete this; + return; + } + // |change_| should not be set until a successful |Init| call. + change_.reset(change); + error_.reset(new SettingsChangeGlobalError(change, this)); + error_->ShowForProfile(profile_); +} + std::string SignSetting(const std::string& value) { crypto::HMAC hmac(crypto::HMAC::SHA256); diff --git a/chrome/browser/protector/protector.h b/chrome/browser/protector/protector.h index 85ac9ae..fe9f6544a 100644 --- a/chrome/browser/protector/protector.h +++ b/chrome/browser/protector/protector.h @@ -31,14 +31,16 @@ class Protector : public SettingsChangeGlobalErrorDelegate { // bubble for. void OpenTab(const GURL& url); - // Returns TemplateURLService for the profile we've shown error bubble - // for. + // Returns TemplateURLService for the profile we've shown error bubble for. TemplateURLService* GetTemplateURLService(); - // Shows global error about the specified change. Ownership of the change - // is passed to the GlobalError object. + // Shows global error about the specified change. Owns |change|. void ShowChange(BaseSettingChange* change); + // Silently discards any change previously shown (without calling Discard), + // removes global error and deletes itself. + void DismissChange(); + // SettingsChangeGlobalErrorDelegate implementation. virtual void OnApplyChange() OVERRIDE; virtual void OnDiscardChange() OVERRIDE; @@ -53,13 +55,17 @@ class Protector : public SettingsChangeGlobalErrorDelegate { // Performs the initial action on settings change and shows it. This is run // asynchronously on UI thread because |ShowChange| may be called in the - // middle of some operations on settings that have changed. + // middle of some operations on settings that have changed. If the initial + // action fails, deletes itself. void InitAndShowChange(BaseSettingChange* change); // Pointer to error bubble controller. Indicates if we're showing change - // notification to user. Owns itself. + // notification to user. scoped_ptr<SettingsChangeGlobalError> error_; + // Setting change which we're showing. + scoped_ptr<BaseSettingChange> change_; + // Profile which settings we are protecting. Profile* profile_; diff --git a/chrome/browser/protector/settings_change_global_error.cc b/chrome/browser/protector/settings_change_global_error.cc index 4a7583c..74d8c83 100644 --- a/chrome/browser/protector/settings_change_global_error.cc +++ b/chrome/browser/protector/settings_change_global_error.cc @@ -10,6 +10,7 @@ #include "base/stl_util.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/protector/base_setting_change.h" #include "chrome/browser/protector/settings_change_global_error_delegate.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/global_error_service.h" @@ -103,8 +104,6 @@ void SettingsChangeGlobalError::BubbleViewCancelButtonPressed() { void SettingsChangeGlobalError::RemoveFromProfile() { if (profile_) GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(this); - if (!closed_by_button_) - delegate_->OnDecisionTimeout(); delegate_->OnRemovedFromProfile(); } @@ -113,7 +112,7 @@ void SettingsChangeGlobalError::BubbleViewDidClose() { if (!closed_by_button_) { BrowserThread::PostDelayedTask( BrowserThread::UI, FROM_HERE, - base::Bind(&SettingsChangeGlobalError::RemoveFromProfile, + base::Bind(&SettingsChangeGlobalError::OnInactiveTimeout, weak_factory_.GetWeakPtr()), kMenuItemDisplayPeriodMs); } else { @@ -148,4 +147,9 @@ void SettingsChangeGlobalError::Show() { ShowBubbleView(browser_); } +void SettingsChangeGlobalError::OnInactiveTimeout() { + delegate_->OnDecisionTimeout(); + RemoveFromProfile(); +} + } // namespace protector diff --git a/chrome/browser/protector/settings_change_global_error.h b/chrome/browser/protector/settings_change_global_error.h index ff0064f..8619414 100644 --- a/chrome/browser/protector/settings_change_global_error.h +++ b/chrome/browser/protector/settings_change_global_error.h @@ -18,13 +18,15 @@ class Profile; namespace protector { +class BaseSettingChange; class SettingsChangeGlobalErrorDelegate; // Global error about unwanted settings changes. class SettingsChangeGlobalError : public GlobalError { public: - // Creates new global error about setting changes |change| and takes - // ownership over it. Uses |delegate| to notify about user decision. + // Creates new global error about setting changes |change| which must not be + // deleted until |delegate->OnRemovedFromProfile| is called. Uses |delegate| + // to notify about user decision. SettingsChangeGlobalError(BaseSettingChange* change, SettingsChangeGlobalErrorDelegate* delegate); virtual ~SettingsChangeGlobalError(); @@ -33,11 +35,12 @@ class SettingsChangeGlobalError : public GlobalError { // Can be called from any thread. void ShowForProfile(Profile* profile); + // Removes global error from its profile. + void RemoveFromProfile(); + // Browser that the bubble has been last time shown for. Browser* browser() const { return browser_; } - BaseSettingChange* mutable_change() { return change_.get(); } - // GlobalError implementation. virtual bool HasBadge() OVERRIDE; virtual bool HasMenuItem() OVERRIDE; @@ -61,11 +64,12 @@ class SettingsChangeGlobalError : public GlobalError { // Displays global error bubble. Must be called on the UI thread. void Show(); - // Removes global error from its profile and deletes |this| later. - void RemoveFromProfile(); + // Called when the wrench menu item has been displayed for enough time + // without user interaction. + void OnInactiveTimeout(); // Change to show. - scoped_ptr<BaseSettingChange> change_; + BaseSettingChange* change_; // Delegate to notify about user actions. SettingsChangeGlobalErrorDelegate* delegate_; |