OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |