diff options
Diffstat (limited to 'chrome')
29 files changed, 541 insertions, 130 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a0c1ac50..a01f659 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -10478,9 +10478,6 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_SYNC_DATATYPE_APPS" desc="Apps, one of the data types that we allow syncing."> Apps </message> - <message name="IDS_SYNC_DATATYPE_SEARCH_ENGINES" desc="Search Engines, one of the data types that we allow syncing."> - Search Engines - </message> <message name="IDS_SYNC_DATATYPE_TABS" desc="Open Tabs, one of the data types that we allow syncing."> Open Tabs </message> diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index aa0efa8..43f8045 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -290,13 +290,6 @@ const Experiment kExperiments[] = { SINGLE_VALUE_TYPE(switches::kEnableSyncTabs) }, { - "sync-search-engines", - IDS_FLAGS_SYNC_SEARCH_ENGINES_NAME, - IDS_FLAGS_SYNC_SEARCH_ENGINES_DESCRIPTION, - kOsAll, - SINGLE_VALUE_TYPE(switches::kEnableSyncSearchEngines) - }, - { "sync-app-notifications", IDS_FLAGS_SYNC_APP_NOTIFICATIONS_NAME, IDS_FLAGS_SYNC_APP_NOTIFICATIONS_DESCRIPTION, diff --git a/chrome/browser/prefs/pref_set_observer.cc b/chrome/browser/prefs/pref_set_observer.cc index 92b8fa6..2486621 100644 --- a/chrome/browser/prefs/pref_set_observer.cc +++ b/chrome/browser/prefs/pref_set_observer.cc @@ -65,6 +65,7 @@ PrefSetObserver* PrefSetObserver::CreateDefaultSearchPrefSetObserver( pref_set->AddPref(prefs::kDefaultSearchProviderIconURL); pref_set->AddPref(prefs::kDefaultSearchProviderInstantURL); pref_set->AddPref(prefs::kDefaultSearchProviderEncodings); + pref_set->AddPref(prefs::kSyncedDefaultSearchProviderGUID); return pref_set; } diff --git a/chrome/browser/resources/sync_setup_overlay.html b/chrome/browser/resources/sync_setup_overlay.html index 12c5200..abec547 100644 --- a/chrome/browser/resources/sync_setup_overlay.html +++ b/chrome/browser/resources/sync_setup_overlay.html @@ -225,14 +225,6 @@ <label for="sessions-checkbox" i18n-content="openTabs" il8n-values="title:tabs" name="dataTypeLabel"></label> </div> - <div id="search-engines-item" class="sync-item-show"> - <input id="search-engines-checkbox" type="checkbox" - name="dataTypeCheckbox"> - <label for="search-engines-checkbox" - i18n-content="searchEngines" - il8n-values="title:searchEngines" - name="dataTypeLabel"></label> - </div> </div> </div> </div> diff --git a/chrome/browser/resources/sync_setup_overlay.js b/chrome/browser/resources/sync_setup_overlay.js index 8e3a955..bd91bb4 100644 --- a/chrome/browser/resources/sync_setup_overlay.js +++ b/chrome/browser/resources/sync_setup_overlay.js @@ -249,7 +249,6 @@ cr.define('options', function() { "syncExtensions": syncAll || $('extensions-checkbox').checked, "syncTypedUrls": syncAll || $('typed-urls-checkbox').checked, "syncApps": syncAll || $('apps-checkbox').checked, - "syncSearchEngines": syncAll || $('search-engines-checkbox').checked, "syncSessions": syncAll || $('sessions-checkbox').checked, "encryptAllData": encryptAllData, "usePassphrase": usePassphrase, @@ -344,12 +343,6 @@ cr.define('options', function() { } else { $('apps-item').className = "sync-item-hide"; } - if (args.searchEnginesRegistered) { - $('search-engines-checkbox').checked = args.syncSearchEngines; - $('search-engines-item').className = "sync-item-show"; - } else { - $('search-engines-item').className = "sync-item-hide"; - } if (args.sessionsRegistered) { $('sessions-checkbox').checked = args.syncSessions; $('sessions-item').className = "sync-item-show"; diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc index b9ea5de..fa85ab9 100644 --- a/chrome/browser/search_engines/template_url_service.cc +++ b/chrome/browser/search_engines/template_url_service.cc @@ -113,7 +113,8 @@ TemplateURLService::TemplateURLService(Profile* profile) time_provider_(&base::Time::Now), models_associated_(false), processing_syncer_changes_(false), - sync_processor_(NULL) { + sync_processor_(NULL), + pending_synced_default_search_(false) { DCHECK(profile_); Init(NULL, 0); } @@ -131,7 +132,8 @@ TemplateURLService::TemplateURLService(const Initializer* initializers, time_provider_(&base::Time::Now), models_associated_(false), processing_syncer_changes_(false), - sync_processor_(NULL) { + sync_processor_(NULL), + pending_synced_default_search_(false) { Init(initializers, count); } @@ -457,7 +459,7 @@ const TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() { scoped_ptr<TemplateURL> prepopulated_default( TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs())); for (TemplateURLVector::iterator i = template_urls_.begin(); - i != template_urls_.end(); ) { + i != template_urls_.end(); ++i) { if ((*i)->prepopulate_id() == prepopulated_default->prepopulate_id()) return *i; } @@ -579,12 +581,17 @@ void TemplateURLService::OnWebDataServiceRequestDone( // Note that this saves the default search provider to prefs. SetDefaultSearchProviderNoNotify(default_search_provider); } else { - // If we had a managed default, replace it with the first provider of - // the list. - if (database_specified_a_default && - NULL == default_search_provider && - !template_urls.empty()) + // If we had a managed default, replace it with the synced default if + // applicable, or the first provider of the list. + const TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); + if (synced_default) { + default_search_provider = synced_default; + pending_synced_default_search_ = false; + } else if (database_specified_a_default && + NULL == default_search_provider && + !template_urls.empty()) { default_search_provider = template_urls[0]; + } // If the default search provider existed previously, then just // set the member variable. Otherwise, we'll set it using the method @@ -651,6 +658,27 @@ void TemplateURLService::Observe(int type, } else if (type == chrome::NOTIFICATION_PREF_CHANGED) { const std::string* pref_name = content::Details<std::string>(details).ptr(); if (!pref_name || default_search_prefs_->IsObserved(*pref_name)) { + // Listen for changes to the default search from Sync. If it is + // specifically the synced default search provider GUID that changed, we + // have to set it (or wait for it). + PrefService* prefs = GetPrefs(); + if (pref_name && *pref_name == prefs::kSyncedDefaultSearchProviderGUID && + prefs) { + const TemplateURL* new_default_search = GetTemplateURLForGUID( + prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID)); + if (new_default_search && !is_default_search_managed_) { + if (new_default_search != GetDefaultSearchProvider()) { + SetDefaultSearchProvider(new_default_search); + pending_synced_default_search_ = false; + } + } else { + // If it's not there, or if default search is currently managed, set a + // flag to indicate that we waiting on the search engine entry to come + // in through Sync. + pending_synced_default_search_ = true; + } + } + // A preference related to default search engine has changed. // Update the model if needed. UpdateDefaultSearch(); @@ -708,17 +736,35 @@ SyncError TemplateURLService::ProcessSyncChanges( GetTemplateURLForKeyword(turl->keyword()); if (iter->change_type() == SyncChange::ACTION_DELETE && existing_turl) { - Remove(existing_turl); + bool delete_default = (existing_turl == GetDefaultSearchProvider()); + + if (delete_default && is_default_search_managed_) { + NOTREACHED() << "Tried to delete managed default search provider"; + } else { + if (delete_default) + default_search_provider_ = NULL; + + Remove(existing_turl); + + if (delete_default) + SetDefaultSearchProvider(FindNewDefaultSearchProvider()); + } } else if (iter->change_type() == SyncChange::ACTION_ADD && !existing_turl) { + std::string guid = turl->sync_guid(); if (existing_keyword_turl) ResolveSyncKeywordConflict(turl.get(), &new_changes); // Force the local ID to 0 so we can add it. turl->set_id(0); Add(turl.release()); + + // Possibly set the newly added |turl| as the default search provider. + SetDefaultSearchProviderIfNewlySynced(guid); } else if (iter->change_type() == SyncChange::ACTION_UPDATE && existing_turl) { - if (existing_keyword_turl) + // Possibly resolve a keyword conflict if they have the same keywords but + // are not the same entry. + if (existing_keyword_turl && existing_keyword_turl != existing_turl) ResolveSyncKeywordConflict(turl.get(), &new_changes); ResetTemplateURL(existing_turl, turl->short_name(), turl->keyword(), turl->url() ? turl->url()->url() : std::string()); @@ -753,6 +799,18 @@ SyncError TemplateURLService::MergeDataAndStartSyncing( DCHECK(!sync_processor_); sync_processor_ = sync_processor; + // We just started syncing, so set our wait-for-default flag if we are + // expecting a default from Sync. + if (GetPrefs()) { + std::string default_guid = GetPrefs()->GetString( + prefs::kSyncedDefaultSearchProviderGUID); + const TemplateURL* current_default = GetDefaultSearchProvider(); + + if (!default_guid.empty() && + (!current_default || current_default->sync_guid() != default_guid)) + pending_synced_default_search_ = true; + } + // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we // don't step on our own toes. AutoReset<bool> processing_changes(&processing_syncer_changes_, true); @@ -812,6 +870,7 @@ SyncError TemplateURLService::MergeDataAndStartSyncing( &new_changes); local_data_map.erase(old_guid); } else { + std::string guid = sync_turl->sync_guid(); // Keyword conflict is possible in this case. Resolve it first before // adding the new TemplateURL. Note that we don't remove the local TURL // from local_data_map in this case as it may still need to be pushed to @@ -820,6 +879,9 @@ SyncError TemplateURLService::MergeDataAndStartSyncing( // Force the local ID to 0 so we can add it. sync_turl->set_id(0); Add(sync_turl.release()); + + // Possibly set the newly added |turl| as the default search provider. + SetDefaultSearchProviderIfNewlySynced(guid); } } } // for @@ -952,7 +1014,7 @@ void TemplateURLService::SetKeywordSearchTermsForURL(const TemplateURL* t_url, } void TemplateURLService::Init(const Initializer* initializers, - int num_initializers) { + int num_initializers) { // Register for notifications. if (profile_) { // TODO(sky): bug 1166191. The keywords should be moved into the history @@ -1488,7 +1550,14 @@ void TemplateURLService::UpdateDefaultSearch() { default_search_provider_ = NULL; RemoveNoNotify(old_default); } - SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider()); + + // The likely default should be from Sync if we were waiting on Sync. + // Otherwise, it should be FindNewDefaultSearchProvider. + const TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider(); + if (synced_default) + pending_synced_default_search_ = false; + SetDefaultSearchProviderNoNotify(synced_default ? synced_default : + FindNewDefaultSearchProvider()); } NotifyObservers(); } @@ -1520,9 +1589,17 @@ void TemplateURLService::SetDefaultSearchProviderNoNotify( } } - if (!is_default_search_managed_) + if (!is_default_search_managed_) { SaveDefaultSearchProviderToPrefs(url); + // If we are syncing, we want to set the synced pref that will notify other + // instances to change their default to this new search provider. + if (sync_processor_ && !url->sync_guid().empty() && GetPrefs()) { + GetPrefs()->SetString(prefs::kSyncedDefaultSearchProviderGUID, + url->sync_guid()); + } + } + if (service_.get()) service_->SetDefaultSearchProvider(url); @@ -1681,7 +1758,8 @@ bool TemplateURLService::ResolveSyncKeywordConflict( const TemplateURL* existing_turl = GetTemplateURLForKeyword(sync_turl->keyword()); - if (!existing_turl) + // If there is no conflict, or it's just conflicting with itself, return. + if (!existing_turl || existing_turl->sync_guid() == sync_turl->sync_guid()) return false; if (existing_turl->last_modified() > sync_turl->last_modified() || @@ -1745,6 +1823,34 @@ void TemplateURLService::MergeSyncAndLocalURLDuplicates( } } +void TemplateURLService::SetDefaultSearchProviderIfNewlySynced( + const std::string& guid) { + // If we're not syncing or if default search is managed by policy, ignore. + if (!sync_processor_ || is_default_search_managed_) + return; + + PrefService* prefs = GetPrefs(); + if (prefs && pending_synced_default_search_ && + prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID) == guid) { + // Make sure this actually exists. We should not be calling this unless we + // really just added this TemplateURL. + const TemplateURL* turl_from_sync = GetTemplateURLForGUID(guid); + DCHECK(turl_from_sync); + SetDefaultSearchProvider(turl_from_sync); + pending_synced_default_search_ = false; + } +} + +const TemplateURL* TemplateURLService::GetPendingSyncedDefaultSearchProvider() { + PrefService* prefs = GetPrefs(); + if (!prefs || !pending_synced_default_search_) + return NULL; + + // Could be NULL if no such thing exists. + return GetTemplateURLForGUID( + prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID)); +} + void TemplateURLService::PatchMissingSyncGUIDs( std::vector<TemplateURL*>* template_urls) { DCHECK(template_urls); diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h index 0eb95b2..f633566 100644 --- a/chrome/browser/search_engines/template_url_service.h +++ b/chrome/browser/search_engines/template_url_service.h @@ -336,8 +336,6 @@ class TemplateURLService : public WebDataServiceConsumer, FindDuplicateOfSyncTemplateURL); FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeSyncAndLocalURLDuplicates); - FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, - CreateGUIDToSyncDataMap); friend class TemplateURLServiceTestUtil; @@ -496,6 +494,14 @@ class TemplateURLService : public WebDataServiceConsumer, TemplateURL* local_url, SyncChangeList* change_list); + // Checks a newly added TemplateURL from Sync by its sync_guid and sets it as + // the default search provider if we were waiting for it. + void SetDefaultSearchProviderIfNewlySynced(const std::string& guid); + + // Retrieve the pending default search provider according to Sync. Returns + // NULL if there was no pending search provider from Sync. + const TemplateURL* GetPendingSyncedDefaultSearchProvider(); + // Goes through a vector of TemplateURLs and ensure that both the in-memory // and database copies have valid sync_guids. This is to fix crbug.com/102038, // where old entries were being pushed to Sync without a sync_guid. @@ -579,6 +585,13 @@ class TemplateURLService : public WebDataServiceConsumer, // Sync's SyncChange handler. We push all our changes through this. SyncChangeProcessor* sync_processor_; + // Whether or not we are waiting on the default search provider to come in + // from Sync. This is to facilitate the fact that changes to the value of + // prefs::kSyncedDefaultSearchProviderGUID do not always come before the + // TemplateURL entry it refers to, and to handle the case when we want to use + // the Synced default when the default search provider becomes unmanaged. + bool pending_synced_default_search_; + DISALLOW_COPY_AND_ASSIGN(TemplateURLService); }; diff --git a/chrome/browser/search_engines/template_url_service_factory.cc b/chrome/browser/search_engines/template_url_service_factory.cc index e3f0e0e..6733c39 100644 --- a/chrome/browser/search_engines/template_url_service_factory.cc +++ b/chrome/browser/search_engines/template_url_service_factory.cc @@ -35,6 +35,9 @@ ProfileKeyedService* TemplateURLServiceFactory::BuildServiceInstanceFor( } void TemplateURLServiceFactory::RegisterUserPrefs(PrefService* prefs) { + prefs->RegisterStringPref(prefs::kSyncedDefaultSearchProviderGUID, + std::string(), + PrefService::SYNCABLE_PREF); prefs->RegisterBooleanPref(prefs::kDefaultSearchProviderEnabled, true, PrefService::UNSYNCABLE_PREF); diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc index b258364..22cf3ef 100644 --- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc +++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc @@ -8,8 +8,13 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_service.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/sync/protocol/search_engine_specifics.pb.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_pref_service.h" #include "chrome/test/base/testing_profile.h" +#include "content/public/browser/notification_service.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; @@ -22,7 +27,7 @@ std::string GetGUID(const SyncData& sync_data) { sync_pb::search_engine).sync_guid(); } -// Extract the keyword from a search engine SyncData. +// Extract the URL from a search engine SyncData. std::string GetURL(const SyncData& sync_data) { return sync_data.GetSpecifics().GetExtension( sync_pb::search_engine).url(); @@ -34,6 +39,51 @@ std::string GetKeyword(const SyncData& sync_data) { sync_pb::search_engine).keyword(); } +// TODO(stevet): Share these with template_url_service_unittest. +// Set the managed preferences for the default search provider and trigger +// notification. +void SetManagedDefaultSearchPreferences(TemplateURLService* turl_service, + TestingProfile* profile, + bool enabled, + const char* name, + const char* search_url, + const char* suggest_url, + const char* icon_url, + const char* encodings, + const char* keyword) { + TestingPrefService* pref_service = profile->GetTestingPrefService(); + pref_service->SetManagedPref(prefs::kDefaultSearchProviderEnabled, + Value::CreateBooleanValue(enabled)); + pref_service->SetManagedPref(prefs::kDefaultSearchProviderName, + Value::CreateStringValue(name)); + pref_service->SetManagedPref(prefs::kDefaultSearchProviderSearchURL, + Value::CreateStringValue(search_url)); + pref_service->SetManagedPref(prefs::kDefaultSearchProviderSuggestURL, + Value::CreateStringValue(suggest_url)); + pref_service->SetManagedPref(prefs::kDefaultSearchProviderIconURL, + Value::CreateStringValue(icon_url)); + pref_service->SetManagedPref(prefs::kDefaultSearchProviderEncodings, + Value::CreateStringValue(encodings)); + pref_service->SetManagedPref(prefs::kDefaultSearchProviderKeyword, + Value::CreateStringValue(keyword)); +} + +// Remove all the managed preferences for the default search provider and +// trigger notification. +void RemoveManagedDefaultSearchPreferences(TemplateURLService* turl_service, + TestingProfile* profile) { + TestingPrefService* pref_service = profile->GetTestingPrefService(); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderSearchURL); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderEnabled); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderName); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderSuggestURL); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderIconURL); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderEncodings); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderKeyword); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderID); + pref_service->RemoveManagedPref(prefs::kDefaultSearchProviderPrepopulateID); +} + // Dummy SyncChangeProcessor used to help review what SyncChanges are pushed // back up to Sync. class TestChangeProcessor : public SyncChangeProcessor { @@ -87,9 +137,13 @@ class TemplateURLServiceSyncTest : public testing::Test { virtual void SetUp() { profile_a_.reset(new TestingProfile); + TemplateURLServiceFactory::GetInstance()->RegisterUserPrefsOnProfile( + profile_a_.get()); model_a_.reset(new TemplateURLService(profile_a_.get())); model_a_->Load(); profile_b_.reset(new TestingProfile); + TemplateURLServiceFactory::GetInstance()->RegisterUserPrefsOnProfile( + profile_b_.get()); model_b_.reset(new TemplateURLService(profile_b_.get())); model_b_->Load(); } @@ -1061,3 +1115,163 @@ TEST_F(TemplateURLServiceSyncTest, MergeTwiceWithSameSyncData) { ASSERT_TRUE(reupdated_turl); AssertEquals(updated_turl, *reupdated_turl); } + +TEST_F(TemplateURLServiceSyncTest, SyncedDefaultGUIDArrivesFirst) { + SyncDataList initial_data = CreateInitialSyncData(); + model()->MergeDataAndStartSyncing( + syncable::SEARCH_ENGINES, + initial_data, + processor()); + model()->SetDefaultSearchProvider(model()->GetTemplateURLForGUID("key2")); + + EXPECT_EQ(3U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); + const TemplateURL* default_search = model()->GetDefaultSearchProvider(); + ASSERT_TRUE(default_search); + + // Change kSyncedDefaultSearchProviderGUID to a GUID that does not exist in + // the model yet. Ensure that the default has not changed in any way. + profile_a_->GetTestingPrefService()->SetString( + prefs::kSyncedDefaultSearchProviderGUID, + "newdefault"); + + ASSERT_EQ(default_search, model()->GetDefaultSearchProvider()); + + // Bring in a random new search engine with a different GUID. Ensure that + // it doesn't change the default. + SyncChangeList changes1; + changes1.push_back(CreateTestSyncChange( + SyncChange::ACTION_ADD, + CreateTestTemplateURL("random", "http://random.com", "random"))); + model()->ProcessSyncChanges(FROM_HERE, changes1); + + EXPECT_EQ(4U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); + ASSERT_EQ(default_search, model()->GetDefaultSearchProvider()); + + // Finally, bring in the expected entry with the right GUID. Ensure that + // the default has changed to the new search engine. + SyncChangeList changes2; + changes2.push_back(CreateTestSyncChange( + SyncChange::ACTION_ADD, + CreateTestTemplateURL("new", "http://new.com", "newdefault"))); + model()->ProcessSyncChanges(FROM_HERE, changes2); + + EXPECT_EQ(5U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); + ASSERT_NE(default_search, model()->GetDefaultSearchProvider()); + ASSERT_EQ("newdefault", model()->GetDefaultSearchProvider()->sync_guid()); +} + +TEST_F(TemplateURLServiceSyncTest, SyncedDefaultArrivesAfterStartup) { + // Start with the default set to something in the model before we start + // syncing. + model()->Add(CreateTestTemplateURL( + "what", "http://thewhat.com", "initdefault")); + model()->SetDefaultSearchProvider( + model()->GetTemplateURLForGUID("initdefault")); + + const TemplateURL* default_search = model()->GetDefaultSearchProvider(); + ASSERT_TRUE(default_search); + + // Set kSyncedDefaultSearchProviderGUID to something that is not yet in + // the model but is expected in the initial sync. Ensure that this doesn't + // change our default since we're not quite syncing yet. + profile_a_->GetTestingPrefService()->SetString( + prefs::kSyncedDefaultSearchProviderGUID, + "key2"); + + EXPECT_EQ(default_search, model()->GetDefaultSearchProvider()); + + // Now sync the initial data, which will include the search engine entry + // destined to become the new default. + SyncDataList initial_data = CreateInitialSyncData(); + model()->MergeDataAndStartSyncing( + syncable::SEARCH_ENGINES, + initial_data, + processor()); + + // Ensure that the new default has been set. + EXPECT_EQ(4U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); + ASSERT_NE(default_search, model()->GetDefaultSearchProvider()); + ASSERT_EQ("key2", model()->GetDefaultSearchProvider()->sync_guid()); +} + +TEST_F(TemplateURLServiceSyncTest, SyncedDefaultAlreadySetOnStartup) { + // Start with the default set to something in the model before we start + // syncing. + const char kGUID[] = "initdefault"; + model()->Add(CreateTestTemplateURL("what", "http://thewhat.com", kGUID)); + model()->SetDefaultSearchProvider(model()->GetTemplateURLForGUID(kGUID)); + + const TemplateURL* default_search = model()->GetDefaultSearchProvider(); + ASSERT_TRUE(default_search); + + // Set kSyncedDefaultSearchProviderGUID to the current default. + profile_a_->GetTestingPrefService()->SetString( + prefs::kSyncedDefaultSearchProviderGUID, + kGUID); + + EXPECT_EQ(default_search, model()->GetDefaultSearchProvider()); + + // Now sync the initial data. + SyncDataList initial_data = CreateInitialSyncData(); + model()->MergeDataAndStartSyncing( + syncable::SEARCH_ENGINES, + initial_data, + processor()); + + // Ensure that the new entries were added and the default has not changed. + EXPECT_EQ(4U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); + ASSERT_EQ(default_search, model()->GetDefaultSearchProvider()); +} + +TEST_F(TemplateURLServiceSyncTest, SyncWithManagedDefaultSearch) { + // First start off with a few entries and make sure we can set an unmanaged + // default search provider. + SyncDataList initial_data = CreateInitialSyncData(); + model()->MergeDataAndStartSyncing( + syncable::SEARCH_ENGINES, + initial_data, + processor()); + model()->SetDefaultSearchProvider(model()->GetTemplateURLForGUID("key2")); + + EXPECT_EQ(3U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); + ASSERT_FALSE(model()->is_default_search_managed()); + ASSERT_TRUE(model()->GetDefaultSearchProvider()); + + // Change the default search provider to a managed one. + const char kName[] = "manageddefault"; + const char kSearchURL[] = "http://manageddefault.com/search?t={searchTerms}"; + const char kIconURL[] = "http://manageddefault.com/icon.jpg"; + const char kEncodings[] = "UTF-16;UTF-32"; + SetManagedDefaultSearchPreferences(model(), profile_a_.get(), true, kName, + kSearchURL, "", kIconURL, kEncodings, ""); + const TemplateURL* dsp_turl = model()->GetDefaultSearchProvider(); + + EXPECT_TRUE(model()->is_default_search_managed()); + + // Add a new entry from Sync. It should still sync in despite the default + // being managed. + SyncChangeList changes; + changes.push_back(CreateTestSyncChange( + SyncChange::ACTION_ADD, + CreateTestTemplateURL("newkeyword", "http://new.com", "newdefault"))); + model()->ProcessSyncChanges(FROM_HERE, changes); + + EXPECT_EQ(4U, model()->GetAllSyncData(syncable::SEARCH_ENGINES).size()); + + // Change kSyncedDefaultSearchProviderGUID to point to the new entry and + // ensure that the DSP remains managed. + profile_a_->GetTestingPrefService()->SetString( + prefs::kSyncedDefaultSearchProviderGUID, + "newdefault"); + + EXPECT_EQ(dsp_turl, model()->GetDefaultSearchProvider()); + EXPECT_TRUE(model()->is_default_search_managed()); + + // Go unmanaged. Ensure that the DSP changes to the expected pending entry + // from Sync. + const TemplateURL* expected_default = + model()->GetTemplateURLForGUID("newdefault"); + RemoveManagedDefaultSearchPreferences(model(), profile_a_.get()); + + EXPECT_EQ(expected_default, model()->GetDefaultSearchProvider()); +} diff --git a/chrome/browser/sync/profile_sync_factory_impl.cc b/chrome/browser/sync/profile_sync_factory_impl.cc index 5d8824e26..a820419 100644 --- a/chrome/browser/sync/profile_sync_factory_impl.cc +++ b/chrome/browser/sync/profile_sync_factory_impl.cc @@ -153,6 +153,13 @@ void ProfileSyncFactoryImpl::RegisterDataTypes(ProfileSyncService* pss) { new TypedUrlDataTypeController(this, profile_)); } + // Search Engine sync is enabled by default. Register only if explicitly + // disabled. + if (!command_line_->HasSwitch(switches::kDisableSyncSearchEngines)) { + pss->RegisterDataTypeController( + new SearchEngineDataTypeController(this, profile_, pss)); + } + // Session sync is disabled by default. Register only if explicitly // enabled. if (command_line_->HasSwitch(switches::kEnableSyncTabs)) { @@ -176,13 +183,6 @@ void ProfileSyncFactoryImpl::RegisterDataTypes(ProfileSyncService* pss) { new AutofillProfileDataTypeController(this, profile_)); } - // Search Engine sync is disabled by default. Register only if explicitly - // enabled. - if (command_line_->HasSwitch(switches::kEnableSyncSearchEngines)) { - pss->RegisterDataTypeController( - new SearchEngineDataTypeController(this, profile_, pss)); - } - // App notifications sync is disabled by default. Register only if // explicitly enabled. if (command_line_->HasSwitch(switches::kEnableSyncAppNotifications)) { diff --git a/chrome/browser/sync/profile_sync_factory_impl_unittest.cc b/chrome/browser/sync/profile_sync_factory_impl_unittest.cc index 74cd79a..91b5e96 100644 --- a/chrome/browser/sync/profile_sync_factory_impl_unittest.cc +++ b/chrome/browser/sync/profile_sync_factory_impl_unittest.cc @@ -44,6 +44,7 @@ class ProfileSyncFactoryImplTest : public testing::Test { datatypes.push_back(syncable::AUTOFILL_PROFILE); datatypes.push_back(syncable::PASSWORDS); datatypes.push_back(syncable::TYPED_URLS); + datatypes.push_back(syncable::SEARCH_ENGINES); return datatypes; } diff --git a/chrome/browser/sync/resources/configure.html b/chrome/browser/sync/resources/configure.html index 107f136..a2963b5 100644 --- a/chrome/browser/sync/resources/configure.html +++ b/chrome/browser/sync/resources/configure.html @@ -358,22 +358,15 @@ html[os='mac'] input[type='submit'] { args.syncApps; document.getElementById("appsItem").className = "sync-item-show"; } else { - document.getElementById("appsItem").className = "sync-item-hide";
- }
- if (args.searchEnginesRegistered) {
- document.getElementById("searchEnginesCheckbox").checked =
- args.syncSearchEngines;
- document.getElementById("searchEnginesItem").className = "sync-item-show";
- } else {
- document.getElementById("searchEnginesItem").className = "sync-item-hide";
- }
- if (args.sessionsRegistered) {
- document.getElementById("sessionsCheckbox").checked = args.syncSessions;
- document.getElementById("sessionsItem").className = "sync-item-show";
- } else {
- document.getElementById("sessionsItem").className = "sync-item-hide";
- }
-
+ document.getElementById("appsItem").className = "sync-item-hide"; + } + if (args.sessionsRegistered) { + document.getElementById("sessionsCheckbox").checked = args.syncSessions; + document.getElementById("sessionsItem").className = "sync-item-show"; + } else { + document.getElementById("sessionsItem").className = "sync-item-hide"; + } + setCheckboxesToKeepEverythingSynced(args.syncAllDataTypes); } @@ -461,9 +454,8 @@ html[os='mac'] input[type='submit'] { "syncPasswords": syncAll || f.passwordsCheckbox.checked, "syncAutofill": syncAll || f.autofillCheckbox.checked, "syncExtensions": syncAll || f.extensionsCheckbox.checked, - "syncTypedUrls": syncAll || f.typedUrlsCheckbox.checked,
- "syncApps": syncAll || f.appsCheckbox.checked,
- "syncSearchEngines": syncAll || f.searchEnginesCheckbox.checked, + "syncTypedUrls": syncAll || f.typedUrlsCheckbox.checked, + "syncApps": syncAll || f.appsCheckbox.checked, "syncSessions": syncAll || f.sessionsCheckbox.checked, "usePassphrase": (getRadioCheckedValue() == 'explicit'), "passphrase": f.passphrase.value @@ -619,13 +611,6 @@ html[os='mac'] input[type='submit'] { for="sessionsCheckbox" i18n-content="foreignsessions" il8n-values="title:sessions"></label> </div> - <!-- Search Engines --> - <div class="sync-item-show" id="searchEnginesItem"> - <input id="searchEnginesCheckbox" name="dataTypeCheckbox" type="checkbox"> - <label id="searchEnginesCheckboxLabel" name="dataTypeLabel" - for="searchEnginesCheckbox" i18n-content="searchengines" - il8n-values="title:searchengines"></label> - </div> </div> </div> </div> diff --git a/chrome/browser/sync/sync_prefs.cc b/chrome/browser/sync/sync_prefs.cc index 65c28f3..1e27f4a 100644 --- a/chrome/browser/sync/sync_prefs.cc +++ b/chrome/browser/sync/sync_prefs.cc @@ -134,11 +134,12 @@ syncable::ModelTypeSet SyncPrefs::GetPreferredDataTypes( return registered_types; } - // Remove autofill_profile since it's controlled by autofill (see - // code below). + // Remove autofill_profile since it's controlled by autofill, and + // search_engines since it's controlled by preferences (see code below). syncable::ModelTypeSet user_selectable_types(registered_types); DCHECK_EQ(user_selectable_types.count(syncable::NIGORI), 0u); user_selectable_types.erase(syncable::AUTOFILL_PROFILE); + user_selectable_types.erase(syncable::SEARCH_ENGINES); // Remove app_notifications since it's controlled by apps (see // code below). @@ -155,13 +156,19 @@ syncable::ModelTypeSet SyncPrefs::GetPreferredDataTypes( } } - // Set autofill_profile to the same enabled/disabled state as - // autofill (since only autofill is shown on the UI). + // Group the enabled/disabled state of autofill_profile with autofill, and + // search_engines with preferences (since only autofill and preferences are + // shown on the UI). if (registered_types.count(syncable::AUTOFILL) && registered_types.count(syncable::AUTOFILL_PROFILE) && GetDataTypePreferred(syncable::AUTOFILL)) { preferred_types.insert(syncable::AUTOFILL_PROFILE); } + if (registered_types.count(syncable::PREFERENCES) && + registered_types.count(syncable::SEARCH_ENGINES) && + GetDataTypePreferred(syncable::PREFERENCES)) { + preferred_types.insert(syncable::SEARCH_ENGINES); + } // Set app_notifications to the same enabled/disabled state as // apps (since only apps is shown on the UI). @@ -202,6 +209,16 @@ void SyncPrefs::SetPreferredDataTypes( preferred_types_with_dependents.erase(syncable::APP_NOTIFICATIONS); } } + // Set search_engines to the same enabled/disabled state as + // preferences (since only preferences is shown in the UI). + if (registered_types.count(syncable::PREFERENCES) && + registered_types.count(syncable::SEARCH_ENGINES)) { + if (preferred_types_with_dependents.count(syncable::PREFERENCES)) { + preferred_types_with_dependents.insert(syncable::SEARCH_ENGINES); + } else { + preferred_types_with_dependents.erase(syncable::SEARCH_ENGINES); + } + } for (syncable::ModelTypeSet::const_iterator it = registered_types.begin(); it != registered_types.end(); ++it) { diff --git a/chrome/browser/sync/sync_prefs_unittest.cc b/chrome/browser/sync/sync_prefs_unittest.cc index fedfa52..6ec9bd4 100644 --- a/chrome/browser/sync/sync_prefs_unittest.cc +++ b/chrome/browser/sync/sync_prefs_unittest.cc @@ -41,6 +41,7 @@ syncable::ModelTypeSet GetNonPassiveTypes() { syncable::ModelTypeSet GetUserVisibleTypes() { syncable::ModelTypeSet user_visible_types(GetNonPassiveTypes()); user_visible_types.erase(syncable::AUTOFILL_PROFILE); + user_visible_types.erase(syncable::SEARCH_ENGINES); user_visible_types.erase(syncable::APP_NOTIFICATIONS); return user_visible_types; } @@ -110,6 +111,9 @@ TEST_F(SyncPrefsTest, PreferredTypesNotKeepEverythingSynced) { if (*it == syncable::AUTOFILL) { expected_preferred_types.insert(syncable::AUTOFILL_PROFILE); } + if (*it == syncable::PREFERENCES) { + expected_preferred_types.insert(syncable::SEARCH_ENGINES); + } if (*it == syncable::APPS) { expected_preferred_types.insert(syncable::APP_NOTIFICATIONS); } diff --git a/chrome/browser/sync/sync_setup_flow.cc b/chrome/browser/sync/sync_setup_flow.cc index 619c8e2..7cb6c7a 100644 --- a/chrome/browser/sync/sync_setup_flow.cc +++ b/chrome/browser/sync/sync_setup_flow.cc @@ -140,8 +140,6 @@ void SyncSetupFlow::GetArgsForConfigure(ProfileSyncService* service, registered_types.count(syncable::TYPED_URLS) > 0); args->SetBoolean("appsRegistered", registered_types.count(syncable::APPS) > 0); - args->SetBoolean("searchEnginesRegistered", - registered_types.count(syncable::SEARCH_ENGINES) > 0); args->SetBoolean("sessionsRegistered", registered_types.count(syncable::SESSIONS) > 0); args->SetBoolean("syncBookmarks", @@ -156,8 +154,6 @@ void SyncSetupFlow::GetArgsForConfigure(ProfileSyncService* service, preferred_types.count(syncable::AUTOFILL) > 0); args->SetBoolean("syncExtensions", preferred_types.count(syncable::EXTENSIONS) > 0); - args->SetBoolean("syncSearchEngines", - preferred_types.count(syncable::SEARCH_ENGINES) > 0); args->SetBoolean("syncSessions", preferred_types.count(syncable::SESSIONS) > 0); args->SetBoolean("syncTypedUrls", diff --git a/chrome/browser/sync/sync_setup_wizard_unittest.cc b/chrome/browser/sync/sync_setup_wizard_unittest.cc index 1c9933c..e407623 100644 --- a/chrome/browser/sync/sync_setup_wizard_unittest.cc +++ b/chrome/browser/sync/sync_setup_wizard_unittest.cc @@ -325,8 +325,8 @@ TEST_F(SyncSetupWizardTest, ChooseDataTypesSetsPrefs) { "{\"syncAllDataTypes\":false,\"syncBookmarks\":true," "\"syncPreferences\":true,\"syncThemes\":false,\"syncPasswords\":false," "\"syncAutofill\":false,\"syncExtensions\":false,\"syncTypedUrls\":true," - "\"syncApps\":true,\"syncSearchEngines\":false,\"syncSessions\":false," - "\"usePassphrase\":false,\"encryptAllData\":false}"; + "\"syncApps\":true,\"syncSessions\":false,\"usePassphrase\":false," + "\"encryptAllData\":false}"; data_type_choices_value.Append(new StringValue(data_type_choices)); // Simulate the user choosing data types; bookmarks, prefs, typed URLS, and @@ -344,7 +344,6 @@ TEST_F(SyncSetupWizardTest, ChooseDataTypesSetsPrefs) { EXPECT_EQ(0U, service_->chosen_data_types_.count(syncable::EXTENSIONS)); EXPECT_EQ(1U, service_->chosen_data_types_.count(syncable::TYPED_URLS)); EXPECT_EQ(1U, service_->chosen_data_types_.count(syncable::APPS)); - EXPECT_EQ(0U, service_->chosen_data_types_.count(syncable::SEARCH_ENGINES)); EXPECT_EQ(0U, service_->chosen_data_types_.count( syncable::APP_NOTIFICATIONS)); } diff --git a/chrome/browser/sync/test/integration/search_engines_helper.cc b/chrome/browser/sync/test/integration/search_engines_helper.cc index 95a9fc7..adc3ed7 100644 --- a/chrome/browser/sync/test/integration/search_engines_helper.cc +++ b/chrome/browser/sync/test/integration/search_engines_helper.cc @@ -137,6 +137,20 @@ bool ServicesMatch(int profile_a, int profile_b) { return false; } + const TemplateURL* default_a = service_a->GetDefaultSearchProvider(); + const TemplateURL* default_b = service_b->GetDefaultSearchProvider(); + CHECK(default_a); + CHECK(default_b); + if (!TURLsMatch(default_a, default_b)) { + LOG(ERROR) << "Default search providers do not match: A's default: " + << default_a->keyword() << " B's default: " + << default_b->keyword(); + return false; + } else { + LOG(INFO) << "A had default with URL: " << default_a->url()->url() + << " and keyword: " << default_a->keyword(); + } + return true; } @@ -155,10 +169,16 @@ bool AllServicesMatch() { return true; } +// Convenience helper for consistently generating the same keyword for a given +// seed. +string16 CreateKeyword(int seed) { + return ASCIIToUTF16(base::StringPrintf("test%d", seed)); +} + TemplateURL* CreateTestTemplateURL(int seed) { TemplateURL* turl = new TemplateURL(); turl->SetURL(base::StringPrintf("http://www.test%d.com/", seed), 0, 0); - turl->set_keyword(ASCIIToUTF16(base::StringPrintf("test%d", seed))); + turl->set_keyword(CreateKeyword(seed)); turl->set_short_name(ASCIIToUTF16(base::StringPrintf("test%d", seed))); turl->set_safe_for_autoreplace(true); GURL favicon_url("http://favicon.url"); @@ -200,18 +220,37 @@ void EditSearchEngine(int profile, } } -void DeleteSearchEngine(int profile, const std::string& keyword) { +void DeleteSearchEngineByKeyword(int profile, const string16 keyword) { const TemplateURL* turl = GetServiceForProfile(profile)-> - GetTemplateURLForKeyword(ASCIIToUTF16(keyword)); + GetTemplateURLForKeyword(keyword); EXPECT_TRUE(turl); GetServiceForProfile(profile)->Remove(turl); // Make sure we do the same on the verifier. if (test()->use_verifier()) { const TemplateURL* verifier_turl = - GetVerifierService()->GetTemplateURLForKeyword(ASCIIToUTF16(keyword)); + GetVerifierService()->GetTemplateURLForKeyword(keyword); EXPECT_TRUE(verifier_turl); GetVerifierService()->Remove(verifier_turl); } } +void DeleteSearchEngineBySeed(int profile, int seed) { + DeleteSearchEngineByKeyword(profile, CreateKeyword(seed)); +} + +void ChangeDefaultSearchProvider(int profile, int seed) { + TemplateURLService* service = GetServiceForProfile(profile); + ASSERT_TRUE(service); + const TemplateURL* new_default = service->GetTemplateURLForKeyword( + CreateKeyword(seed)); + ASSERT_TRUE(new_default); + service->SetDefaultSearchProvider(new_default); + if (test()->use_verifier()) { + new_default = GetVerifierService()->GetTemplateURLForKeyword( + CreateKeyword(seed)); + ASSERT_TRUE(new_default); + GetVerifierService()->SetDefaultSearchProvider(new_default); + } +} + } // namespace search_engines_helper diff --git a/chrome/browser/sync/test/integration/search_engines_helper.h b/chrome/browser/sync/test/integration/search_engines_helper.h index 75acc4b..4858280 100644 --- a/chrome/browser/sync/test/integration/search_engines_helper.h +++ b/chrome/browser/sync/test/integration/search_engines_helper.h @@ -9,6 +9,8 @@ #include <map> #include <string> +#include "base/string16.h" + class TemplateURL; class TemplateURLService; @@ -59,7 +61,15 @@ void EditSearchEngine(int profile, // Deletes a search engine from the service at index |profile| with original // keyword |keyword|. Does the same to the verifier, if it is used. -void DeleteSearchEngine(int profile, const std::string& keyword); +void DeleteSearchEngineByKeyword(int profile, const string16 keyword); + +// Deletes a search engine from the service at index |profile| which was +// generated by seed |seed|. +void DeleteSearchEngineBySeed(int profile, int seed); + +// Change the search engine generated with |seed| in service at index |profile| +// to be the new default. Does the same to the verifier, if it is used. +void ChangeDefaultSearchProvider(int profile, int seed); } // namespace search_engines_helper diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 6d39389..34518d2 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc @@ -224,10 +224,6 @@ void SyncTest::AddOptionalTypesToCommandLine(CommandLine* cl) { // TODO(sync): Remove this once sessions sync is enabled by default. if (!cl->HasSwitch(switches::kEnableSyncTabs)) cl->AppendSwitch(switches::kEnableSyncTabs); - - // TODO(stevet): Remove this once search engines sync is enabled by default. - if (!cl->HasSwitch(switches::kEnableSyncSearchEngines)) - cl->AppendSwitch(switches::kEnableSyncSearchEngines); } // static @@ -703,6 +699,15 @@ void SyncTest::TriggerSetSyncTabs() { UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); } +int SyncTest::NumberOfDefaultSyncItems() const { + // Just return the current number of basic sync items that are synced, + // including preferences, themes, and search engines. + // TODO(stevet): It would be nice if there was some mechanism for retrieving + // this sum from each data type without having to manually count and update + // this value. + return 7; +} + void SyncTest::SetProxyConfig(net::URLRequestContextGetter* context_getter, const net::ProxyConfig& proxy_config) { base::WaitableEvent done(false, false); diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h index 73c03de..a276ca1091 100644 --- a/chrome/browser/sync/test/integration/sync_test.h +++ b/chrome/browser/sync/test/integration/sync_test.h @@ -181,6 +181,9 @@ class SyncTest : public InProcessBrowserTest { // Triggers setting the sync_tabs field of the nigori node. void TriggerSetSyncTabs(); + // Returns the number of default items that every client syncs. + int NumberOfDefaultSyncItems() const; + protected: // Add custom switches needed for running the test. virtual void AddTestSwitches(CommandLine* cl); diff --git a/chrome/browser/sync/test/integration/two_client_search_engines_sync_test.cc b/chrome/browser/sync/test/integration/two_client_search_engines_sync_test.cc index d3caa6e..710eaf4 100644 --- a/chrome/browser/sync/test/integration/two_client_search_engines_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_search_engines_sync_test.cc @@ -11,8 +11,10 @@ using search_engines_helper::AddSearchEngine; using search_engines_helper::AllServicesMatch; +using search_engines_helper::ChangeDefaultSearchProvider; using search_engines_helper::CreateTestTemplateURL; -using search_engines_helper::DeleteSearchEngine; +using search_engines_helper::DeleteSearchEngineByKeyword; +using search_engines_helper::DeleteSearchEngineBySeed; using search_engines_helper::EditSearchEngine; using search_engines_helper::GetServiceForProfile; using search_engines_helper::GetVerifierService; @@ -97,7 +99,7 @@ IN_PROC_BROWSER_TEST_F(TwoClientSearchEnginesSyncTest, Delete) { ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); ASSERT_TRUE(AllServicesMatch()); - DeleteSearchEngine(0, "test0"); + DeleteSearchEngineBySeed(0, 0); ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); ASSERT_TRUE(AllServicesMatch()); @@ -119,3 +121,42 @@ IN_PROC_BROWSER_TEST_F(TwoClientSearchEnginesSyncTest, DisableSync) { ASSERT_TRUE(AwaitQuiescence()); ASSERT_TRUE(AllServicesMatch()); } + +// TCM ID - 8891809. +IN_PROC_BROWSER_TEST_F(TwoClientSearchEnginesSyncTest, SyncDefault) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_TRUE(AllServicesMatch()); + + AddSearchEngine(0, 0); + ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); + + // Change the default to the new search engine, sync, and ensure that it + // changed in the second client. AllServicesMatch does a default search + // provider check. + ChangeDefaultSearchProvider(0, 0); + ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); + + ASSERT_TRUE(AllServicesMatch()); +} + +// Ensure that we can change the search engine and immediately delete it +// without putting the clients out of sync. +IN_PROC_BROWSER_TEST_F(TwoClientSearchEnginesSyncTest, DeleteSyncedDefault) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_TRUE(AllServicesMatch()); + + AddSearchEngine(0, 0); + AddSearchEngine(0, 1); + ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); + + ChangeDefaultSearchProvider(0, 0); + ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); + ASSERT_TRUE(AllServicesMatch()); + + // Change the default on the first client and delete the old default. + ChangeDefaultSearchProvider(0, 1); + DeleteSearchEngineBySeed(0, 0); + ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); + + ASSERT_TRUE(AllServicesMatch()); +} diff --git a/chrome/browser/sync/test/integration/two_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/two_client_sessions_sync_test.cc index 84c8a19..8748125 100644 --- a/chrome/browser/sync/test/integration/two_client_sessions_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_sessions_sync_test.cc @@ -160,10 +160,10 @@ IN_PROC_BROWSER_TEST_F(TwoClientSessionsSyncTest, ASSERT_TRUE(GetClient(1)->AwaitPassphraseRequired()); ASSERT_EQ(0, GetClient(1)->GetLastSessionSnapshot()-> num_blocking_conflicting_updates); - // We have 6 non-blocking conflicts due to the two meta nodes (one for each - // client), the one tab node, and the six basic preference/themes/search - // engines. - ASSERT_EQ(9, GetClient(1)->GetLastSessionSnapshot()-> + // We have two meta nodes (one for each client), the one tab node, plus the + // basic preference/themes/search engines items. + ASSERT_EQ(NumberOfDefaultSyncItems() + 3, + GetClient(1)->GetLastSessionSnapshot()-> num_conflicting_updates); // The encrypted nodes. GetClient(1)->service()->SetPassphrase(kValidPassphrase, true); @@ -197,9 +197,10 @@ IN_PROC_BROWSER_TEST_F(TwoClientSessionsSyncTest, ASSERT_TRUE(GetClient(1)->AwaitPassphraseRequired()); ASSERT_EQ(0, GetClient(1)->GetLastSessionSnapshot()-> num_blocking_conflicting_updates); - // We have eight non-blocking conflicts due to the two meta nodes (one for - // each client), and the 6 basic preference/themes/search engines nodes. - ASSERT_EQ(8, GetClient(1)->GetLastSessionSnapshot()-> + // We have nine non-blocking conflicts due to the two meta nodes (one for + // each client), plus the basic preference/themes/search engines nodes. + ASSERT_EQ(NumberOfDefaultSyncItems() + 2, + GetClient(1)->GetLastSessionSnapshot()-> num_conflicting_updates); // The encrypted nodes. ScopedWindowMap client0_windows; @@ -208,7 +209,8 @@ IN_PROC_BROWSER_TEST_F(TwoClientSessionsSyncTest, ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1))); ASSERT_EQ(0, GetClient(1)->GetLastSessionSnapshot()-> num_blocking_conflicting_updates); - ASSERT_EQ(9, GetClient(1)->GetLastSessionSnapshot()-> + ASSERT_EQ(NumberOfDefaultSyncItems() + 3, + GetClient(1)->GetLastSessionSnapshot()-> num_conflicting_updates); // The encrypted nodes. GetClient(1)->service()->SetPassphrase(kValidPassphrase, true); @@ -242,8 +244,9 @@ IN_PROC_BROWSER_TEST_F(TwoClientSessionsSyncTest, ASSERT_EQ(0, GetClient(1)->GetLastSessionSnapshot()-> num_blocking_conflicting_updates); // We have two non-blocking conflicts due to the two meta nodes (one for each - // client), and the 6 basic preference/themes/search engines nodes. - ASSERT_EQ(8, GetClient(1)->GetLastSessionSnapshot()-> + // client), plus the basic preference/themes/search engines nodes. + ASSERT_EQ(NumberOfDefaultSyncItems() + 2, + GetClient(1)->GetLastSessionSnapshot()-> num_conflicting_updates); // The encrypted nodes. // These changes are either made with the old passphrase or not encrypted at @@ -295,9 +298,10 @@ IN_PROC_BROWSER_TEST_F(TwoClientSessionsSyncTest, ASSERT_EQ(0, GetClient(1)->GetLastSessionSnapshot()-> num_blocking_conflicting_updates); // We have three non-blocking conflicts due to the two meta nodes (one for - // each client), the one tab node, and the 6 basic preference/themes/search + // each client), the one tab node, plus the basic preference/themes/search // engines nodes. - ASSERT_GE(9, GetClient(1)->GetLastSessionSnapshot()-> + ASSERT_GE(NumberOfDefaultSyncItems() + 3, + GetClient(1)->GetLastSessionSnapshot()-> num_conflicting_updates); // The encrypted nodes. // At this point we enter the passphrase, triggering a resync. @@ -339,9 +343,10 @@ IN_PROC_BROWSER_TEST_F(TwoClientSessionsSyncTest, ASSERT_EQ(0, GetClient(1)->GetLastSessionSnapshot()-> num_blocking_conflicting_updates); // We have three non-blocking conflicts due to the two meta nodes (one for - // each client), the one tab node, and the 6 basic preference/themes/search + // each client), the one tab node, plus the basic preference/themes/search // engines nodes. - ASSERT_EQ(9, GetClient(1)->GetLastSessionSnapshot()-> + ASSERT_EQ(NumberOfDefaultSyncItems() + 3, + GetClient(1)->GetLastSessionSnapshot()-> num_conflicting_updates); // The encrypted nodes. GetClient(1)->service()->SetPassphrase(kValidPassphrase, true); diff --git a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc index dc76d3a..f34bd5a 100644 --- a/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc +++ b/chrome/browser/ui/webui/ntp/ntp_resource_cache.cc @@ -304,8 +304,6 @@ void NTPResourceCache::CreateNewTabHTML() { l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED)); localized_strings.SetString("closedwindowsingle", l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE)); - localized_strings.SetString("searchengines", - l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_SEARCH_ENGINES)); localized_strings.SetString("foreignsessions", l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_TABS)); localized_strings.SetString("closedwindowmultiple", diff --git a/chrome/browser/ui/webui/options/personal_options_handler.cc b/chrome/browser/ui/webui/options/personal_options_handler.cc index 281dfc2..10fcf2a 100644 --- a/chrome/browser/ui/webui/options/personal_options_handler.cc +++ b/chrome/browser/ui/webui/options/personal_options_handler.cc @@ -192,8 +192,6 @@ void PersonalOptionsHandler::GetLocalizedValues( l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_THEMES)); localized_strings->SetString("syncapps", l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_APPS)); - localized_strings->SetString("syncsearchengines", - l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_SEARCH_ENGINES)); localized_strings->SetString("syncsessions", l10n_util::GetStringUTF16(IDS_SYNC_DATATYPE_TABS)); diff --git a/chrome/browser/ui/webui/sync_setup_handler.cc b/chrome/browser/ui/webui/sync_setup_handler.cc index cb2ec55..63ff4362 100644 --- a/chrome/browser/ui/webui/sync_setup_handler.cc +++ b/chrome/browser/ui/webui/sync_setup_handler.cc @@ -127,12 +127,6 @@ bool GetConfiguration(const std::string& json, SyncConfiguration* config) { if (sync_typed_urls) config->data_types.insert(syncable::TYPED_URLS); - bool sync_search_engines; - if (!result->GetBoolean("syncSearchEngines", &sync_search_engines)) - return false; - if (sync_search_engines) - config->data_types.insert(syncable::SEARCH_ENGINES); - bool sync_sessions; if (!result->GetBoolean("syncSessions", &sync_sessions)) return false; @@ -216,8 +210,6 @@ bool HasConfigurationChanged(const SyncConfiguration& config, pref_service->GetBoolean(prefs::kSyncExtensionSettings)) || ((types.find(syncable::TYPED_URLS) != types.end()) != pref_service->GetBoolean(prefs::kSyncTypedUrls)) || - ((types.find(syncable::SEARCH_ENGINES) != types.end()) != - pref_service->GetBoolean(prefs::kSyncSearchEngines)) || ((types.find(syncable::SESSIONS) != types.end()) != pref_service->GetBoolean(prefs::kSyncSessions)) || ((types.find(syncable::APPS) != types.end()) != @@ -349,7 +341,6 @@ void SyncSetupHandler::GetStaticLocalizedValues( { "extensions", IDS_SYNC_DATATYPE_EXTENSIONS }, { "typedURLs", IDS_SYNC_DATATYPE_TYPED_URLS }, { "apps", IDS_SYNC_DATATYPE_APPS }, - { "searchEngines", IDS_SYNC_DATATYPE_SEARCH_ENGINES }, { "openTabs", IDS_SYNC_DATATYPE_TABS }, { "syncZeroDataTypesError", IDS_SYNC_ZERO_DATA_TYPES_ERROR }, { "serviceUnavailableError", IDS_SYNC_SETUP_ABORTED_BY_PENDING_CLEAR }, @@ -604,8 +595,6 @@ void SyncSetupHandler::HandleConfigure(const ListValue* args) { types.find(syncable::EXTENSION_SETTINGS) != types.end()); UMA_HISTOGRAM_BOOLEAN("Sync.CustomSyncTypedUrls", types.find(syncable::TYPED_URLS) != types.end()); - UMA_HISTOGRAM_BOOLEAN("Sync.CustomSyncSearchEngines", - types.find(syncable::SEARCH_ENGINES) != types.end()); UMA_HISTOGRAM_BOOLEAN("Sync.CustomSyncSessions", types.find(syncable::SESSIONS) != types.end()); UMA_HISTOGRAM_BOOLEAN("Sync.CustomSyncApps", diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index b5739f3..0fb27145 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -336,6 +336,9 @@ const char kDisableSyncPasswords[] = "disable-sync-passwords"; // Disables syncing of preferences. const char kDisableSyncPreferences[] = "disable-sync-preferences"; +// Disable syncing custom search engines. +const char kDisableSyncSearchEngines[] = "disable-sync-search-engines"; + // Disables syncing of themes. const char kDisableSyncThemes[] = "disable-sync-themes"; @@ -546,9 +549,6 @@ const char kEnableSyncExtensionSettings[] = "enable-sync-extension-settings"; // Enables OAuth sign-in for sync. const char kEnableSyncOAuth[] = "enable-sync-oauth"; -// Enables syncing custom search engines. -const char kEnableSyncSearchEngines[] = "enable-sync-search-engines"; - // Enables syncing browser sessions. const char kEnableSyncTabs[] = "enable-sync-tabs"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 655bca9..b13bb50 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -102,6 +102,7 @@ extern const char kDisableSyncEncryption[]; extern const char kDisableSyncExtensions[]; extern const char kDisableSyncPasswords[]; extern const char kDisableSyncPreferences[]; +extern const char kDisableSyncSearchEngines[]; extern const char kDisableSyncThemes[]; extern const char kDisableSyncTypedUrls[]; extern const char kDisableTabCloseableStateWatcher[]; @@ -157,7 +158,6 @@ extern const char kEnableSmoothScrolling[]; // been figured out. extern const char kEnableSyncExtensionSettings[]; extern const char kEnableSyncOAuth[]; -extern const char kEnableSyncSearchEngines[]; extern const char kEnableSyncTabs[]; extern const char kEnableSyncTabsForOtherClients[]; extern const char kEnableSyncAppNotifications[]; diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 1bc3ac2..aeb79e4 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -255,6 +255,14 @@ const char kConfirmToQuitEnabled[] = "browser.confirm_to_quit"; // 2 - block all cookies const char kCookieBehavior[] = "security.cookie_behavior"; +// The GUID of the synced default search provider. Note that this acts like a +// pointer to which synced search engine should be the default, rather than the +// prefs below which describe the locally saved default search provider details +// (and are not synced). This is ignored in the case of the default search +// provider being managed by policy. +const char kSyncedDefaultSearchProviderGUID[] = + "default_search_provider.synced_guid"; + // Whether having a default search provider is enabled. const char kDefaultSearchProviderEnabled[] = "default_search_provider.enabled"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 0b5c9fd..ebc958a 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -110,6 +110,7 @@ extern const char kIncognitoModeAvailability[]; extern const char kSearchSuggestEnabled[]; extern const char kConfirmToQuitEnabled[]; extern const char kCookieBehavior[]; // OBSOLETE +extern const char kSyncedDefaultSearchProviderGUID[]; extern const char kDefaultSearchProviderEnabled[]; extern const char kDefaultSearchProviderSearchURL[]; extern const char kDefaultSearchProviderSuggestURL[]; |