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

Side by Side Diff: components/search_engines/template_url_service.cc

Issue 1411543011: Omnibox: Make Keyword Provide More Generous with Matching (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: finish converting AddToMap() calls Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/search_engines/template_url_service.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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(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(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(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(
1520 keyword_domain_to_turl_and_length_.equal_range(domain));
1521 for (auto it(match_range.first); it != match_range.second; ) {
1522 if (it->second.first == template_url)
1523 it = keyword_domain_to_turl_and_length_.erase(it);
1524 else
1525 ++it;
1526 }
1527 }
1528
1529 void TemplateURLService::AddToDomainMap(TemplateURL* template_url) {
1530 const base::string16 domain = GetDomainAndRegistry(template_url->keyword());
1531 // Only bother adding an entry to the domain map if its key in the domain
1532 // map would be different from the key in the regular map.
1533 if (domain != template_url->keyword()) {
1534 keyword_domain_to_turl_and_length_.insert(std::make_pair(
1535 domain,
1536 TURLAndMeaningfulLength(
1537 template_url, GetMeaningfulKeywordLength(domain, template_url))));
1538 }
1539 }
1540
1541 void TemplateURLService::AddToMap(TemplateURL* template_url) {
Mark P 2015/11/13 06:06:49 FYI, I had to revise this function. To see my cha
Mark P 2015/11/13 16:33:14 For the record, I realized I could do something me
1542 const base::string16& keyword = template_url->keyword();
1543 keyword_to_turl_and_length_[keyword] =
1544 TURLAndMeaningfulLength(
1545 template_url, GetMeaningfulKeywordLength(keyword, template_url));
1546 }
1547
1486 // Helper for partition() call in next function. 1548 // Helper for partition() call in next function.
1487 bool HasValidID(TemplateURL* t_url) { 1549 bool HasValidID(TemplateURL* t_url) {
1488 return t_url->id() != kInvalidTemplateURLID; 1550 return t_url->id() != kInvalidTemplateURLID;
1489 } 1551 }
1490 1552
1491 void TemplateURLService::SetTemplateURLs(TemplateURLVector* urls) { 1553 void TemplateURLService::SetTemplateURLs(TemplateURLVector* urls) {
1492 // Partition the URLs first, instead of implementing the loops below by simply 1554 // 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 1555 // 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 1556 // 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 1557 // 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
1586 bool TemplateURLService::UpdateNoNotify(TemplateURL* existing_turl, 1648 bool TemplateURLService::UpdateNoNotify(TemplateURL* existing_turl,
1587 const TemplateURL& new_values) { 1649 const TemplateURL& new_values) {
1588 DCHECK(existing_turl); 1650 DCHECK(existing_turl);
1589 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == 1651 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) ==
1590 template_urls_.end()) 1652 template_urls_.end())
1591 return false; 1653 return false;
1592 1654
1593 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, existing_turl->GetType()); 1655 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, existing_turl->GetType());
1594 1656
1595 base::string16 old_keyword(existing_turl->keyword()); 1657 base::string16 old_keyword(existing_turl->keyword());
1596 keyword_to_template_map_.erase(old_keyword); 1658 keyword_to_turl_and_length_.erase(old_keyword);
1659 RemoveFromDomainMap(existing_turl);
1597 if (!existing_turl->sync_guid().empty()) 1660 if (!existing_turl->sync_guid().empty())
1598 guid_to_template_map_.erase(existing_turl->sync_guid()); 1661 guid_to_turl_.erase(existing_turl->sync_guid());
1599 1662
1600 // |provider_map_| is only initialized after loading has completed. 1663 // |provider_map_| is only initialized after loading has completed.
1601 if (loaded_) 1664 if (loaded_)
1602 provider_map_->Remove(existing_turl); 1665 provider_map_->Remove(existing_turl);
1603 1666
1604 TemplateURLID previous_id = existing_turl->id(); 1667 TemplateURLID previous_id = existing_turl->id();
1605 existing_turl->CopyFrom(new_values); 1668 existing_turl->CopyFrom(new_values);
1606 existing_turl->data_.id = previous_id; 1669 existing_turl->data_.id = previous_id;
1607 1670
1608 if (loaded_) { 1671 if (loaded_) {
1609 provider_map_->Add(existing_turl, search_terms_data()); 1672 provider_map_->Add(existing_turl, search_terms_data());
1610 } 1673 }
1611 1674
1612 const base::string16& keyword = existing_turl->keyword(); 1675 const base::string16& keyword = existing_turl->keyword();
1613 KeywordToTemplateMap::const_iterator i = 1676 KeywordToTURLAndMeaningfulLength::const_iterator i =
1614 keyword_to_template_map_.find(keyword); 1677 keyword_to_turl_and_length_.find(keyword);
1615 if (i == keyword_to_template_map_.end()) { 1678 if (i == keyword_to_turl_and_length_.end()) {
1616 keyword_to_template_map_[keyword] = existing_turl; 1679 AddToMap(existing_turl);
1680 AddToDomainMap(existing_turl);
1617 } else { 1681 } else {
1618 // We can theoretically reach here in two cases: 1682 // We can theoretically reach here in two cases:
1619 // * There is an existing extension keyword and sync brings in a rename of 1683 // * 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 1684 // a non-extension keyword to match. In this case we just need to pick
1621 // which keyword has priority to update the keyword map. 1685 // which keyword has priority to update the keyword map.
1622 // * Autogeneration of the keyword for a Google default search provider 1686 // * Autogeneration of the keyword for a Google default search provider
1623 // at load time causes it to conflict with an existing keyword. In this 1687 // 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 1688 // case we delete the existing keyword if it's replaceable, or else undo
1625 // the change in keyword for |existing_turl|. 1689 // the change in keyword for |existing_turl|.
1626 TemplateURL* existing_keyword_turl = i->second; 1690 TemplateURL* existing_keyword_turl = i->second.first;
1627 if (existing_keyword_turl->GetType() != TemplateURL::NORMAL) { 1691 if (existing_keyword_turl->GetType() != TemplateURL::NORMAL) {
1628 if (!CanReplace(existing_turl)) 1692 if (!CanReplace(existing_turl)) {
1629 keyword_to_template_map_[keyword] = existing_turl; 1693 AddToMap(existing_turl);
1694 AddToDomainMap(existing_turl);
1695 }
1630 } else { 1696 } else {
1631 if (CanReplace(existing_keyword_turl)) { 1697 if (CanReplace(existing_keyword_turl)) {
1632 RemoveNoNotify(existing_keyword_turl); 1698 RemoveNoNotify(existing_keyword_turl);
1633 } else { 1699 } else {
1634 existing_turl->data_.SetKeyword(old_keyword); 1700 existing_turl->data_.SetKeyword(old_keyword);
1635 keyword_to_template_map_[old_keyword] = existing_turl; 1701 AddToMap(existing_turl);
1702 AddToDomainMap(existing_turl);
1636 } 1703 }
1637 } 1704 }
1638 } 1705 }
1639 if (!existing_turl->sync_guid().empty()) 1706 if (!existing_turl->sync_guid().empty())
1640 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; 1707 guid_to_turl_[existing_turl->sync_guid()] = existing_turl;
1641 1708
1642 if (web_data_service_.get()) 1709 if (web_data_service_.get())
1643 web_data_service_->UpdateKeyword(existing_turl->data()); 1710 web_data_service_->UpdateKeyword(existing_turl->data());
1644 1711
1645 // Inform sync of the update. 1712 // Inform sync of the update.
1646 ProcessTemplateURLChange( 1713 ProcessTemplateURLChange(
1647 FROM_HERE, existing_turl, syncer::SyncChange::ACTION_UPDATE); 1714 FROM_HERE, existing_turl, syncer::SyncChange::ACTION_UPDATE);
1648 1715
1649 if (default_search_provider_ == existing_turl && 1716 if (default_search_provider_ == existing_turl &&
1650 default_search_provider_source_ == DefaultSearchManager::FROM_USER) { 1717 default_search_provider_source_ == DefaultSearchManager::FROM_USER) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 return; 1814 return;
1748 1815
1749 KeywordWebDataService::BatchModeScoper scoper(web_data_service_.get()); 1816 KeywordWebDataService::BatchModeScoper scoper(web_data_service_.get());
1750 bool something_changed = false; 1817 bool something_changed = false;
1751 for (TemplateURLVector::iterator i(template_urls_.begin()); 1818 for (TemplateURLVector::iterator i(template_urls_.begin());
1752 i != template_urls_.end(); ++i) { 1819 i != template_urls_.end(); ++i) {
1753 TemplateURL* t_url = *i; 1820 TemplateURL* t_url = *i;
1754 if (t_url->HasGoogleBaseURLs(search_terms_data())) { 1821 if (t_url->HasGoogleBaseURLs(search_terms_data())) {
1755 TemplateURL updated_turl(t_url->data()); 1822 TemplateURL updated_turl(t_url->data());
1756 updated_turl.ResetKeywordIfNecessary(search_terms_data(), false); 1823 updated_turl.ResetKeywordIfNecessary(search_terms_data(), false);
1757 KeywordToTemplateMap::const_iterator existing_entry = 1824 KeywordToTURLAndMeaningfulLength::const_iterator existing_entry =
1758 keyword_to_template_map_.find(updated_turl.keyword()); 1825 keyword_to_turl_and_length_.find(updated_turl.keyword());
1759 if ((existing_entry != keyword_to_template_map_.end()) && 1826 if ((existing_entry != keyword_to_turl_and_length_.end()) &&
1760 (existing_entry->second != t_url)) { 1827 (existing_entry->second.first != t_url)) {
1761 // The new autogenerated keyword conflicts with another TemplateURL. 1828 // The new autogenerated keyword conflicts with another TemplateURL.
1762 // Overwrite it if it's replaceable; otherwise, leave |t_url| using its 1829 // Overwrite it if it's replaceable; otherwise, leave |t_url| using its
1763 // current keyword. (This will not prevent |t_url| from auto-updating 1830 // current keyword. (This will not prevent |t_url| from auto-updating
1764 // the keyword in the future if the conflicting TemplateURL disappears.) 1831 // the keyword in the future if the conflicting TemplateURL disappears.)
1765 // Note that we must still update |t_url| in this case, or the 1832 // Note that we must still update |t_url| in this case, or the
1766 // |provider_map_| will not be updated correctly. 1833 // |provider_map_| will not be updated correctly.
1767 if (CanReplace(existing_entry->second)) 1834 if (CanReplace(existing_entry->second.first))
1768 RemoveNoNotify(existing_entry->second); 1835 RemoveNoNotify(existing_entry->second.first);
1769 else 1836 else
1770 updated_turl.data_.SetKeyword(t_url->keyword()); 1837 updated_turl.data_.SetKeyword(t_url->keyword());
1771 } 1838 }
1772 something_changed = true; 1839 something_changed = true;
1773 // This will send the keyword change to sync. Note that other clients 1840 // 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 1841 // need to reset the keyword to an appropriate local value when this
1775 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). 1842 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData().
1776 UpdateNoNotify(t_url, updated_turl); 1843 UpdateNoNotify(t_url, updated_turl);
1777 } 1844 }
1778 } 1845 }
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1957 } 2024 }
1958 template_urls_.push_back(template_url); 2025 template_urls_.push_back(template_url);
1959 AddToMaps(template_url); 2026 AddToMaps(template_url);
1960 2027
1961 if (newly_adding && 2028 if (newly_adding &&
1962 (template_url->GetType() == TemplateURL::NORMAL)) { 2029 (template_url->GetType() == TemplateURL::NORMAL)) {
1963 if (web_data_service_.get()) 2030 if (web_data_service_.get())
1964 web_data_service_->AddKeyword(template_url->data()); 2031 web_data_service_->AddKeyword(template_url->data());
1965 2032
1966 // Inform sync of the addition. Note that this will assign a GUID to 2033 // 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_. 2034 // template_url and add it to the guid_to_turl_.
1968 ProcessTemplateURLChange(FROM_HERE, 2035 ProcessTemplateURLChange(FROM_HERE,
1969 template_url, 2036 template_url,
1970 syncer::SyncChange::ACTION_ADD); 2037 syncer::SyncChange::ACTION_ADD);
1971 } 2038 }
1972 2039
1973 return true; 2040 return true;
1974 } 2041 }
1975 2042
1976 void TemplateURLService::RemoveNoNotify(TemplateURL* template_url) { 2043 void TemplateURLService::RemoveNoNotify(TemplateURL* template_url) {
1977 DCHECK(template_url != default_search_provider_); 2044 DCHECK(template_url != default_search_provider_);
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
2273 if (new_guid.empty()) { 2340 if (new_guid.empty()) {
2274 default_search_manager_.ClearUserSelectedDefaultSearchEngine(); 2341 default_search_manager_.ClearUserSelectedDefaultSearchEngine();
2275 return; 2342 return;
2276 } 2343 }
2277 2344
2278 TemplateURL* turl = GetTemplateURLForGUID(new_guid); 2345 TemplateURL* turl = GetTemplateURLForGUID(new_guid);
2279 if (turl) 2346 if (turl)
2280 default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data()); 2347 default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data());
2281 } 2348 }
2282 2349
2350 template <typename Container>
2351 void TemplateURLService::AddMatchingKeywordsHelper(
2352 const Container& keyword_to_turl_and_length,
2353 const base::string16& prefix,
2354 bool supports_replacement_only,
2355 TURLsAndMeaningfulLengths* matches) {
2356 // Sanity check args.
2357 if (prefix.empty())
2358 return;
2359 DCHECK(matches);
2360
2361 // Find matching keyword range. Searches the element map for keywords
2362 // beginning with |prefix| and stores the endpoints of the resulting set in
2363 // |match_range|.
2364 const auto match_range(std::equal_range(
2365 keyword_to_turl_and_length.begin(), keyword_to_turl_and_length.end(),
2366 typename Container::value_type(prefix,
2367 TURLAndMeaningfulLength(nullptr, 0)),
2368 LessWithPrefix()));
2369
2370 // Add to vector of matching keywords.
2371 for (typename Container::const_iterator i(match_range.first);
2372 i != match_range.second; ++i) {
2373 if (!supports_replacement_only ||
2374 i->second.first->url_ref().SupportsReplacement(search_terms_data()))
2375 matches->push_back(i->second);
2376 }
2377 }
2378
2283 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL( 2379 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL(
2284 int prepopulated_id) { 2380 int prepopulated_id) {
2285 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2381 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2286 i != template_urls_.end(); ++i) { 2382 i != template_urls_.end(); ++i) {
2287 if ((*i)->prepopulate_id() == prepopulated_id) 2383 if ((*i)->prepopulate_id() == prepopulated_id)
2288 return *i; 2384 return *i;
2289 } 2385 }
2290 return NULL; 2386 return NULL;
2291 } 2387 }
2292 2388
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 2427
2332 if (most_recently_intalled_default) { 2428 if (most_recently_intalled_default) {
2333 base::AutoReset<DefaultSearchChangeOrigin> change_origin( 2429 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2334 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION); 2430 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION);
2335 default_search_manager_.SetExtensionControlledDefaultSearchEngine( 2431 default_search_manager_.SetExtensionControlledDefaultSearchEngine(
2336 most_recently_intalled_default->data()); 2432 most_recently_intalled_default->data());
2337 } else { 2433 } else {
2338 default_search_manager_.ClearExtensionControlledDefaultSearchEngine(); 2434 default_search_manager_.ClearExtensionControlledDefaultSearchEngine();
2339 } 2435 }
2340 } 2436 }
OLDNEW
« no previous file with comments | « components/search_engines/template_url_service.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698