summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravayvod@chromium.org <avayvod@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 20:40:09 +0000
committeravayvod@chromium.org <avayvod@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 20:40:09 +0000
commit75a4eca838076cd01dd87429c8d714ec348b55a8 (patch)
tree8386872d500b27ff8ee586deef57ec9399314322
parent18709a656fc31107fffd21dba76e36ce9eccfbd4 (diff)
downloadchromium_src-75a4eca838076cd01dd87429c8d714ec348b55a8.zip
chromium_src-75a4eca838076cd01dd87429c8d714ec348b55a8.tar.gz
chromium_src-75a4eca838076cd01dd87429c8d714ec348b55a8.tar.bz2
Added Protector, hooked up DSE verification with error bubble.
Moved signing key to a separate cc file. R=ivankr@chromium.org,sky@chromium.org BUG=94447 TEST=Before launching Chrome modify Default Search Engine ID value in Web Data SQL db. Check that error bubble is shown on Chrome startup and its buttons work as expected. Review URL: http://codereview.chromium.org/8342049 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107426 0039d316-1c4b-4281-b951-d872f2087c98
-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',