diff options
author | vasilii@chromium.org <vasilii@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 14:44:56 +0000 |
---|---|---|
committer | vasilii@chromium.org <vasilii@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-29 14:44:56 +0000 |
commit | 4a40facd835161458b7c9b9ac427e989742664fd (patch) | |
tree | e41a8afd95ef50f3f4aa32bf2690d200527676a4 /chrome | |
parent | 6e206fadeaac18ef6fcf1a3cc924732aa08312bd (diff) | |
download | chromium_src-4a40facd835161458b7c9b9ac427e989742664fd.zip chromium_src-4a40facd835161458b7c9b9ac427e989742664fd.tar.gz chromium_src-4a40facd835161458b7c9b9ac427e989742664fd.tar.bz2 |
New methods allow to
- delete prepopulated search engines from user prefs
- delete the default search engine from user prefs
- reset unmanaged and non-extension URLs to prepopulated list.
New unit tests:
- TemplateURLPrepopulateDataTest.ClearProvidersFromPrefs
- TemplateURLServiceTest.ResetNonExtensionURLs
- TemplateURLServiceTest.ResetURLsWithManagedDefault
BUG=235037,244291
Review URL: https://chromiumcodereview.appspot.com/15572002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202869 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
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. |