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 |