| 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/i18n/case_conversion.h" | 10 #include "base/i18n/case_conversion.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 void PruneSyncChanges(const SyncDataMap* sync_data, | 137 void PruneSyncChanges(const SyncDataMap* sync_data, |
| 138 SyncChangeList* change_list) { | 138 SyncChangeList* change_list) { |
| 139 for (size_t i = 0; i < change_list->size(); ) { | 139 for (size_t i = 0; i < change_list->size(); ) { |
| 140 if (ShouldRemoveSyncChange(i, change_list, sync_data)) | 140 if (ShouldRemoveSyncChange(i, change_list, sync_data)) |
| 141 change_list->erase(change_list->begin() + i); | 141 change_list->erase(change_list->begin() + i); |
| 142 else | 142 else |
| 143 ++i; | 143 ++i; |
| 144 } | 144 } |
| 145 } | 145 } |
| 146 | 146 |
| 147 // Helper class that reports a specific string as the Google base URL. We use |
| 148 // this so that code can calculate a TemplateURL's previous search URL after a |
| 149 // change to the global base URL. |
| 150 class OldBaseURLSearchTermsData : public UIThreadSearchTermsData { |
| 151 public: |
| 152 OldBaseURLSearchTermsData(Profile* profile, const std::string& old_base_url); |
| 153 virtual ~OldBaseURLSearchTermsData(); |
| 154 |
| 155 virtual std::string GoogleBaseURLValue() const OVERRIDE; |
| 156 |
| 157 private: |
| 158 std::string old_base_url; |
| 159 }; |
| 160 |
| 161 OldBaseURLSearchTermsData::OldBaseURLSearchTermsData( |
| 162 Profile* profile, |
| 163 const std::string& old_base_url) |
| 164 : UIThreadSearchTermsData(profile), |
| 165 old_base_url(old_base_url) { |
| 166 } |
| 167 |
| 168 OldBaseURLSearchTermsData::~OldBaseURLSearchTermsData() { |
| 169 } |
| 170 |
| 171 std::string OldBaseURLSearchTermsData::GoogleBaseURLValue() const { |
| 172 return old_base_url; |
| 173 } |
| 174 |
| 147 } // namespace | 175 } // namespace |
| 148 | 176 |
| 149 | 177 |
| 150 class TemplateURLService::LessWithPrefix { | 178 class TemplateURLService::LessWithPrefix { |
| 151 public: | 179 public: |
| 152 // We want to find the set of keywords that begin with a prefix. The STL | 180 // We want to find the set of keywords that begin with a prefix. The STL |
| 153 // algorithms will return the set of elements that are "equal to" the | 181 // algorithms will return the set of elements that are "equal to" the |
| 154 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When | 182 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When |
| 155 // cmp() is the typical std::less<>, this results in lexicographic equality; | 183 // cmp() is the typical std::less<>, this results in lexicographic equality; |
| 156 // we need to extend this to mark a prefix as "not less than" a keyword it | 184 // we need to extend this to mark a prefix as "not less than" a keyword it |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 data.short_name = title; | 543 data.short_name = title; |
| 516 data.SetKeyword(keyword); | 544 data.SetKeyword(keyword); |
| 517 if (search_url != data.url()) { | 545 if (search_url != data.url()) { |
| 518 data.SetURL(search_url); | 546 data.SetURL(search_url); |
| 519 // The urls have changed, reset the favicon url. | 547 // The urls have changed, reset the favicon url. |
| 520 data.favicon_url = GURL(); | 548 data.favicon_url = GURL(); |
| 521 } | 549 } |
| 522 data.safe_for_autoreplace = false; | 550 data.safe_for_autoreplace = false; |
| 523 data.last_modified = time_provider_(); | 551 data.last_modified = time_provider_(); |
| 524 TemplateURL new_url(url->profile(), data); | 552 TemplateURL new_url(url->profile(), data); |
| 525 if (UpdateNoNotify(url, new_url)) | 553 UIThreadSearchTermsData search_terms_data(url->profile()); |
| 554 if (UpdateNoNotify(url, new_url, search_terms_data)) |
| 526 NotifyObservers(); | 555 NotifyObservers(); |
| 527 } | 556 } |
| 528 | 557 |
| 529 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { | 558 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { |
| 530 return url != GetDefaultSearchProvider() && | 559 return url != GetDefaultSearchProvider() && |
| 531 url->url_ref().SupportsReplacement() && !is_default_search_managed(); | 560 url->url_ref().SupportsReplacement() && !is_default_search_managed(); |
| 532 } | 561 } |
| 533 | 562 |
| 534 void TemplateURLService::SetDefaultSearchProvider(TemplateURL* url) { | 563 void TemplateURLService::SetDefaultSearchProvider(TemplateURL* url) { |
| 535 DCHECK(!is_default_search_managed_); | 564 DCHECK(!is_default_search_managed_); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 visits_to_add_.push_back(*visit_details.ptr()); | 817 visits_to_add_.push_back(*visit_details.ptr()); |
| 789 else | 818 else |
| 790 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); | 819 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); |
| 791 } else if (type == chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED) { | 820 } else if (type == chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED) { |
| 792 // Policy has been updated, so the default search prefs may be different. | 821 // Policy has been updated, so the default search prefs may be different. |
| 793 // Reload the default search provider from them. | 822 // Reload the default search provider from them. |
| 794 // TODO(pkasting): Rather than communicating via prefs, we should eventually | 823 // TODO(pkasting): Rather than communicating via prefs, we should eventually |
| 795 // observe policy changes directly. | 824 // observe policy changes directly. |
| 796 UpdateDefaultSearch(); | 825 UpdateDefaultSearch(); |
| 797 } else if (type == chrome::NOTIFICATION_GOOGLE_URL_UPDATED) { | 826 } else if (type == chrome::NOTIFICATION_GOOGLE_URL_UPDATED) { |
| 798 if (loaded_) | 827 if (loaded_) { |
| 799 GoogleBaseURLChanged(); | 828 GoogleBaseURLChanged( |
| 829 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first); |
| 830 } |
| 800 } else if (type == chrome::NOTIFICATION_PREF_CHANGED) { | 831 } else if (type == chrome::NOTIFICATION_PREF_CHANGED) { |
| 801 // Listen for changes to the default search from Sync. | 832 // Listen for changes to the default search from Sync. |
| 802 DCHECK_EQ(std::string(prefs::kSyncedDefaultSearchProviderGUID), | 833 DCHECK_EQ(std::string(prefs::kSyncedDefaultSearchProviderGUID), |
| 803 *content::Details<std::string>(details).ptr()); | 834 *content::Details<std::string>(details).ptr()); |
| 804 PrefService* prefs = GetPrefs(); | 835 PrefService* prefs = GetPrefs(); |
| 805 TemplateURL* new_default_search = GetTemplateURLForGUID( | 836 TemplateURL* new_default_search = GetTemplateURLForGUID( |
| 806 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID)); | 837 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID)); |
| 807 if (new_default_search && !is_default_search_managed_) { | 838 if (new_default_search && !is_default_search_managed_) { |
| 808 if (new_default_search != GetDefaultSearchProvider()) { | 839 if (new_default_search != GetDefaultSearchProvider()) { |
| 809 SetDefaultSearchProvider(new_default_search); | 840 SetDefaultSearchProvider(new_default_search); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 FROM_HERE, | 954 FROM_HERE, |
| 924 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); | 955 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); |
| 925 continue; | 956 continue; |
| 926 } | 957 } |
| 927 // Possibly resolve a keyword conflict if they have the same keywords but | 958 // Possibly resolve a keyword conflict if they have the same keywords but |
| 928 // are not the same entry. | 959 // are not the same entry. |
| 929 if (existing_keyword_turl && existing_keyword_turl != existing_turl) { | 960 if (existing_keyword_turl && existing_keyword_turl != existing_turl) { |
| 930 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, | 961 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, |
| 931 &new_changes); | 962 &new_changes); |
| 932 } | 963 } |
| 933 if (UpdateNoNotify(existing_turl, *turl)) | 964 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); |
| 965 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) |
| 934 NotifyObservers(); | 966 NotifyObservers(); |
| 935 } else { | 967 } else { |
| 936 // We've unexpectedly received an ACTION_INVALID. | 968 // We've unexpectedly received an ACTION_INVALID. |
| 937 NOTREACHED() << "Unexpected sync change state."; | 969 NOTREACHED() << "Unexpected sync change state."; |
| 938 error = sync_error_factory_->CreateAndUploadError( | 970 error = sync_error_factory_->CreateAndUploadError( |
| 939 FROM_HERE, | 971 FROM_HERE, |
| 940 "ProcessSyncChanges received an ACTION_INVALID"); | 972 "ProcessSyncChanges received an ACTION_INVALID"); |
| 941 } | 973 } |
| 942 } | 974 } |
| 943 | 975 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 if (local_turl) { | 1041 if (local_turl) { |
| 1010 // This local search engine is already synced. If the timestamp differs | 1042 // This local search engine is already synced. If the timestamp differs |
| 1011 // from Sync, we need to update locally or to the cloud. Note that if the | 1043 // from Sync, we need to update locally or to the cloud. Note that if the |
| 1012 // timestamps are equal, we touch neither. | 1044 // timestamps are equal, we touch neither. |
| 1013 if (sync_turl->last_modified() > local_turl->last_modified()) { | 1045 if (sync_turl->last_modified() > local_turl->last_modified()) { |
| 1014 // We've received an update from Sync. We should replace all synced | 1046 // We've received an update from Sync. We should replace all synced |
| 1015 // fields in the local TemplateURL. Note that this includes the | 1047 // fields in the local TemplateURL. Note that this includes the |
| 1016 // TemplateURLID and the TemplateURL may have to be reparsed. This | 1048 // TemplateURLID and the TemplateURL may have to be reparsed. This |
| 1017 // also makes the local data's last_modified timestamp equal to Sync's, | 1049 // also makes the local data's last_modified timestamp equal to Sync's, |
| 1018 // avoiding an Update on the next MergeData call. | 1050 // avoiding an Update on the next MergeData call. |
| 1019 if (UpdateNoNotify(local_turl, *sync_turl)) | 1051 UIThreadSearchTermsData search_terms_data(local_turl->profile()); |
| 1052 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data)) |
| 1020 NotifyObservers(); | 1053 NotifyObservers(); |
| 1021 } else if (sync_turl->last_modified() < local_turl->last_modified()) { | 1054 } else if (sync_turl->last_modified() < local_turl->last_modified()) { |
| 1022 // Otherwise, we know we have newer data, so update Sync with our | 1055 // Otherwise, we know we have newer data, so update Sync with our |
| 1023 // data fields. | 1056 // data fields. |
| 1024 new_changes.push_back(SyncChange(SyncChange::ACTION_UPDATE, | 1057 new_changes.push_back(SyncChange(SyncChange::ACTION_UPDATE, |
| 1025 local_data_map[local_turl->sync_guid()])); | 1058 local_data_map[local_turl->sync_guid()])); |
| 1026 } | 1059 } |
| 1027 local_data_map.erase(iter->first); | 1060 local_data_map.erase(iter->first); |
| 1028 } else { | 1061 } else { |
| 1029 // The search engine from the cloud has not been synced locally, but there | 1062 // The search engine from the cloud has not been synced locally, but there |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 sync_pb::SearchEngineSpecifics specifics = | 1189 sync_pb::SearchEngineSpecifics specifics = |
| 1157 sync_data.GetSpecifics().search_engine(); | 1190 sync_data.GetSpecifics().search_engine(); |
| 1158 | 1191 |
| 1159 // Past bugs might have caused either of these fields to be empty. Just | 1192 // Past bugs might have caused either of these fields to be empty. Just |
| 1160 // delete this data off the server. | 1193 // delete this data off the server. |
| 1161 if (specifics.url().empty() || specifics.sync_guid().empty()) { | 1194 if (specifics.url().empty() || specifics.sync_guid().empty()) { |
| 1162 change_list->push_back(SyncChange(SyncChange::ACTION_DELETE, sync_data)); | 1195 change_list->push_back(SyncChange(SyncChange::ACTION_DELETE, sync_data)); |
| 1163 return NULL; | 1196 return NULL; |
| 1164 } | 1197 } |
| 1165 | 1198 |
| 1166 TemplateURLData data; | 1199 TemplateURLData data(existing_turl ? |
| 1200 existing_turl->data() : TemplateURLData()); |
| 1167 data.short_name = UTF8ToUTF16(specifics.short_name()); | 1201 data.short_name = UTF8ToUTF16(specifics.short_name()); |
| 1168 data.originating_url = GURL(specifics.originating_url()); | 1202 data.originating_url = GURL(specifics.originating_url()); |
| 1169 string16 keyword(UTF8ToUTF16(specifics.keyword())); | 1203 string16 keyword(UTF8ToUTF16(specifics.keyword())); |
| 1170 // NOTE: Once this code has shipped in a couple of stable releases, we can | 1204 // NOTE: Once this code has shipped in a couple of stable releases, we can |
| 1171 // probably remove the migration portion, comment out the | 1205 // probably remove the migration portion, comment out the |
| 1172 // "autogenerate_keyword" field entirely in the .proto file, and fold the | 1206 // "autogenerate_keyword" field entirely in the .proto file, and fold the |
| 1173 // empty keyword case into the "delete data" block above. | 1207 // empty keyword case into the "delete data" block above. |
| 1174 bool reset_keyword = | 1208 bool reset_keyword = |
| 1175 specifics.autogenerate_keyword() || specifics.keyword().empty(); | 1209 specifics.autogenerate_keyword() || specifics.keyword().empty(); |
| 1176 if (reset_keyword) | 1210 if (reset_keyword) |
| 1177 keyword = ASCIIToUTF16("dummy"); // Will be replaced below. | 1211 keyword = ASCIIToUTF16("dummy"); // Will be replaced below. |
| 1178 DCHECK(!keyword.empty()); | 1212 DCHECK(!keyword.empty()); |
| 1179 data.SetKeyword(keyword); | 1213 data.SetKeyword(keyword); |
| 1180 data.SetURL(specifics.url()); | 1214 data.SetURL(specifics.url()); |
| 1181 data.suggestions_url = specifics.suggestions_url(); | 1215 data.suggestions_url = specifics.suggestions_url(); |
| 1182 data.instant_url = specifics.instant_url(); | 1216 data.instant_url = specifics.instant_url(); |
| 1183 data.favicon_url = GURL(specifics.favicon_url()); | 1217 data.favicon_url = GURL(specifics.favicon_url()); |
| 1184 data.show_in_default_list = specifics.show_in_default_list(); | 1218 data.show_in_default_list = specifics.show_in_default_list(); |
| 1185 data.safe_for_autoreplace = specifics.safe_for_autoreplace(); | 1219 data.safe_for_autoreplace = specifics.safe_for_autoreplace(); |
| 1186 base::SplitString(specifics.input_encodings(), ';', &data.input_encodings); | 1220 base::SplitString(specifics.input_encodings(), ';', &data.input_encodings); |
| 1187 data.date_created = base::Time::FromInternalValue(specifics.date_created()); | 1221 data.date_created = base::Time::FromInternalValue(specifics.date_created()); |
| 1188 data.last_modified = base::Time::FromInternalValue(specifics.last_modified()); | 1222 data.last_modified = base::Time::FromInternalValue(specifics.last_modified()); |
| 1189 data.prepopulate_id = specifics.prepopulate_id(); | 1223 data.prepopulate_id = specifics.prepopulate_id(); |
| 1190 data.sync_guid = specifics.sync_guid(); | 1224 data.sync_guid = specifics.sync_guid(); |
| 1191 if (existing_turl) { | |
| 1192 data.id = existing_turl->id(); | |
| 1193 data.created_by_policy = existing_turl->created_by_policy(); | |
| 1194 data.usage_count = existing_turl->usage_count(); | |
| 1195 } | |
| 1196 | 1225 |
| 1197 TemplateURL* turl = new TemplateURL(profile, data); | 1226 TemplateURL* turl = new TemplateURL(profile, data); |
| 1198 DCHECK(!turl->IsExtensionKeyword()); | 1227 DCHECK(!turl->IsExtensionKeyword()); |
| 1199 if (reset_keyword) { | 1228 if (reset_keyword) { |
| 1200 turl->ResetKeywordIfNecessary(true); | 1229 turl->ResetKeywordIfNecessary(true); |
| 1201 SyncData sync_data = CreateSyncDataFromTemplateURL(*turl); | 1230 SyncData sync_data = CreateSyncDataFromTemplateURL(*turl); |
| 1202 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); | 1231 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); |
| 1232 } else if (turl->IsGoogleSearchURLWithReplaceableKeyword()) { |
| 1233 if (!existing_turl) { |
| 1234 // We're adding a new TemplateURL that uses the Google base URL, so set |
| 1235 // its keyword appropriately for the local environment. |
| 1236 turl->ResetKeywordIfNecessary(false); |
| 1237 } else if (existing_turl->IsGoogleSearchURLWithReplaceableKeyword()) { |
| 1238 // Ignore keyword changes triggered by the Google base URL changing on |
| 1239 // another client. If the base URL changes in this client as well, we'll |
| 1240 // pick that up separately at the appropriate time. Otherwise, changing |
| 1241 // the keyword here could result in having the wrong keyword for the local |
| 1242 // environment. |
| 1243 turl->data_.SetKeyword(existing_turl->keyword()); |
| 1244 } |
| 1203 } | 1245 } |
| 1246 |
| 1204 return turl; | 1247 return turl; |
| 1205 } | 1248 } |
| 1206 | 1249 |
| 1207 // static | 1250 // static |
| 1208 SyncDataMap TemplateURLService::CreateGUIDToSyncDataMap( | 1251 SyncDataMap TemplateURLService::CreateGUIDToSyncDataMap( |
| 1209 const SyncDataList& sync_data) { | 1252 const SyncDataList& sync_data) { |
| 1210 SyncDataMap data_map; | 1253 SyncDataMap data_map; |
| 1211 for (SyncDataList::const_iterator i(sync_data.begin()); i != sync_data.end(); | 1254 for (SyncDataList::const_iterator i(sync_data.begin()); i != sync_data.end(); |
| 1212 ++i) | 1255 ++i) |
| 1213 data_map[i->GetSpecifics().search_engine().sync_guid()] = *i; | 1256 data_map[i->GetSpecifics().search_engine().sync_guid()] = *i; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1315 | 1358 |
| 1316 // If the keyword we're removing is from an extension, we're now done, since | 1359 // If the keyword we're removing is from an extension, we're now done, since |
| 1317 // it won't be synced or stored in the provider map. | 1360 // it won't be synced or stored in the provider map. |
| 1318 // TODO(mpcomplete): If we allow editing extension keywords, then those should | 1361 // TODO(mpcomplete): If we allow editing extension keywords, then those should |
| 1319 // be synced. | 1362 // be synced. |
| 1320 if (template_url->IsExtensionKeyword()) | 1363 if (template_url->IsExtensionKeyword()) |
| 1321 return; | 1364 return; |
| 1322 | 1365 |
| 1323 if (!template_url->sync_guid().empty()) | 1366 if (!template_url->sync_guid().empty()) |
| 1324 guid_to_template_map_.erase(template_url->sync_guid()); | 1367 guid_to_template_map_.erase(template_url->sync_guid()); |
| 1325 if (loaded_) | 1368 if (loaded_) { |
| 1326 provider_map_->Remove(template_url); | 1369 UIThreadSearchTermsData search_terms_data(template_url->profile()); |
| 1370 provider_map_->Remove(template_url, search_terms_data); |
| 1371 } |
| 1327 } | 1372 } |
| 1328 | 1373 |
| 1329 void TemplateURLService::RemoveFromKeywordMapByPointer( | 1374 void TemplateURLService::RemoveFromKeywordMapByPointer( |
| 1330 TemplateURL* template_url) { | 1375 TemplateURL* template_url) { |
| 1331 DCHECK(template_url); | 1376 DCHECK(template_url); |
| 1332 for (KeywordToTemplateMap::iterator i = keyword_to_template_map_.begin(); | 1377 for (KeywordToTemplateMap::iterator i = keyword_to_template_map_.begin(); |
| 1333 i != keyword_to_template_map_.end(); ++i) { | 1378 i != keyword_to_template_map_.end(); ++i) { |
| 1334 if (i->second == template_url) { | 1379 if (i->second == template_url) { |
| 1335 keyword_to_template_map_.erase(i); | 1380 keyword_to_template_map_.erase(i); |
| 1336 // A given TemplateURL only occurs once in the map. As soon as we find the | 1381 // A given TemplateURL only occurs once in the map. As soon as we find the |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 // The extension keyword in the model may be hiding a replaceable | 1612 // The extension keyword in the model may be hiding a replaceable |
| 1568 // non-extension keyword. Look for it. | 1613 // non-extension keyword. Look for it. |
| 1569 for (TemplateURLVector::const_iterator i(template_urls_.begin()); | 1614 for (TemplateURLVector::const_iterator i(template_urls_.begin()); |
| 1570 i != template_urls_.end(); ++i) { | 1615 i != template_urls_.end(); ++i) { |
| 1571 if (!(*i)->IsExtensionKeyword() && ((*i)->keyword() == keyword)) | 1616 if (!(*i)->IsExtensionKeyword() && ((*i)->keyword() == keyword)) |
| 1572 return *i; | 1617 return *i; |
| 1573 } | 1618 } |
| 1574 return NULL; | 1619 return NULL; |
| 1575 } | 1620 } |
| 1576 | 1621 |
| 1577 bool TemplateURLService::UpdateNoNotify(TemplateURL* existing_turl, | 1622 bool TemplateURLService::UpdateNoNotify( |
| 1578 const TemplateURL& new_values) { | 1623 TemplateURL* existing_turl, |
| 1624 const TemplateURL& new_values, |
| 1625 const SearchTermsData& old_search_terms_data) { |
| 1579 DCHECK(loaded_); | 1626 DCHECK(loaded_); |
| 1580 DCHECK(existing_turl); | 1627 DCHECK(existing_turl); |
| 1581 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == | 1628 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == |
| 1582 template_urls_.end()) | 1629 template_urls_.end()) |
| 1583 return false; | 1630 return false; |
| 1584 | 1631 |
| 1585 // TODO(mpcomplete): If we allow editing extension keywords, then those should | 1632 // TODO(mpcomplete): If we allow editing extension keywords, then those should |
| 1586 // be persisted to disk and synced. In this case this DCHECK should be | 1633 // be persisted to disk and synced. In this case this DCHECK should be |
| 1587 // removed. | 1634 // removed. |
| 1588 DCHECK(!existing_turl->IsExtensionKeyword()); | 1635 DCHECK(!existing_turl->IsExtensionKeyword()); |
| 1589 | 1636 |
| 1590 string16 old_keyword(existing_turl->keyword()); | 1637 string16 old_keyword(existing_turl->keyword()); |
| 1591 keyword_to_template_map_.erase(old_keyword); | 1638 keyword_to_template_map_.erase(old_keyword); |
| 1592 if (!existing_turl->sync_guid().empty()) | 1639 if (!existing_turl->sync_guid().empty()) |
| 1593 guid_to_template_map_.erase(existing_turl->sync_guid()); | 1640 guid_to_template_map_.erase(existing_turl->sync_guid()); |
| 1594 | 1641 |
| 1595 provider_map_->Remove(existing_turl); | 1642 provider_map_->Remove(existing_turl, old_search_terms_data); |
| 1596 TemplateURLID previous_id = existing_turl->id(); | 1643 TemplateURLID previous_id = existing_turl->id(); |
| 1597 existing_turl->CopyFrom(new_values); | 1644 existing_turl->CopyFrom(new_values); |
| 1598 existing_turl->data_.id = previous_id; | 1645 existing_turl->data_.id = previous_id; |
| 1599 UIThreadSearchTermsData search_terms_data(profile_); | 1646 UIThreadSearchTermsData new_search_terms_data(profile_); |
| 1600 provider_map_->Add(existing_turl, search_terms_data); | 1647 provider_map_->Add(existing_turl, new_search_terms_data); |
| 1601 | 1648 |
| 1602 const string16& keyword = existing_turl->keyword(); | 1649 const string16& keyword = existing_turl->keyword(); |
| 1603 KeywordToTemplateMap::const_iterator i = | 1650 KeywordToTemplateMap::const_iterator i = |
| 1604 keyword_to_template_map_.find(keyword); | 1651 keyword_to_template_map_.find(keyword); |
| 1605 if (i == keyword_to_template_map_.end()) { | 1652 if (i == keyword_to_template_map_.end()) { |
| 1606 keyword_to_template_map_[keyword] = existing_turl; | 1653 keyword_to_template_map_[keyword] = existing_turl; |
| 1607 } else { | 1654 } else { |
| 1608 // We can theoretically reach here in two cases: | 1655 // We can theoretically reach here in two cases: |
| 1609 // * There is an existing extension keyword and sync brings in a rename of | 1656 // * There is an existing extension keyword and sync brings in a rename of |
| 1610 // a non-extension keyword to match. In this case we just need to pick | 1657 // a non-extension keyword to match. In this case we just need to pick |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 } | 1804 } |
| 1758 } else { | 1805 } else { |
| 1759 valid_term_count++; | 1806 valid_term_count++; |
| 1760 (*query_terms)[key_string] = value_string; | 1807 (*query_terms)[key_string] = value_string; |
| 1761 } | 1808 } |
| 1762 } | 1809 } |
| 1763 } | 1810 } |
| 1764 return (valid_term_count > 0); | 1811 return (valid_term_count > 0); |
| 1765 } | 1812 } |
| 1766 | 1813 |
| 1767 void TemplateURLService::GoogleBaseURLChanged() { | 1814 void TemplateURLService::GoogleBaseURLChanged(const GURL& old_base_url) { |
| 1768 bool something_changed = false; | 1815 bool something_changed = false; |
| 1769 for (TemplateURLVector::iterator i(template_urls_.begin()); | 1816 for (TemplateURLVector::iterator i(template_urls_.begin()); |
| 1770 i != template_urls_.end(); ++i) { | 1817 i != template_urls_.end(); ++i) { |
| 1771 TemplateURL* t_url = *i; | 1818 TemplateURL* t_url = *i; |
| 1772 if (t_url->url_ref().HasGoogleBaseURLs() || | 1819 if (t_url->url_ref().HasGoogleBaseURLs() || |
| 1773 t_url->suggestions_url_ref().HasGoogleBaseURLs()) { | 1820 t_url->suggestions_url_ref().HasGoogleBaseURLs()) { |
| 1821 TemplateURL updated_turl(t_url->profile(), t_url->data()); |
| 1822 updated_turl.ResetKeywordIfNecessary(false); |
| 1823 KeywordToTemplateMap::const_iterator existing_entry = |
| 1824 keyword_to_template_map_.find(updated_turl.keyword()); |
| 1825 if ((existing_entry != keyword_to_template_map_.end()) && |
| 1826 (existing_entry->second != t_url)) { |
| 1827 // The new autogenerated keyword conflicts with another TemplateURL. |
| 1828 // Overwrite it if it's replaceable; otherwise, leave |t_url| using its |
| 1829 // current keyword. (This will not prevent |t_url| from auto-updating |
| 1830 // the keyword in the future if the conflicting TemplateURL disappears.) |
| 1831 // Note that we must still update |t_url| in this case, or the |
| 1832 // |provider_map_| will not be updated correctly. |
| 1833 if (CanReplace(existing_entry->second)) |
| 1834 RemoveNoNotify(existing_entry->second); |
| 1835 else |
| 1836 updated_turl.data_.SetKeyword(t_url->keyword()); |
| 1837 } |
| 1774 something_changed = true; | 1838 something_changed = true; |
| 1775 string16 original_keyword(t_url->keyword()); | 1839 // This will send the keyword change to sync. Note that other clients |
| 1776 t_url->InvalidateCachedValues(); | 1840 // need to reset the keyword to an appropriate local value when this |
| 1777 const string16& new_keyword(t_url->keyword()); | 1841 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). |
| 1778 KeywordToTemplateMap::const_iterator i = | 1842 UpdateNoNotify(t_url, updated_turl, |
| 1779 keyword_to_template_map_.find(new_keyword); | 1843 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec())); |
| 1780 if ((i != keyword_to_template_map_.end()) && (i->second != t_url)) { | |
| 1781 // The new autogenerated keyword conflicts with another TemplateURL. | |
| 1782 // Overwrite it if it's replaceable; otherwise just reset |t_url|'s | |
| 1783 // keyword. (This will not prevent |t_url| from auto-updating the | |
| 1784 // keyword in the future if the conflicting TemplateURL disappears.) | |
| 1785 if (!CanReplace(i->second)) { | |
| 1786 t_url->data_.SetKeyword(original_keyword); | |
| 1787 continue; | |
| 1788 } | |
| 1789 RemoveNoNotify(i->second); | |
| 1790 } | |
| 1791 RemoveFromKeywordMapByPointer(t_url); | |
| 1792 keyword_to_template_map_[new_keyword] = t_url; | |
| 1793 } | 1844 } |
| 1794 } | 1845 } |
| 1795 | 1846 if (something_changed) |
| 1796 if (something_changed && loaded_) { | |
| 1797 UIThreadSearchTermsData search_terms_data(profile_); | |
| 1798 provider_map_->UpdateGoogleBaseURLs(search_terms_data); | |
| 1799 NotifyObservers(); | 1847 NotifyObservers(); |
| 1800 } | |
| 1801 } | 1848 } |
| 1802 | 1849 |
| 1803 void TemplateURLService::UpdateDefaultSearch() { | 1850 void TemplateURLService::UpdateDefaultSearch() { |
| 1804 if (!loaded_) { | 1851 if (!loaded_) { |
| 1805 // Set |initial_default_search_provider_| from the preferences. We use this | 1852 // Set |initial_default_search_provider_| from the preferences. We use this |
| 1806 // value for default search provider until the database has been loaded. | 1853 // value for default search provider until the database has been loaded. |
| 1807 if (!LoadDefaultSearchProviderFromPrefs(&initial_default_search_provider_, | 1854 if (!LoadDefaultSearchProviderFromPrefs(&initial_default_search_provider_, |
| 1808 &is_default_search_managed_)) { | 1855 &is_default_search_managed_)) { |
| 1809 // Prefs does not specify, so rely on the prepopulated engines. This | 1856 // Prefs does not specify, so rely on the prepopulated engines. This |
| 1810 // should happen only the first time Chrome is started. | 1857 // should happen only the first time Chrome is started. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1840 // default_search_provider_ can't be NULL otherwise | 1887 // default_search_provider_ can't be NULL otherwise |
| 1841 // TemplateURLsHaveSamePrefs would have returned true. Remove this now | 1888 // TemplateURLsHaveSamePrefs would have returned true. Remove this now |
| 1842 // invalid value. | 1889 // invalid value. |
| 1843 TemplateURL* old_default = default_search_provider_; | 1890 TemplateURL* old_default = default_search_provider_; |
| 1844 bool success = SetDefaultSearchProviderNoNotify(NULL); | 1891 bool success = SetDefaultSearchProviderNoNotify(NULL); |
| 1845 DCHECK(success); | 1892 DCHECK(success); |
| 1846 RemoveNoNotify(old_default); | 1893 RemoveNoNotify(old_default); |
| 1847 } else if (default_search_provider_) { | 1894 } else if (default_search_provider_) { |
| 1848 TemplateURLData data(new_default_from_prefs->data()); | 1895 TemplateURLData data(new_default_from_prefs->data()); |
| 1849 data.created_by_policy = true; | 1896 data.created_by_policy = true; |
| 1850 TemplateURL new_values(profile_, data); | 1897 TemplateURL new_values(new_default_from_prefs->profile(), data); |
| 1851 UpdateNoNotify(default_search_provider_, new_values); | 1898 UIThreadSearchTermsData search_terms_data( |
| 1899 default_search_provider_->profile()); |
| 1900 UpdateNoNotify(default_search_provider_, new_values, search_terms_data); |
| 1852 } else { | 1901 } else { |
| 1853 TemplateURL* new_template = NULL; | 1902 TemplateURL* new_template = NULL; |
| 1854 if (new_default_from_prefs.get()) { | 1903 if (new_default_from_prefs.get()) { |
| 1855 TemplateURLData data(new_default_from_prefs->data()); | 1904 TemplateURLData data(new_default_from_prefs->data()); |
| 1856 data.created_by_policy = true; | 1905 data.created_by_policy = true; |
| 1857 new_template = new TemplateURL(profile_, data); | 1906 new_template = new TemplateURL(profile_, data); |
| 1858 if (!AddNoNotify(new_template, true)) | 1907 if (!AddNoNotify(new_template, true)) |
| 1859 return; | 1908 return; |
| 1860 } | 1909 } |
| 1861 bool success = SetDefaultSearchProviderNoNotify(new_template); | 1910 bool success = SetDefaultSearchProviderNoNotify(new_template); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2099 } | 2148 } |
| 2100 | 2149 |
| 2101 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, | 2150 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, |
| 2102 const std::string& guid) { | 2151 const std::string& guid) { |
| 2103 DCHECK(loaded_); | 2152 DCHECK(loaded_); |
| 2104 DCHECK(!guid.empty()); | 2153 DCHECK(!guid.empty()); |
| 2105 | 2154 |
| 2106 TemplateURLData data(url->data()); | 2155 TemplateURLData data(url->data()); |
| 2107 data.sync_guid = guid; | 2156 data.sync_guid = guid; |
| 2108 TemplateURL new_url(url->profile(), data); | 2157 TemplateURL new_url(url->profile(), data); |
| 2109 UpdateNoNotify(url, new_url); | 2158 UIThreadSearchTermsData search_terms_data(url->profile()); |
| 2159 UpdateNoNotify(url, new_url, search_terms_data); |
| 2110 } | 2160 } |
| 2111 | 2161 |
| 2112 string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl) { | 2162 string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl) { |
| 2113 // Already unique. | 2163 // Already unique. |
| 2114 if (!GetTemplateURLForKeyword(turl.keyword())) | 2164 if (!GetTemplateURLForKeyword(turl.keyword())) |
| 2115 return turl.keyword(); | 2165 return turl.keyword(); |
| 2116 | 2166 |
| 2117 // First, try to return the generated keyword for the TemplateURL. | 2167 // First, try to return the generated keyword for the TemplateURL. |
| 2118 GURL gurl(turl.url()); | 2168 GURL gurl(turl.url()); |
| 2119 if (gurl.is_valid()) { | 2169 if (gurl.is_valid()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2152 sync_turl->data_.SetKeyword(new_keyword); | 2202 sync_turl->data_.SetKeyword(new_keyword); |
| 2153 // If we update the cloud TURL, we need to push an update back to sync | 2203 // If we update the cloud TURL, we need to push an update back to sync |
| 2154 // informing it that something has changed. | 2204 // informing it that something has changed. |
| 2155 SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl); | 2205 SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl); |
| 2156 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); | 2206 change_list->push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data)); |
| 2157 } else { | 2207 } else { |
| 2158 string16 new_keyword = UniquifyKeyword(*local_turl); | 2208 string16 new_keyword = UniquifyKeyword(*local_turl); |
| 2159 TemplateURLData data(local_turl->data()); | 2209 TemplateURLData data(local_turl->data()); |
| 2160 data.SetKeyword(new_keyword); | 2210 data.SetKeyword(new_keyword); |
| 2161 TemplateURL new_turl(local_turl->profile(), data); | 2211 TemplateURL new_turl(local_turl->profile(), data); |
| 2162 if (UpdateNoNotify(local_turl, new_turl)) | 2212 UIThreadSearchTermsData search_terms_data(local_turl->profile()); |
| 2213 if (UpdateNoNotify(local_turl, new_turl, search_terms_data)) |
| 2163 NotifyObservers(); | 2214 NotifyObservers(); |
| 2164 if (!models_associated_) { | 2215 if (!models_associated_) { |
| 2165 // We're doing our initial sync, so UpdateNoNotify() won't have generated | 2216 // We're doing our initial sync, so UpdateNoNotify() won't have generated |
| 2166 // an ACTION_UPDATE. If this local URL is one that was just newly brought | 2217 // an ACTION_UPDATE. If this local URL is one that was just newly brought |
| 2167 // down from the sync server, we need to go ahead and generate an update | 2218 // down from the sync server, we need to go ahead and generate an update |
| 2168 // for it. If it was pre-existing, then this is unnecessary (and in fact | 2219 // for it. If it was pre-existing, then this is unnecessary (and in fact |
| 2169 // wrong) because MergeDataAndStartSyncing() will later add an ACTION_ADD | 2220 // wrong) because MergeDataAndStartSyncing() will later add an ACTION_ADD |
| 2170 // for this URL; but in this case, PruneSyncChanges() will prune out the | 2221 // for this URL; but in this case, PruneSyncChanges() will prune out the |
| 2171 // ACTION_UPDATE we create here. | 2222 // ACTION_UPDATE we create here. |
| 2172 SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl); | 2223 SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2270 // TODO(mpcomplete): If we allow editing extension keywords, then those | 2321 // TODO(mpcomplete): If we allow editing extension keywords, then those |
| 2271 // should be persisted to disk and synced. | 2322 // should be persisted to disk and synced. |
| 2272 if (template_url->sync_guid().empty() && | 2323 if (template_url->sync_guid().empty() && |
| 2273 !template_url->IsExtensionKeyword()) { | 2324 !template_url->IsExtensionKeyword()) { |
| 2274 template_url->data_.sync_guid = guid::GenerateGUID(); | 2325 template_url->data_.sync_guid = guid::GenerateGUID(); |
| 2275 if (service_.get()) | 2326 if (service_.get()) |
| 2276 service_->UpdateKeyword(template_url->data()); | 2327 service_->UpdateKeyword(template_url->data()); |
| 2277 } | 2328 } |
| 2278 } | 2329 } |
| 2279 } | 2330 } |
| OLD | NEW |