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

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

Issue 10806065: 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: Cleanup new code Created 8 years, 5 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/environment.h" 9 #include "base/environment.h"
10 #include "base/guid.h" 10 #include "base/guid.h"
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 old_base_url(old_base_url) { 184 old_base_url(old_base_url) {
185 } 185 }
186 186
187 OldBaseURLSearchTermsData::~OldBaseURLSearchTermsData() { 187 OldBaseURLSearchTermsData::~OldBaseURLSearchTermsData() {
188 } 188 }
189 189
190 std::string OldBaseURLSearchTermsData::GoogleBaseURLValue() const { 190 std::string OldBaseURLSearchTermsData::GoogleBaseURLValue() const {
191 return old_base_url; 191 return old_base_url;
192 } 192 }
193 193
194 // Returns true if |turl|'s GUID is not found inside |sync_data|. This is to be
195 // used in MergeDataAndStartSyncing to differentiate between TemplateURLs from
196 // Sync and TemplateURLs that were initially local, assuming |sync_data| is the
197 // |initial_sync_data| parameter.
198 bool IsFromSync(const TemplateURL* turl, const SyncDataMap& sync_data) {
199 return (sync_data.find(turl->sync_guid()) != sync_data.end());
200 }
201
194 } // namespace 202 } // namespace
195 203
196
197 class TemplateURLService::LessWithPrefix { 204 class TemplateURLService::LessWithPrefix {
198 public: 205 public:
199 // We want to find the set of keywords that begin with a prefix. The STL 206 // We want to find the set of keywords that begin with a prefix. The STL
200 // algorithms will return the set of elements that are "equal to" the 207 // algorithms will return the set of elements that are "equal to" the
201 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When 208 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When
202 // cmp() is the typical std::less<>, this results in lexicographic equality; 209 // cmp() is the typical std::less<>, this results in lexicographic equality;
203 // we need to extend this to mark a prefix as "not less than" a keyword it 210 // we need to extend this to mark a prefix as "not less than" a keyword it
204 // begins, which will cause the desired elements to be considered "equal to" 211 // begins, which will cause the desired elements to be considered "equal to"
205 // the prefix. Note: this is still a strict weak ordering, as required by 212 // the prefix. Note: this is still a strict weak ordering, as required by
206 // equal_range() (though I will not prove that here). 213 // equal_range() (though I will not prove that here).
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 Remove(existing_turl); 997 Remove(existing_turl);
991 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { 998 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) {
992 if (existing_turl) { 999 if (existing_turl) {
993 NOTREACHED() << "Unexpected sync change state."; 1000 NOTREACHED() << "Unexpected sync change state.";
994 error = sync_error_factory_->CreateAndUploadError( 1001 error = sync_error_factory_->CreateAndUploadError(
995 FROM_HERE, 1002 FROM_HERE,
996 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); 1003 "ProcessSyncChanges failed on ChangeType ACTION_ADD");
997 LOG(ERROR) << "Trying to add an existing TemplateURL."; 1004 LOG(ERROR) << "Trying to add an existing TemplateURL.";
998 continue; 1005 continue;
999 } 1006 }
1000 std::string guid = turl->sync_guid(); 1007 const std::string guid = turl->sync_guid();
1001 if (!existing_keyword_turl || ResolveSyncKeywordConflict(turl.get(), 1008 if (existing_keyword_turl) {
1002 existing_keyword_turl, &new_changes)) { 1009 // Resolve any conflicts so we can safely add the new entry.
1003 // Force the local ID to kInvalidTemplateURLID so we can add it. 1010 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1004 TemplateURLData data(turl->data()); 1011 &new_changes);
1005 data.id = kInvalidTemplateURLID; 1012 }
1006 Add(new TemplateURL(profile_, data)); 1013 // Force the local ID to kInvalidTemplateURLID so we can add it.
1014 TemplateURLData data(turl->data());
1015 data.id = kInvalidTemplateURLID;
1016 Add(new TemplateURL(profile_, data));
1007 1017
1008 // Possibly set the newly added |turl| as the default search provider. 1018 // Possibly set the newly added |turl| as the default search provider.
1009 SetDefaultSearchProviderIfNewlySynced(guid); 1019 SetDefaultSearchProviderIfNewlySynced(guid);
1010 }
1011 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { 1020 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) {
1012 if (!existing_turl) { 1021 if (!existing_turl) {
1013 NOTREACHED() << "Unexpected sync change state."; 1022 NOTREACHED() << "Unexpected sync change state.";
1014 error = sync_error_factory_->CreateAndUploadError( 1023 error = sync_error_factory_->CreateAndUploadError(
1015 FROM_HERE, 1024 FROM_HERE,
1016 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); 1025 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE");
1017 LOG(ERROR) << "Trying to update a non-existent TemplateURL."; 1026 LOG(ERROR) << "Trying to update a non-existent TemplateURL.";
1018 continue; 1027 continue;
1019 } 1028 }
1020 // Possibly resolve a keyword conflict if they have the same keywords but 1029 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) {
1021 // are not the same entry. 1030 // Resolve any conflicts with other entries so we can safely update the
1022 if (existing_keyword_turl && (existing_keyword_turl != existing_turl) && 1031 // keyword.
1023 !ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 1032 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1024 &new_changes)) { 1033 &new_changes);
1025 // Note that because we're processing changes, this Remove() call won't
1026 // generate an ACTION_DELETE; but ResolveSyncKeywordConflict() did
1027 // already, so we should be OK.
1028 Remove(existing_turl);
1029 continue;
1030 } 1034 }
1031 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); 1035 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1032 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) 1036 if (UpdateNoNotify(existing_turl, *turl, search_terms_data))
1033 NotifyObservers(); 1037 NotifyObservers();
1034 } else { 1038 } else {
1035 // We've unexpectedly received an ACTION_INVALID. 1039 // We've unexpectedly received an ACTION_INVALID.
1036 NOTREACHED() << "Unexpected sync change state."; 1040 NOTREACHED() << "Unexpected sync change state.";
1037 error = sync_error_factory_->CreateAndUploadError( 1041 error = sync_error_factory_->CreateAndUploadError(
1038 FROM_HERE, 1042 FROM_HERE,
1039 "ProcessSyncChanges received an ACTION_INVALID"); 1043 "ProcessSyncChanges received an ACTION_INVALID");
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 // preprocessing in TemplateURLService's loading code). Ignore it and send 1111 // preprocessing in TemplateURLService's loading code). Ignore it and send
1108 // an ACTION_DELETE up to the server. 1112 // an ACTION_DELETE up to the server.
1109 new_changes.push_back( 1113 new_changes.push_back(
1110 syncer::SyncChange(FROM_HERE, 1114 syncer::SyncChange(FROM_HERE,
1111 syncer::SyncChange::ACTION_DELETE, 1115 syncer::SyncChange::ACTION_DELETE,
1112 iter->second)); 1116 iter->second));
1113 continue; 1117 continue;
1114 } 1118 }
1115 1119
1116 if (local_turl) { 1120 if (local_turl) {
1121 DCHECK(IsFromSync(local_turl, sync_data_map));
1117 // This local search engine is already synced. If the timestamp differs 1122 // This local search engine is already synced. If the timestamp differs
1118 // from Sync, we need to update locally or to the cloud. Note that if the 1123 // from Sync, we need to update locally or to the cloud. Note that if the
1119 // timestamps are equal, we touch neither. 1124 // timestamps are equal, we touch neither.
1120 if (sync_turl->last_modified() > local_turl->last_modified()) { 1125 if (sync_turl->last_modified() > local_turl->last_modified()) {
1121 // We've received an update from Sync. We should replace all synced 1126 // We've received an update from Sync. We should replace all synced
1122 // fields in the local TemplateURL. Note that this includes the 1127 // fields in the local TemplateURL. Note that this includes the
1123 // TemplateURLID and the TemplateURL may have to be reparsed. This 1128 // TemplateURLID and the TemplateURL may have to be reparsed. This
1124 // also makes the local data's last_modified timestamp equal to Sync's, 1129 // also makes the local data's last_modified timestamp equal to Sync's,
1125 // avoiding an Update on the next MergeData call. 1130 // avoiding an Update on the next MergeData call.
1126 UIThreadSearchTermsData search_terms_data(local_turl->profile()); 1131 UIThreadSearchTermsData search_terms_data(local_turl->profile());
1127 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data)) 1132 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data))
1128 NotifyObservers(); 1133 NotifyObservers();
1129 } else if (sync_turl->last_modified() < local_turl->last_modified()) { 1134 } else if (sync_turl->last_modified() < local_turl->last_modified()) {
1130 // Otherwise, we know we have newer data, so update Sync with our 1135 // Otherwise, we know we have newer data, so update Sync with our
1131 // data fields. 1136 // data fields.
1132 new_changes.push_back( 1137 new_changes.push_back(
1133 syncer::SyncChange(FROM_HERE, 1138 syncer::SyncChange(FROM_HERE,
1134 syncer::SyncChange::ACTION_UPDATE, 1139 syncer::SyncChange::ACTION_UPDATE,
1135 local_data_map[local_turl->sync_guid()])); 1140 local_data_map[local_turl->sync_guid()]));
1136 } 1141 }
1137 local_data_map.erase(iter->first); 1142 local_data_map.erase(iter->first);
1138 } else { 1143 } else {
1139 // The search engine from the cloud has not been synced locally, but there 1144 // The search engine from the cloud has not been synced locally. Merge it
1140 // might be a local search engine that is a duplicate that needs to be 1145 // into our local model. This will handle any conflicts with local (and
1141 // merged. 1146 // already-synced) TemplateURLs. It will prefer to keep entries from Sync
1142 TemplateURL* dupe_turl = FindDuplicateOfSyncTemplateURL(*sync_turl); 1147 // over not-yet-synced TemplateURLs.
1143 if (dupe_turl) { 1148 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes,
1144 // Merge duplicates and remove the processed local TURL from the map. 1149 &local_data_map);
1145 std::string old_guid = dupe_turl->sync_guid();
1146 MergeSyncAndLocalURLDuplicates(sync_turl.release(), dupe_turl,
1147 &new_changes);
1148 local_data_map.erase(old_guid);
1149 } else {
1150 std::string guid = sync_turl->sync_guid();
1151 // Keyword conflict is possible in this case. Resolve it first before
1152 // adding the new TemplateURL. Note that we don't remove the local TURL
1153 // from local_data_map in this case as it may still need to be pushed to
1154 // the cloud. We also explicitly don't resolve conflicts against
1155 // extension keywords; see comments in ProcessSyncChanges().
1156 TemplateURL* existing_keyword_turl =
1157 FindNonExtensionTemplateURLForKeyword(sync_turl->keyword());
1158 if (!existing_keyword_turl || ResolveSyncKeywordConflict(
1159 sync_turl.get(), existing_keyword_turl, &new_changes)) {
1160 // Force the local ID to kInvalidTemplateURLID so we can add it.
1161 TemplateURLData data(sync_turl->data());
1162 data.id = kInvalidTemplateURLID;
1163 Add(new TemplateURL(profile_, data));
1164
1165 // Possibly set the newly added |turl| as the default search provider.
1166 SetDefaultSearchProviderIfNewlySynced(guid);
1167 }
1168 }
1169 } 1150 }
1170 } 1151 }
1171 1152
1172 // The remaining SyncData in local_data_map should be everything that needs to 1153 // The remaining SyncData in local_data_map should be everything that needs to
1173 // be pushed as ADDs to sync. 1154 // be pushed as ADDs to sync.
1174 for (SyncDataMap::const_iterator iter = local_data_map.begin(); 1155 for (SyncDataMap::const_iterator iter = local_data_map.begin();
1175 iter != local_data_map.end(); ++iter) { 1156 iter != local_data_map.end(); ++iter) {
1176 new_changes.push_back( 1157 new_changes.push_back(
1177 syncer::SyncChange(FROM_HERE, 1158 syncer::SyncChange(FROM_HERE,
1178 syncer::SyncChange::ACTION_ADD, 1159 syncer::SyncChange::ACTION_ADD,
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2302 // This is a best-effort approach where we try to preserve the original 2283 // This is a best-effort approach where we try to preserve the original
2303 // keyword and let the user do what they will after our attempt. 2284 // keyword and let the user do what they will after our attempt.
2304 string16 keyword_candidate(turl.keyword()); 2285 string16 keyword_candidate(turl.keyword());
2305 do { 2286 do {
2306 keyword_candidate.append(ASCIIToUTF16("_")); 2287 keyword_candidate.append(ASCIIToUTF16("_"));
2307 } while (GetTemplateURLForKeyword(keyword_candidate)); 2288 } while (GetTemplateURLForKeyword(keyword_candidate));
2308 2289
2309 return keyword_candidate; 2290 return keyword_candidate;
2310 } 2291 }
2311 2292
2312 bool TemplateURLService::ResolveSyncKeywordConflict( 2293 bool TemplateURLService::IsLocalTemplateURLBetter(
2313 TemplateURL* sync_turl, 2294 const TemplateURL* local_turl,
2314 TemplateURL* local_turl, 2295 const TemplateURL* sync_turl) {
2296 DCHECK(GetTemplateURLForGUID(local_turl->sync_guid()));
2297 return local_turl->last_modified() > sync_turl->last_modified() ||
2298 local_turl->created_by_policy() ||
2299 local_turl== GetDefaultSearchProvider();
2300 }
2301
2302 void TemplateURLService::ResolveSyncKeywordConflict(
2303 TemplateURL* unapplied_sync_turl,
2304 TemplateURL* applied_sync_turl,
2315 syncer::SyncChangeList* change_list) { 2305 syncer::SyncChangeList* change_list) {
2316 DCHECK(loaded_); 2306 DCHECK(loaded_);
2317 DCHECK(sync_turl); 2307 DCHECK(unapplied_sync_turl);
2318 DCHECK(local_turl); 2308 DCHECK(applied_sync_turl);
2319 DCHECK(sync_turl->sync_guid() != local_turl->sync_guid());
2320 DCHECK(!local_turl->IsExtensionKeyword());
2321 DCHECK(change_list); 2309 DCHECK(change_list);
2310 DCHECK(applied_sync_turl->keyword() == unapplied_sync_turl->keyword());
Nicolas Zea 2012/07/28 00:27:32 dcheck_eq
SteveT 2012/08/05 20:22:39 Done.
2311 DCHECK(!applied_sync_turl->IsExtensionKeyword());
Nicolas Zea 2012/07/28 00:27:32 dcheck that unapplied_sync_turl's guid is not know
SteveT 2012/08/05 20:22:39 Hm, this DCHECK would fire in the scenario where w
Nicolas Zea 2012/08/06 19:35:23 Ah, I see. Not sure if there's a better name. I gu
2322 2312
2323 const bool local_is_better = 2313 // Both |unapplied_sync_turl| and |applied_sync_turl| are known to Sync, so
2324 (local_turl->last_modified() > sync_turl->last_modified()) || 2314 // don't delete either of them. Instead, determine which is "better" and
2325 local_turl->created_by_policy() || 2315 // uniquify the other one, sending an update to the server for the updated
2326 (local_turl == GetDefaultSearchProvider()); 2316 // entry.
2327 const bool can_replace_local = CanReplace(local_turl); 2317 const bool applied_turl_is_better =
2328 if (CanReplace(sync_turl) && (local_is_better || !can_replace_local)) { 2318 IsLocalTemplateURLBetter(applied_sync_turl, unapplied_sync_turl);
2329 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl); 2319 TemplateURL* loser = applied_turl_is_better ?
2330 change_list->push_back(syncer::SyncChange(FROM_HERE, 2320 unapplied_sync_turl : applied_sync_turl;
2331 syncer::SyncChange::ACTION_DELETE, 2321 string16 new_keyword = UniquifyKeyword(*loser, false);
2332 sync_data)); 2322 DCHECK(!GetTemplateURLForKeyword(new_keyword));
2333 return false; 2323 if (applied_turl_is_better) {
2324 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible
2325 // for adding or updating unapplied_sync_turl in the local model.
2326 unapplied_sync_turl->data_.SetKeyword(new_keyword);
2327 } else {
2328 // Update |applied_sync_turl| in the local model with the new keyword.
2329 TemplateURLData data(applied_sync_turl->data());
2330 data.SetKeyword(new_keyword);
2331 TemplateURL new_turl(applied_sync_turl->profile(), data);
Nicolas Zea 2012/07/28 00:27:32 Is this created because we can't directly applied_
SteveT 2012/08/05 20:22:39 Yeah, that's how UpdateNoNotify works... it requir
2332 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile());
2333 if (UpdateNoNotify(applied_sync_turl, new_turl, search_terms_data))
2334 NotifyObservers();
2334 } 2335 }
2335 if (can_replace_local) { 2336 // The losing TemplateURL should have their keyword updated. Send a change to
2336 // Since we're processing sync changes, the upcoming Remove() won't generate 2337 // the server to reflect this change.
2337 // an ACTION_DELETE. We need to do it manually to keep the server in sync 2338 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser);
2338 // with us. Note that if we're being called from 2339 change_list->push_back(syncer::SyncChange(FROM_HERE,
2339 // MergeDataAndStartSyncing(), and this TemplateURL was pre-existing rather 2340 syncer::SyncChange::ACTION_UPDATE,
2340 // than having just been brought down, then this is wrong, because the 2341 sync_data));
2341 // server doesn't yet know about this entity; but in this case,
2342 // PruneSyncChanges() will prune out the ACTION_DELETE we create here.
2343 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
2344 change_list->push_back(syncer::SyncChange(FROM_HERE,
2345 syncer::SyncChange::ACTION_DELETE,
2346 sync_data));
2347 Remove(local_turl);
2348 } else if (local_is_better) {
2349 string16 new_keyword = UniquifyKeyword(*sync_turl, false);
2350 DCHECK(!GetTemplateURLForKeyword(new_keyword));
2351 sync_turl->data_.SetKeyword(new_keyword);
2352 // If we update the cloud TURL, we need to push an update back to sync
2353 // informing it that something has changed.
2354 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl);
2355 change_list->push_back(syncer::SyncChange(FROM_HERE,
2356 syncer::SyncChange::ACTION_UPDATE,
2357 sync_data));
2358 } else {
2359 string16 new_keyword = UniquifyKeyword(*local_turl, false);
2360 TemplateURLData data(local_turl->data());
2361 data.SetKeyword(new_keyword);
2362 TemplateURL new_turl(local_turl->profile(), data);
2363 UIThreadSearchTermsData search_terms_data(local_turl->profile());
2364 if (UpdateNoNotify(local_turl, new_turl, search_terms_data))
2365 NotifyObservers();
2366 // Since we're processing sync changes, the UpdateNoNotify() above didn't
2367 // generate an ACTION_UPDATE. We need to do it manually to keep the server
2368 // in sync with us. Note that if we're being called from
2369 // MergeDataAndStartSyncing(), and this TemplateURL was pre-existing rather
2370 // than having just been brought down, then this is wrong, because the
2371 // server won't know about this entity until it processes the ACTION_ADD our
2372 // caller will later generate; but in this case, PruneSyncChanges() will
2373 // prune out the ACTION_UPDATE we create here.
2374 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
2375 change_list->push_back(syncer::SyncChange(FROM_HERE,
2376 syncer::SyncChange::ACTION_UPDATE,
2377 sync_data));
2378 }
2379 return true;
2380 } 2342 }
2381 2343
2382 TemplateURL* TemplateURLService::FindDuplicateOfSyncTemplateURL( 2344 void TemplateURLService::MergeInSyncTemplateURL(
2383 const TemplateURL& sync_turl) { 2345 TemplateURL* sync_turl,
2384 TemplateURL* existing_turl = GetTemplateURLForKeyword(sync_turl.keyword()); 2346 const SyncDataMap& sync_data,
2385 return existing_turl && (existing_turl->url() == sync_turl.url()) ? 2347 syncer::SyncChangeList* change_list,
2386 existing_turl : NULL; 2348 SyncDataMap* initial_data) {
2387 } 2349 DCHECK(sync_turl);
2350 DCHECK(!GetTemplateURLForGUID(sync_turl->sync_guid()));
2351 DCHECK(IsFromSync(sync_turl, sync_data));
2388 2352
2389 void TemplateURLService::MergeSyncAndLocalURLDuplicates( 2353 TemplateURL* conflicting_turl =
2390 TemplateURL* sync_turl, 2354 FindNonExtensionTemplateURLForKeyword(sync_turl->keyword());
2391 TemplateURL* local_turl, 2355 bool should_add_sync_turl = conflicting_turl == NULL;
Nicolas Zea 2012/07/28 00:27:32 nit: I think it's more readable to have should_add
SteveT 2012/08/05 20:22:39 Done.
2392 syncer::SyncChangeList* change_list) {
2393 DCHECK(loaded_);
2394 DCHECK(sync_turl);
2395 DCHECK(local_turl);
2396 DCHECK(change_list);
2397 scoped_ptr<TemplateURL> scoped_sync_turl(sync_turl);
2398 if (sync_turl->last_modified() > local_turl->last_modified()) {
2399 // Fully replace local_url with Sync's copy. Note that because use Add
2400 // rather than ResetTemplateURL, |sync_url| is added with a fresh
2401 // TemplateURLID. We don't need to sync the new ID back to the server since
2402 // it's only relevant locally.
2403 bool delete_default = (local_turl == GetDefaultSearchProvider());
2404 DCHECK(!delete_default || !is_default_search_managed_);
2405 if (delete_default)
2406 default_search_provider_ = NULL;
2407 2356
2408 // See comments in ResolveSyncKeywordConflict() regarding generating an 2357 // If there was no TemplateURL in the local model that conflicts with
2409 // ACTION_DELETE manually since Remove() won't do it. 2358 // |sync_turl|, skip the following preparation steps and just |sync_turl|
2410 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl); 2359 // directly. Otherwise, modify |conflicting_turl| to make room for
2411 change_list->push_back(syncer::SyncChange(FROM_HERE, 2360 // |sync_turl|.
2412 syncer::SyncChange::ACTION_DELETE, 2361 if (!should_add_sync_turl) {
2413 sync_data)); 2362 DCHECK(conflicting_turl);
2414 Remove(local_turl);
2415 2363
2364 if (IsFromSync(conflicting_turl, sync_data)) {
2365 // |conflicting_turl| is already known to Sync, so we're not allowed to
2366 // remove it. In this case, we want to uniquify the worse one and send an
2367 // update for the changed keyword to sync. We can reuse the logic from
2368 // ResolveSyncKeywordConflict for this.
2369 ResolveSyncKeywordConflict(sync_turl, conflicting_turl, change_list);
2370 should_add_sync_turl = true;
2371 } else {
2372 // |conflicting_turl| is not yet known to Sync. If it is better, then we
2373 // want to transfer its values up to sync. Otherwise, we remove it and
2374 // allow the entry from Sync to overtake it in the model.
2375 const std::string guid = conflicting_turl->sync_guid();
2376 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) {
2377 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid());
2378 syncer::SyncData sync_data =
2379 CreateSyncDataFromTemplateURL(*conflicting_turl);
2380 change_list->push_back(syncer::SyncChange(
2381 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data));
2382 if (conflicting_turl == GetDefaultSearchProvider() &&
2383 !pending_synced_default_search_) {
2384 // If we're not waiting for the Synced default to come in, we should
2385 // override the pref with our new GUID. Note that the default might
Nicolas Zea 2012/07/28 00:27:32 I'm not sure I understand the "note:" part. What s
SteveT 2012/08/05 20:22:39 I was referring to the case where |pending_synced_
2386 // have already been set by sync (either in the Pref association code,
2387 // or earlier in MergeDataAndStartSyncing). In that case, this is a
2388 // no-op.
2389 PrefService* prefs = GetPrefs();
2390 if (prefs) {
2391 prefs->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2392 conflicting_turl->sync_guid());
2393 }
2394 }
2395 // Note that in this case we do not set |should_add_sync_turl|, since
2396 // we've effectively "merged" it in by updating the conflicting entry
2397 // with its sync_guid.
2398 } else {
2399 // We guarantee that this isn't the local search provider. Otherwise,
2400 // local would have won.
2401 DCHECK(conflicting_turl != GetDefaultSearchProvider());
2402 Remove(conflicting_turl);
2403 should_add_sync_turl = true;
2404 }
2405 // Remove the entry from the initial data so it isn't pushed up to Sync.
Nicolas Zea 2012/07/28 00:27:32 Mention that we do this because we either removed
SteveT 2012/08/05 20:22:39 Done.
2406 initial_data->erase(guid);
2407 }
2408 }
2409
2410 if (should_add_sync_turl) {
2411 const std::string guid = sync_turl->sync_guid();
2416 // Force the local ID to kInvalidTemplateURLID so we can add it. 2412 // Force the local ID to kInvalidTemplateURLID so we can add it.
2417 sync_turl->data_.id = kInvalidTemplateURLID; 2413 TemplateURLData data(sync_turl->data());
2418 Add(scoped_sync_turl.release()); 2414 data.id = kInvalidTemplateURLID;
2419 if (delete_default) 2415 Add(new TemplateURL(profile_, data));
2420 SetDefaultSearchProvider(sync_turl); 2416
2421 } else { 2417 // Possibly set the newly added |turl| as the default search provider.
2422 // Change the local TURL's GUID to the server's GUID and push an update to 2418 SetDefaultSearchProviderIfNewlySynced(guid);
2423 // Sync. This ensures that the rest of local_url's fields are sync'd up to
2424 // the server, and the next time local_url is synced, it is recognized by
2425 // having the same GUID.
2426 ResetTemplateURLGUID(local_turl, sync_turl->sync_guid());
2427 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
2428 change_list->push_back(syncer::SyncChange(FROM_HERE,
2429 syncer::SyncChange::ACTION_UPDATE,
2430 sync_data));
2431 } 2419 }
2432 } 2420 }
2433 2421
2434 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced( 2422 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced(
2435 const std::string& guid) { 2423 const std::string& guid) {
2436 // If we're not syncing or if default search is managed by policy, ignore. 2424 // If we're not syncing or if default search is managed by policy, ignore.
2437 if (!sync_processor_.get() || is_default_search_managed_) 2425 if (!sync_processor_.get() || is_default_search_managed_)
2438 return; 2426 return;
2439 2427
2440 PrefService* prefs = GetPrefs(); 2428 PrefService* prefs = GetPrefs();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 // TODO(mpcomplete): If we allow editing extension keywords, then those 2461 // TODO(mpcomplete): If we allow editing extension keywords, then those
2474 // should be persisted to disk and synced. 2462 // should be persisted to disk and synced.
2475 if (template_url->sync_guid().empty() && 2463 if (template_url->sync_guid().empty() &&
2476 !template_url->IsExtensionKeyword()) { 2464 !template_url->IsExtensionKeyword()) {
2477 template_url->data_.sync_guid = base::GenerateGUID(); 2465 template_url->data_.sync_guid = base::GenerateGUID();
2478 if (service_.get()) 2466 if (service_.get())
2479 service_->UpdateKeyword(template_url->data()); 2467 service_->UpdateKeyword(template_url->data());
2480 } 2468 }
2481 } 2469 }
2482 } 2470 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698