Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(956)

Side by Side Diff: chrome/browser/search_engines/template_url_service.cc

Issue 10836240: Revert 151391 - Rewrite TemplateURLService's SyncableService implmentation to avoid sending ACTION_… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/search_engines/template_url_service.h" 5 #include "chrome/browser/search_engines/template_url_service.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/environment.h" 10 #include "base/environment.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 old_base_url(old_base_url) { 187 old_base_url(old_base_url) {
188 } 188 }
189 189
190 OldBaseURLSearchTermsData::~OldBaseURLSearchTermsData() { 190 OldBaseURLSearchTermsData::~OldBaseURLSearchTermsData() {
191 } 191 }
192 192
193 std::string OldBaseURLSearchTermsData::GoogleBaseURLValue() const { 193 std::string OldBaseURLSearchTermsData::GoogleBaseURLValue() const {
194 return old_base_url; 194 return old_base_url;
195 } 195 }
196 196
197 // Returns true if |turl|'s GUID is not found inside |sync_data|. This is to be
198 // used in MergeDataAndStartSyncing to differentiate between TemplateURLs from
199 // Sync and TemplateURLs that were initially local, assuming |sync_data| is the
200 // |initial_sync_data| parameter.
201 bool IsFromSync(const TemplateURL* turl, const SyncDataMap& sync_data) {
202 return (sync_data.find(turl->sync_guid()) != sync_data.end());
203 }
204
205 } // namespace 197 } // namespace
206 198
199
207 class TemplateURLService::LessWithPrefix { 200 class TemplateURLService::LessWithPrefix {
208 public: 201 public:
209 // We want to find the set of keywords that begin with a prefix. The STL 202 // We want to find the set of keywords that begin with a prefix. The STL
210 // algorithms will return the set of elements that are "equal to" the 203 // algorithms will return the set of elements that are "equal to" the
211 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When 204 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When
212 // cmp() is the typical std::less<>, this results in lexicographic equality; 205 // cmp() is the typical std::less<>, this results in lexicographic equality;
213 // we need to extend this to mark a prefix as "not less than" a keyword it 206 // we need to extend this to mark a prefix as "not less than" a keyword it
214 // begins, which will cause the desired elements to be considered "equal to" 207 // begins, which will cause the desired elements to be considered "equal to"
215 // the prefix. Note: this is still a strict weak ordering, as required by 208 // the prefix. Note: this is still a strict weak ordering, as required by
216 // equal_range() (though I will not prove that here). 209 // equal_range() (though I will not prove that here).
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 Remove(existing_turl); 1005 Remove(existing_turl);
1013 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { 1006 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) {
1014 if (existing_turl) { 1007 if (existing_turl) {
1015 NOTREACHED() << "Unexpected sync change state."; 1008 NOTREACHED() << "Unexpected sync change state.";
1016 error = sync_error_factory_->CreateAndUploadError( 1009 error = sync_error_factory_->CreateAndUploadError(
1017 FROM_HERE, 1010 FROM_HERE,
1018 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); 1011 "ProcessSyncChanges failed on ChangeType ACTION_ADD");
1019 LOG(ERROR) << "Trying to add an existing TemplateURL."; 1012 LOG(ERROR) << "Trying to add an existing TemplateURL.";
1020 continue; 1013 continue;
1021 } 1014 }
1022 const std::string guid = turl->sync_guid(); 1015 std::string guid = turl->sync_guid();
1023 if (existing_keyword_turl) { 1016 if (!existing_keyword_turl || ResolveSyncKeywordConflict(turl.get(),
1024 // Resolve any conflicts so we can safely add the new entry. 1017 existing_keyword_turl, &new_changes)) {
1025 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 1018 // Force the local ID to kInvalidTemplateURLID so we can add it.
1026 &new_changes); 1019 TemplateURLData data(turl->data());
1020 data.id = kInvalidTemplateURLID;
1021 Add(new TemplateURL(profile_, data));
1022
1023 // Possibly set the newly added |turl| as the default search provider.
1024 SetDefaultSearchProviderIfNewlySynced(guid);
1027 } 1025 }
1028 // Force the local ID to kInvalidTemplateURLID so we can add it.
1029 TemplateURLData data(turl->data());
1030 data.id = kInvalidTemplateURLID;
1031 Add(new TemplateURL(profile_, data));
1032
1033 // Possibly set the newly added |turl| as the default search provider.
1034 SetDefaultSearchProviderIfNewlySynced(guid);
1035 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { 1026 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) {
1036 if (!existing_turl) { 1027 if (!existing_turl) {
1037 NOTREACHED() << "Unexpected sync change state."; 1028 NOTREACHED() << "Unexpected sync change state.";
1038 error = sync_error_factory_->CreateAndUploadError( 1029 error = sync_error_factory_->CreateAndUploadError(
1039 FROM_HERE, 1030 FROM_HERE,
1040 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); 1031 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE");
1041 LOG(ERROR) << "Trying to update a non-existent TemplateURL."; 1032 LOG(ERROR) << "Trying to update a non-existent TemplateURL.";
1042 continue; 1033 continue;
1043 } 1034 }
1044 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) { 1035 // Possibly resolve a keyword conflict if they have the same keywords but
1045 // Resolve any conflicts with other entries so we can safely update the 1036 // are not the same entry.
1046 // keyword. 1037 if (existing_keyword_turl && (existing_keyword_turl != existing_turl) &&
1047 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 1038 !ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1048 &new_changes); 1039 &new_changes)) {
1040 // Note that because we're processing changes, this Remove() call won't
1041 // generate an ACTION_DELETE; but ResolveSyncKeywordConflict() did
1042 // already, so we should be OK.
1043 Remove(existing_turl);
1044 continue;
1049 } 1045 }
1050 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); 1046 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1051 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) 1047 if (UpdateNoNotify(existing_turl, *turl, search_terms_data))
1052 NotifyObservers(); 1048 NotifyObservers();
1053 } else { 1049 } else {
1054 // We've unexpectedly received an ACTION_INVALID. 1050 // We've unexpectedly received an ACTION_INVALID.
1055 NOTREACHED() << "Unexpected sync change state."; 1051 NOTREACHED() << "Unexpected sync change state.";
1056 error = sync_error_factory_->CreateAndUploadError( 1052 error = sync_error_factory_->CreateAndUploadError(
1057 FROM_HERE, 1053 FROM_HERE,
1058 "ProcessSyncChanges received an ACTION_INVALID"); 1054 "ProcessSyncChanges received an ACTION_INVALID");
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 // preprocessing in TemplateURLService's loading code). Ignore it and send 1122 // preprocessing in TemplateURLService's loading code). Ignore it and send
1127 // an ACTION_DELETE up to the server. 1123 // an ACTION_DELETE up to the server.
1128 new_changes.push_back( 1124 new_changes.push_back(
1129 syncer::SyncChange(FROM_HERE, 1125 syncer::SyncChange(FROM_HERE,
1130 syncer::SyncChange::ACTION_DELETE, 1126 syncer::SyncChange::ACTION_DELETE,
1131 iter->second)); 1127 iter->second));
1132 continue; 1128 continue;
1133 } 1129 }
1134 1130
1135 if (local_turl) { 1131 if (local_turl) {
1136 DCHECK(IsFromSync(local_turl, sync_data_map));
1137 // This local search engine is already synced. If the timestamp differs 1132 // This local search engine is already synced. If the timestamp differs
1138 // from Sync, we need to update locally or to the cloud. Note that if the 1133 // from Sync, we need to update locally or to the cloud. Note that if the
1139 // timestamps are equal, we touch neither. 1134 // timestamps are equal, we touch neither.
1140 if (sync_turl->last_modified() > local_turl->last_modified()) { 1135 if (sync_turl->last_modified() > local_turl->last_modified()) {
1141 // We've received an update from Sync. We should replace all synced 1136 // We've received an update from Sync. We should replace all synced
1142 // fields in the local TemplateURL. Note that this includes the 1137 // fields in the local TemplateURL. Note that this includes the
1143 // TemplateURLID and the TemplateURL may have to be reparsed. This 1138 // TemplateURLID and the TemplateURL may have to be reparsed. This
1144 // also makes the local data's last_modified timestamp equal to Sync's, 1139 // also makes the local data's last_modified timestamp equal to Sync's,
1145 // avoiding an Update on the next MergeData call. 1140 // avoiding an Update on the next MergeData call.
1146 UIThreadSearchTermsData search_terms_data(local_turl->profile()); 1141 UIThreadSearchTermsData search_terms_data(local_turl->profile());
1147 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data)) 1142 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data))
1148 NotifyObservers(); 1143 NotifyObservers();
1149 } else if (sync_turl->last_modified() < local_turl->last_modified()) { 1144 } else if (sync_turl->last_modified() < local_turl->last_modified()) {
1150 // Otherwise, we know we have newer data, so update Sync with our 1145 // Otherwise, we know we have newer data, so update Sync with our
1151 // data fields. 1146 // data fields.
1152 new_changes.push_back( 1147 new_changes.push_back(
1153 syncer::SyncChange(FROM_HERE, 1148 syncer::SyncChange(FROM_HERE,
1154 syncer::SyncChange::ACTION_UPDATE, 1149 syncer::SyncChange::ACTION_UPDATE,
1155 local_data_map[local_turl->sync_guid()])); 1150 local_data_map[local_turl->sync_guid()]));
1156 } 1151 }
1157 local_data_map.erase(iter->first); 1152 local_data_map.erase(iter->first);
1158 } else { 1153 } else {
1159 // The search engine from the cloud has not been synced locally. Merge it 1154 // The search engine from the cloud has not been synced locally, but there
1160 // into our local model. This will handle any conflicts with local (and 1155 // might be a local search engine that is a duplicate that needs to be
1161 // already-synced) TemplateURLs. It will prefer to keep entries from Sync 1156 // merged.
1162 // over not-yet-synced TemplateURLs. 1157 TemplateURL* dupe_turl = FindDuplicateOfSyncTemplateURL(*sync_turl);
1163 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes, 1158 if (dupe_turl) {
1164 &local_data_map); 1159 // Merge duplicates and remove the processed local TURL from the map.
1160 std::string old_guid = dupe_turl->sync_guid();
1161 MergeSyncAndLocalURLDuplicates(sync_turl.release(), dupe_turl,
1162 &new_changes);
1163 local_data_map.erase(old_guid);
1164 } else {
1165 std::string guid = sync_turl->sync_guid();
1166 // Keyword conflict is possible in this case. Resolve it first before
1167 // adding the new TemplateURL. Note that we don't remove the local TURL
1168 // from local_data_map in this case as it may still need to be pushed to
1169 // the cloud. We also explicitly don't resolve conflicts against
1170 // extension keywords; see comments in ProcessSyncChanges().
1171 TemplateURL* existing_keyword_turl =
1172 FindNonExtensionTemplateURLForKeyword(sync_turl->keyword());
1173 if (!existing_keyword_turl || ResolveSyncKeywordConflict(
1174 sync_turl.get(), existing_keyword_turl, &new_changes)) {
1175 // Force the local ID to kInvalidTemplateURLID so we can add it.
1176 TemplateURLData data(sync_turl->data());
1177 data.id = kInvalidTemplateURLID;
1178 Add(new TemplateURL(profile_, data));
1179
1180 // Possibly set the newly added |turl| as the default search provider.
1181 SetDefaultSearchProviderIfNewlySynced(guid);
1182 }
1183 }
1165 } 1184 }
1166 } 1185 }
1167 1186
1168 // The remaining SyncData in local_data_map should be everything that needs to 1187 // The remaining SyncData in local_data_map should be everything that needs to
1169 // be pushed as ADDs to sync. 1188 // be pushed as ADDs to sync.
1170 for (SyncDataMap::const_iterator iter = local_data_map.begin(); 1189 for (SyncDataMap::const_iterator iter = local_data_map.begin();
1171 iter != local_data_map.end(); ++iter) { 1190 iter != local_data_map.end(); ++iter) {
1172 new_changes.push_back( 1191 new_changes.push_back(
1173 syncer::SyncChange(FROM_HERE, 1192 syncer::SyncChange(FROM_HERE,
1174 syncer::SyncChange::ACTION_ADD, 1193 syncer::SyncChange::ACTION_ADD,
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2298 // This is a best-effort approach where we try to preserve the original 2317 // This is a best-effort approach where we try to preserve the original
2299 // keyword and let the user do what they will after our attempt. 2318 // keyword and let the user do what they will after our attempt.
2300 string16 keyword_candidate(turl.keyword()); 2319 string16 keyword_candidate(turl.keyword());
2301 do { 2320 do {
2302 keyword_candidate.append(ASCIIToUTF16("_")); 2321 keyword_candidate.append(ASCIIToUTF16("_"));
2303 } while (GetTemplateURLForKeyword(keyword_candidate)); 2322 } while (GetTemplateURLForKeyword(keyword_candidate));
2304 2323
2305 return keyword_candidate; 2324 return keyword_candidate;
2306 } 2325 }
2307 2326
2308 bool TemplateURLService::IsLocalTemplateURLBetter( 2327 bool TemplateURLService::ResolveSyncKeywordConflict(
2309 const TemplateURL* local_turl, 2328 TemplateURL* sync_turl,
2310 const TemplateURL* sync_turl) { 2329 TemplateURL* local_turl,
2311 DCHECK(GetTemplateURLForGUID(local_turl->sync_guid())); 2330 syncer::SyncChangeList* change_list) {
2312 return local_turl->last_modified() > sync_turl->last_modified() || 2331 DCHECK(loaded_);
2313 local_turl->created_by_policy() || 2332 DCHECK(sync_turl);
2314 local_turl== GetDefaultSearchProvider(); 2333 DCHECK(local_turl);
2334 DCHECK(sync_turl->sync_guid() != local_turl->sync_guid());
2335 DCHECK(!local_turl->IsExtensionKeyword());
2336 DCHECK(change_list);
2337
2338 const bool local_is_better =
2339 (local_turl->last_modified() > sync_turl->last_modified()) ||
2340 local_turl->created_by_policy() ||
2341 (local_turl == GetDefaultSearchProvider());
2342 const bool can_replace_local = CanReplace(local_turl);
2343 if (CanReplace(sync_turl) && (local_is_better || !can_replace_local)) {
2344 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl);
2345 change_list->push_back(syncer::SyncChange(FROM_HERE,
2346 syncer::SyncChange::ACTION_DELETE,
2347 sync_data));
2348 return false;
2349 }
2350 if (can_replace_local) {
2351 // Since we're processing sync changes, the upcoming Remove() won't generate
2352 // an ACTION_DELETE. We need to do it manually to keep the server in sync
2353 // with us. Note that if we're being called from
2354 // MergeDataAndStartSyncing(), and this TemplateURL was pre-existing rather
2355 // than having just been brought down, then this is wrong, because the
2356 // server doesn't yet know about this entity; but in this case,
2357 // PruneSyncChanges() will prune out the ACTION_DELETE we create here.
2358 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
2359 change_list->push_back(syncer::SyncChange(FROM_HERE,
2360 syncer::SyncChange::ACTION_DELETE,
2361 sync_data));
2362 Remove(local_turl);
2363 } else if (local_is_better) {
2364 string16 new_keyword = UniquifyKeyword(*sync_turl, false);
2365 DCHECK(!GetTemplateURLForKeyword(new_keyword));
2366 sync_turl->data_.SetKeyword(new_keyword);
2367 // If we update the cloud TURL, we need to push an update back to sync
2368 // informing it that something has changed.
2369 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl);
2370 change_list->push_back(syncer::SyncChange(FROM_HERE,
2371 syncer::SyncChange::ACTION_UPDATE,
2372 sync_data));
2373 } else {
2374 string16 new_keyword = UniquifyKeyword(*local_turl, false);
2375 TemplateURLData data(local_turl->data());
2376 data.SetKeyword(new_keyword);
2377 TemplateURL new_turl(local_turl->profile(), data);
2378 UIThreadSearchTermsData search_terms_data(local_turl->profile());
2379 if (UpdateNoNotify(local_turl, new_turl, search_terms_data))
2380 NotifyObservers();
2381 // Since we're processing sync changes, the UpdateNoNotify() above didn't
2382 // generate an ACTION_UPDATE. We need to do it manually to keep the server
2383 // in sync with us. Note that if we're being called from
2384 // MergeDataAndStartSyncing(), and this TemplateURL was pre-existing rather
2385 // than having just been brought down, then this is wrong, because the
2386 // server won't know about this entity until it processes the ACTION_ADD our
2387 // caller will later generate; but in this case, PruneSyncChanges() will
2388 // prune out the ACTION_UPDATE we create here.
2389 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
2390 change_list->push_back(syncer::SyncChange(FROM_HERE,
2391 syncer::SyncChange::ACTION_UPDATE,
2392 sync_data));
2393 }
2394 return true;
2315 } 2395 }
2316 2396
2317 void TemplateURLService::ResolveSyncKeywordConflict( 2397 TemplateURL* TemplateURLService::FindDuplicateOfSyncTemplateURL(
2318 TemplateURL* unapplied_sync_turl, 2398 const TemplateURL& sync_turl) {
2319 TemplateURL* applied_sync_turl, 2399 TemplateURL* existing_turl = GetTemplateURLForKeyword(sync_turl.keyword());
2400 return existing_turl && (existing_turl->url() == sync_turl.url()) ?
2401 existing_turl : NULL;
2402 }
2403
2404 void TemplateURLService::MergeSyncAndLocalURLDuplicates(
2405 TemplateURL* sync_turl,
2406 TemplateURL* local_turl,
2320 syncer::SyncChangeList* change_list) { 2407 syncer::SyncChangeList* change_list) {
2321 DCHECK(loaded_); 2408 DCHECK(loaded_);
2322 DCHECK(unapplied_sync_turl); 2409 DCHECK(sync_turl);
2323 DCHECK(applied_sync_turl); 2410 DCHECK(local_turl);
2324 DCHECK(change_list); 2411 DCHECK(change_list);
2325 DCHECK_EQ(applied_sync_turl->keyword(), unapplied_sync_turl->keyword()); 2412 scoped_ptr<TemplateURL> scoped_sync_turl(sync_turl);
2326 DCHECK(!applied_sync_turl->IsExtensionKeyword()); 2413 if (sync_turl->last_modified() > local_turl->last_modified()) {
2414 // Fully replace local_url with Sync's copy. Note that because use Add
2415 // rather than ResetTemplateURL, |sync_url| is added with a fresh
2416 // TemplateURLID. We don't need to sync the new ID back to the server since
2417 // it's only relevant locally.
2418 bool delete_default = (local_turl == GetDefaultSearchProvider());
2419 DCHECK(!delete_default || !is_default_search_managed_);
2420 if (delete_default)
2421 default_search_provider_ = NULL;
2327 2422
2328 // Both |unapplied_sync_turl| and |applied_sync_turl| are known to Sync, so 2423 // See comments in ResolveSyncKeywordConflict() regarding generating an
2329 // don't delete either of them. Instead, determine which is "better" and 2424 // ACTION_DELETE manually since Remove() won't do it.
2330 // uniquify the other one, sending an update to the server for the updated 2425 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
2331 // entry. 2426 change_list->push_back(syncer::SyncChange(FROM_HERE,
2332 const bool applied_turl_is_better = 2427 syncer::SyncChange::ACTION_DELETE,
2333 IsLocalTemplateURLBetter(applied_sync_turl, unapplied_sync_turl); 2428 sync_data));
2334 TemplateURL* loser = applied_turl_is_better ? 2429 Remove(local_turl);
2335 unapplied_sync_turl : applied_sync_turl; 2430
2336 string16 new_keyword = UniquifyKeyword(*loser, false); 2431 // Force the local ID to kInvalidTemplateURLID so we can add it.
2337 DCHECK(!GetTemplateURLForKeyword(new_keyword)); 2432 sync_turl->data_.id = kInvalidTemplateURLID;
2338 if (applied_turl_is_better) { 2433 Add(scoped_sync_turl.release());
2339 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible 2434 if (delete_default)
2340 // for adding or updating unapplied_sync_turl in the local model. 2435 SetDefaultSearchProvider(sync_turl);
2341 unapplied_sync_turl->data_.SetKeyword(new_keyword);
2342 } else { 2436 } else {
2343 // Update |applied_sync_turl| in the local model with the new keyword. 2437 // Change the local TURL's GUID to the server's GUID and push an update to
2344 TemplateURLData data(applied_sync_turl->data()); 2438 // Sync. This ensures that the rest of local_url's fields are sync'd up to
2345 data.SetKeyword(new_keyword); 2439 // the server, and the next time local_url is synced, it is recognized by
2346 TemplateURL new_turl(applied_sync_turl->profile(), data); 2440 // having the same GUID.
2347 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile()); 2441 ResetTemplateURLGUID(local_turl, sync_turl->sync_guid());
2348 if (UpdateNoNotify(applied_sync_turl, new_turl, search_terms_data)) 2442 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
2349 NotifyObservers(); 2443 change_list->push_back(syncer::SyncChange(FROM_HERE,
2350 } 2444 syncer::SyncChange::ACTION_UPDATE,
2351 // The losing TemplateURL should have their keyword updated. Send a change to 2445 sync_data));
2352 // the server to reflect this change.
2353 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser);
2354 change_list->push_back(syncer::SyncChange(FROM_HERE,
2355 syncer::SyncChange::ACTION_UPDATE,
2356 sync_data));
2357 }
2358
2359 void TemplateURLService::MergeInSyncTemplateURL(
2360 TemplateURL* sync_turl,
2361 const SyncDataMap& sync_data,
2362 syncer::SyncChangeList* change_list,
2363 SyncDataMap* local_data) {
2364 DCHECK(sync_turl);
2365 DCHECK(!GetTemplateURLForGUID(sync_turl->sync_guid()));
2366 DCHECK(IsFromSync(sync_turl, sync_data));
2367
2368 TemplateURL* conflicting_turl =
2369 FindNonExtensionTemplateURLForKeyword(sync_turl->keyword());
2370 bool should_add_sync_turl = true;
2371
2372 // If there was no TemplateURL in the local model that conflicts with
2373 // |sync_turl|, skip the following preparation steps and just add |sync_turl|
2374 // directly. Otherwise, modify |conflicting_turl| to make room for
2375 // |sync_turl|.
2376 if (conflicting_turl) {
2377 DCHECK(conflicting_turl);
2378
2379 if (IsFromSync(conflicting_turl, sync_data)) {
2380 // |conflicting_turl| is already known to Sync, so we're not allowed to
2381 // remove it. In this case, we want to uniquify the worse one and send an
2382 // update for the changed keyword to sync. We can reuse the logic from
2383 // ResolveSyncKeywordConflict for this.
2384 ResolveSyncKeywordConflict(sync_turl, conflicting_turl, change_list);
2385 } else {
2386 // |conflicting_turl| is not yet known to Sync. If it is better, then we
2387 // want to transfer its values up to sync. Otherwise, we remove it and
2388 // allow the entry from Sync to overtake it in the model.
2389 const std::string guid = conflicting_turl->sync_guid();
2390 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) {
2391 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid());
2392 syncer::SyncData sync_data =
2393 CreateSyncDataFromTemplateURL(*conflicting_turl);
2394 change_list->push_back(syncer::SyncChange(
2395 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data));
2396 if (conflicting_turl == GetDefaultSearchProvider() &&
2397 !pending_synced_default_search_) {
2398 // If we're not waiting for the Synced default to come in, we should
2399 // override the pref with our new GUID. If we are waiting for the
2400 // arrival of a synced default, setting the pref here would cause us
2401 // to lose the GUID we are waiting on.
2402 PrefService* prefs = GetPrefs();
2403 if (prefs) {
2404 prefs->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2405 conflicting_turl->sync_guid());
2406 }
2407 }
2408 // Note that in this case we do not add the Sync TemplateURL to the
2409 // local model, since we've effectively "merged" it in by updating the
2410 // local conflicting entry with its sync_guid.
2411 should_add_sync_turl = false;
2412 } else {
2413 // We guarantee that this isn't the local search provider. Otherwise,
2414 // local would have won.
2415 DCHECK(conflicting_turl != GetDefaultSearchProvider());
2416 Remove(conflicting_turl);
2417 }
2418 // This TemplateURL was either removed or overwritten in the local model.
2419 // Remove the entry from the local data so it isn't pushed up to Sync.
2420 local_data->erase(guid);
2421 }
2422 }
2423
2424 if (should_add_sync_turl) {
2425 const std::string guid = sync_turl->sync_guid();
2426 // Force the local ID to kInvalidTemplateURLID so we can add it.
2427 TemplateURLData data(sync_turl->data());
2428 data.id = kInvalidTemplateURLID;
2429 Add(new TemplateURL(profile_, data));
2430
2431 // Possibly set the newly added |turl| as the default search provider.
2432 SetDefaultSearchProviderIfNewlySynced(guid);
2433 } 2446 }
2434 } 2447 }
2435 2448
2436 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced( 2449 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced(
2437 const std::string& guid) { 2450 const std::string& guid) {
2438 // If we're not syncing or if default search is managed by policy, ignore. 2451 // If we're not syncing or if default search is managed by policy, ignore.
2439 if (!sync_processor_.get() || is_default_search_managed_) 2452 if (!sync_processor_.get() || is_default_search_managed_)
2440 return; 2453 return;
2441 2454
2442 PrefService* prefs = GetPrefs(); 2455 PrefService* prefs = GetPrefs();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 // TODO(mpcomplete): If we allow editing extension keywords, then those 2488 // TODO(mpcomplete): If we allow editing extension keywords, then those
2476 // should be persisted to disk and synced. 2489 // should be persisted to disk and synced.
2477 if (template_url->sync_guid().empty() && 2490 if (template_url->sync_guid().empty() &&
2478 !template_url->IsExtensionKeyword()) { 2491 !template_url->IsExtensionKeyword()) {
2479 template_url->data_.sync_guid = base::GenerateGUID(); 2492 template_url->data_.sync_guid = base::GenerateGUID();
2480 if (service_.get()) 2493 if (service_.get())
2481 service_->UpdateKeyword(template_url->data()); 2494 service_->UpdateKeyword(template_url->data());
2482 } 2495 }
2483 } 2496 }
2484 } 2497 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698