summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/protector/default_search_provider_change.cc120
-rw-r--r--chrome/browser/protector/histograms.cc12
-rw-r--r--chrome/browser/protector/histograms.h27
-rw-r--r--chrome/browser/protector/keys.cc13
-rw-r--r--chrome/browser/protector/keys.h18
-rw-r--r--chrome/browser/protector/protector.cc80
-rw-r--r--chrome/browser/protector/protector.h73
-rw-r--r--chrome/browser/protector/setting_change.h73
-rw-r--r--chrome/browser/protector/settings_change_global_error.cc107
-rw-r--r--chrome/browser/protector/settings_change_global_error.h76
-rw-r--r--chrome/browser/protector/settings_change_global_error_delegate.h32
-rw-r--r--chrome/browser/search_engines/template_url_service.cc51
-rw-r--r--chrome/browser/search_engines/template_url_service.h11
-rw-r--r--chrome/browser/search_engines/util.cc49
-rw-r--r--chrome/browser/search_engines/util.h9
-rw-r--r--chrome/browser/webdata/keyword_table.cc70
-rw-r--r--chrome/browser/webdata/keyword_table.h9
-rw-r--r--chrome/browser/webdata/keyword_table_unittest.cc4
-rw-r--r--chrome/browser/webdata/web_data_service.cc4
-rw-r--r--chrome/browser/webdata/web_data_service.h5
-rw-r--r--chrome/browser/webdata/web_data_service_unittest.cc44
-rw-r--r--chrome/chrome_browser.gypi9
22 files changed, 746 insertions, 150 deletions
diff --git a/chrome/browser/protector/default_search_provider_change.cc b/chrome/browser/protector/default_search_provider_change.cc
new file mode 100644
index 0000000..9075f41
--- /dev/null
+++ b/chrome/browser/protector/default_search_provider_change.cc
@@ -0,0 +1,120 @@
+// Copyright (c) 2011 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 "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "chrome/browser/protector/protector.h"
+#include "chrome/browser/protector/setting_change.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/webdata/keyword_table.h"
+#include "chrome/common/url_constants.h"
+#include "googleurl/src/gurl.h"
+
+namespace protector {
+
+class DefaultSearchProviderChange : public SettingChange {
+ public:
+ DefaultSearchProviderChange(const TemplateURL* old_url,
+ const TemplateURL* new_url);
+
+ // SettingChange overrides:
+ virtual string16 GetOldSetting() const OVERRIDE;
+ virtual string16 GetNewSetting() const OVERRIDE;
+ virtual void Accept(Protector* protector) OVERRIDE;
+ virtual void Revert(Protector* protector) OVERRIDE;
+ virtual void DoDefault(Protector* protector) OVERRIDE;
+
+ private:
+ virtual ~DefaultSearchProviderChange();
+
+ // Sets the given default search provider to profile that |protector| is
+ // guarding.
+ void SetDefaultSearchProvider(Protector* protector, int64 id);
+
+ int64 old_id_;
+ int64 new_id_;
+ string16 old_name_;
+ string16 new_name_;
+
+ DISALLOW_COPY_AND_ASSIGN(DefaultSearchProviderChange);
+};
+
+DefaultSearchProviderChange::DefaultSearchProviderChange(
+ const TemplateURL* old_url,
+ const TemplateURL* new_url)
+ : SettingChange(kSearchEngineChanged),
+ old_id_(0),
+ new_id_(0) {
+ DCHECK(new_url);
+ new_id_ = new_url->id();
+ new_name_ = new_url->short_name();
+ if (old_url) {
+ old_id_ = old_url->id();
+ old_name_ = old_url->short_name();
+ }
+}
+
+DefaultSearchProviderChange::~DefaultSearchProviderChange() {
+}
+
+string16 DefaultSearchProviderChange::GetOldSetting() const {
+ return old_name_;
+}
+
+string16 DefaultSearchProviderChange::GetNewSetting() const {
+ return new_name_;
+}
+
+void DefaultSearchProviderChange::Accept(Protector* protector) {
+ SetDefaultSearchProvider(protector, new_id_);
+ // TODO(avayvod): Add histrogram.
+}
+
+void DefaultSearchProviderChange::Revert(Protector* protector) {
+ SetDefaultSearchProvider(protector, old_id_);
+ if (!old_id_) {
+ // Open settings page in case the original setting was lost.
+ protector->OpenTab(
+ GURL(std::string(chrome::kChromeUISettingsURL) +
+ chrome::kSearchEnginesSubPage));
+ }
+ // TODO(avayvod): Add histrogram.
+}
+
+void DefaultSearchProviderChange::DoDefault(Protector* protector) {
+ SetDefaultSearchProvider(protector, old_id_);
+ // TODO(avayvod): Add histrogram.
+}
+
+void DefaultSearchProviderChange::SetDefaultSearchProvider(
+ Protector* protector,
+ int64 id) {
+ DCHECK(protector);
+ TemplateURLService* url_service = protector->GetTemplateURLService();
+ if (!url_service) {
+ LOG(WARNING) << "Can't get TemplateURLService object.";
+ return;
+ }
+ const TemplateURL* url = NULL;
+ const TemplateURLService::TemplateURLVector& urls =
+ url_service->GetTemplateURLs();
+ for (size_t i = 0; i < urls.size(); ++i)
+ if (urls[i]->id() == id) {
+ url = urls[i];
+ break;
+ }
+ if (!url)
+ url = url_service->FindNewDefaultSearchProvider();
+ url_service->SetDefaultSearchProvider(url);
+}
+
+SettingChange* CreateDefaultSearchProviderChange(
+ const TemplateURL* actual,
+ const TemplateURL* backup) {
+ return new DefaultSearchProviderChange(backup, actual);
+}
+
+} // namespace protector
diff --git a/chrome/browser/protector/histograms.cc b/chrome/browser/protector/histograms.cc
new file mode 100644
index 0000000..558e26b
--- /dev/null
+++ b/chrome/browser/protector/histograms.cc
@@ -0,0 +1,12 @@
+// Copyright (c) 2011 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/protector/histograms.h"
+
+namespace protector {
+
+const char kProtectorHistogramDefaultSearchProvider[] =
+ "Protector.DefaultSearchProvider";
+
+} // namespace protector
diff --git a/chrome/browser/protector/histograms.h b/chrome/browser/protector/histograms.h
new file mode 100644
index 0000000..71b5e68
--- /dev/null
+++ b/chrome/browser/protector/histograms.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2011 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_PROTECTOR_HISTOGRAMS_H_
+#define CHROME_BROWSER_PROTECTOR_HISTOGRAMS_H_
+#pragma once
+
+namespace protector {
+
+// Histogram name to report protection errors for the default search
+// provider.
+extern const char kProtectorHistogramDefaultSearchProvider[];
+
+// Protector histogram values.
+enum ProtectorError {
+ kProtectorErrorBackupInvalid,
+ kProtectorErrorValueChanged,
+
+ // This is for convenience only, must always be the last.
+ kProtectorErrorCount
+};
+
+} // namespace protector
+
+#endif // CHROME_BROWSER_PROTECTOR_HISTOGRAMS_H_
+
diff --git a/chrome/browser/protector/keys.cc b/chrome/browser/protector/keys.cc
new file mode 100644
index 0000000..6f4630b
--- /dev/null
+++ b/chrome/browser/protector/keys.cc
@@ -0,0 +1,13 @@
+// Copyright (c) 2011 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/protector/keys.h"
+
+namespace protector {
+
+// When changing the key, be sure to add migration code to keep user's
+// settings safe.
+const char kProtectorSigningKey[] = "Please, don't change this Chrome setting";
+
+} // namespace protector
diff --git a/chrome/browser/protector/keys.h b/chrome/browser/protector/keys.h
new file mode 100644
index 0000000..69791f4
--- /dev/null
+++ b/chrome/browser/protector/keys.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2011 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_PROTECTOR_KEYS_H_
+#define CHROME_BROWSER_PROTECTOR_KEYS_H_
+#pragma once
+
+namespace protector {
+
+// When changing the key, be sure to add migration code to keep user's
+// settings safe.
+extern const char kProtectorSigningKey[];
+
+} // namespace protector
+
+#endif // CHROME_BROWSER_PROTECTOR_KEYS_H_
+
diff --git a/chrome/browser/protector/protector.cc b/chrome/browser/protector/protector.cc
new file mode 100644
index 0000000..f3acaca
--- /dev/null
+++ b/chrome/browser/protector/protector.cc
@@ -0,0 +1,80 @@
+// Copyright (c) 2011 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/protector/protector.h"
+
+#include "base/logging.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/protector/settings_change_global_error.h"
+#include "chrome/browser/protector/keys.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/browser/browser_thread.h"
+#include "content/public/browser/notification_source.h"
+#include "crypto/hmac.h"
+
+namespace protector {
+
+Protector::Protector(Profile* profile)
+ : profile_(profile) {
+}
+
+Protector::~Protector() {
+}
+
+void Protector::OpenTab(const GURL& url) {
+ if (!error_.get() || !error_->browser()) {
+ LOG(WARNING) << "Don't have browser to show tab in.";
+ return;
+ }
+ error_->browser()->ShowSingletonTab(url);
+}
+
+TemplateURLService* Protector::GetTemplateURLService() {
+ return TemplateURLServiceFactory::GetForProfile(profile_);
+}
+
+void Protector::ShowChange(SettingChange* change) {
+ DCHECK(change);
+ SettingChangeVector changes(1, change);
+
+ error_.reset(new SettingsChangeGlobalError(changes, this));
+ error_->ShowForProfile(profile_);
+}
+
+void Protector::OnApplyChanges() {
+ OnChangesAction(&SettingChange::Accept);
+}
+
+void Protector::OnDiscardChanges() {
+ OnChangesAction(&SettingChange::Revert);
+}
+
+void Protector::OnDecisionTimeout() {
+ OnChangesAction(&SettingChange::DoDefault);
+}
+
+void Protector::OnChangesAction(SettingChangeAction action) {
+ DCHECK(error_.get());
+ SettingChangeVector* changes = error_->mutable_changes();
+ for (SettingChangeVector::iterator it = changes->begin();
+ it != changes->end(); ++it)
+ ((*it)->*action)(this);
+ BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
+}
+
+
+std::string SignSetting(const std::string& value) {
+ crypto::HMAC hmac(crypto::HMAC::SHA256);
+ DCHECK(hmac.Init(kProtectorSigningKey));
+
+ std::vector<unsigned char> digest(hmac.DigestLength());
+ DCHECK(hmac.Sign(value, &digest[0], digest.size()));
+
+ return std::string(&digest[0], &digest[0] + digest.size());
+}
+
+} // namespace protector
diff --git a/chrome/browser/protector/protector.h b/chrome/browser/protector/protector.h
new file mode 100644
index 0000000..c508d73
--- /dev/null
+++ b/chrome/browser/protector/protector.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2011 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_PROTECTOR_PROTECTOR_H_
+#define CHROME_BROWSER_PROTECTOR_PROTECTOR_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/task.h"
+#include "chrome/browser/protector/setting_change.h"
+#include "chrome/browser/protector/settings_change_global_error_delegate.h"
+
+class GURL;
+class Profile;
+class TemplateURLService;
+
+namespace protector {
+
+class SettingsChangeGlobalError;
+
+// Accumulates settings changes and shows them altogether to user.
+// Deletes itself when changes are shown to the user and some action is taken
+// or timeout expires.
+class Protector : public SettingsChangeGlobalErrorDelegate {
+ public:
+ explicit Protector(Profile* profile);
+
+ // Opens a tab with specified URL in the browser window we've shown error
+ // bubble for.
+ void OpenTab(const GURL& url);
+
+ // 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 error object.
+ void ShowChange(SettingChange* change);
+
+ // SettingsChangeGlobalErrorDelegate implementation.
+ virtual void OnApplyChanges() OVERRIDE;
+ virtual void OnDiscardChanges() OVERRIDE;
+ virtual void OnDecisionTimeout() OVERRIDE;
+
+ private:
+ friend class DeleteTask<Protector>;
+
+ // The object can only be allocated and destroyed on heap.
+ virtual ~Protector();
+
+ // Common handler for error delegate handlers. Calls the specified method
+ // on each change we showed error for.
+ void OnChangesAction(SettingChangeAction action);
+
+ // Pointer to error bubble controller. Indicates if we're showing change
+ // notification to user. Owns itself.
+ scoped_ptr<SettingsChangeGlobalError> error_;
+
+ // Profile which settings we are protecting.
+ Profile* profile_;
+
+ DISALLOW_COPY_AND_ASSIGN(Protector);
+};
+
+// Signs string value with protector's key.
+std::string SignSetting(const std::string& value);
+
+} // namespace protector
+
+#endif // CHROME_BROWSER_PROTECTOR_PROTECTOR_H_
diff --git a/chrome/browser/protector/setting_change.h b/chrome/browser/protector/setting_change.h
new file mode 100644
index 0000000..0a1e1d2
--- /dev/null
+++ b/chrome/browser/protector/setting_change.h
@@ -0,0 +1,73 @@
+// Copyright (c) 2011 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_PROTECTOR_SETTING_CHANGE_H_
+#define CHROME_BROWSER_PROTECTOR_SETTING_CHANGE_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/string16.h"
+
+class TemplateURL;
+
+namespace protector {
+
+class Protector;
+
+// Base class for setting change tracked by Protector.
+class SettingChange {
+ public:
+ // IDs of changes Protector currently tracks.
+ enum Type {
+ // Default search engine has been changed.
+ kSearchEngineChanged,
+
+ // Home page has been changed.
+ kHomePageChanged,
+ };
+
+ explicit SettingChange(Type type) : type_(type) {}
+ virtual ~SettingChange() {}
+
+ Type type() const { return type_; }
+
+ // Returns the old setting presentation to be shown to user.
+ // Returns empty string if the old setting is unavailable.
+ virtual string16 GetOldSetting() const = 0;
+
+ // Returns the new setting presentation to be shown to user.
+ virtual string16 GetNewSetting() const = 0;
+
+ // Persists new setting if needed.
+ virtual void Accept(Protector* protector) {}
+
+ // Restores old setting value if needed.
+ virtual void Revert(Protector* protector) {}
+
+ // Called when user ignored the change.
+ virtual void DoDefault(Protector* protector) {}
+
+ private:
+ // Type of the change. Used for strings lookup by UI.
+ // TODO(avayvod): Refactor string selection logic via polymorphism.
+ Type type_;
+
+ DISALLOW_COPY_AND_ASSIGN(SettingChange);
+};
+
+typedef std::vector<SettingChange*> SettingChangeVector;
+typedef void (SettingChange::*SettingChangeAction)(Protector*);
+
+// Allocates and initializes SettingChange implementation for default search
+// provider setting.
+SettingChange* CreateDefaultSearchProviderChange(
+ const TemplateURL* actual,
+ const TemplateURL* backup);
+
+} // namespace protector
+
+#endif // CHROME_BROWSER_PROTECTOR_SETTING_CHANGE_H_
diff --git a/chrome/browser/protector/settings_change_global_error.cc b/chrome/browser/protector/settings_change_global_error.cc
index a472d30..d8e161c 100644
--- a/chrome/browser/protector/settings_change_global_error.cc
+++ b/chrome/browser/protector/settings_change_global_error.cc
@@ -5,46 +5,57 @@
#include "chrome/browser/protector/settings_change_global_error.h"
#include "base/bind.h"
-#include "base/task.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/stl_util.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.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"
#include "chrome/browser/ui/global_error_service_factory.h"
+#include "content/browser/browser_thread.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
+namespace protector {
+
namespace {
// Timeout before the global error is removed (wrench menu item disappears).
const int kMenuItemDisplayPeriodMs = 10*60*1000; // 10 min
+
// IDs of menu item labels.
const int kMenuItemLabelIDs[] = {
IDS_SEARCH_ENGINE_CHANGE_WRENCH_MENU_ITEM,
IDS_HOMEPAGE_CHANGE_WRENCH_MENU_ITEM
};
+
// IDs of bubble title messages.
const int kBubbleTitleIDs[] = {
IDS_SEARCH_ENGINE_CHANGE_BUBBLE_TITLE,
IDS_HOMEPAGE_CHANGE_BUBBLE_TITLE
};
+
// IDs of bubble text messages.
const int kBubbleMessageIDs[] = {
IDS_SEARCH_ENGINE_CHANGE_BUBBLE_TEXT,
IDS_HOMEPAGE_CHANGE_BUBBLE_TEXT
};
+
// IDs of bubble text messages when the old setting is unknown.
const int kBubbleMessageOldUnknownIDs[] = {
IDS_SEARCH_ENGINE_CHANGE_UNKNOWN_BUBBLE_TEXT,
IDS_HOMEPAGE_CHANGE_UNKNOWN_BUBBLE_TEXT
};
+
// IDs of "Keep Setting" button titles.
const int kBubbleKeepSettingIDs[] = {
IDS_SEARCH_ENGINE_CHANGE_RESTORE,
IDS_HOMEPAGE_CHANGE_RESTORE
};
+
// IDs of "Change Setting" button titles.
const int kBubbleChangeSettingIDs[] = {
IDS_SEARCH_ENGINE_CHANGE_APPLY,
@@ -54,19 +65,19 @@ const int kBubbleChangeSettingIDs[] = {
} // namespace
SettingsChangeGlobalError::SettingsChangeGlobalError(
- const ChangesVector& changes,
- const base::Closure& apply_changes_cb,
- const base::Closure& revert_changes_cb)
+ const SettingChangeVector& changes,
+ SettingsChangeGlobalErrorDelegate* delegate)
: changes_(changes),
- apply_changes_cb_(apply_changes_cb),
- revert_changes_cb_(revert_changes_cb),
+ delegate_(delegate),
profile_(NULL),
+ browser_(NULL),
closed_by_button_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
DCHECK(changes.size() > 0);
}
SettingsChangeGlobalError::~SettingsChangeGlobalError() {
+ STLDeleteElements(&changes_);
}
bool SettingsChangeGlobalError::HasBadge() {
@@ -86,12 +97,14 @@ int SettingsChangeGlobalError::MenuItemCommandID() {
// can display warning about multiple changes.
string16 SettingsChangeGlobalError::MenuItemLabel() {
- return l10n_util::GetStringUTF16(kMenuItemLabelIDs[changes_.front().type]);
+ return l10n_util::GetStringUTF16(kMenuItemLabelIDs[changes_.front()->type()]);
}
void SettingsChangeGlobalError::ExecuteMenuItem(Browser* browser) {
- weak_factory_.InvalidateWeakPtrs(); // Cancel previously posted tasks.
- ShowBubbleView(browser);
+ // Cancel previously posted tasks.
+ weak_factory_.InvalidateWeakPtrs();
+ browser_ = browser;
+ ShowBubbleView(browser_);
}
bool SettingsChangeGlobalError::HasBubbleView() {
@@ -99,30 +112,40 @@ bool SettingsChangeGlobalError::HasBubbleView() {
}
string16 SettingsChangeGlobalError::GetBubbleViewTitle() {
- return l10n_util::GetStringUTF16(kBubbleTitleIDs[changes_.front().type]);
+ return l10n_util::GetStringUTF16(kBubbleTitleIDs[changes_.front()->type()]);
}
string16 SettingsChangeGlobalError::GetBubbleViewMessage() {
- const Change& change = changes_.front();
- return change.old_setting.empty() ?
- l10n_util::GetStringFUTF16(kBubbleMessageOldUnknownIDs[change.type],
- change.new_setting) :
- l10n_util::GetStringFUTF16(kBubbleMessageIDs[change.type],
- change.old_setting, change.new_setting);
+ SettingChange* change = changes_.front();
+ const string16& old_setting = change->GetOldSetting();
+ if (old_setting.empty()) {
+ return l10n_util::GetStringFUTF16(
+ kBubbleMessageOldUnknownIDs[change->type()],
+ change->GetNewSetting());
+ } else {
+ return l10n_util::GetStringFUTF16(
+ kBubbleMessageIDs[change->type()],
+ old_setting,
+ change->GetNewSetting());
+ }
}
string16 SettingsChangeGlobalError::GetBubbleViewAcceptButtonLabel() {
- const Change& change = changes_.front();
- return l10n_util::GetStringFUTF16(kBubbleChangeSettingIDs[change.type],
- change.new_setting);
+ SettingChange* change = changes_.front();
+ return l10n_util::GetStringFUTF16(kBubbleChangeSettingIDs[change->type()],
+ change->GetNewSetting());
}
string16 SettingsChangeGlobalError::GetBubbleViewCancelButtonLabel() {
- const Change& change = changes_.front();
- return change.old_setting.empty() ?
- l10n_util::GetStringUTF16(IDS_SETTINGS_CHANGE_OPEN_SETTINGS) :
- l10n_util::GetStringFUTF16(kBubbleKeepSettingIDs[change.type],
- change.old_setting);
+ SettingChange* change = changes_.front();
+ string16 old_setting = change->GetOldSetting();
+ if (old_setting.empty()) {
+ return l10n_util::GetStringUTF16(IDS_SETTINGS_CHANGE_OPEN_SETTINGS);
+ } else {
+ return l10n_util::GetStringFUTF16(
+ kBubbleKeepSettingIDs[change->type()],
+ old_setting);
+ }
}
bool SettingsChangeGlobalError::IsAcceptButtonDefault() {
@@ -130,24 +153,29 @@ bool SettingsChangeGlobalError::IsAcceptButtonDefault() {
}
void SettingsChangeGlobalError::BubbleViewAcceptButtonPressed() {
+ DCHECK(delegate_);
VLOG(1) << "Apply changes";
- apply_changes_cb_.Run();
+ delegate_->OnApplyChanges();
closed_by_button_ = true;
}
void SettingsChangeGlobalError::BubbleViewCancelButtonPressed() {
- VLOG(1) << "Revert changes";
- revert_changes_cb_.Run();
+ DCHECK(delegate_);
+ VLOG(1) << "Discard changes";
+ delegate_->OnDiscardChanges();
closed_by_button_ = true;
}
void SettingsChangeGlobalError::RemoveFromProfile() {
+ DCHECK(delegate_);
if (profile_)
GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(this);
- BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
+ if (!closed_by_button_)
+ delegate_->OnDecisionTimeout();
}
void SettingsChangeGlobalError::BubbleViewDidClose() {
+ browser_ = NULL;
if (!closed_by_button_) {
BrowserThread::PostDelayedTask(
BrowserThread::UI, FROM_HERE,
@@ -159,20 +187,21 @@ void SettingsChangeGlobalError::BubbleViewDidClose() {
}
}
-void SettingsChangeGlobalError::ShowForDefaultProfile() {
+void SettingsChangeGlobalError::ShowForProfile(Profile* profile) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- AddToDefaultProfile();
+ AddToProfile(profile);
} else {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&SettingsChangeGlobalError::AddToDefaultProfile,
- base::Unretained(this)));
+ base::Bind(&SettingsChangeGlobalError::AddToProfile,
+ base::Unretained(this),
+ profile));
}
}
-void SettingsChangeGlobalError::AddToDefaultProfile() {
+void SettingsChangeGlobalError::AddToProfile(Profile* profile) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- profile_ = ProfileManager::GetDefaultProfile();
+ profile_ = profile;
GlobalErrorServiceFactory::GetForProfile(profile_)->AddGlobalError(this);
Show();
}
@@ -180,7 +209,9 @@ void SettingsChangeGlobalError::AddToDefaultProfile() {
void SettingsChangeGlobalError::Show() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(profile_);
- Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
- if (browser)
- ShowBubbleView(browser);
+ browser_ = BrowserList::GetLastActiveWithProfile(profile_);
+ if (browser_)
+ ShowBubbleView(browser_);
}
+
+} // namespace protector
diff --git a/chrome/browser/protector/settings_change_global_error.h b/chrome/browser/protector/settings_change_global_error.h
index 9e08df8..6694fe8 100644
--- a/chrome/browser/protector/settings_change_global_error.h
+++ b/chrome/browser/protector/settings_change_global_error.h
@@ -6,44 +6,38 @@
#define CHROME_BROWSER_PROTECTOR_SETTINGS_CHANGE_GLOBAL_ERROR_H_
#pragma once
-#include <vector>
-
#include "base/basictypes.h"
-#include "base/callback.h"
#include "base/compiler_specific.h"
-#include "base/string16.h"
#include "base/memory/weak_ptr.h"
+#include "chrome/browser/protector/setting_change.h"
#include "chrome/browser/ui/global_error.h"
+class Browser;
class Profile;
+namespace protector {
+
+class SettingsChangeGlobalErrorDelegate;
+
// Global error about unwanted settings changes.
class SettingsChangeGlobalError : public GlobalError {
public:
- enum ChangeType {
- kSearchEngineChanged = 0, // Default search engine has been changed.
- kHomePageChanged, // Home page has been changed.
- };
-
- struct Change {
- ChangeType type; // Which setting has been changed.
- string16 old_setting; // Old setting value or "" if unknown.
- string16 new_setting; // New setting value.
- };
-
- typedef std::vector<Change> ChangesVector;
-
- // Creates new global error about settings changes |changes|.
- // If user decides to apply changes, |apply_changes_cb| is called.
- // If user decides to keep previous settings, |revert_changes_cb| is called.
- SettingsChangeGlobalError(const ChangesVector& changes,
- const base::Closure& apply_changes_cb,
- const base::Closure& revert_changes_cb);
+ // Creates new global error about settings changes |changes|. Takes
+ // ownership over |changes| contents.
+ // Uses |delegate| to notify about user decision.
+ SettingsChangeGlobalError(
+ const SettingChangeVector& changes,
+ SettingsChangeGlobalErrorDelegate* delegate);
virtual ~SettingsChangeGlobalError();
- // Displays a global error bubble for the default browser profile.
+ // Displays a global error bubble for the given browser profile.
// Can be called from any thread.
- void ShowForDefaultProfile();
+ void ShowForProfile(Profile* profile);
+
+ // Browser that the bubble has been last time shown for.
+ Browser* browser() const { return browser_; }
+
+ SettingChangeVector* mutable_changes() { return &changes_; }
// GlobalError implementation.
virtual bool HasBadge() OVERRIDE;
@@ -62,30 +56,36 @@ class SettingsChangeGlobalError : public GlobalError {
virtual void BubbleViewCancelButtonPressed() OVERRIDE;
private:
- ChangesVector changes_;
+ // Helper called on the UI thread to add this global error to the default
+ // profile (stored in |profile_|).
+ void AddToProfile(Profile* profile);
+
+ // 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();
- base::Closure apply_changes_cb_;
- base::Closure revert_changes_cb_;
+ // List of changes to show.
+ SettingChangeVector changes_;
+
+ // Delegate to notify about user actions.
+ SettingsChangeGlobalErrorDelegate* delegate_;
// 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_;
base::WeakPtrFactory<SettingsChangeGlobalError> weak_factory_;
- // Helper called on the UI thread to add this global error to the default
- // profile (stored in |profile_|).
- void AddToDefaultProfile();
-
- // 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();
-
DISALLOW_COPY_AND_ASSIGN(SettingsChangeGlobalError);
};
+} // namespace protector
+
#endif // CHROME_BROWSER_PROTECTOR_SETTINGS_CHANGE_GLOBAL_ERROR_H_
diff --git a/chrome/browser/protector/settings_change_global_error_delegate.h b/chrome/browser/protector/settings_change_global_error_delegate.h
new file mode 100644
index 0000000..e761850
--- /dev/null
+++ b/chrome/browser/protector/settings_change_global_error_delegate.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2011 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_PROTECTOR_SETTINGS_CHANGE_GLOBAL_ERROR_DELEGATE_H_
+#define CHROME_BROWSER_PROTECTOR_SETTINGS_CHANGE_GLOBAL_ERROR_DELEGATE_H_
+#pragma once
+
+#include "base/basictypes.h"
+
+namespace protector {
+
+// Interface for notifications about settings change error bubble closing.
+class SettingsChangeGlobalErrorDelegate {
+ public:
+ virtual ~SettingsChangeGlobalErrorDelegate() {}
+
+ // Called if user clicks "Apply change" button.
+ virtual void OnApplyChanges() = 0;
+
+ // Called if user clicks "Discard change" button.
+ virtual void OnDiscardChanges() = 0;
+
+ // Called if user clicked outside the bubble and timeout for its reshow
+ // has passed.
+ virtual void OnDecisionTimeout() = 0;
+};
+
+} // namespace protector
+
+#endif // CHROME_BROWSER_PROTECTOR_SETTINGS_CHANGE_GLOBAL_ERROR_DELEGATE_H_
+
diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc
index 9d9f694..96fec74 100644
--- a/chrome/browser/search_engines/template_url_service.cc
+++ b/chrome/browser/search_engines/template_url_service.cc
@@ -22,6 +22,8 @@
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/pref_set_observer.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/protector/protector.h"
+#include "chrome/browser/protector/setting_change.h"
#include "chrome/browser/rlz/rlz.h"
#include "chrome/browser/search_engines/search_host_to_urls_map.h"
#include "chrome/browser/search_engines/search_terms_data.h"
@@ -436,8 +438,8 @@ void TemplateURLService::SetDefaultSearchProvider(const TemplateURL* url) {
NOTREACHED();
return;
}
- if (default_search_provider_ == url)
- return;
+ // Always persist the setting in the database, that way if the backup
+ // signature has changed out from under us it gets reset correctly.
SetDefaultSearchProviderNoNotify(url);
NotifyObservers();
}
@@ -450,6 +452,19 @@ const TemplateURL* TemplateURLService::GetDefaultSearchProvider() {
return initial_default_search_provider_.get();
}
+const TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() {
+ // See if the prepoluated default still exists.
+ scoped_ptr<TemplateURL> prepopulated_default(
+ TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs()));
+ for (TemplateURLVector::iterator i = template_urls_.begin();
+ i != template_urls_.end(); ) {
+ if ((*i)->prepopulate_id() == prepopulated_default->prepopulate_id())
+ return *i;
+ }
+ // If not, use the first of the templates.
+ return template_urls_.empty() ? NULL : template_urls_[0];
+}
+
void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) {
model_observers_.AddObserver(observer);
}
@@ -511,6 +526,22 @@ void TemplateURLService::OnWebDataServiceRequestDone(
LoadDefaultSearchProviderFromPrefs(&default_from_prefs,
&is_default_search_managed_);
+ // Check if the default search provider has been changed and notify
+ // Protector instance about it. Don't check if the default search is
+ // managed.
+ const TemplateURL* backup_default_search_provider = NULL;
+ if (!is_default_search_managed_ &&
+ DidDefaultSearchProviderChange(
+ *result,
+ template_urls,
+ &backup_default_search_provider)) {
+ // Protector will delete itself when it's needed no longer.
+ protector::Protector* protector = new protector::Protector(profile());
+ protector->ShowChange(protector::CreateDefaultSearchProviderChange(
+ default_search_provider,
+ backup_default_search_provider));
+ }
+
// Remove entries that were created because of policy as they may have
// changed since the database was saved.
RemoveProvidersCreatedByPolicy(&template_urls,
@@ -1454,22 +1485,6 @@ void TemplateURLService::UpdateDefaultSearch() {
NotifyObservers();
}
-const TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() {
- // See if the prepoluated default still exists.
- scoped_ptr<TemplateURL> prepopulated_default(
- TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs()));
- for (TemplateURLVector::iterator i = template_urls_.begin();
- i != template_urls_.end(); ) {
- if ((*i)->prepopulate_id() == prepopulated_default->prepopulate_id())
- return *i;
- }
- // If not, use the first of the templates.
- if (!template_urls_.empty()) {
- return template_urls_[0];
- }
- return NULL;
-}
-
void TemplateURLService::SetDefaultSearchProviderNoNotify(
const TemplateURL* url) {
DCHECK(!url || find(template_urls_.begin(), template_urls_.end(), url) !=
diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h
index fb98de6..fa2f381 100644
--- a/chrome/browser/search_engines/template_url_service.h
+++ b/chrome/browser/search_engines/template_url_service.h
@@ -202,6 +202,12 @@ class TemplateURLService : public WebDataServiceConsumer,
// Returns true if the default search is managed through group policy.
bool is_default_search_managed() const { return is_default_search_managed_; }
+ // Returns the default search specified in the prepopulated data, if it
+ // exists. If not, returns first URL in |template_urls_|, or NULL if that's
+ // empty. The returned object is owned by TemplateURLService and can be
+ // destroyed at any time so should be used right after the call.
+ const TemplateURL* FindNewDefaultSearchProvider();
+
// Observers used to listen for changes to the model.
// TemplateURLService does NOT delete the observers when deleted.
void AddObserver(TemplateURLServiceObserver* observer);
@@ -425,11 +431,6 @@ class TemplateURLService : public WebDataServiceConsumer,
// preference has changed.
void UpdateDefaultSearch();
- // Returns the default search specified in the prepopulated data, if it
- // exists. If not, returns first URL in |template_urls_|, or NULL if that's
- // empty.
- const TemplateURL* FindNewDefaultSearchProvider();
-
// Set the default search provider even if it is managed. |url| may be null.
// Caller is responsible for notifying observers.
void SetDefaultSearchProviderNoNotify(const TemplateURL* url);
diff --git a/chrome/browser/search_engines/util.cc b/chrome/browser/search_engines/util.cc
index 2cbbe08..f2b8512 100644
--- a/chrome/browser/search_engines/util.cc
+++ b/chrome/browser/search_engines/util.cc
@@ -64,6 +64,20 @@ static void RemoveDuplicatePrepopulateIDs(
}
}
+// Returns the TemplateURL with id specified from the list of TemplateURLs.
+// If not found, returns NULL.
+TemplateURL* GetTemplateURLByID(
+ const std::vector<TemplateURL*>& template_urls,
+ int64 id) {
+ for (std::vector<TemplateURL*>::const_iterator i = template_urls.begin();
+ i != template_urls.end(); ++i) {
+ if ((*i)->id() == id) {
+ return *i;
+ }
+ }
+ return NULL;
+}
+
// Loads engines from prepopulate data and merges them in with the existing
// engines. This is invoked when the version of the prepopulate data changes.
void MergeEnginesFromPrepopulateData(
@@ -162,7 +176,7 @@ void GetSearchProvidersUsingKeywordResult(
DCHECK(template_urls->empty());
DCHECK(default_search_provider);
DCHECK(*default_search_provider == NULL);
- DCHECK(result.GetType() == KEYWORDS_RESULT);
+ DCHECK_EQ(result.GetType(), KEYWORDS_RESULT);
DCHECK(new_resource_keyword_version);
*new_resource_keyword_version = 0;
@@ -180,15 +194,10 @@ void GetSearchProvidersUsingKeywordResult(
RemoveDuplicatePrepopulateIDs(template_urls, service);
}
- if (keyword_result.default_search_provider_id) {
- // See if we can find the default search provider.
- for (std::vector<TemplateURL*>::iterator i = template_urls->begin();
- i != template_urls->end(); ++i) {
- if ((*i)->id() == keyword_result.default_search_provider_id) {
- *default_search_provider = *i;
- break;
- }
- }
+ int64 default_search_provider_id = keyword_result.default_search_provider_id;
+ if (default_search_provider_id) {
+ *default_search_provider =
+ GetTemplateURLByID(*template_urls, default_search_provider_id);
}
if (keyword_result.builtin_keyword_version != resource_keyword_version) {
@@ -198,3 +207,23 @@ void GetSearchProvidersUsingKeywordResult(
}
}
+bool DidDefaultSearchProviderChange(
+ const WDTypedResult& result,
+ const std::vector<TemplateURL*>& template_urls,
+ const TemplateURL** backup_default_search_provider) {
+ DCHECK(backup_default_search_provider);
+ DCHECK(*backup_default_search_provider == NULL);
+ DCHECK_EQ(result.GetType(), KEYWORDS_RESULT);
+
+ WDKeywordsResult keyword_result = reinterpret_cast<
+ const WDResult<WDKeywordsResult>*>(&result)->GetValue();
+
+ if (!keyword_result.did_default_search_provider_change)
+ return false;
+
+ *backup_default_search_provider = GetTemplateURLByID(
+ template_urls,
+ keyword_result.default_search_provider_id_backup);
+ return true;
+}
+
diff --git a/chrome/browser/search_engines/util.h b/chrome/browser/search_engines/util.h
index e517ba6..09f001f 100644
--- a/chrome/browser/search_engines/util.h
+++ b/chrome/browser/search_engines/util.h
@@ -40,4 +40,13 @@ void GetSearchProvidersUsingKeywordResult(
const TemplateURL** default_search_provider,
int* new_resource_keyword_version);
+// Returns true if the default search provider setting has been changed or
+// corrupted. Returns the backup setting in |backup_default_search_provider|.
+// |*backup_default_search_provider| can be NULL if the original setting is
+// lost.
+bool DidDefaultSearchProviderChange(
+ const WDTypedResult& result,
+ const std::vector<TemplateURL*>& template_urls,
+ const TemplateURL** backup_default_search_provider);
+
#endif // CHROME_BROWSER_SEARCH_ENGINES_UTIL_H_
diff --git a/chrome/browser/webdata/keyword_table.cc b/chrome/browser/webdata/keyword_table.cc
index 1258f89..b539194 100644
--- a/chrome/browser/webdata/keyword_table.cc
+++ b/chrome/browser/webdata/keyword_table.cc
@@ -11,8 +11,9 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/history/history_database.h"
+#include "chrome/browser/protector/histograms.h"
+#include "chrome/browser/protector/protector.h"
#include "chrome/browser/search_engines/template_url.h"
-#include "crypto/hmac.h"
#include "googleurl/src/gurl.h"
#include "sql/statement.h"
@@ -27,11 +28,6 @@ const int kUrlIdPosition = 18;
const char kDefaultSearchProviderKey[] = "Default Search Provider ID";
const char kBuiltinKeywordVersion[] = "Builtin Keyword Version";
-// Key for signing the default search provider backup.
-// TOOD(avayvod): Add key for Google Chrome to internal repository.
-const char kDefaultSearchProviderBackupSigningKey[] =
- "Please, don't change default search engine!";
-
// Meta table key to store backup value for the default search provider.
const char kDefaultSearchProviderBackupKey[] =
"Default Search Provider ID Backup";
@@ -41,20 +37,6 @@ const char kDefaultSearchProviderBackupKey[] =
const char kDefaultSearchProviderBackupSignatureKey[] =
"Default Search Provider ID Backup Signature";
-// Histogram name to report protection errors for the default search
-// provider.
-const char kProtectorHistogramDefaultSearchProvider[] =
- "Protector.DefaultSearchProvider";
-
-// Protector histogram values. TODO(avayvod): Move to protector.h/cc
-enum ProtectorError {
- kProtectorErrorBackupInvalid,
- kProtectorErrorValueChanged,
-
- // This is for convenience only, must always be the last.
- kProtectorErrorCount
-};
-
void BindURLToStatement(const TemplateURL& url, sql::Statement* s) {
s->BindString(0, UTF16ToUTF8(url.short_name()));
s->BindString(1, UTF16ToUTF8(url.keyword()));
@@ -91,14 +73,7 @@ void BindURLToStatement(const TemplateURL& url, sql::Statement* s) {
// Signs search provider id and returns its signature.
std::string GetSearchProviderIDSignature(int64 id) {
- crypto::HMAC hmac(crypto::HMAC::SHA256);
- DCHECK(hmac.Init(kDefaultSearchProviderBackupSigningKey));
-
- std::string id_to_sign(base::Int64ToString(id));
- std::vector<unsigned char> digest(hmac.DigestLength());
- DCHECK(hmac.Sign(id_to_sign, &digest[0], digest.size()));
-
- return std::string(&digest[0], &digest[0] + digest.size());
+ return protector::SignSetting(base::Int64ToString(id));
}
// Checks if signature for search provider id is correct and returns the
@@ -281,25 +256,40 @@ bool KeywordTable::SetDefaultSearchProviderID(int64 id) {
int64 KeywordTable::GetDefaultSearchProviderID() {
int64 value = 0;
meta_table_->GetValue(kDefaultSearchProviderKey, &value);
+ return value;
+}
+
+int64 KeywordTable::GetDefaultSearchProviderIDBackup() {
+ int64 backup_value = 0;
+ meta_table_->GetValue(kDefaultSearchProviderBackupKey, &backup_value);
+ std::string backup_signature;
+ meta_table_->GetValue(
+ kDefaultSearchProviderBackupSignatureKey, &backup_signature);
+ if (!IsSearchProviderIDValid(backup_value, backup_signature))
+ return 0;
+ return backup_value;
+}
+
+bool KeywordTable::DidDefaultSearchProviderChange() {
int64 backup_value = 0;
meta_table_->GetValue(kDefaultSearchProviderBackupKey, &backup_value);
std::string backup_signature;
meta_table_->GetValue(
kDefaultSearchProviderBackupSignatureKey, &backup_signature);
- // For now only track how often signature or backup is lost or value is
- // changed. Don't change the value since UI is not working yet.
if (!IsSearchProviderIDValid(backup_value, backup_signature)) {
- UMA_HISTOGRAM_ENUMERATION(kProtectorHistogramDefaultSearchProvider,
- kProtectorErrorBackupInvalid,
- kProtectorErrorCount);
- SetDefaultSearchProviderBackupID(value);
- } else if (value != backup_value) {
- UMA_HISTOGRAM_ENUMERATION(kProtectorHistogramDefaultSearchProvider,
- kProtectorErrorValueChanged,
- kProtectorErrorCount);
- SetDefaultSearchProviderBackupID(value);
+ UMA_HISTOGRAM_ENUMERATION(
+ protector::kProtectorHistogramDefaultSearchProvider,
+ protector::kProtectorErrorBackupInvalid,
+ protector::kProtectorErrorCount);
+ return true;
+ } else if (backup_value != GetDefaultSearchProviderID()) {
+ UMA_HISTOGRAM_ENUMERATION(
+ protector::kProtectorHistogramDefaultSearchProvider,
+ protector::kProtectorErrorValueChanged,
+ protector::kProtectorErrorCount);
+ return true;
}
- return value;
+ return false;
}
bool KeywordTable::SetBuiltinKeywordVersion(int version) {
diff --git a/chrome/browser/webdata/keyword_table.h b/chrome/browser/webdata/keyword_table.h
index 3efce63..901fbcb 100644
--- a/chrome/browser/webdata/keyword_table.h
+++ b/chrome/browser/webdata/keyword_table.h
@@ -9,6 +9,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/string16.h"
#include "chrome/browser/webdata/web_database_table.h"
#include "chrome/browser/search_engines/template_url_id.h"
@@ -82,6 +83,14 @@ class KeywordTable : public WebDatabaseTable {
bool SetDefaultSearchProviderID(int64 id);
int64 GetDefaultSearchProviderID();
+ // Backup of the default search provider. 0 if the setting can't be verified.
+ int64 GetDefaultSearchProviderIDBackup();
+
+ // Returns true if the default search provider has been changed out under
+ // us. This can happen if another process modifies our database or the
+ // file was corrupted.
+ bool DidDefaultSearchProviderChange();
+
// Version of the built-in keywords.
bool SetBuiltinKeywordVersion(int version);
int GetBuiltinKeywordVersion();
diff --git a/chrome/browser/webdata/keyword_table_unittest.cc b/chrome/browser/webdata/keyword_table_unittest.cc
index 595dcb15..37ffb59 100644
--- a/chrome/browser/webdata/keyword_table_unittest.cc
+++ b/chrome/browser/webdata/keyword_table_unittest.cc
@@ -165,10 +165,14 @@ TEST_F(KeywordTableTest, DefaultSearchProviderBackup) {
ASSERT_TRUE(db.GetKeywordTable()->SetDefaultSearchProviderID(10));
EXPECT_EQ(10, db.GetKeywordTable()->GetDefaultSearchProviderID());
+ EXPECT_EQ(10, db.GetKeywordTable()->GetDefaultSearchProviderIDBackup());
+ EXPECT_FALSE(db.GetKeywordTable()->DidDefaultSearchProviderChange());
// Verify that backup doesn't affect the actual value for now.
ASSERT_TRUE(db.GetKeywordTable()->SetDefaultSearchProviderBackupID(11));
EXPECT_EQ(10, db.GetKeywordTable()->GetDefaultSearchProviderID());
+ EXPECT_EQ(11, db.GetKeywordTable()->GetDefaultSearchProviderIDBackup());
+ EXPECT_TRUE(db.GetKeywordTable()->DidDefaultSearchProviderChange());
}
TEST_F(KeywordTableTest, UpdateKeyword) {
diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc
index 00ce1c3..9442bd8 100644
--- a/chrome/browser/webdata/web_data_service.cc
+++ b/chrome/browser/webdata/web_data_service.cc
@@ -749,6 +749,10 @@ void WebDataService::GetKeywordsImpl(WebDataRequest* request) {
db_->GetKeywordTable()->GetDefaultSearchProviderID();
result.builtin_keyword_version =
db_->GetKeywordTable()->GetBuiltinKeywordVersion();
+ result.default_search_provider_id_backup =
+ db_->GetKeywordTable()->GetDefaultSearchProviderIDBackup();
+ result.did_default_search_provider_change =
+ db_->GetKeywordTable()->DidDefaultSearchProviderChange();
request->SetResult(
new WDResult<WDKeywordsResult>(KEYWORDS_RESULT, result));
}
diff --git a/chrome/browser/webdata/web_data_service.h b/chrome/browser/webdata/web_data_service.h
index f40ad00..422fcfd 100644
--- a/chrome/browser/webdata/web_data_service.h
+++ b/chrome/browser/webdata/web_data_service.h
@@ -104,6 +104,11 @@ struct WDKeywordsResult {
int64 default_search_provider_id;
// Version of the built-in keywords. A value of 0 indicates a first run.
int builtin_keyword_version;
+ // Backup of the default search provider ID.
+ int64 default_search_provider_id_backup;
+ // Indicates if default search provider has been changed by something
+ // other than user's action in the browser.
+ bool did_default_search_provider_change;
};
//
diff --git a/chrome/browser/webdata/web_data_service_unittest.cc b/chrome/browser/webdata/web_data_service_unittest.cc
index 4f3ecac..123fc71 100644
--- a/chrome/browser/webdata/web_data_service_unittest.cc
+++ b/chrome/browser/webdata/web_data_service_unittest.cc
@@ -146,7 +146,7 @@ class WebDataServiceAutofillTest : public WebDataServiceTest {
// Simple consumer for WebIntents data. Stores the result data and quits UI
// message loop when callback is invoked.
-class WebIntentsConsumer: public WebDataServiceConsumer {
+class WebIntentsConsumer : public WebDataServiceConsumer {
public:
virtual void OnWebDataServiceRequestDone(WebDataService::Handle h,
const WDTypedResult* result) {
@@ -173,6 +173,39 @@ class WebIntentsConsumer: public WebDataServiceConsumer {
std::vector<WebIntentServiceData> intents;
};
+// Simple consumer for Keywords data. Stores the result data and quits UI
+// message loop when callback is invoked.
+class KeywordsConsumer : public WebDataServiceConsumer {
+ public:
+ KeywordsConsumer() : load_succeeded(false) {}
+
+ virtual void OnWebDataServiceRequestDone(WebDataService::Handle h,
+ const WDTypedResult* result) {
+ if (result) {
+ load_succeeded = true;
+ DCHECK(result->GetType() == KEYWORDS_RESULT);
+ keywords_result =
+ reinterpret_cast<const WDResult<WDKeywordsResult>*>(
+ result)->GetValue();
+ }
+
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ MessageLoop::current()->Quit();
+ }
+
+ // Run the current message loop. OnWebDataServiceRequestDone will invoke
+ // MessageLoop::Quit on completion, so this call will finish at that point.
+ static void WaitUntilCalled() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ MessageLoop::current()->Run();
+ }
+
+ // True if keywords data was loaded successfully.
+ bool load_succeeded;
+ // Result data from completion callback.
+ WDKeywordsResult keywords_result;
+};
+
TEST_F(WebDataServiceAutofillTest, FormFillAdd) {
const AutofillChange expected_changes[] = {
AutofillChange(AutofillChange::ADD, AutofillKey(name1_, value1_)),
@@ -662,3 +695,12 @@ TEST_F(WebDataServiceTest, WebIntentsGetAll) {
service.action = ASCIIToUTF16("share");
EXPECT_EQ(service, consumer.intents[1]);
}
+
+TEST_F(WebDataServiceTest, DidDefaultSearchProviderChangeOnNewProfile) {
+ KeywordsConsumer consumer;
+ wds_->GetKeywords(&consumer);
+ KeywordsConsumer::WaitUntilCalled();
+ ASSERT_TRUE(consumer.load_succeeded);
+ EXPECT_FALSE(consumer.keywords_result.did_default_search_provider_change);
+ EXPECT_EQ(0, consumer.keywords_result.default_search_provider_id_backup);
+}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index e58edbf..ca85b6a6 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1969,8 +1969,17 @@
'browser/profiles/profile_keyed_service_factory.h',
'browser/profiles/profile_manager.cc',
'browser/profiles/profile_manager.h',
+ 'browser/protector/default_search_provider_change.cc',
+ 'browser/protector/histograms.cc',
+ 'browser/protector/histograms.h',
+ 'browser/protector/keys.cc',
+ 'browser/protector/keys.h',
+ 'browser/protector/protector.cc',
+ 'browser/protector/protector.h',
+ 'browser/protector/setting_change.h',
'browser/protector/settings_change_global_error.cc',
'browser/protector/settings_change_global_error.h',
+ 'browser/protector/settings_change_global_error_delegate.h',
'browser/remove_rows_table_model.h',
'browser/renderer_host/chrome_render_message_filter.cc',
'browser/renderer_host/chrome_render_message_filter.h',