Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/search_engines/template_url_service.h" | 5 #include "components/search_engines/template_url_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 13 #include "base/guid.h" | 13 #include "base/guid.h" |
| 14 #include "base/i18n/case_conversion.h" | 14 #include "base/i18n/case_conversion.h" |
| 15 #include "base/memory/scoped_vector.h" | 15 #include "base/memory/scoped_vector.h" |
| 16 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/prefs/pref_service.h" | 17 #include "base/prefs/pref_service.h" |
| 18 #include "base/profiler/scoped_tracker.h" | 18 #include "base/profiler/scoped_tracker.h" |
| 19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 20 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
| 21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 22 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 23 #include "base/time/default_clock.h" | 23 #include "base/time/default_clock.h" |
| 24 #include "base/time/time.h" | 24 #include "base/time/time.h" |
| 25 #include "components/omnibox/browser/omnibox_field_trial.h" | |
| 25 #include "components/pref_registry/pref_registry_syncable.h" | 26 #include "components/pref_registry/pref_registry_syncable.h" |
| 26 #include "components/rappor/rappor_service.h" | 27 #include "components/rappor/rappor_service.h" |
| 27 #include "components/search_engines/search_engines_pref_names.h" | 28 #include "components/search_engines/search_engines_pref_names.h" |
| 28 #include "components/search_engines/search_host_to_urls_map.h" | 29 #include "components/search_engines/search_host_to_urls_map.h" |
| 29 #include "components/search_engines/search_terms_data.h" | 30 #include "components/search_engines/search_terms_data.h" |
| 30 #include "components/search_engines/template_url.h" | 31 #include "components/search_engines/template_url.h" |
| 31 #include "components/search_engines/template_url_prepopulate_data.h" | 32 #include "components/search_engines/template_url_prepopulate_data.h" |
| 32 #include "components/search_engines/template_url_service_client.h" | 33 #include "components/search_engines/template_url_service_client.h" |
| 33 #include "components/search_engines/template_url_service_observer.h" | 34 #include "components/search_engines/template_url_service_observer.h" |
| 34 #include "components/search_engines/util.h" | 35 #include "components/search_engines/util.h" |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 int num_dupes = 0; | 143 int num_dupes = 0; |
| 143 for (std::map<std::string, int>::const_iterator it = duplicates.begin(); | 144 for (std::map<std::string, int>::const_iterator it = duplicates.begin(); |
| 144 it != duplicates.end(); ++it) { | 145 it != duplicates.end(); ++it) { |
| 145 if (it->second > 1) | 146 if (it->second > 1) |
| 146 num_dupes++; | 147 num_dupes++; |
| 147 } | 148 } |
| 148 | 149 |
| 149 UMA_HISTOGRAM_COUNTS_100("Search.SearchEngineDuplicateCounts", num_dupes); | 150 UMA_HISTOGRAM_COUNTS_100("Search.SearchEngineDuplicateCounts", num_dupes); |
| 150 } | 151 } |
| 151 | 152 |
| 153 // Returns the length of the registry portion of a hostname. For example, | |
| 154 // www.google.co.uk will return 5 (the length of co.uk). | |
| 155 size_t GetRegistryLength(const base::string16& host) { | |
| 156 return net::registry_controlled_domains::GetRegistryLength( | |
| 157 base::UTF16ToUTF8(host), | |
| 158 net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, | |
| 159 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | |
| 160 } | |
| 161 | |
| 162 // Returns the domain name (including registry) of a hostname. For example, | |
| 163 // www.google.co.uk will return google.co.uk. | |
| 164 base::string16 GetDomainAndRegistry(const base::string16& host) { | |
| 165 return base::UTF8ToUTF16( | |
| 166 net::registry_controlled_domains::GetDomainAndRegistry( | |
| 167 base::UTF16ToUTF8(host), | |
| 168 net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES)); | |
| 169 } | |
| 170 | |
| 171 // Returns the length of the important part of the |keyword|, assumed to be | |
| 172 // associated with the TemplateURL. For instance, for the keyword | |
| 173 // google.co.uk, this can return 6 (the length of "google"). | |
| 174 size_t GetMeaningfulKeywordLength(const base::string16& keyword, | |
| 175 const TemplateURL* turl) { | |
| 176 if (OmniboxFieldTrial::KeywordRequiresRegistry()) | |
| 177 return keyword.length(); | |
| 178 const size_t registry_length = GetRegistryLength(keyword); | |
| 179 if (registry_length == std::string::npos) | |
| 180 return keyword.length(); | |
| 181 DCHECK_LT(registry_length, keyword.length()); | |
| 182 // The meaningful keyword length is the length of any portion before the | |
| 183 // registry ("co.uk") and its preceding dot. | |
| 184 return keyword.length() - (registry_length ? (registry_length + 1) : 0); | |
| 185 | |
| 186 } | |
| 187 | |
| 152 } // namespace | 188 } // namespace |
| 153 | 189 |
| 154 | |
| 155 // TemplateURLService::LessWithPrefix ----------------------------------------- | 190 // TemplateURLService::LessWithPrefix ----------------------------------------- |
| 156 | 191 |
| 157 class TemplateURLService::LessWithPrefix { | 192 class TemplateURLService::LessWithPrefix { |
| 158 public: | 193 public: |
| 159 // We want to find the set of keywords that begin with a prefix. The STL | 194 // We want to find the set of keywords that begin with a prefix. The STL |
| 160 // algorithms will return the set of elements that are "equal to" the | 195 // algorithms will return the set of elements that are "equal to" the |
| 161 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When | 196 // prefix, where "equal(x, y)" means "!(cmp(x, y) || cmp(y, x))". When |
| 162 // cmp() is the typical std::less<>, this results in lexicographic equality; | 197 // cmp() is the typical std::less<>, this results in lexicographic equality; |
| 163 // we need to extend this to mark a prefix as "not less than" a keyword it | 198 // we need to extend this to mark a prefix as "not less than" a keyword it |
| 164 // begins, which will cause the desired elements to be considered "equal to" | 199 // begins, which will cause the desired elements to be considered "equal to" |
| 165 // the prefix. Note: this is still a strict weak ordering, as required by | 200 // the prefix. Note: this is still a strict weak ordering, as required by |
| 166 // equal_range() (though I will not prove that here). | 201 // equal_range() (though I will not prove that here). |
| 167 // | 202 // |
| 168 // Unfortunately the calling convention is not "prefix and element" but | 203 // Unfortunately the calling convention is not "prefix and element" but |
| 169 // rather "two elements", so we pass the prefix as a fake "element" which has | 204 // rather "two elements", so we pass the prefix as a fake "element" which has |
| 170 // a NULL KeywordDataElement pointer. | 205 // a NULL KeywordDataElement pointer. |
| 171 bool operator()(const KeywordToTemplateMap::value_type& elem1, | 206 bool operator()( |
| 172 const KeywordToTemplateMap::value_type& elem2) const { | 207 const KeywordToTURLAndMeaningfulLength::value_type& elem1, |
| 173 return (elem1.second == NULL) ? | 208 const KeywordToTURLAndMeaningfulLength::value_type& elem2) const { |
| 209 return (elem1.second.first == NULL) ? | |
| 174 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) : | 210 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) : |
| 175 (elem1.first < elem2.first); | 211 (elem1.first < elem2.first); |
| 176 } | 212 } |
| 177 }; | 213 }; |
| 178 | 214 |
| 179 | 215 |
| 180 // TemplateURLService --------------------------------------------------------- | 216 // TemplateURLService --------------------------------------------------------- |
| 181 | 217 |
| 182 TemplateURLService::TemplateURLService( | 218 TemplateURLService::TemplateURLService( |
| 183 PrefService* prefs, | 219 PrefService* prefs, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 // We don't have a TemplateURL with keyword. We still may not allow this | 373 // We don't have a TemplateURL with keyword. We still may not allow this |
| 338 // keyword if there's evidence we may have created this keyword before and | 374 // keyword if there's evidence we may have created this keyword before and |
| 339 // the user renamed it (because, for instance, the keyword is a common word | 375 // the user renamed it (because, for instance, the keyword is a common word |
| 340 // that may interfere with search queries). An easy heuristic for this is | 376 // that may interfere with search queries). An easy heuristic for this is |
| 341 // whether the user has a TemplateURL that has been manually modified (e.g., | 377 // whether the user has a TemplateURL that has been manually modified (e.g., |
| 342 // renamed) connected to the same host. | 378 // renamed) connected to the same host. |
| 343 return !url.is_valid() || url.host().empty() || | 379 return !url.is_valid() || url.host().empty() || |
| 344 CanAddAutogeneratedKeywordForHost(url.host()); | 380 CanAddAutogeneratedKeywordForHost(url.host()); |
| 345 } | 381 } |
| 346 | 382 |
| 347 void TemplateURLService::FindMatchingKeywords( | 383 void TemplateURLService::AddMatchingKeywords( |
| 348 const base::string16& prefix, | 384 const base::string16& prefix, |
| 349 bool support_replacement_only, | 385 bool supports_replacement_only, |
| 350 TemplateURLVector* matches) { | 386 TURLsAndMeaningfulLengths* matches) { |
| 351 // Sanity check args. | 387 AddMatchingKeywordsHelper( |
| 352 if (prefix.empty()) | 388 keyword_to_turl_and_length_, prefix, supports_replacement_only, matches); |
| 353 return; | 389 } |
| 354 DCHECK(matches != NULL); | |
| 355 DCHECK(matches->empty()); // The code for exact matches assumes this. | |
| 356 | 390 |
| 357 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair | 391 void TemplateURLService::AddMatchingDomainKeywords( |
| 358 TemplateURL* const kNullTemplateURL = NULL; | 392 const base::string16& prefix, |
| 359 | 393 bool supports_replacement_only, |
| 360 // Find matching keyword range. Searches the element map for keywords | 394 TURLsAndMeaningfulLengths* matches) { |
| 361 // beginning with |prefix| and stores the endpoints of the resulting set in | 395 AddMatchingKeywordsHelper( |
| 362 // |match_range|. | 396 keyword_domain_to_turl_and_length_, prefix, supports_replacement_only, |
| 363 const std::pair<KeywordToTemplateMap::const_iterator, | 397 matches); |
| 364 KeywordToTemplateMap::const_iterator> match_range( | |
| 365 std::equal_range( | |
| 366 keyword_to_template_map_.begin(), keyword_to_template_map_.end(), | |
| 367 KeywordToTemplateMap::value_type(prefix, kNullTemplateURL), | |
| 368 LessWithPrefix())); | |
| 369 | |
| 370 // Return vector of matching keywords. | |
| 371 for (KeywordToTemplateMap::const_iterator i(match_range.first); | |
| 372 i != match_range.second; ++i) { | |
| 373 if (!support_replacement_only || | |
| 374 i->second->url_ref().SupportsReplacement(search_terms_data())) | |
| 375 matches->push_back(i->second); | |
| 376 } | |
| 377 } | 398 } |
| 378 | 399 |
| 379 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( | 400 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( |
| 380 const base::string16& keyword) { | 401 const base::string16& keyword) { |
| 381 KeywordToTemplateMap::const_iterator elem( | 402 KeywordToTURLAndMeaningfulLength::const_iterator elem( |
| 382 keyword_to_template_map_.find(keyword)); | 403 keyword_to_turl_and_length_.find(keyword)); |
| 383 if (elem != keyword_to_template_map_.end()) | 404 if (elem != keyword_to_turl_and_length_.end()) |
| 384 return elem->second; | 405 return elem->second.first; |
| 385 return (!loaded_ && | 406 return (!loaded_ && |
| 386 initial_default_search_provider_.get() && | 407 initial_default_search_provider_.get() && |
| 387 (initial_default_search_provider_->keyword() == keyword)) ? | 408 (initial_default_search_provider_->keyword() == keyword)) ? |
| 388 initial_default_search_provider_.get() : NULL; | 409 initial_default_search_provider_.get() : NULL; |
| 389 } | 410 } |
| 390 | 411 |
| 391 TemplateURL* TemplateURLService::GetTemplateURLForGUID( | 412 TemplateURL* TemplateURLService::GetTemplateURLForGUID( |
| 392 const std::string& sync_guid) { | 413 const std::string& sync_guid) { |
| 393 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid)); | 414 GUIDToTURL::const_iterator elem(guid_to_turl_.find(sync_guid)); |
| 394 if (elem != guid_to_template_map_.end()) | 415 if (elem != guid_to_turl_.end()) |
| 395 return elem->second; | 416 return elem->second; |
| 396 return (!loaded_ && | 417 return (!loaded_ && |
| 397 initial_default_search_provider_.get() && | 418 initial_default_search_provider_.get() && |
| 398 (initial_default_search_provider_->sync_guid() == sync_guid)) ? | 419 (initial_default_search_provider_->sync_guid() == sync_guid)) ? |
| 399 initial_default_search_provider_.get() : NULL; | 420 initial_default_search_provider_.get() : NULL; |
| 400 } | 421 } |
| 401 | 422 |
| 402 TemplateURL* TemplateURLService::GetTemplateURLForHost( | 423 TemplateURL* TemplateURLService::GetTemplateURLForHost( |
| 403 const std::string& host) { | 424 const std::string& host) { |
| 404 if (loaded_) | 425 if (loaded_) |
| (...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1406 } | 1427 } |
| 1407 } | 1428 } |
| 1408 | 1429 |
| 1409 // Request a server check for the correct Google URL if Google is the | 1430 // Request a server check for the correct Google URL if Google is the |
| 1410 // default search engine. | 1431 // default search engine. |
| 1411 RequestGoogleURLTrackerServerCheckIfNecessary(); | 1432 RequestGoogleURLTrackerServerCheckIfNecessary(); |
| 1412 } | 1433 } |
| 1413 | 1434 |
| 1414 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { | 1435 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { |
| 1415 const base::string16& keyword = template_url->keyword(); | 1436 const base::string16& keyword = template_url->keyword(); |
| 1416 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); | 1437 DCHECK_NE(0U, keyword_to_turl_and_length_.count(keyword)); |
| 1417 if (keyword_to_template_map_[keyword] == template_url) { | 1438 if (keyword_to_turl_and_length_[keyword].first == template_url) { |
| 1418 // We need to check whether the keyword can now be provided by another | 1439 // We need to check whether the keyword can now be provided by another |
| 1419 // TemplateURL. See the comments in AddToMaps() for more information on | 1440 // TemplateURL. See the comments in AddToMaps() for more information on |
| 1420 // extension keywords and how they can coexist with non-extension keywords. | 1441 // extension keywords and how they can coexist with non-extension keywords. |
| 1421 // In the case of more than one extension, we use the most recently | 1442 // In the case of more than one extension, we use the most recently |
| 1422 // installed (which will be the most recently added, which will have the | 1443 // installed (which will be the most recently added, which will have the |
| 1423 // highest ID). | 1444 // highest ID). |
| 1424 TemplateURL* best_fallback = NULL; | 1445 TemplateURL* best_fallback = NULL; |
| 1425 for (TemplateURLVector::const_iterator i(template_urls_.begin()); | 1446 for (TemplateURLVector::const_iterator i(template_urls_.begin()); |
| 1426 i != template_urls_.end(); ++i) { | 1447 i != template_urls_.end(); ++i) { |
| 1427 TemplateURL* turl = *i; | 1448 TemplateURL* turl = *i; |
| 1428 // This next statement relies on the fact that there can only be one | 1449 // This next statement relies on the fact that there can only be one |
| 1429 // non-Omnibox API TemplateURL with a given keyword. | 1450 // non-Omnibox API TemplateURL with a given keyword. |
| 1430 if ((turl != template_url) && (turl->keyword() == keyword) && | 1451 if ((turl != template_url) && (turl->keyword() == keyword) && |
| 1431 (!best_fallback || | 1452 (!best_fallback || |
| 1432 (best_fallback->GetType() != TemplateURL::OMNIBOX_API_EXTENSION) || | 1453 (best_fallback->GetType() != TemplateURL::OMNIBOX_API_EXTENSION) || |
| 1433 ((turl->GetType() == TemplateURL::OMNIBOX_API_EXTENSION) && | 1454 ((turl->GetType() == TemplateURL::OMNIBOX_API_EXTENSION) && |
| 1434 (turl->id() > best_fallback->id())))) | 1455 (turl->id() > best_fallback->id())))) |
| 1435 best_fallback = turl; | 1456 best_fallback = turl; |
| 1436 } | 1457 } |
| 1437 if (best_fallback) | 1458 RemoveFromDomainMap(template_url); |
| 1438 keyword_to_template_map_[keyword] = best_fallback; | 1459 if (best_fallback) { |
| 1439 else | 1460 AddToMap(&keyword_to_turl_and_length_, keyword, best_fallback); |
| 1440 keyword_to_template_map_.erase(keyword); | 1461 AddToDomainMap(best_fallback); |
| 1462 } else { | |
| 1463 keyword_to_turl_and_length_.erase(keyword); | |
| 1464 } | |
| 1441 } | 1465 } |
| 1442 | 1466 |
| 1443 if (template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION) | 1467 if (template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION) |
| 1444 return; | 1468 return; |
| 1445 | 1469 |
| 1446 if (!template_url->sync_guid().empty()) | 1470 if (!template_url->sync_guid().empty()) |
| 1447 guid_to_template_map_.erase(template_url->sync_guid()); | 1471 guid_to_turl_.erase(template_url->sync_guid()); |
| 1448 // |provider_map_| is only initialized after loading has completed. | 1472 // |provider_map_| is only initialized after loading has completed. |
| 1449 if (loaded_) { | 1473 if (loaded_) { |
| 1450 provider_map_->Remove(template_url); | 1474 provider_map_->Remove(template_url); |
| 1451 } | 1475 } |
| 1452 } | 1476 } |
| 1453 | 1477 |
| 1454 void TemplateURLService::AddToMaps(TemplateURL* template_url) { | 1478 void TemplateURLService::AddToMaps(TemplateURL* template_url) { |
| 1455 bool template_url_is_omnibox_api = | 1479 bool template_url_is_omnibox_api = |
| 1456 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; | 1480 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; |
| 1457 const base::string16& keyword = template_url->keyword(); | 1481 const base::string16& keyword = template_url->keyword(); |
| 1458 KeywordToTemplateMap::const_iterator i = | 1482 KeywordToTURLAndMeaningfulLength::const_iterator i = |
| 1459 keyword_to_template_map_.find(keyword); | 1483 keyword_to_turl_and_length_.find(keyword); |
| 1460 if (i == keyword_to_template_map_.end()) { | 1484 if (i == keyword_to_turl_and_length_.end()) { |
| 1461 keyword_to_template_map_[keyword] = template_url; | 1485 AddToMap(&keyword_to_turl_and_length_, keyword, template_url); |
| 1486 AddToDomainMap(template_url); | |
| 1462 } else { | 1487 } else { |
| 1463 const TemplateURL* existing_url = i->second; | 1488 const TemplateURL* existing_url = i->second.first; |
| 1464 // We should only have overlapping keywords when at least one comes from | 1489 // We should only have overlapping keywords when at least one comes from |
| 1465 // an extension. In that case, the ranking order is: | 1490 // an extension. In that case, the ranking order is: |
| 1466 // Manually-modified keywords > extension keywords > replaceable keywords | 1491 // Manually-modified keywords > extension keywords > replaceable keywords |
| 1467 // When there are multiple extensions, the last-added wins. | 1492 // When there are multiple extensions, the last-added wins. |
| 1468 bool existing_url_is_omnibox_api = | 1493 bool existing_url_is_omnibox_api = |
| 1469 existing_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; | 1494 existing_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; |
| 1470 DCHECK(existing_url_is_omnibox_api || template_url_is_omnibox_api); | 1495 DCHECK(existing_url_is_omnibox_api || template_url_is_omnibox_api); |
| 1471 if (existing_url_is_omnibox_api ? | 1496 if (existing_url_is_omnibox_api ? |
| 1472 !CanReplace(template_url) : CanReplace(existing_url)) | 1497 !CanReplace(template_url) : CanReplace(existing_url)) { |
| 1473 keyword_to_template_map_[keyword] = template_url; | 1498 RemoveFromDomainMap(existing_url); |
| 1499 AddToMap(&keyword_to_turl_and_length_, keyword, template_url); | |
| 1500 AddToDomainMap(template_url); | |
| 1501 } | |
| 1474 } | 1502 } |
| 1475 | 1503 |
| 1476 if (template_url_is_omnibox_api) | 1504 if (template_url_is_omnibox_api) |
| 1477 return; | 1505 return; |
| 1478 | 1506 |
| 1479 if (!template_url->sync_guid().empty()) | 1507 if (!template_url->sync_guid().empty()) |
| 1480 guid_to_template_map_[template_url->sync_guid()] = template_url; | 1508 guid_to_turl_[template_url->sync_guid()] = template_url; |
| 1481 // |provider_map_| is only initialized after loading has completed. | 1509 // |provider_map_| is only initialized after loading has completed. |
| 1482 if (loaded_) | 1510 if (loaded_) |
| 1483 provider_map_->Add(template_url, search_terms_data()); | 1511 provider_map_->Add(template_url, search_terms_data()); |
| 1484 } | 1512 } |
| 1485 | 1513 |
| 1514 void TemplateURLService::RemoveFromDomainMap(const TemplateURL* template_url) { | |
| 1515 const base::string16 domain = GetDomainAndRegistry(template_url->keyword()); | |
| 1516 if (domain.empty()) | |
| 1517 return; | |
| 1518 | |
| 1519 const auto match_range( | |
|
Peter Kasting
2015/11/13 00:00:41
I just realized "auto" might not compile here; the
Mark P
2015/11/13 00:11:15
Acknowledged.
It compiled locally on linux. I'll
| |
| 1520 keyword_domain_to_turl_and_length_.equal_range(domain)); | |
| 1521 for (KeywordDomainToTURLAndMeaningfulLength::const_iterator | |
|
Peter Kasting
2015/11/13 00:00:41
OTOH, you almost certainly _can_ use auto here. A
Mark P
2015/11/13 00:11:14
Funny that it didn't hit a compiler error. Fixed.
| |
| 1522 it(match_range.first); it != match_range.second; ) { | |
| 1523 if (it->second.first == template_url) | |
| 1524 it = keyword_domain_to_turl_and_length_.erase(it); | |
| 1525 else | |
| 1526 ++it; | |
| 1527 } | |
| 1528 } | |
| 1529 | |
| 1530 void TemplateURLService::AddToDomainMap(TemplateURL* template_url) { | |
| 1531 const base::string16 domain = GetDomainAndRegistry(template_url->keyword()); | |
| 1532 // Only bother adding an entry to the domain map if its key in the domain | |
| 1533 // map would be different from the key in the regular map. | |
| 1534 if (domain != template_url->keyword()) | |
| 1535 AddToMap(&keyword_domain_to_turl_and_length_, domain, template_url); | |
| 1536 } | |
| 1537 | |
| 1538 // static | |
| 1539 template <typename Container> | |
| 1540 void TemplateURLService::AddToMap( | |
| 1541 Container* keyword_to_turl_and_length, | |
| 1542 const base::string16& keyword, | |
| 1543 TemplateURL* template_url) { | |
| 1544 keyword_to_turl_and_length->insert(std::make_pair( | |
| 1545 keyword, | |
| 1546 TURLAndMeaningfulLength( | |
| 1547 template_url, GetMeaningfulKeywordLength(keyword, template_url)))); | |
| 1548 } | |
| 1549 | |
| 1486 // Helper for partition() call in next function. | 1550 // Helper for partition() call in next function. |
| 1487 bool HasValidID(TemplateURL* t_url) { | 1551 bool HasValidID(TemplateURL* t_url) { |
| 1488 return t_url->id() != kInvalidTemplateURLID; | 1552 return t_url->id() != kInvalidTemplateURLID; |
| 1489 } | 1553 } |
| 1490 | 1554 |
| 1491 void TemplateURLService::SetTemplateURLs(TemplateURLVector* urls) { | 1555 void TemplateURLService::SetTemplateURLs(TemplateURLVector* urls) { |
| 1492 // Partition the URLs first, instead of implementing the loops below by simply | 1556 // Partition the URLs first, instead of implementing the loops below by simply |
| 1493 // scanning the input twice. While it's not supposed to happen normally, it's | 1557 // scanning the input twice. While it's not supposed to happen normally, it's |
| 1494 // possible for corrupt databases to return multiple entries with the same | 1558 // possible for corrupt databases to return multiple entries with the same |
| 1495 // keyword. In this case, the first loop may delete the first entry when | 1559 // keyword. In this case, the first loop may delete the first entry when |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1586 bool TemplateURLService::UpdateNoNotify(TemplateURL* existing_turl, | 1650 bool TemplateURLService::UpdateNoNotify(TemplateURL* existing_turl, |
| 1587 const TemplateURL& new_values) { | 1651 const TemplateURL& new_values) { |
| 1588 DCHECK(existing_turl); | 1652 DCHECK(existing_turl); |
| 1589 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == | 1653 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == |
| 1590 template_urls_.end()) | 1654 template_urls_.end()) |
| 1591 return false; | 1655 return false; |
| 1592 | 1656 |
| 1593 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, existing_turl->GetType()); | 1657 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, existing_turl->GetType()); |
| 1594 | 1658 |
| 1595 base::string16 old_keyword(existing_turl->keyword()); | 1659 base::string16 old_keyword(existing_turl->keyword()); |
| 1596 keyword_to_template_map_.erase(old_keyword); | 1660 keyword_to_turl_and_length_.erase(old_keyword); |
| 1661 RemoveFromDomainMap(existing_turl); | |
| 1597 if (!existing_turl->sync_guid().empty()) | 1662 if (!existing_turl->sync_guid().empty()) |
| 1598 guid_to_template_map_.erase(existing_turl->sync_guid()); | 1663 guid_to_turl_.erase(existing_turl->sync_guid()); |
| 1599 | 1664 |
| 1600 // |provider_map_| is only initialized after loading has completed. | 1665 // |provider_map_| is only initialized after loading has completed. |
| 1601 if (loaded_) | 1666 if (loaded_) |
| 1602 provider_map_->Remove(existing_turl); | 1667 provider_map_->Remove(existing_turl); |
| 1603 | 1668 |
| 1604 TemplateURLID previous_id = existing_turl->id(); | 1669 TemplateURLID previous_id = existing_turl->id(); |
| 1605 existing_turl->CopyFrom(new_values); | 1670 existing_turl->CopyFrom(new_values); |
| 1606 existing_turl->data_.id = previous_id; | 1671 existing_turl->data_.id = previous_id; |
| 1607 | 1672 |
| 1608 if (loaded_) { | 1673 if (loaded_) { |
| 1609 provider_map_->Add(existing_turl, search_terms_data()); | 1674 provider_map_->Add(existing_turl, search_terms_data()); |
| 1610 } | 1675 } |
| 1611 | 1676 |
| 1612 const base::string16& keyword = existing_turl->keyword(); | 1677 const base::string16& keyword = existing_turl->keyword(); |
| 1613 KeywordToTemplateMap::const_iterator i = | 1678 KeywordToTURLAndMeaningfulLength::const_iterator i = |
| 1614 keyword_to_template_map_.find(keyword); | 1679 keyword_to_turl_and_length_.find(keyword); |
| 1615 if (i == keyword_to_template_map_.end()) { | 1680 if (i == keyword_to_turl_and_length_.end()) { |
| 1616 keyword_to_template_map_[keyword] = existing_turl; | 1681 AddToMap(&keyword_to_turl_and_length_, keyword, existing_turl); |
| 1682 AddToDomainMap(existing_turl); | |
| 1617 } else { | 1683 } else { |
| 1618 // We can theoretically reach here in two cases: | 1684 // We can theoretically reach here in two cases: |
| 1619 // * There is an existing extension keyword and sync brings in a rename of | 1685 // * There is an existing extension keyword and sync brings in a rename of |
| 1620 // a non-extension keyword to match. In this case we just need to pick | 1686 // a non-extension keyword to match. In this case we just need to pick |
| 1621 // which keyword has priority to update the keyword map. | 1687 // which keyword has priority to update the keyword map. |
| 1622 // * Autogeneration of the keyword for a Google default search provider | 1688 // * Autogeneration of the keyword for a Google default search provider |
| 1623 // at load time causes it to conflict with an existing keyword. In this | 1689 // at load time causes it to conflict with an existing keyword. In this |
| 1624 // case we delete the existing keyword if it's replaceable, or else undo | 1690 // case we delete the existing keyword if it's replaceable, or else undo |
| 1625 // the change in keyword for |existing_turl|. | 1691 // the change in keyword for |existing_turl|. |
| 1626 TemplateURL* existing_keyword_turl = i->second; | 1692 TemplateURL* existing_keyword_turl = i->second.first; |
| 1627 if (existing_keyword_turl->GetType() != TemplateURL::NORMAL) { | 1693 if (existing_keyword_turl->GetType() != TemplateURL::NORMAL) { |
| 1628 if (!CanReplace(existing_turl)) | 1694 if (!CanReplace(existing_turl)) { |
| 1629 keyword_to_template_map_[keyword] = existing_turl; | 1695 AddToMap(&keyword_to_turl_and_length_, keyword, existing_turl); |
| 1696 AddToDomainMap(existing_turl); | |
| 1697 } | |
| 1630 } else { | 1698 } else { |
| 1631 if (CanReplace(existing_keyword_turl)) { | 1699 if (CanReplace(existing_keyword_turl)) { |
| 1632 RemoveNoNotify(existing_keyword_turl); | 1700 RemoveNoNotify(existing_keyword_turl); |
| 1633 } else { | 1701 } else { |
| 1634 existing_turl->data_.SetKeyword(old_keyword); | 1702 existing_turl->data_.SetKeyword(old_keyword); |
| 1635 keyword_to_template_map_[old_keyword] = existing_turl; | 1703 AddToMap(&keyword_to_turl_and_length_, old_keyword, existing_turl); |
| 1704 AddToDomainMap(existing_turl); | |
| 1636 } | 1705 } |
| 1637 } | 1706 } |
| 1638 } | 1707 } |
| 1639 if (!existing_turl->sync_guid().empty()) | 1708 if (!existing_turl->sync_guid().empty()) |
| 1640 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; | 1709 guid_to_turl_[existing_turl->sync_guid()] = existing_turl; |
| 1641 | 1710 |
| 1642 if (web_data_service_.get()) | 1711 if (web_data_service_.get()) |
| 1643 web_data_service_->UpdateKeyword(existing_turl->data()); | 1712 web_data_service_->UpdateKeyword(existing_turl->data()); |
| 1644 | 1713 |
| 1645 // Inform sync of the update. | 1714 // Inform sync of the update. |
| 1646 ProcessTemplateURLChange( | 1715 ProcessTemplateURLChange( |
| 1647 FROM_HERE, existing_turl, syncer::SyncChange::ACTION_UPDATE); | 1716 FROM_HERE, existing_turl, syncer::SyncChange::ACTION_UPDATE); |
| 1648 | 1717 |
| 1649 if (default_search_provider_ == existing_turl && | 1718 if (default_search_provider_ == existing_turl && |
| 1650 default_search_provider_source_ == DefaultSearchManager::FROM_USER) { | 1719 default_search_provider_source_ == DefaultSearchManager::FROM_USER) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1747 return; | 1816 return; |
| 1748 | 1817 |
| 1749 KeywordWebDataService::BatchModeScoper scoper(web_data_service_.get()); | 1818 KeywordWebDataService::BatchModeScoper scoper(web_data_service_.get()); |
| 1750 bool something_changed = false; | 1819 bool something_changed = false; |
| 1751 for (TemplateURLVector::iterator i(template_urls_.begin()); | 1820 for (TemplateURLVector::iterator i(template_urls_.begin()); |
| 1752 i != template_urls_.end(); ++i) { | 1821 i != template_urls_.end(); ++i) { |
| 1753 TemplateURL* t_url = *i; | 1822 TemplateURL* t_url = *i; |
| 1754 if (t_url->HasGoogleBaseURLs(search_terms_data())) { | 1823 if (t_url->HasGoogleBaseURLs(search_terms_data())) { |
| 1755 TemplateURL updated_turl(t_url->data()); | 1824 TemplateURL updated_turl(t_url->data()); |
| 1756 updated_turl.ResetKeywordIfNecessary(search_terms_data(), false); | 1825 updated_turl.ResetKeywordIfNecessary(search_terms_data(), false); |
| 1757 KeywordToTemplateMap::const_iterator existing_entry = | 1826 KeywordToTURLAndMeaningfulLength::const_iterator existing_entry = |
| 1758 keyword_to_template_map_.find(updated_turl.keyword()); | 1827 keyword_to_turl_and_length_.find(updated_turl.keyword()); |
| 1759 if ((existing_entry != keyword_to_template_map_.end()) && | 1828 if ((existing_entry != keyword_to_turl_and_length_.end()) && |
| 1760 (existing_entry->second != t_url)) { | 1829 (existing_entry->second.first != t_url)) { |
| 1761 // The new autogenerated keyword conflicts with another TemplateURL. | 1830 // The new autogenerated keyword conflicts with another TemplateURL. |
| 1762 // Overwrite it if it's replaceable; otherwise, leave |t_url| using its | 1831 // Overwrite it if it's replaceable; otherwise, leave |t_url| using its |
| 1763 // current keyword. (This will not prevent |t_url| from auto-updating | 1832 // current keyword. (This will not prevent |t_url| from auto-updating |
| 1764 // the keyword in the future if the conflicting TemplateURL disappears.) | 1833 // the keyword in the future if the conflicting TemplateURL disappears.) |
| 1765 // Note that we must still update |t_url| in this case, or the | 1834 // Note that we must still update |t_url| in this case, or the |
| 1766 // |provider_map_| will not be updated correctly. | 1835 // |provider_map_| will not be updated correctly. |
| 1767 if (CanReplace(existing_entry->second)) | 1836 if (CanReplace(existing_entry->second.first)) |
| 1768 RemoveNoNotify(existing_entry->second); | 1837 RemoveNoNotify(existing_entry->second.first); |
| 1769 else | 1838 else |
| 1770 updated_turl.data_.SetKeyword(t_url->keyword()); | 1839 updated_turl.data_.SetKeyword(t_url->keyword()); |
| 1771 } | 1840 } |
| 1772 something_changed = true; | 1841 something_changed = true; |
| 1773 // This will send the keyword change to sync. Note that other clients | 1842 // This will send the keyword change to sync. Note that other clients |
| 1774 // need to reset the keyword to an appropriate local value when this | 1843 // need to reset the keyword to an appropriate local value when this |
| 1775 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). | 1844 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). |
| 1776 UpdateNoNotify(t_url, updated_turl); | 1845 UpdateNoNotify(t_url, updated_turl); |
| 1777 } | 1846 } |
| 1778 } | 1847 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1957 } | 2026 } |
| 1958 template_urls_.push_back(template_url); | 2027 template_urls_.push_back(template_url); |
| 1959 AddToMaps(template_url); | 2028 AddToMaps(template_url); |
| 1960 | 2029 |
| 1961 if (newly_adding && | 2030 if (newly_adding && |
| 1962 (template_url->GetType() == TemplateURL::NORMAL)) { | 2031 (template_url->GetType() == TemplateURL::NORMAL)) { |
| 1963 if (web_data_service_.get()) | 2032 if (web_data_service_.get()) |
| 1964 web_data_service_->AddKeyword(template_url->data()); | 2033 web_data_service_->AddKeyword(template_url->data()); |
| 1965 | 2034 |
| 1966 // Inform sync of the addition. Note that this will assign a GUID to | 2035 // Inform sync of the addition. Note that this will assign a GUID to |
| 1967 // template_url and add it to the guid_to_template_map_. | 2036 // template_url and add it to the guid_to_turl_. |
| 1968 ProcessTemplateURLChange(FROM_HERE, | 2037 ProcessTemplateURLChange(FROM_HERE, |
| 1969 template_url, | 2038 template_url, |
| 1970 syncer::SyncChange::ACTION_ADD); | 2039 syncer::SyncChange::ACTION_ADD); |
| 1971 } | 2040 } |
| 1972 | 2041 |
| 1973 return true; | 2042 return true; |
| 1974 } | 2043 } |
| 1975 | 2044 |
| 1976 void TemplateURLService::RemoveNoNotify(TemplateURL* template_url) { | 2045 void TemplateURLService::RemoveNoNotify(TemplateURL* template_url) { |
| 1977 DCHECK(template_url != default_search_provider_); | 2046 DCHECK(template_url != default_search_provider_); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2273 if (new_guid.empty()) { | 2342 if (new_guid.empty()) { |
| 2274 default_search_manager_.ClearUserSelectedDefaultSearchEngine(); | 2343 default_search_manager_.ClearUserSelectedDefaultSearchEngine(); |
| 2275 return; | 2344 return; |
| 2276 } | 2345 } |
| 2277 | 2346 |
| 2278 TemplateURL* turl = GetTemplateURLForGUID(new_guid); | 2347 TemplateURL* turl = GetTemplateURLForGUID(new_guid); |
| 2279 if (turl) | 2348 if (turl) |
| 2280 default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data()); | 2349 default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data()); |
| 2281 } | 2350 } |
| 2282 | 2351 |
| 2352 template <typename Container> | |
| 2353 void TemplateURLService::AddMatchingKeywordsHelper( | |
| 2354 const Container& keyword_to_turl_and_length, | |
| 2355 const base::string16& prefix, | |
| 2356 bool supports_replacement_only, | |
| 2357 TURLsAndMeaningfulLengths* matches) { | |
| 2358 // Sanity check args. | |
| 2359 if (prefix.empty()) | |
| 2360 return; | |
| 2361 DCHECK(matches); | |
| 2362 | |
| 2363 // Find matching keyword range. Searches the element map for keywords | |
| 2364 // beginning with |prefix| and stores the endpoints of the resulting set in | |
| 2365 // |match_range|. | |
| 2366 const auto match_range(std::equal_range( | |
| 2367 keyword_to_turl_and_length.begin(), keyword_to_turl_and_length.end(), | |
| 2368 typename Container::value_type(prefix, | |
| 2369 TURLAndMeaningfulLength(nullptr, 0)), | |
| 2370 LessWithPrefix())); | |
| 2371 | |
| 2372 // Add to vector of matching keywords. | |
| 2373 for (typename Container::const_iterator i(match_range.first); | |
| 2374 i != match_range.second; ++i) { | |
| 2375 if (!supports_replacement_only || | |
| 2376 i->second.first->url_ref().SupportsReplacement(search_terms_data())) | |
| 2377 matches->push_back(i->second); | |
| 2378 } | |
| 2379 } | |
| 2380 | |
| 2283 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL( | 2381 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL( |
| 2284 int prepopulated_id) { | 2382 int prepopulated_id) { |
| 2285 for (TemplateURLVector::const_iterator i = template_urls_.begin(); | 2383 for (TemplateURLVector::const_iterator i = template_urls_.begin(); |
| 2286 i != template_urls_.end(); ++i) { | 2384 i != template_urls_.end(); ++i) { |
| 2287 if ((*i)->prepopulate_id() == prepopulated_id) | 2385 if ((*i)->prepopulate_id() == prepopulated_id) |
| 2288 return *i; | 2386 return *i; |
| 2289 } | 2387 } |
| 2290 return NULL; | 2388 return NULL; |
| 2291 } | 2389 } |
| 2292 | 2390 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2331 | 2429 |
| 2332 if (most_recently_intalled_default) { | 2430 if (most_recently_intalled_default) { |
| 2333 base::AutoReset<DefaultSearchChangeOrigin> change_origin( | 2431 base::AutoReset<DefaultSearchChangeOrigin> change_origin( |
| 2334 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION); | 2432 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION); |
| 2335 default_search_manager_.SetExtensionControlledDefaultSearchEngine( | 2433 default_search_manager_.SetExtensionControlledDefaultSearchEngine( |
| 2336 most_recently_intalled_default->data()); | 2434 most_recently_intalled_default->data()); |
| 2337 } else { | 2435 } else { |
| 2338 default_search_manager_.ClearExtensionControlledDefaultSearchEngine(); | 2436 default_search_manager_.ClearExtensionControlledDefaultSearchEngine(); |
| 2339 } | 2437 } |
| 2340 } | 2438 } |
| OLD | NEW |