summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/about_flags.cc7
-rw-r--r--chrome/browser/prefs/pref_set_observer.cc1
-rw-r--r--chrome/browser/resources/sync_setup_overlay.html8
-rw-r--r--chrome/browser/resources/sync_setup_overlay.js7
-rw-r--r--chrome/browser/search_engines/template_url_service.cc134
-rw-r--r--chrome/browser/search_engines/template_url_service.h17
-rw-r--r--chrome/browser/search_engines/template_url_service_factory.cc3
-rw-r--r--chrome/browser/search_engines/template_url_service_sync_unittest.cc216
-rw-r--r--chrome/browser/sync/profile_sync_factory_impl.cc14
-rw-r--r--chrome/browser/sync/profile_sync_factory_impl_unittest.cc1
-rw-r--r--chrome/browser/sync/resources/configure.html37
-rw-r--r--chrome/browser/sync/sync_prefs.cc25
-rw-r--r--chrome/browser/sync/sync_prefs_unittest.cc4
-rw-r--r--chrome/browser/sync/sync_setup_flow.cc4
-rw-r--r--chrome/browser/sync/sync_setup_wizard_unittest.cc5
-rw-r--r--chrome/browser/sync/test/integration/search_engines_helper.cc47
-rw-r--r--chrome/browser/sync/test/integration/search_engines_helper.h12
-rw-r--r--chrome/browser/sync/test/integration/sync_test.cc13
-rw-r--r--chrome/browser/sync/test/integration/sync_test.h3
-rw-r--r--chrome/browser/sync/test/integration/two_client_search_engines_sync_test.cc45
-rw-r--r--chrome/browser/sync/test/integration/two_client_sessions_sync_test.cc33
-rw-r--r--chrome/browser/ui/webui/ntp/ntp_resource_cache.cc2
-rw-r--r--chrome/browser/ui/webui/options/personal_options_handler.cc2
-rw-r--r--chrome/browser/ui/webui/sync_setup_handler.cc11
-rw-r--r--chrome/common/chrome_switches.cc6
-rw-r--r--chrome/common/chrome_switches.h2
-rw-r--r--chrome/common/pref_names.cc8
-rw-r--r--chrome/common/pref_names.h1
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[];