Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/search_engines/template_url_service.h" | 5 #include "chrome/browser/search_engines/template_url_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1528 } | 1528 } |
| 1529 | 1529 |
| 1530 if (!template_url->sync_guid().empty()) | 1530 if (!template_url->sync_guid().empty()) |
| 1531 guid_to_template_map_[template_url->sync_guid()] = template_url; | 1531 guid_to_template_map_[template_url->sync_guid()] = template_url; |
| 1532 if (loaded_) { | 1532 if (loaded_) { |
| 1533 UIThreadSearchTermsData search_terms_data(profile_); | 1533 UIThreadSearchTermsData search_terms_data(profile_); |
| 1534 provider_map_->Add(template_url, search_terms_data); | 1534 provider_map_->Add(template_url, search_terms_data); |
| 1535 } | 1535 } |
| 1536 } | 1536 } |
| 1537 | 1537 |
| 1538 void TemplateURLService::SetTemplateURLs(const TemplateURLVector& urls) { | 1538 // Helper for partition() call in next function. |
| 1539 // Add mappings for the new items. | 1539 bool HasValidID(TemplateURL* t_url) { |
| 1540 return t_url->id() != kInvalidTemplateURLID; | |
| 1541 } | |
| 1540 | 1542 |
| 1541 // First, add the items that already have id's, so that the next_id_ | 1543 void TemplateURLService::SetTemplateURLs(TemplateURLVector* urls) { |
| 1542 // gets properly set. | 1544 // Partition the URLs first, instead of implementing the loops below by simply |
| 1543 for (TemplateURLVector::const_iterator i = urls.begin(); i != urls.end(); | 1545 // scanning the input twice. While it's not supposed to happen normally, it's |
| 1546 // possible for corrupt databases to return multiple entries with the same | |
| 1547 // keyword. In this case, the first loop may delete the first entry when | |
| 1548 // adding the second. If this happens, the second loop must not attempt to | |
| 1549 // access the deleted entry. Partitioning ensures this constraint. | |
| 1550 TemplateURLVector::iterator first_invalid( | |
| 1551 std::partition(urls->begin(), urls->end(), HasValidID)); | |
|
beaudoin
2013/09/14 03:24:03
Clever use of partition!
| |
| 1552 | |
| 1553 // First, add the items that already have id's, so that the next_id_ gets | |
| 1554 // properly set. | |
| 1555 for (TemplateURLVector::const_iterator i = urls->begin(); i != first_invalid; | |
| 1544 ++i) { | 1556 ++i) { |
| 1545 if ((*i)->id() != kInvalidTemplateURLID) { | 1557 next_id_ = std::max(next_id_, (*i)->id()); |
| 1546 next_id_ = std::max(next_id_, (*i)->id()); | 1558 AddNoNotify(*i, false); |
| 1547 AddNoNotify(*i, false); | |
| 1548 } | |
| 1549 } | 1559 } |
| 1550 | 1560 |
| 1551 // Next add the new items that don't have id's. | 1561 // Next add the new items that don't have id's. |
| 1552 for (TemplateURLVector::const_iterator i = urls.begin(); i != urls.end(); | 1562 for (TemplateURLVector::const_iterator i = first_invalid; i != urls->end(); |
| 1553 ++i) { | 1563 ++i) |
| 1554 if ((*i)->id() == kInvalidTemplateURLID) | 1564 AddNoNotify(*i, true); |
| 1555 AddNoNotify(*i, true); | 1565 |
| 1556 } | 1566 // Clear the input vector to reduce the chance callers will try to use a |
| 1567 // (possibly deleted) entry. | |
| 1568 urls->clear(); | |
| 1557 } | 1569 } |
| 1558 | 1570 |
| 1559 void TemplateURLService::ChangeToLoadedState() { | 1571 void TemplateURLService::ChangeToLoadedState() { |
| 1560 DCHECK(!loaded_); | 1572 DCHECK(!loaded_); |
| 1561 | 1573 |
| 1562 UIThreadSearchTermsData search_terms_data(profile_); | 1574 UIThreadSearchTermsData search_terms_data(profile_); |
| 1563 provider_map_->Init(template_urls_, search_terms_data); | 1575 provider_map_->Init(template_urls_, search_terms_data); |
| 1564 loaded_ = true; | 1576 loaded_ = true; |
| 1565 } | 1577 } |
| 1566 | 1578 |
| (...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2526 | 2538 |
| 2527 // Remove entries that were created because of policy as they may have | 2539 // Remove entries that were created because of policy as they may have |
| 2528 // changed since the database was saved. | 2540 // changed since the database was saved. |
| 2529 RemoveProvidersCreatedByPolicy(template_urls, | 2541 RemoveProvidersCreatedByPolicy(template_urls, |
| 2530 &default_search_provider, | 2542 &default_search_provider, |
| 2531 default_from_prefs.get()); | 2543 default_from_prefs.get()); |
| 2532 | 2544 |
| 2533 PatchMissingSyncGUIDs(template_urls); | 2545 PatchMissingSyncGUIDs(template_urls); |
| 2534 | 2546 |
| 2535 if (is_default_search_managed_) { | 2547 if (is_default_search_managed_) { |
| 2536 SetTemplateURLs(*template_urls); | 2548 SetTemplateURLs(template_urls); |
| 2537 | 2549 |
| 2538 if (TemplateURLsHaveSamePrefs(default_search_provider, | 2550 if (TemplateURLsHaveSamePrefs(default_search_provider, |
| 2539 default_from_prefs.get())) { | 2551 default_from_prefs.get())) { |
| 2540 // The value from the preferences was previously stored in the database. | 2552 // The value from the preferences was previously stored in the database. |
| 2541 // Reuse it. | 2553 // Reuse it. |
| 2542 } else { | 2554 } else { |
| 2543 // The value from the preferences takes over. | 2555 // The value from the preferences takes over. |
| 2544 default_search_provider = NULL; | 2556 default_search_provider = NULL; |
| 2545 if (default_from_prefs.get()) { | 2557 if (default_from_prefs.get()) { |
| 2546 TemplateURLData data(default_from_prefs->data()); | 2558 TemplateURLData data(default_from_prefs->data()); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2574 } | 2586 } |
| 2575 | 2587 |
| 2576 // If the default search provider existed previously, then just | 2588 // If the default search provider existed previously, then just |
| 2577 // set the member variable. Otherwise, we'll set it using the method | 2589 // set the member variable. Otherwise, we'll set it using the method |
| 2578 // to ensure that it is saved properly after its id is set. | 2590 // to ensure that it is saved properly after its id is set. |
| 2579 if (default_search_provider && | 2591 if (default_search_provider && |
| 2580 (default_search_provider->id() != kInvalidTemplateURLID)) { | 2592 (default_search_provider->id() != kInvalidTemplateURLID)) { |
| 2581 default_search_provider_ = default_search_provider; | 2593 default_search_provider_ = default_search_provider; |
| 2582 default_search_provider = NULL; | 2594 default_search_provider = NULL; |
| 2583 } | 2595 } |
| 2584 SetTemplateURLs(*template_urls); | 2596 SetTemplateURLs(template_urls); |
| 2585 | 2597 |
| 2586 if (default_search_provider) { | 2598 if (default_search_provider) { |
| 2587 // Note that this saves the default search provider to prefs. | 2599 // Note that this saves the default search provider to prefs. |
| 2588 SetDefaultSearchProvider(default_search_provider); | 2600 SetDefaultSearchProvider(default_search_provider); |
| 2589 } else { | 2601 } else { |
| 2590 // Always save the default search provider to prefs. That way we don't | 2602 // Always save the default search provider to prefs. That way we don't |
| 2591 // have to worry about it being out of sync. | 2603 // have to worry about it being out of sync. |
| 2592 if (default_search_provider_) | 2604 if (default_search_provider_) |
| 2593 SaveDefaultSearchProviderToPrefs(default_search_provider_); | 2605 SaveDefaultSearchProviderToPrefs(default_search_provider_); |
| 2594 } | 2606 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2626 const ExtensionKeyword& extension_keyword) const { | 2638 const ExtensionKeyword& extension_keyword) const { |
| 2627 TemplateURLData data; | 2639 TemplateURLData data; |
| 2628 data.short_name = UTF8ToUTF16(extension_keyword.extension_name); | 2640 data.short_name = UTF8ToUTF16(extension_keyword.extension_name); |
| 2629 data.SetKeyword(UTF8ToUTF16(extension_keyword.extension_keyword)); | 2641 data.SetKeyword(UTF8ToUTF16(extension_keyword.extension_keyword)); |
| 2630 // This URL is not actually used for navigation. It holds the extension's | 2642 // This URL is not actually used for navigation. It holds the extension's |
| 2631 // ID, as well as forcing the TemplateURL to be treated as a search keyword. | 2643 // ID, as well as forcing the TemplateURL to be treated as a search keyword. |
| 2632 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + | 2644 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + |
| 2633 extension_keyword.extension_id + "/?q={searchTerms}"); | 2645 extension_keyword.extension_id + "/?q={searchTerms}"); |
| 2634 return new TemplateURL(profile_, data); | 2646 return new TemplateURL(profile_, data); |
| 2635 } | 2647 } |
| OLD | NEW |