summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/profile_resetter/profile_resetter.cc44
-rw-r--r--chrome/browser/profile_resetter/profile_resetter.h16
-rw-r--r--chrome/browser/profile_resetter/profile_resetter_unittest.cc3
-rw-r--r--chrome/browser/search_engines/template_url_prepopulate_data.cc10
-rw-r--r--chrome/browser/search_engines/template_url_prepopulate_data.h3
-rw-r--r--chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc47
-rw-r--r--chrome/browser/search_engines/template_url_service.cc261
-rw-r--r--chrome/browser/search_engines/template_url_service.h19
-rw-r--r--chrome/browser/search_engines/template_url_service_unittest.cc77
-rw-r--r--chrome/browser/search_engines/util.cc32
-rw-r--r--chrome/browser/search_engines/util.h15
11 files changed, 417 insertions, 110 deletions
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc
index 95fbd4a..cb8aab3 100644
--- a/chrome/browser/profile_resetter/profile_resetter.cc
+++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -5,14 +5,24 @@
#include "chrome/browser/profile_resetter/profile_resetter.h"
#include "base/prefs/pref_service.h"
+#include "chrome/browser/google/google_url_tracker.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
+#include "chrome/browser/search_engines/template_url_service.h"
+#include "chrome/browser/search_engines/template_url_service_factory.h"
+#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
ProfileResetter::ProfileResetter(Profile* profile)
: profile_(profile),
+ template_url_service_(TemplateURLServiceFactory::GetForProfile(profile_)),
pending_reset_flags_(0) {
DCHECK(CalledOnValidThread());
+ DCHECK(profile_);
+ DCHECK(template_url_service_);
+ registrar_.Add(this, chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED,
+ content::Source<TemplateURLService>(template_url_service_));
}
ProfileResetter::~ProfileResetter() {}
@@ -81,16 +91,32 @@ void ProfileResetter::MarkAsDone(Resettable resettable) {
pending_reset_flags_ &= ~resettable;
- if (!pending_reset_flags_)
+ if (!pending_reset_flags_) {
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
callback_);
+ callback_.Reset();
+ }
}
void ProfileResetter::ResetDefaultSearchEngine() {
DCHECK(CalledOnValidThread());
- NOTIMPLEMENTED();
- // TODO(battre/vabr): Implement
- MarkAsDone(DEFAULT_SEARCH_ENGINE);
+
+ // If TemplateURLServiceFactory is ready we can clean it right now.
+ // Otherwise, load it and continue from ProfileResetter::Observe.
+ if (template_url_service_->loaded()) {
+ // Reset Google search URL.
+ PrefService* prefs = profile_->GetPrefs();
+ DCHECK(prefs);
+ prefs->ClearPref(prefs::kLastPromptedGoogleURL);
+ GoogleURLTracker::RequestServerCheck(profile_);
+
+ TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(profile_);
+ template_url_service_->ResetNonExtensionURLs();
+
+ MarkAsDone(DEFAULT_SEARCH_ENGINE);
+ } else {
+ template_url_service_->Load();
+ }
}
void ProfileResetter::ResetHomepage() {
@@ -133,3 +159,13 @@ void ProfileResetter::ResetStartPage() {
prefs->SetBoolean(prefs::kRestoreOnStartupMigrated, true);
MarkAsDone(STARTUP_PAGE);
}
+
+void ProfileResetter::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK(CalledOnValidThread());
+ // TemplateURLService has loaded. If we need to clean search engines, it's
+ // time to go on.
+ if (pending_reset_flags_ & DEFAULT_SEARCH_ENGINE)
+ ResetDefaultSearchEngine();
+}
diff --git a/chrome/browser/profile_resetter/profile_resetter.h b/chrome/browser/profile_resetter/profile_resetter.h
index 1030fb4..810ca5c 100644
--- a/chrome/browser/profile_resetter/profile_resetter.h
+++ b/chrome/browser/profile_resetter/profile_resetter.h
@@ -8,13 +8,17 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/threading/non_thread_safe.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
class Profile;
+class TemplateURLService;
// This class allows resetting certain aspects of a profile to default values.
// It is used in case the profile has been damaged due to malware or bad user
// settings.
-class ProfileResetter : public base::NonThreadSafe {
+class ProfileResetter : public base::NonThreadSafe,
+ public content::NotificationObserver {
public:
// Flags indicating what aspects of a profile shall be reset.
enum Resettable {
@@ -43,7 +47,7 @@ class ProfileResetter : public base::NonThreadSafe {
type_ResettableFlags_doesnt_match_Resettable);
explicit ProfileResetter(Profile* profile);
- ~ProfileResetter();
+ virtual ~ProfileResetter();
// Resets |resettable_flags| and calls |callback| on the UI thread on
// completion. If |resettable_flags| contains EXTENSIONS, these are handled
@@ -66,7 +70,13 @@ class ProfileResetter : public base::NonThreadSafe {
void ResetExtensions(ExtensionHandling extension_handling);
void ResetStartPage();
+ // content::NotificationObserver:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
Profile* profile_;
+ TemplateURLService* template_url_service_;
// Flags of a Resetable indicating which reset operations we are still waiting
// for.
@@ -75,6 +85,8 @@ class ProfileResetter : public base::NonThreadSafe {
// Called on UI thread when reset has been completed.
base::Closure callback_;
+ content::NotificationRegistrar registrar_;
+
DISALLOW_COPY_AND_ASSIGN(ProfileResetter);
};
diff --git a/chrome/browser/profile_resetter/profile_resetter_unittest.cc b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
index 2cb521b..53a4166 100644
--- a/chrome/browser/profile_resetter/profile_resetter_unittest.cc
+++ b/chrome/browser/profile_resetter/profile_resetter_unittest.cc
@@ -39,6 +39,7 @@ class ProfileResetterTest : public testing::Test {
protected:
ProfileResetterTest();
~ProfileResetterTest();
+
// testing::Test:
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
@@ -64,7 +65,6 @@ void ProfileResetterTest::TearDown() {
}
TEST_F(ProfileResetterTest, ResetDefaultSearchEngine) {
- test_util_.VerifyLoad();
resetter_->Reset(
ProfileResetter::DEFAULT_SEARCH_ENGINE,
ProfileResetter::DISABLE_EXTENSIONS,
@@ -144,7 +144,6 @@ TEST_F(ProfileResetterTest, ResetStartPage) {
TEST_F(ProfileResetterTest, ResetExtensionsAll) {
// mock_object_ is a StrictMock, so we verify that it is called only once.
- test_util_.VerifyLoad();
resetter_->Reset(
ProfileResetter::ALL,
ProfileResetter::UNINSTALL_EXTENSIONS,
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.cc b/chrome/browser/search_engines/template_url_prepopulate_data.cc
index 235f621..efbb266 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.cc
@@ -1197,6 +1197,16 @@ void GetPrepopulatedTemplateFromPrefs(Profile* profile,
}
}
+void ClearPrepopulatedEnginesInPrefs(Profile* profile) {
+ if (!profile)
+ return;
+
+ PrefService* prefs = profile->GetPrefs();
+ DCHECK(prefs);
+ prefs->ClearPref(prefs::kSearchProviderOverrides);
+ prefs->ClearPref(prefs::kSearchProviderOverridesVersion);
+}
+
// The caller owns the returned TemplateURL.
TemplateURL* MakePrepopulatedTemplateURLFromPrepopulateEngine(
Profile* profile,
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.h b/chrome/browser/search_engines/template_url_prepopulate_data.h
index 6bd7882..3d1fa43 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data.h
+++ b/chrome/browser/search_engines/template_url_prepopulate_data.h
@@ -54,6 +54,9 @@ void GetPrepopulatedEngines(Profile* profile,
std::vector<TemplateURL*>* t_urls,
size_t* default_search_provider_index);
+// Removes prepopulated engines and their version stored in user prefs.
+void ClearPrepopulatedEnginesInPrefs(Profile* profile);
+
// Returns the default search provider specified by the prepopulate data.
// The caller owns the returned value, which may be NULL.
// If |profile| is NULL, any search provider overrides from the preferences are
diff --git a/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc b/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
index a11adf3..342f10f 100644
--- a/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
+++ b/chrome/browser/search_engines/template_url_prepopulate_data_unittest.cc
@@ -6,6 +6,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_vector.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/search_engines/prepopulated_engines.h"
#include "chrome/browser/search_engines/search_terms_data.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_prepopulate_data.h"
@@ -181,6 +182,52 @@ TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
EXPECT_EQ(2u, t_urls.size());
}
+TEST(TemplateURLPrepopulateDataTest, ClearProvidersFromPrefs) {
+ TestingProfile profile;
+ TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
+ prefs->SetUserPref(prefs::kSearchProviderOverridesVersion,
+ Value::CreateIntegerValue(1));
+ ListValue* overrides = new ListValue;
+ DictionaryValue* entry(new DictionaryValue);
+ // Set only the minimal required settings for a search provider configuration.
+ entry->SetString("name", "foo");
+ entry->SetString("keyword", "fook");
+ entry->SetString("search_url", "http://foo.com/s?q={searchTerms}");
+ entry->SetString("favicon_url", "http://foi.com/favicon.ico");
+ entry->SetString("encoding", "UTF-8");
+ entry->SetInteger("id", 1001);
+ overrides->Append(entry);
+ prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
+
+ int version = TemplateURLPrepopulateData::GetDataVersion(prefs);
+ EXPECT_EQ(1, version);
+
+ // This call removes the above search engine.
+ TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(&profile);
+
+ version = TemplateURLPrepopulateData::GetDataVersion(prefs);
+ EXPECT_EQ(TemplateURLPrepopulateData::kCurrentDataVersion, version);
+
+ ScopedVector<TemplateURL> t_urls;
+ size_t default_index;
+ TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile, &t_urls.get(),
+ &default_index);
+ ASSERT_FALSE(t_urls.empty());
+ for (size_t i = 0; i < t_urls.size(); ++i) {
+ EXPECT_NE(ASCIIToUTF16("foo"), t_urls[i]->short_name());
+ EXPECT_NE(ASCIIToUTF16("fook"), t_urls[i]->keyword());
+ EXPECT_NE("foi.com", t_urls[i]->favicon_url().host());
+ EXPECT_NE("foo.com", t_urls[i]->url_ref().GetHost());
+ EXPECT_NE(1001, t_urls[i]->prepopulate_id());
+ }
+ // Ensures the default URL is Google and has the optional fields filled.
+ EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
+ EXPECT_FALSE(t_urls[default_index]->suggestions_url().empty());
+ EXPECT_FALSE(t_urls[default_index]->instant_url().empty());
+ EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
+ TemplateURLPrepopulateData::GetEngineType(t_urls[default_index]->url()));
+}
+
// Verifies that built-in search providers are processed correctly.
TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrepopulated) {
// Use United States.
diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc
index 8c78bd3..7588369 100644
--- a/chrome/browser/search_engines/template_url_service.cc
+++ b/chrome/browser/search_engines/template_url_service.cc
@@ -671,6 +671,53 @@ TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() {
return FirstPotentialDefaultEngine(template_urls_);
}
+void TemplateURLService::ResetNonExtensionURLs() {
+ // Can't clean DB if it hasn't been loaded.
+ DCHECK(loaded());
+ ClearDefaultProviderFromPrefs();
+
+ TemplateURLVector entries_to_process;
+ for (TemplateURLVector::const_iterator i = template_urls_.begin();
+ i != template_urls_.end(); ++i) {
+ if (!(*i)->IsExtensionKeyword())
+ entries_to_process.push_back(*i);
+ }
+ // Clear default provider to be able to delete it.
+ default_search_provider_ = NULL;
+ // Remove non-extension keywords.
+ for (TemplateURLVector::const_iterator i = entries_to_process.begin();
+ i != entries_to_process.end(); ++i)
+ RemoveNoNotify(*i);
+
+ // Store the remaining engines in entries_to_process and merge them with
+ // prepopulated ones.
+ entries_to_process.clear();
+ entries_to_process.swap(template_urls_);
+ provider_map_.reset(new SearchHostToURLsMap);
+ UIThreadSearchTermsData search_terms_data(profile_);
+ provider_map_->Init(TemplateURLVector(), search_terms_data);
+
+ TemplateURL* default_search_provider = NULL;
+ // Force GetSearchProvidersUsingLoadedEngines() to include the prepopulated
+ // engines in the list by claiming we are currently on version 0, ensuring
+ // that the prepopulate data version will be newer.
+ int new_resource_keyword_version = 0;
+ GetSearchProvidersUsingLoadedEngines(service_.get(), profile_,
+ &entries_to_process,
+ &default_search_provider,
+ &new_resource_keyword_version,
+ &pre_sync_deletes_);
+ // Setup search engines and a default one.
+ AddTemplateURLsAndSetupDefaultEngine(&entries_to_process,
+ default_search_provider);
+
+ if (new_resource_keyword_version)
+ service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
+
+ EnsureDefaultSearchProviderExists();
+ NotifyObservers();
+}
+
void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) {
model_observers_.AddObserver(observer);
}
@@ -714,7 +761,6 @@ void TemplateURLService::OnWebDataServiceRequestDone(
// initial_default_search_provider_ is only needed before we've finished
// loading. Now that we've loaded we can nuke it.
initial_default_search_provider_.reset();
- is_default_search_managed_ = false;
TemplateURLVector template_urls;
TemplateURL* default_search_provider = NULL;
@@ -723,81 +769,7 @@ void TemplateURLService::OnWebDataServiceRequestDone(
&template_urls, &default_search_provider, &new_resource_keyword_version,
&pre_sync_deletes_);
- bool database_specified_a_default = (default_search_provider != NULL);
-
- // Check if default search provider is now managed.
- scoped_ptr<TemplateURL> default_from_prefs;
- LoadDefaultSearchProviderFromPrefs(&default_from_prefs,
- &is_default_search_managed_);
-
- // Remove entries that were created because of policy as they may have
- // changed since the database was saved.
- RemoveProvidersCreatedByPolicy(&template_urls,
- &default_search_provider,
- default_from_prefs.get());
-
- PatchMissingSyncGUIDs(&template_urls);
-
- if (is_default_search_managed_) {
- SetTemplateURLs(template_urls);
-
- if (TemplateURLsHaveSamePrefs(default_search_provider,
- default_from_prefs.get())) {
- // The value from the preferences was previously stored in the database.
- // Reuse it.
- } else {
- // The value from the preferences takes over.
- default_search_provider = NULL;
- if (default_from_prefs.get()) {
- TemplateURLData data(default_from_prefs->data());
- data.created_by_policy = true;
- data.id = kInvalidTemplateURLID;
- default_search_provider = new TemplateURL(profile_, data);
- if (!AddNoNotify(default_search_provider, true))
- default_search_provider = NULL;
- }
- }
- // Note that this saves the default search provider to prefs.
- if (!default_search_provider ||
- (!default_search_provider->IsExtensionKeyword() &&
- default_search_provider->SupportsReplacement())) {
- bool success = SetDefaultSearchProviderNoNotify(default_search_provider);
- DCHECK(success);
- }
- } else {
- // If we had a managed default, replace it with the synced default if
- // applicable, or the first provider of the list.
- TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
- if (synced_default) {
- default_search_provider = synced_default;
- pending_synced_default_search_ = false;
- } else if (database_specified_a_default &&
- default_search_provider == NULL) {
- UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
- FIRST_POTENTIAL_CALLSITE_ON_LOAD, FIRST_POTENTIAL_CALLSITE_MAX);
- default_search_provider = FirstPotentialDefaultEngine(template_urls);
- }
-
- // If the default search provider existed previously, then just
- // set the member variable. Otherwise, we'll set it using the method
- // to ensure that it is saved properly after its id is set.
- if (default_search_provider &&
- (default_search_provider->id() != kInvalidTemplateURLID)) {
- default_search_provider_ = default_search_provider;
- default_search_provider = NULL;
- }
- SetTemplateURLs(template_urls);
-
- if (default_search_provider) {
- // Note that this saves the default search provider to prefs.
- SetDefaultSearchProvider(default_search_provider);
- } else {
- // Always save the default search provider to prefs. That way we don't
- // have to worry about it being out of sync.
- if (default_search_provider_)
- SaveDefaultSearchProviderToPrefs(default_search_provider_);
- }
- }
+ AddTemplateURLsAndSetupDefaultEngine(&template_urls, default_search_provider);
// This initializes provider_map_ which should be done before
// calling UpdateKeywordSearchTermsForURL.
@@ -811,26 +783,7 @@ void TemplateURLService::OnWebDataServiceRequestDone(
if (new_resource_keyword_version)
service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
- if (!is_default_search_managed_) {
- bool has_default_search_provider = default_search_provider_ != NULL &&
- default_search_provider_->SupportsReplacement();
- UMA_HISTOGRAM_BOOLEAN(kHasDSPHistogramName,
- has_default_search_provider);
- // Ensure that default search provider exists. See http://crbug.com/116952.
- if (!has_default_search_provider) {
- bool success =
- SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
- DCHECK(success);
- }
- // Don't log anything if the user has a NULL default search provider. A
- // logged value of 0 indicates a custom default search provider.
- if (default_search_provider_) {
- UMA_HISTOGRAM_ENUMERATION(
- kDSPHistogramName,
- default_search_provider_->prepopulate_id(),
- TemplateURLPrepopulateData::kMaxPrepopulatedEngineID);
- }
- }
+ EnsureDefaultSearchProviderExists();
NotifyObservers();
NotifyLoaded();
@@ -1721,6 +1674,16 @@ bool TemplateURLService::LoadDefaultSearchProviderFromPrefs(
return true;
}
+void TemplateURLService::ClearDefaultProviderFromPrefs() {
+ // We overwrite user preferences. If the default search engine is managed,
+ // there is no effect.
+ SaveDefaultSearchProviderToPrefs(NULL);
+ // Default value for kDefaultSearchProviderEnabled is true.
+ PrefService* prefs = GetPrefs();
+ if (prefs)
+ prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, true);
+}
+
bool TemplateURLService::CanReplaceKeywordForHost(
const std::string& host,
TemplateURL** to_replace) {
@@ -2497,3 +2460,109 @@ void TemplateURLService::PatchMissingSyncGUIDs(
}
}
}
+
+void TemplateURLService::AddTemplateURLsAndSetupDefaultEngine(
+ TemplateURLVector* template_urls,
+ TemplateURL* default_search_provider) {
+ DCHECK(template_urls);
+ is_default_search_managed_ = false;
+ bool database_specified_a_default = (default_search_provider != NULL);
+
+ // Check if default search provider is now managed.
+ scoped_ptr<TemplateURL> default_from_prefs;
+ LoadDefaultSearchProviderFromPrefs(&default_from_prefs,
+ &is_default_search_managed_);
+
+ // Remove entries that were created because of policy as they may have
+ // changed since the database was saved.
+ RemoveProvidersCreatedByPolicy(template_urls,
+ &default_search_provider,
+ default_from_prefs.get());
+
+ PatchMissingSyncGUIDs(template_urls);
+
+ if (is_default_search_managed_) {
+ SetTemplateURLs(*template_urls);
+
+ if (TemplateURLsHaveSamePrefs(default_search_provider,
+ default_from_prefs.get())) {
+ // The value from the preferences was previously stored in the database.
+ // Reuse it.
+ } else {
+ // The value from the preferences takes over.
+ default_search_provider = NULL;
+ if (default_from_prefs.get()) {
+ TemplateURLData data(default_from_prefs->data());
+ data.created_by_policy = true;
+ data.id = kInvalidTemplateURLID;
+ default_search_provider = new TemplateURL(profile_, data);
+ if (!AddNoNotify(default_search_provider, true))
+ default_search_provider = NULL;
+ }
+ }
+ // Note that this saves the default search provider to prefs.
+ if (!default_search_provider ||
+ (!default_search_provider->IsExtensionKeyword() &&
+ default_search_provider->SupportsReplacement())) {
+ bool success = SetDefaultSearchProviderNoNotify(default_search_provider);
+ DCHECK(success);
+ }
+ } else {
+ // If we had a managed default, replace it with the synced default if
+ // applicable, or the first provider of the list.
+ TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
+ if (synced_default) {
+ default_search_provider = synced_default;
+ pending_synced_default_search_ = false;
+ } else if (database_specified_a_default &&
+ default_search_provider == NULL) {
+ UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
+ FIRST_POTENTIAL_CALLSITE_ON_LOAD,
+ FIRST_POTENTIAL_CALLSITE_MAX);
+ default_search_provider = FirstPotentialDefaultEngine(*template_urls);
+ }
+
+ // If the default search provider existed previously, then just
+ // set the member variable. Otherwise, we'll set it using the method
+ // to ensure that it is saved properly after its id is set.
+ if (default_search_provider &&
+ (default_search_provider->id() != kInvalidTemplateURLID)) {
+ default_search_provider_ = default_search_provider;
+ default_search_provider = NULL;
+ }
+ SetTemplateURLs(*template_urls);
+
+ if (default_search_provider) {
+ // Note that this saves the default search provider to prefs.
+ SetDefaultSearchProvider(default_search_provider);
+ } else {
+ // Always save the default search provider to prefs. That way we don't
+ // have to worry about it being out of sync.
+ if (default_search_provider_)
+ SaveDefaultSearchProviderToPrefs(default_search_provider_);
+ }
+ }
+}
+
+void TemplateURLService::EnsureDefaultSearchProviderExists() {
+ if (!is_default_search_managed_) {
+ bool has_default_search_provider = default_search_provider_ &&
+ default_search_provider_->SupportsReplacement();
+ UMA_HISTOGRAM_BOOLEAN(kHasDSPHistogramName,
+ has_default_search_provider);
+ // Ensure that default search provider exists. See http://crbug.com/116952.
+ if (!has_default_search_provider) {
+ bool success =
+ SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
+ DCHECK(success);
+ }
+ // Don't log anything if the user has a NULL default search provider. A
+ // logged value of 0 indicates a custom default search provider.
+ if (default_search_provider_) {
+ UMA_HISTOGRAM_ENUMERATION(
+ kDSPHistogramName,
+ default_search_provider_->prepopulate_id(),
+ TemplateURLPrepopulateData::kMaxPrepopulatedEngineID);
+ }
+ }
+}
diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h
index adabac7..83826d5 100644
--- a/chrome/browser/search_engines/template_url_service.h
+++ b/chrome/browser/search_engines/template_url_service.h
@@ -225,6 +225,11 @@ class TemplateURLService : public WebDataServiceConsumer,
// destroyed at any time so should be used right after the call.
TemplateURL* FindNewDefaultSearchProvider();
+ // Resets the search providers to the prepopulated engines plus any
+ // extension-supplied engines. Also resets the default search engine unless
+ // it's managed.
+ void ResetNonExtensionURLs();
+
// Observers used to listen for changes to the model.
// TemplateURLService does NOT delete the observers when deleted.
void AddObserver(TemplateURLServiceObserver* observer);
@@ -421,6 +426,9 @@ class TemplateURLService : public WebDataServiceConsumer,
scoped_ptr<TemplateURL>* default_provider,
bool* is_managed);
+ // Clears user preferences describing the default search engine.
+ void ClearDefaultProviderFromPrefs();
+
// Returns true if there is no TemplateURL that has a search url with the
// specified host, or the only TemplateURLs matching the specified host can
// be replaced.
@@ -582,6 +590,17 @@ class TemplateURLService : public WebDataServiceConsumer,
void OnSyncedDefaultSearchProviderGUIDChanged();
+ // Adds |template_urls| to |template_urls_| and sets up the default search
+ // provider. If |default_search_provider| is non-NULL, it must refer to one
+ // of the |template_urls|, and will be used as the new default.
+ void AddTemplateURLsAndSetupDefaultEngine(
+ TemplateURLVector* template_urls,
+ TemplateURL* default_search_provider);
+
+ // If there is no current default search provider, sets the default to the
+ // result of calling FindNewDefaultSearchProvider().
+ void EnsureDefaultSearchProviderExists();
+
content::NotificationRegistrar notification_registrar_;
PrefChangeRegistrar pref_change_registrar_;
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc
index 0256bf6..d681c86 100644
--- a/chrome/browser/search_engines/template_url_service_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -922,6 +922,83 @@ TEST_F(TemplateURLServiceTest, DefaultSearchProviderLoadedFromPrefs) {
AssertEquals(*cloned_url, *model()->GetDefaultSearchProvider());
}
+TEST_F(TemplateURLServiceTest, ResetNonExtensionURLs) {
+ test_util_.VerifyLoad();
+
+ TemplateURL* new_provider = AddKeywordWithDate(
+ "short_name", "keyword", "http://test.com/search?t={searchTerms}",
+ std::string(), std::string(), std::string(),
+ true, "UTF-8", Time(), Time());
+ model()->SetDefaultSearchProvider(new_provider);
+ AddKeywordWithDate(
+ "extension1", "ext_keyword",
+ std::string(extensions::kExtensionScheme) + "://test1", std::string(),
+ std::string(), std::string(), false, "UTF-8", Time(), Time());
+ TemplateURL* default_provider = model()->GetDefaultSearchProvider();
+ EXPECT_NE(SEARCH_ENGINE_GOOGLE,
+ TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
+
+ // Non-extension URLs should go away. Default search engine is Google again.
+ model()->ResetNonExtensionURLs();
+ default_provider = model()->GetDefaultSearchProvider();
+ ASSERT_TRUE(default_provider);
+ EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
+ TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
+ EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword")));
+ EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
+
+ // Reload URLs. Result should be the same except that extension keywords
+ // aren't persisted.
+ test_util_.ResetModel(true);
+ default_provider = model()->GetDefaultSearchProvider();
+ ASSERT_TRUE(default_provider);
+ EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
+ TemplateURLPrepopulateData::GetEngineType(default_provider->url()));
+ EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext_keyword")));
+ EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")));
+}
+
+TEST_F(TemplateURLServiceTest, ResetURLsWithManagedDefault) {
+ // Set a managed preference that establishes a default search provider.
+ const char kName[] = "test1";
+ const char kKeyword[] = "test.com";
+ const char kSearchURL[] = "http://test.com/search?t={searchTerms}";
+ const char kIconURL[] = "http://test.com/icon.jpg";
+ const char kEncodings[] = "UTF-16;UTF-32";
+ const char kAlternateURL[] = "http://test.com/search#t={searchTerms}";
+ const char kSearchTermsReplacementKey[] = "espv";
+ test_util_.SetManagedDefaultSearchPreferences(true, kName, kKeyword,
+ kSearchURL, std::string(),
+ kIconURL, kEncodings,
+ kAlternateURL,
+ kSearchTermsReplacementKey);
+ test_util_.VerifyLoad();
+ // Verify that the default manager we are getting is the managed one.
+ TemplateURLData data;
+ data.short_name = ASCIIToUTF16(kName);
+ data.SetKeyword(ASCIIToUTF16(kKeyword));
+ data.SetURL(kSearchURL);
+ data.favicon_url = GURL(kIconURL);
+ data.show_in_default_list = true;
+ base::SplitString(kEncodings, ';', &data.input_encodings);
+ data.alternate_urls.push_back(kAlternateURL);
+ data.search_terms_replacement_key = kSearchTermsReplacementKey;
+ Profile* profile = test_util_.profile();
+ scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(profile,
+ data));
+ EXPECT_TRUE(model()->is_default_search_managed());
+ const TemplateURL* actual_managed_default =
+ model()->GetDefaultSearchProvider();
+ ExpectSimilar(expected_managed_default.get(), actual_managed_default);
+
+ // The following call has no effect on the managed search engine.
+ model()->ResetNonExtensionURLs();
+
+ EXPECT_TRUE(model()->is_default_search_managed());
+ actual_managed_default = model()->GetDefaultSearchProvider();
+ ExpectSimilar(expected_managed_default.get(), actual_managed_default);
+}
+
TEST_F(TemplateURLServiceTest, UpdateKeywordSearchTermsForURL) {
struct TestData {
const std::string url;
diff --git a/chrome/browser/search_engines/util.cc b/chrome/browser/search_engines/util.cc
index 581f513..5e7d285 100644
--- a/chrome/browser/search_engines/util.cc
+++ b/chrome/browser/search_engines/util.cc
@@ -149,8 +149,8 @@ void MergeIntoPrepopulatedEngineData(TemplateURLData* prepopulated_url,
prepopulated_url->last_modified = original_turl->last_modified();
}
-// Loads engines from prepopulate data and merges them in with the existing
-// engines. This is invoked when the version of the prepopulate data changes.
+// Merges the provided prepopulated engines with the provided existing engines.
+// This is invoked when the version of the prepopulate data changes.
// If |removed_keyword_guids| is not NULL, the Sync GUID of each item removed
// from the DB will be added to it. Note that this function will take
// ownership of |prepopulated_urls| and will clear the vector.
@@ -262,7 +262,6 @@ void GetSearchProvidersUsingKeywordResult(
DCHECK_EQ(KEYWORDS_RESULT, result.GetType());
DCHECK(new_resource_keyword_version);
- *new_resource_keyword_version = 0;
WDKeywordsResult keyword_result = reinterpret_cast<
const WDResult<WDKeywordsResult>*>(&result)->GetValue();
@@ -288,6 +287,25 @@ void GetSearchProvidersUsingKeywordResult(
GetTemplateURLByID(*template_urls, default_search_provider_id);
}
+ *new_resource_keyword_version = keyword_result.builtin_keyword_version;
+ GetSearchProvidersUsingLoadedEngines(service, profile, template_urls,
+ default_search_provider,
+ new_resource_keyword_version,
+ removed_keyword_guids);
+}
+
+void GetSearchProvidersUsingLoadedEngines(
+ WebDataService* service,
+ Profile* profile,
+ TemplateURLService::TemplateURLVector* template_urls,
+ TemplateURL** default_search_provider,
+ int* resource_keyword_version,
+ std::set<std::string>* removed_keyword_guids) {
+ DCHECK(service == NULL || BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(template_urls);
+ DCHECK(default_search_provider);
+ DCHECK(resource_keyword_version);
+
ScopedVector<TemplateURL> prepopulated_urls;
size_t default_search_index;
TemplateURLPrepopulateData::GetPrepopulatedEngines(profile,
@@ -296,14 +314,16 @@ void GetSearchProvidersUsingKeywordResult(
*default_search_provider, template_urls,
removed_keyword_guids);
- const int resource_keyword_version =
+ const int prepopulate_resource_keyword_version =
TemplateURLPrepopulateData::GetDataVersion(
profile ? profile->GetPrefs() : NULL);
- if (keyword_result.builtin_keyword_version != resource_keyword_version) {
+ if (*resource_keyword_version < prepopulate_resource_keyword_version) {
MergeEnginesFromPrepopulateData(profile, service, &prepopulated_urls,
default_search_index, template_urls, default_search_provider,
removed_keyword_guids);
- *new_resource_keyword_version = resource_keyword_version;
+ *resource_keyword_version = prepopulate_resource_keyword_version;
+ } else {
+ *resource_keyword_version = 0;
}
}
diff --git a/chrome/browser/search_engines/util.h b/chrome/browser/search_engines/util.h
index 432569f..158841a 100644
--- a/chrome/browser/search_engines/util.h
+++ b/chrome/browser/search_engines/util.h
@@ -50,6 +50,21 @@ void GetSearchProvidersUsingKeywordResult(
int* new_resource_keyword_version,
std::set<std::string>* removed_keyword_guids);
+// Like GetSearchProvidersUsingKeywordResult(), but allows the caller to pass in
+// engines in |template_urls| instead of getting them via processing a web data
+// service request.
+// |resource_keyword_version| should contain the version number of the current
+// keyword data, i.e. the version number of the most recent prepopulate data
+// that has been merged into the current keyword data. On exit, this will be
+// set as in GetSearchProvidersUsingKeywordResult().
+void GetSearchProvidersUsingLoadedEngines(
+ WebDataService* service,
+ Profile* profile,
+ TemplateURLService::TemplateURLVector* template_urls,
+ TemplateURL** default_search_provider,
+ int* resource_keyword_version,
+ std::set<std::string>* removed_keyword_guids);
+
// Due to a bug, the |input_encodings| field of TemplateURLData could have
// contained duplicate entries. This removes those entries and returns whether
// any were found.