Chromium Code Reviews| 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 |