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

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

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

Powered by Google App Engine
This is Rietveld 408576698