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

Side by Side Diff: chrome/browser/search_engines/template_url_service.cc

Issue 280113002: Revert of Use the DefaultSearchManager as the exclusive authority on DSE, ignoring Web Data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months 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 | Annotate | Revision Log
OLDNEW
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "sync/protocol/search_engine_specifics.pb.h" 51 #include "sync/protocol/search_engine_specifics.pb.h"
52 #include "sync/protocol/sync.pb.h" 52 #include "sync/protocol/sync.pb.h"
53 #include "ui/base/l10n/l10n_util.h" 53 #include "ui/base/l10n/l10n_util.h"
54 #include "url/gurl.h" 54 #include "url/gurl.h"
55 55
56 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet; 56 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet;
57 typedef TemplateURLService::SyncDataMap SyncDataMap; 57 typedef TemplateURLService::SyncDataMap SyncDataMap;
58 58
59 namespace { 59 namespace {
60 60
61 bool IdenticalSyncGUIDs(const TemplateURLData* data, const TemplateURL* turl) { 61 const char kFirstPotentialEngineHistogramName[] =
62 if (!data || !turl) 62 "Search.FirstPotentialEngineCalled";
63 return !data && !turl;
64 63
65 return data->sync_guid == turl->sync_guid(); 64 // Values for an enumerated histogram used to track whenever
66 } 65 // FirstPotentialDefaultEngine is called, and from where.
66 enum FirstPotentialEngineCaller {
67 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP,
68 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_PROCESSING_SYNC_CHANGES,
69 FIRST_POTENTIAL_CALLSITE_ON_LOAD,
70 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_SYNCING,
71 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_NOT_SYNCING,
72 FIRST_POTENTIAL_CALLSITE_MAX,
73 };
67 74
68 const char kDeleteSyncedEngineHistogramName[] = 75 const char kDeleteSyncedEngineHistogramName[] =
69 "Search.DeleteSyncedSearchEngine"; 76 "Search.DeleteSyncedSearchEngine";
70 77
71 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is 78 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is
72 // sent to the server for search engines. 79 // sent to the server for search engines.
73 enum DeleteSyncedSearchEngineEvent { 80 enum DeleteSyncedSearchEngineEvent {
74 DELETE_ENGINE_USER_ACTION, 81 DELETE_ENGINE_USER_ACTION,
75 DELETE_ENGINE_PRE_SYNC, 82 DELETE_ENGINE_PRE_SYNC,
76 DELETE_ENGINE_EMPTY_FIELD, 83 DELETE_ENGINE_EMPTY_FIELD,
77 DELETE_ENGINE_MAX, 84 DELETE_ENGINE_MAX,
78 }; 85 };
79 86
87 TemplateURL* FirstPotentialDefaultEngine(
88 const TemplateURLService::TemplateURLVector& template_urls) {
89 for (TemplateURLService::TemplateURLVector::const_iterator i(
90 template_urls.begin()); i != template_urls.end(); ++i) {
91 if ((*i)->ShowInDefaultList() &&
92 ((*i)->GetType() == TemplateURL::NORMAL))
93 return *i;
94 }
95 return NULL;
96 }
97
80 // Returns true iff the change in |change_list| at index |i| should not be sent 98 // Returns true iff the change in |change_list| at index |i| should not be sent
81 // up to the server based on its GUIDs presence in |sync_data| or when compared 99 // up to the server based on its GUIDs presence in |sync_data| or when compared
82 // to changes after it in |change_list|. 100 // to changes after it in |change_list|.
83 // The criteria is: 101 // The criteria is:
84 // 1) It is an ACTION_UPDATE or ACTION_DELETE and the sync_guid associated 102 // 1) It is an ACTION_UPDATE or ACTION_DELETE and the sync_guid associated
85 // with it is NOT found in |sync_data|. We can only update and remove 103 // with it is NOT found in |sync_data|. We can only update and remove
86 // entries that were originally from the Sync server. 104 // entries that were originally from the Sync server.
87 // 2) It is an ACTION_ADD and the sync_guid associated with it is found in 105 // 2) It is an ACTION_ADD and the sync_guid associated with it is found in
88 // |sync_data|. We cannot re-add entries that Sync already knew about. 106 // |sync_data|. We cannot re-add entries that Sync already knew about.
89 // 3) There is an update after an update for the same GUID. We prune earlier 107 // 3) There is an update after an update for the same GUID. We prune earlier
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 const KeywordToTemplateMap::value_type& elem2) const { 244 const KeywordToTemplateMap::value_type& elem2) const {
227 return (elem1.second == NULL) ? 245 return (elem1.second == NULL) ?
228 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) : 246 (elem2.first.compare(0, elem1.first.length(), elem1.first) > 0) :
229 (elem1.first < elem2.first); 247 (elem1.first < elem2.first);
230 } 248 }
231 }; 249 };
232 250
233 251
234 // TemplateURLService --------------------------------------------------------- 252 // TemplateURLService ---------------------------------------------------------
235 253
236 // static
237 bool TemplateURLService::g_fallback_search_engines_disabled = false;
238
239 TemplateURLService::TemplateURLService(Profile* profile) 254 TemplateURLService::TemplateURLService(Profile* profile)
240 : provider_map_(new SearchHostToURLsMap), 255 : provider_map_(new SearchHostToURLsMap),
241 profile_(profile), 256 profile_(profile),
242 loaded_(false), 257 loaded_(false),
243 load_failed_(false), 258 load_failed_(false),
244 load_handle_(0), 259 load_handle_(0),
245 default_search_provider_(NULL), 260 default_search_provider_(NULL),
261 is_default_search_managed_(false),
246 next_id_(kInvalidTemplateURLID + 1), 262 next_id_(kInvalidTemplateURLID + 1),
247 time_provider_(&base::Time::Now), 263 time_provider_(&base::Time::Now),
248 models_associated_(false), 264 models_associated_(false),
249 processing_syncer_changes_(false), 265 processing_syncer_changes_(false),
266 pending_synced_default_search_(false),
250 dsp_change_origin_(DSP_CHANGE_OTHER), 267 dsp_change_origin_(DSP_CHANGE_OTHER),
251 default_search_manager_( 268 default_search_manager_(
252 GetPrefs(), 269 GetPrefs(), DefaultSearchManager::ObserverCallback()) {
253 base::Bind(&TemplateURLService::OnDefaultSearchChange,
254 base::Unretained(this))) {
255 DCHECK(profile_); 270 DCHECK(profile_);
256 Init(NULL, 0); 271 Init(NULL, 0);
257 } 272 }
258 273
259 TemplateURLService::TemplateURLService(const Initializer* initializers, 274 TemplateURLService::TemplateURLService(const Initializer* initializers,
260 const int count) 275 const int count)
261 : provider_map_(new SearchHostToURLsMap), 276 : provider_map_(new SearchHostToURLsMap),
262 profile_(NULL), 277 profile_(NULL),
263 loaded_(false), 278 loaded_(false),
264 load_failed_(false), 279 load_failed_(false),
265 load_handle_(0), 280 load_handle_(0),
266 service_(NULL), 281 service_(NULL),
267 default_search_provider_(NULL), 282 default_search_provider_(NULL),
283 is_default_search_managed_(false),
268 next_id_(kInvalidTemplateURLID + 1), 284 next_id_(kInvalidTemplateURLID + 1),
269 time_provider_(&base::Time::Now), 285 time_provider_(&base::Time::Now),
270 models_associated_(false), 286 models_associated_(false),
271 processing_syncer_changes_(false), 287 processing_syncer_changes_(false),
288 pending_synced_default_search_(false),
272 dsp_change_origin_(DSP_CHANGE_OTHER), 289 dsp_change_origin_(DSP_CHANGE_OTHER),
273 default_search_manager_( 290 default_search_manager_(
274 GetPrefs(), 291 GetPrefs(), DefaultSearchManager::ObserverCallback()) {
275 base::Bind(&TemplateURLService::OnDefaultSearchChange,
276 base::Unretained(this))) {
277 Init(initializers, count); 292 Init(initializers, count);
278 } 293 }
279 294
280 TemplateURLService::~TemplateURLService() { 295 TemplateURLService::~TemplateURLService() {
281 // |service_| should be deleted during Shutdown(). 296 // |service_| should be deleted during Shutdown().
282 DCHECK(!service_); 297 DCHECK(!service_);
283 STLDeleteElements(&template_urls_); 298 STLDeleteElements(&template_urls_);
284 } 299 }
285 300
286 // static 301 // static
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 // case the term replaces the URL it's unlikely another keyword would have the 466 // case the term replaces the URL it's unlikely another keyword would have the
452 // same url. 467 // same url.
453 // TODO(jnd): Add additional parameters to get post data when the search URL 468 // TODO(jnd): Add additional parameters to get post data when the search URL
454 // has post parameters. 469 // has post parameters.
455 return GURL(search_ref.ReplaceSearchTermsUsingTermsData( 470 return GURL(search_ref.ReplaceSearchTermsUsingTermsData(
456 TemplateURLRef::SearchTermsArgs( 471 TemplateURLRef::SearchTermsArgs(
457 base::ASCIIToUTF16("blah.blah.blah.blah.blah")), 472 base::ASCIIToUTF16("blah.blah.blah.blah.blah")),
458 search_terms_data, NULL)); 473 search_terms_data, NULL));
459 } 474 }
460 475
461 // static
462 void TemplateURLService::SaveDefaultSearchProviderToPrefs( 476 void TemplateURLService::SaveDefaultSearchProviderToPrefs(
463 const TemplateURL* t_url, 477 const TemplateURL* t_url,
464 PrefService* prefs) { 478 PrefService* prefs) const {
465 if (!prefs) 479 if (!prefs || load_failed_)
466 return; 480 return;
467 481
468 bool enabled = false; 482 bool enabled = false;
469 std::string search_url; 483 std::string search_url;
470 std::string suggest_url; 484 std::string suggest_url;
471 std::string instant_url; 485 std::string instant_url;
472 std::string image_url; 486 std::string image_url;
473 std::string new_tab_url; 487 std::string new_tab_url;
474 std::string search_url_post_params; 488 std::string search_url_post_params;
475 std::string suggest_url_post_params; 489 std::string suggest_url_post_params;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 matches->push_back(i->second); 601 matches->push_back(i->second);
588 } 602 }
589 } 603 }
590 604
591 TemplateURL* TemplateURLService::GetTemplateURLForKeyword( 605 TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
592 const base::string16& keyword) { 606 const base::string16& keyword) {
593 KeywordToTemplateMap::const_iterator elem( 607 KeywordToTemplateMap::const_iterator elem(
594 keyword_to_template_map_.find(keyword)); 608 keyword_to_template_map_.find(keyword));
595 if (elem != keyword_to_template_map_.end()) 609 if (elem != keyword_to_template_map_.end())
596 return elem->second; 610 return elem->second;
597 return (!loaded_ && 611 return ((!loaded_ || load_failed_) &&
598 initial_default_search_provider_.get() && 612 initial_default_search_provider_.get() &&
599 (initial_default_search_provider_->keyword() == keyword)) ? 613 (initial_default_search_provider_->keyword() == keyword)) ?
600 initial_default_search_provider_.get() : NULL; 614 initial_default_search_provider_.get() : NULL;
601 } 615 }
602 616
603 TemplateURL* TemplateURLService::GetTemplateURLForGUID( 617 TemplateURL* TemplateURLService::GetTemplateURLForGUID(
604 const std::string& sync_guid) { 618 const std::string& sync_guid) {
605 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid)); 619 GUIDToTemplateMap::const_iterator elem(guid_to_template_map_.find(sync_guid));
606 if (elem != guid_to_template_map_.end()) 620 if (elem != guid_to_template_map_.end())
607 return elem->second; 621 return elem->second;
608 return (!loaded_ && 622 return ((!loaded_ || load_failed_) &&
609 initial_default_search_provider_.get() && 623 initial_default_search_provider_.get() &&
610 (initial_default_search_provider_->sync_guid() == sync_guid)) ? 624 (initial_default_search_provider_->sync_guid() == sync_guid)) ?
611 initial_default_search_provider_.get() : NULL; 625 initial_default_search_provider_.get() : NULL;
612 } 626 }
613 627
614 TemplateURL* TemplateURLService::GetTemplateURLForHost( 628 TemplateURL* TemplateURLService::GetTemplateURLForHost(
615 const std::string& host) { 629 const std::string& host) {
616 if (loaded_) { 630 if (loaded_) {
617 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host); 631 TemplateURL* t_url = provider_map_->GetTemplateURLForHost(host);
618 if (t_url) 632 if (t_url)
619 return t_url; 633 return t_url;
620 } 634 }
621 return (!loaded_ && 635 return ((!loaded_ || load_failed_) &&
622 initial_default_search_provider_.get() && 636 initial_default_search_provider_.get() &&
623 (GenerateSearchURL(initial_default_search_provider_.get()).host() == 637 (GenerateSearchURL(initial_default_search_provider_.get()).host() ==
624 host)) ? initial_default_search_provider_.get() : NULL; 638 host)) ? initial_default_search_provider_.get() : NULL;
625 } 639 }
626 640
627 bool TemplateURLService::Add(TemplateURL* template_url) { 641 void TemplateURLService::Add(TemplateURL* template_url) {
628 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 642 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
629 if (!AddNoNotify(template_url, true)) 643 if (AddNoNotify(template_url, true))
630 return false; 644 NotifyObservers();
631 NotifyObservers();
632 return true;
633 } 645 }
634 646
635 void TemplateURLService::AddAndSetProfile(TemplateURL* template_url, 647 void TemplateURLService::AddAndSetProfile(TemplateURL* template_url,
636 Profile* profile) { 648 Profile* profile) {
637 template_url->profile_ = profile; 649 template_url->profile_ = profile;
638 Add(template_url); 650 Add(template_url);
639 } 651 }
640 652
641 void TemplateURLService::AddWithOverrides(TemplateURL* template_url, 653 void TemplateURLService::AddWithOverrides(TemplateURL* template_url,
642 const base::string16& short_name, 654 const base::string16& short_name,
(...skipping 16 matching lines...) Expand all
659 DCHECK(info); 671 DCHECK(info);
660 DCHECK_EQ(info->wants_to_be_default_engine, 672 DCHECK_EQ(info->wants_to_be_default_engine,
661 template_url->show_in_default_list()); 673 template_url->show_in_default_list());
662 template_url->extension_info_.swap(info); 674 template_url->extension_info_.swap(info);
663 DCHECK(!FindTemplateURLForExtension( 675 DCHECK(!FindTemplateURLForExtension(
664 template_url->GetExtensionId(), 676 template_url->GetExtensionId(),
665 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)); 677 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION));
666 678
667 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 679 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
668 if (AddNoNotify(template_url, true)) { 680 if (AddNoNotify(template_url, true)) {
669 if (template_url->extension_info_->wants_to_be_default_engine) 681 // Note that we can't call CanMakeDefault() here, since it would return
670 UpdateExtensionDefaultSearchEngine(); 682 // false when another extension is already controlling the default search
683 // engine, and we want to allow new extensions to take over.
684 if (template_url->extension_info_->wants_to_be_default_engine &&
685 !is_default_search_managed()) {
686 TemplateURL* default_candidate = FindExtensionDefaultSearchEngine();
687 if (default_candidate == template_url) {
688 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
689 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION);
690 SetDefaultSearchProviderNoNotify(template_url);
691 }
692 }
671 NotifyObservers(); 693 NotifyObservers();
672 } 694 }
673 } 695 }
674 696
675 void TemplateURLService::Remove(TemplateURL* template_url) { 697 void TemplateURLService::Remove(TemplateURL* template_url) {
676 RemoveNoNotify(template_url); 698 RemoveNoNotify(template_url);
677 NotifyObservers(); 699 NotifyObservers();
678 } 700 }
679 701
680 void TemplateURLService::RemoveExtensionControlledTURL( 702 void TemplateURLService::RemoveExtensionControlledTURL(
681 const std::string& extension_id) { 703 const std::string& extension_id) {
682 DCHECK(loaded_); 704 DCHECK(loaded_);
683 TemplateURL* url = FindTemplateURLForExtension( 705 TemplateURL* url = FindTemplateURLForExtension(
684 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION); 706 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
685 if (!url) 707 if (!url)
686 return; 708 return;
687 // NULL this out so that we can call RemoveNoNotify. 709 bool restore_dse = (url == GetDefaultSearchProvider());
688 // UpdateExtensionDefaultSearchEngine will cause it to be reset. 710 if (restore_dse) {
689 if (default_search_provider_ == url) 711 DCHECK(!is_default_search_managed());
690 default_search_provider_ = NULL; 712 default_search_provider_ = NULL;
713 }
691 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 714 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
692 RemoveNoNotify(url); 715 RemoveNoNotify(url);
693 UpdateExtensionDefaultSearchEngine(); 716 if (restore_dse)
717 SetDefaultSearchProviderAfterRemovingDefaultExtension();
694 NotifyObservers(); 718 NotifyObservers();
695 } 719 }
696 720
697 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) { 721 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) {
698 RemoveAutoGeneratedBetween(created_after, base::Time()); 722 RemoveAutoGeneratedBetween(created_after, base::Time());
699 } 723 }
700 724
701 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after, 725 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after,
702 base::Time created_before) { 726 base::Time created_before) {
703 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before); 727 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 794
771 void TemplateURLService::ResetTemplateURL(TemplateURL* url, 795 void TemplateURLService::ResetTemplateURL(TemplateURL* url,
772 const base::string16& title, 796 const base::string16& title,
773 const base::string16& keyword, 797 const base::string16& keyword,
774 const std::string& search_url) { 798 const std::string& search_url) {
775 if (ResetTemplateURLNoNotify(url, title, keyword, search_url)) 799 if (ResetTemplateURLNoNotify(url, title, keyword, search_url))
776 NotifyObservers(); 800 NotifyObservers();
777 } 801 }
778 802
779 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { 803 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) {
780 return 804 return !is_default_search_managed() &&
781 ((default_search_provider_source_ == DefaultSearchManager::FROM_USER) || 805 !IsExtensionControlledDefaultSearch() &&
782 (default_search_provider_source_ == 806 (url != GetDefaultSearchProvider()) &&
783 DefaultSearchManager::FROM_FALLBACK)) && 807 url->url_ref().SupportsReplacement() &&
784 (url != GetDefaultSearchProvider()) && 808 (url->GetType() == TemplateURL::NORMAL);
785 url->url_ref().SupportsReplacement() &&
786 (url->GetType() == TemplateURL::NORMAL);
787 } 809 }
788 810
789 void TemplateURLService::SetUserSelectedDefaultSearchProvider( 811 void TemplateURLService::SetUserSelectedDefaultSearchProvider(
790 TemplateURL* url) { 812 TemplateURL* url) {
791 // Omnibox keywords cannot be made default. Extension-controlled search 813 SetDefaultSearchProvider(url);
792 // engines can be made default only by the extension itself because they 814 if (url)
793 // aren't persisted. 815 default_search_manager_.SetUserSelectedDefaultSearchEngine(url->data());
794 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL)); 816 else
795 if (load_failed_) { 817 default_search_manager_.ClearUserSelectedDefaultSearchEngine();
796 // Skip the DefaultSearchManager, which will persist to user preferences.
797 if ((default_search_provider_source_ == DefaultSearchManager::FROM_USER) ||
798 (default_search_provider_source_ ==
799 DefaultSearchManager::FROM_FALLBACK)) {
800 ApplyDefaultSearchChange(url ? &url->data() : NULL,
801 DefaultSearchManager::FROM_USER);
802 }
803 } else {
804 // We rely on the DefaultSearchManager to call OnDefaultSearchChange if, in
805 // fact, the effective DSE changes.
806 if (url)
807 default_search_manager_.SetUserSelectedDefaultSearchEngine(url->data());
808 else
809 default_search_manager_.ClearUserSelectedDefaultSearchEngine();
810 }
811 } 818 }
812 819
813 TemplateURL* TemplateURLService::GetDefaultSearchProvider() { 820 TemplateURL* TemplateURLService::GetDefaultSearchProvider() {
814 return loaded_ ? 821 return (loaded_ && !load_failed_) ?
815 default_search_provider_ : initial_default_search_provider_.get(); 822 default_search_provider_ : initial_default_search_provider_.get();
816 } 823 }
817 824
818 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider( 825 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider(
819 const GURL& url) { 826 const GURL& url) {
820 TemplateURL* default_provider = GetDefaultSearchProvider(); 827 TemplateURL* default_provider = GetDefaultSearchProvider();
821 return default_provider && default_provider->IsSearchURL(url); 828 return default_provider && default_provider->IsSearchURL(url);
822 } 829 }
823 830
824 bool TemplateURLService::IsExtensionControlledDefaultSearch() { 831 bool TemplateURLService::IsExtensionControlledDefaultSearch() {
825 return default_search_provider_source_ == 832 const TemplateURL* default_provider = GetDefaultSearchProvider();
826 DefaultSearchManager::FROM_EXTENSION; 833 return default_provider && (default_provider->GetType() ==
834 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
835 }
836
837 TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() {
838 // See if the prepopulated default still exists.
839 scoped_ptr<TemplateURLData> prepopulated_default =
840 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs());
841
842 for (TemplateURLVector::iterator i = template_urls_.begin();
843 i != template_urls_.end(); ++i) {
844 if ((*i)->prepopulate_id() == prepopulated_default->prepopulate_id)
845 return *i;
846 }
847 // If not, use the first non-extension keyword of the templates that supports
848 // search term replacement.
849 if (processing_syncer_changes_) {
850 UMA_HISTOGRAM_ENUMERATION(
851 kFirstPotentialEngineHistogramName,
852 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_PROCESSING_SYNC_CHANGES,
853 FIRST_POTENTIAL_CALLSITE_MAX);
854 } else {
855 if (sync_processor_.get()) {
856 // We're not currently in a sync cycle, but we're syncing.
857 UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
858 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_SYNCING,
859 FIRST_POTENTIAL_CALLSITE_MAX);
860 } else {
861 // We're not syncing at all.
862 UMA_HISTOGRAM_ENUMERATION(
863 kFirstPotentialEngineHistogramName,
864 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_NOT_SYNCING,
865 FIRST_POTENTIAL_CALLSITE_MAX);
866 }
867 }
868 return FirstPotentialDefaultEngine(template_urls_);
827 } 869 }
828 870
829 void TemplateURLService::RepairPrepopulatedSearchEngines() { 871 void TemplateURLService::RepairPrepopulatedSearchEngines() {
830 // Can't clean DB if it hasn't been loaded. 872 // Can't clean DB if it hasn't been loaded.
831 DCHECK(loaded()); 873 DCHECK(loaded());
832 874
833 if ((default_search_provider_source_ == DefaultSearchManager::FROM_USER) ||
834 (default_search_provider_source_ ==
835 DefaultSearchManager::FROM_FALLBACK)) {
836 // Clear |default_search_provider_| in case we want to remove the engine it
837 // points to. This will get reset at the end of the function anyway.
838 default_search_provider_ = NULL;
839 }
840
841 size_t default_search_provider_index = 0; 875 size_t default_search_provider_index = 0;
842 ScopedVector<TemplateURLData> prepopulated_urls = 876 ScopedVector<TemplateURLData> prepopulated_urls =
843 TemplateURLPrepopulateData::GetPrepopulatedEngines( 877 TemplateURLPrepopulateData::GetPrepopulatedEngines(
844 GetPrefs(), &default_search_provider_index); 878 GetPrefs(), &default_search_provider_index);
845 DCHECK(!prepopulated_urls.empty()); 879 DCHECK(!prepopulated_urls.empty());
880 int default_search_engine_id =
881 prepopulated_urls[default_search_provider_index]->prepopulate_id;
882 TemplateURL* current_dse = default_search_provider_;
846 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData( 883 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData(
847 &prepopulated_urls, template_urls_, default_search_provider_)); 884 &prepopulated_urls, template_urls_, current_dse));
848 885
849 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 886 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
850 887
851 // Remove items. 888 // Remove items.
852 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); 889 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin();
853 i < actions.removed_engines.end(); ++i) 890 i < actions.removed_engines.end(); ++i)
854 RemoveNoNotify(*i); 891 RemoveNoNotify(*i);
855 892
856 // Edit items. 893 // Edit items.
857 for (EditedEngines::iterator i(actions.edited_engines.begin()); 894 for (EditedEngines::iterator i(actions.edited_engines.begin());
858 i < actions.edited_engines.end(); ++i) { 895 i < actions.edited_engines.end(); ++i) {
859 UIThreadSearchTermsData search_terms_data(profile()); 896 UIThreadSearchTermsData search_terms_data(profile());
860 TemplateURL new_values(profile(), i->second); 897 TemplateURL new_values(profile(), i->second);
861 UpdateNoNotify(i->first, new_values, search_terms_data); 898 UpdateNoNotify(i->first, new_values, search_terms_data);
862 } 899 }
863 900
864 // Add items. 901 // Add items.
865 for (std::vector<TemplateURLData>::const_iterator i = 902 for (std::vector<TemplateURLData>::const_iterator i =
866 actions.added_engines.begin(); 903 actions.added_engines.begin();
867 i < actions.added_engines.end(); 904 i < actions.added_engines.end();
868 ++i) { 905 ++i) {
869 AddNoNotify(new TemplateURL(profile_, *i), true); 906 AddNoNotify(new TemplateURL(profile_, *i), true);
870 } 907 }
871 908
872 base::AutoReset<DefaultSearchChangeOrigin> change_origin( 909 // Change the DSE.
873 &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET); 910 TemplateURL* new_dse = FindURLByPrepopulateID(template_urls_,
874 911 default_search_engine_id);
875 default_search_manager_.ClearUserSelectedDefaultSearchEngine(); 912 DCHECK(new_dse);
876 913 if (CanMakeDefault(new_dse)) {
877 if (!default_search_provider_) { 914 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
878 DefaultSearchManager::Source source; 915 &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET);
879 const TemplateURLData* new_dse = 916 SetDefaultSearchProviderNoNotify(new_dse);
880 default_search_manager_.GetDefaultSearchEngine(&source);
881 // ApplyDefaultSearchChange will notify observers once it is done.
882 ApplyDefaultSearchChange(new_dse, source);
883 } else {
884 NotifyObservers();
885 } 917 }
918 NotifyObservers();
886 } 919 }
887 920
888 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) { 921 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) {
889 model_observers_.AddObserver(observer); 922 model_observers_.AddObserver(observer);
890 } 923 }
891 924
892 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) { 925 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) {
893 model_observers_.RemoveObserver(observer); 926 model_observers_.RemoveObserver(observer);
894 } 927 }
895 928
896 void TemplateURLService::Load() { 929 void TemplateURLService::Load() {
897 if (loaded_ || load_handle_) 930 if (loaded_ || load_handle_)
898 return; 931 return;
899 932
900 if (!service_) 933 if (!service_)
901 service_ = WebDataService::FromBrowserContext(profile_); 934 service_ = WebDataService::FromBrowserContext(profile_);
902 935
903 if (service_) 936 if (service_) {
904 load_handle_ = service_->GetKeywords(this); 937 load_handle_ = service_->GetKeywords(this);
905 else 938 } else {
906 ChangeToLoadedState(); 939 ChangeToLoadedState();
940 on_loaded_callbacks_.Notify();
941 }
907 } 942 }
908 943
909 scoped_ptr<TemplateURLService::Subscription> 944 scoped_ptr<TemplateURLService::Subscription>
910 TemplateURLService::RegisterOnLoadedCallback( 945 TemplateURLService::RegisterOnLoadedCallback(
911 const base::Closure& callback) { 946 const base::Closure& callback) {
912 return loaded_ ? 947 return loaded_ ?
913 scoped_ptr<TemplateURLService::Subscription>() : 948 scoped_ptr<TemplateURLService::Subscription>() :
914 on_loaded_callbacks_.Add(callback); 949 on_loaded_callbacks_.Add(callback);
915 } 950 }
916 951
917 void TemplateURLService::OnWebDataServiceRequestDone( 952 void TemplateURLService::OnWebDataServiceRequestDone(
918 WebDataService::Handle h, 953 WebDataService::Handle h,
919 const WDTypedResult* result) { 954 const WDTypedResult* result) {
920 // Reset the load_handle so that we don't try and cancel the load in 955 // Reset the load_handle so that we don't try and cancel the load in
921 // the destructor. 956 // the destructor.
922 load_handle_ = 0; 957 load_handle_ = 0;
923 958
924 if (!result) { 959 if (!result) {
925 // Results are null if the database went away or (most likely) wasn't 960 // Results are null if the database went away or (most likely) wasn't
926 // loaded. 961 // loaded.
927 load_failed_ = true; 962 load_failed_ = true;
928 service_ = NULL; 963 service_ = NULL;
929 ChangeToLoadedState(); 964 ChangeToLoadedState();
965 on_loaded_callbacks_.Notify();
930 return; 966 return;
931 } 967 }
932 968
969 // initial_default_search_provider_ is only needed before we've finished
970 // loading. Now that we've loaded we can nuke it.
971 initial_default_search_provider_.reset();
972
933 TemplateURLVector template_urls; 973 TemplateURLVector template_urls;
974 TemplateURL* default_search_provider = NULL;
934 int new_resource_keyword_version = 0; 975 int new_resource_keyword_version = 0;
935 GetSearchProvidersUsingKeywordResult( 976 GetSearchProvidersUsingKeywordResult(*result, service_.get(), profile_,
936 *result, 977 &template_urls, &default_search_provider, &new_resource_keyword_version,
937 service_.get(),
938 profile_,
939 &template_urls,
940 (default_search_provider_source_ == DefaultSearchManager::FROM_USER) ?
941 initial_default_search_provider_.get() : NULL,
942 &new_resource_keyword_version,
943 &pre_sync_deletes_); 978 &pre_sync_deletes_);
944 979
945 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 980 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
946 981
947 PatchMissingSyncGUIDs(&template_urls); 982 AddTemplateURLsAndSetupDefaultEngine(&template_urls, default_search_provider);
948 SetTemplateURLs(&template_urls);
949 983
950 // This initializes provider_map_ which should be done before 984 // This initializes provider_map_ which should be done before
951 // calling UpdateKeywordSearchTermsForURL. 985 // calling UpdateKeywordSearchTermsForURL.
952 // This also calls NotifyObservers.
953 ChangeToLoadedState(); 986 ChangeToLoadedState();
954 987
955 // Index any visits that occurred before we finished loading. 988 // Index any visits that occurred before we finished loading.
956 for (size_t i = 0; i < visits_to_add_.size(); ++i) 989 for (size_t i = 0; i < visits_to_add_.size(); ++i)
957 UpdateKeywordSearchTermsForURL(visits_to_add_[i]); 990 UpdateKeywordSearchTermsForURL(visits_to_add_[i]);
958 visits_to_add_.clear(); 991 visits_to_add_.clear();
959 992
960 if (new_resource_keyword_version) 993 if (new_resource_keyword_version)
961 service_->SetBuiltinKeywordVersion(new_resource_keyword_version); 994 service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
995
996 EnsureDefaultSearchProviderExists();
997
998 NotifyObservers();
999 on_loaded_callbacks_.Notify();
962 } 1000 }
963 1001
964 base::string16 TemplateURLService::GetKeywordShortName( 1002 base::string16 TemplateURLService::GetKeywordShortName(
965 const base::string16& keyword, 1003 const base::string16& keyword,
966 bool* is_omnibox_api_extension_keyword) { 1004 bool* is_omnibox_api_extension_keyword) {
967 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); 1005 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword);
968 1006
969 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService 1007 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService
970 // to track changes to the model, this should become a DCHECK. 1008 // to track changes to the model, this should become a DCHECK.
971 if (template_url) { 1009 if (template_url) {
972 *is_omnibox_api_extension_keyword = 1010 *is_omnibox_api_extension_keyword =
973 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; 1011 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION;
974 return template_url->AdjustedShortNameForLocaleDirection(); 1012 return template_url->AdjustedShortNameForLocaleDirection();
975 } 1013 }
976 *is_omnibox_api_extension_keyword = false; 1014 *is_omnibox_api_extension_keyword = false;
977 return base::string16(); 1015 return base::string16();
978 } 1016 }
979 1017
980 void TemplateURLService::Observe(int type, 1018 void TemplateURLService::Observe(int type,
981 const content::NotificationSource& source, 1019 const content::NotificationSource& source,
982 const content::NotificationDetails& details) { 1020 const content::NotificationDetails& details) {
983 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { 1021 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) {
984 content::Details<history::URLVisitedDetails> visit_details(details); 1022 content::Details<history::URLVisitedDetails> visit_details(details);
985 if (!loaded_) 1023 if (!loaded_)
986 visits_to_add_.push_back(*visit_details.ptr()); 1024 visits_to_add_.push_back(*visit_details.ptr());
987 else 1025 else
988 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); 1026 UpdateKeywordSearchTermsForURL(*visit_details.ptr());
1027 } else if (type == chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED) {
1028 // Policy has been updated, so the default search prefs may be different.
1029 // Reload the default search provider from them.
1030 // TODO(pkasting): Rather than communicating via prefs, we should eventually
1031 // observe policy changes directly.
1032 UpdateDefaultSearch();
989 } else { 1033 } else {
990 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type); 1034 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type);
991 if (loaded_) { 1035 if (loaded_) {
992 GoogleBaseURLChanged( 1036 GoogleBaseURLChanged(
993 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first); 1037 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first);
994 } 1038 }
995 } 1039 }
996 } 1040 }
997 1041
998 void TemplateURLService::Shutdown() { 1042 void TemplateURLService::Shutdown() {
999 // This check has to be done at Shutdown() instead of in the dtor to ensure 1043 // This check has to be done at Shutdown() instead of in the dtor to ensure
1000 // that no clients of WebDataService are holding ptrs to it after the first 1044 // that no clients of WebDataService are holding ptrs to it after the first
1001 // phase of the KeyedService Shutdown() process. 1045 // phase of the KeyedService Shutdown() process.
1002 if (load_handle_) { 1046 if (load_handle_) {
1003 DCHECK(service_.get()); 1047 DCHECK(service_.get());
1004 service_->CancelRequest(load_handle_); 1048 service_->CancelRequest(load_handle_);
1005 } 1049 }
1006 service_ = NULL; 1050 service_ = NULL;
1007 } 1051 }
1008 1052
1053 void TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged() {
1054 // Listen for changes to the default search from Sync.
1055 PrefService* prefs = GetPrefs();
1056 TemplateURL* new_default_search = GetTemplateURLForGUID(
1057 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID));
1058 if (new_default_search && !is_default_search_managed_) {
1059 if (new_default_search != GetDefaultSearchProvider()) {
1060 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
1061 &dsp_change_origin_, DSP_CHANGE_SYNC_PREF);
1062 SetUserSelectedDefaultSearchProvider(new_default_search);
1063 pending_synced_default_search_ = false;
1064 }
1065 } else {
1066 // If it's not there, or if default search is currently managed, set a
1067 // flag to indicate that we waiting on the search engine entry to come
1068 // in through Sync.
1069 pending_synced_default_search_ = true;
1070 }
1071 UpdateDefaultSearch();
1072 }
1073
1009 syncer::SyncDataList TemplateURLService::GetAllSyncData( 1074 syncer::SyncDataList TemplateURLService::GetAllSyncData(
1010 syncer::ModelType type) const { 1075 syncer::ModelType type) const {
1011 DCHECK_EQ(syncer::SEARCH_ENGINES, type); 1076 DCHECK_EQ(syncer::SEARCH_ENGINES, type);
1012 1077
1013 syncer::SyncDataList current_data; 1078 syncer::SyncDataList current_data;
1014 for (TemplateURLVector::const_iterator iter = template_urls_.begin(); 1079 for (TemplateURLVector::const_iterator iter = template_urls_.begin();
1015 iter != template_urls_.end(); ++iter) { 1080 iter != template_urls_.end(); ++iter) {
1016 // We don't sync keywords managed by policy. 1081 // We don't sync keywords managed by policy.
1017 if ((*iter)->created_by_policy()) 1082 if ((*iter)->created_by_policy())
1018 continue; 1083 continue;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 FROM_HERE, 1179 FROM_HERE,
1115 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); 1180 "ProcessSyncChanges failed on ChangeType ACTION_ADD");
1116 continue; 1181 continue;
1117 } 1182 }
1118 const std::string guid = turl->sync_guid(); 1183 const std::string guid = turl->sync_guid();
1119 if (existing_keyword_turl) { 1184 if (existing_keyword_turl) {
1120 // Resolve any conflicts so we can safely add the new entry. 1185 // Resolve any conflicts so we can safely add the new entry.
1121 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 1186 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1122 &new_changes); 1187 &new_changes);
1123 } 1188 }
1124 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
1125 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
1126 // Force the local ID to kInvalidTemplateURLID so we can add it. 1189 // Force the local ID to kInvalidTemplateURLID so we can add it.
1127 TemplateURLData data(turl->data()); 1190 TemplateURLData data(turl->data());
1128 data.id = kInvalidTemplateURLID; 1191 data.id = kInvalidTemplateURLID;
1129 TemplateURL* added = new TemplateURL(profile_, data); 1192 Add(new TemplateURL(profile_, data));
1130 if (Add(added)) 1193
1131 MaybeUpdateDSEAfterSync(added); 1194 // Possibly set the newly added |turl| as the default search provider.
1195 SetDefaultSearchProviderIfNewlySynced(guid);
1132 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { 1196 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) {
1133 if (!existing_turl) { 1197 if (!existing_turl) {
1134 error = sync_error_factory_->CreateAndUploadError( 1198 error = sync_error_factory_->CreateAndUploadError(
1135 FROM_HERE, 1199 FROM_HERE,
1136 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); 1200 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE");
1137 continue; 1201 continue;
1138 } 1202 }
1139 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) { 1203 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) {
1140 // Resolve any conflicts with other entries so we can safely update the 1204 // Resolve any conflicts with other entries so we can safely update the
1141 // keyword. 1205 // keyword.
1142 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 1206 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1143 &new_changes); 1207 &new_changes);
1144 } 1208 }
1145 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); 1209 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1146 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) { 1210 if (UpdateNoNotify(existing_turl, *turl, search_terms_data))
1147 NotifyObservers(); 1211 NotifyObservers();
1148 MaybeUpdateDSEAfterSync(existing_turl);
1149 }
1150 } else { 1212 } else {
1151 // We've unexpectedly received an ACTION_INVALID. 1213 // We've unexpectedly received an ACTION_INVALID.
1152 error = sync_error_factory_->CreateAndUploadError( 1214 error = sync_error_factory_->CreateAndUploadError(
1153 FROM_HERE, 1215 FROM_HERE,
1154 "ProcessSyncChanges received an ACTION_INVALID"); 1216 "ProcessSyncChanges received an ACTION_INVALID");
1155 } 1217 }
1156 } 1218 }
1157 1219
1158 // If something went wrong, we want to prematurely exit to avoid pushing 1220 // If something went wrong, we want to prematurely exit to avoid pushing
1159 // inconsistent data to Sync. We return the last error we received. 1221 // inconsistent data to Sync. We return the last error we received.
(...skipping 21 matching lines...) Expand all
1181 if (load_failed_) { 1243 if (load_failed_) {
1182 merge_result.set_error(syncer::SyncError( 1244 merge_result.set_error(syncer::SyncError(
1183 FROM_HERE, syncer::SyncError::DATATYPE_ERROR, 1245 FROM_HERE, syncer::SyncError::DATATYPE_ERROR,
1184 "Local database load failed.", syncer::SEARCH_ENGINES)); 1246 "Local database load failed.", syncer::SEARCH_ENGINES));
1185 return merge_result; 1247 return merge_result;
1186 } 1248 }
1187 1249
1188 sync_processor_ = sync_processor.Pass(); 1250 sync_processor_ = sync_processor.Pass();
1189 sync_error_factory_ = sync_error_factory.Pass(); 1251 sync_error_factory_ = sync_error_factory.Pass();
1190 1252
1253 // We just started syncing, so set our wait-for-default flag if we are
1254 // expecting a default from Sync.
1255 if (GetPrefs()) {
1256 std::string default_guid = GetPrefs()->GetString(
1257 prefs::kSyncedDefaultSearchProviderGUID);
1258 const TemplateURL* current_default = GetDefaultSearchProvider();
1259
1260 if (!default_guid.empty() &&
1261 (!current_default || current_default->sync_guid() != default_guid))
1262 pending_synced_default_search_ = true;
1263 }
1264
1191 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we 1265 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we
1192 // don't step on our own toes. 1266 // don't step on our own toes.
1193 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 1267 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
1194 1268
1195 // We've started syncing, so set our origin member to the base Sync value. 1269 // We've started syncing, so set our origin member to the base Sync value.
1196 // As we move through Sync Code, we may set this to increasingly specific 1270 // As we move through Sync Code, we may set this to increasingly specific
1197 // origins so we can tell what exactly caused a DSP change. 1271 // origins so we can tell what exactly caused a DSP change.
1198 base::AutoReset<DefaultSearchChangeOrigin> change_origin(&dsp_change_origin_, 1272 base::AutoReset<DefaultSearchChangeOrigin> change_origin(&dsp_change_origin_,
1199 DSP_CHANGE_SYNC_UNINTENTIONAL); 1273 DSP_CHANGE_SYNC_UNINTENTIONAL);
1200 1274
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 } else { 1333 } else {
1260 // The search engine from the cloud has not been synced locally. Merge it 1334 // The search engine from the cloud has not been synced locally. Merge it
1261 // into our local model. This will handle any conflicts with local (and 1335 // into our local model. This will handle any conflicts with local (and
1262 // already-synced) TemplateURLs. It will prefer to keep entries from Sync 1336 // already-synced) TemplateURLs. It will prefer to keep entries from Sync
1263 // over not-yet-synced TemplateURLs. 1337 // over not-yet-synced TemplateURLs.
1264 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes, 1338 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes,
1265 &local_data_map, &merge_result); 1339 &local_data_map, &merge_result);
1266 } 1340 }
1267 } 1341 }
1268 1342
1343 // If there is a pending synced default search provider that was processed
1344 // above, set it now.
1345 TemplateURL* pending_default = GetPendingSyncedDefaultSearchProvider();
1346 if (pending_default) {
1347 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
1348 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
1349 SetUserSelectedDefaultSearchProvider(pending_default);
1350 }
1351
1269 // The remaining SyncData in local_data_map should be everything that needs to 1352 // The remaining SyncData in local_data_map should be everything that needs to
1270 // be pushed as ADDs to sync. 1353 // be pushed as ADDs to sync.
1271 for (SyncDataMap::const_iterator iter = local_data_map.begin(); 1354 for (SyncDataMap::const_iterator iter = local_data_map.begin();
1272 iter != local_data_map.end(); ++iter) { 1355 iter != local_data_map.end(); ++iter) {
1273 new_changes.push_back( 1356 new_changes.push_back(
1274 syncer::SyncChange(FROM_HERE, 1357 syncer::SyncChange(FROM_HERE,
1275 syncer::SyncChange::ACTION_ADD, 1358 syncer::SyncChange::ACTION_ADD,
1276 iter->second)); 1359 iter->second));
1277 } 1360 }
1278 1361
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 profile_source); 1593 profile_source);
1511 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, 1594 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
1512 profile_source); 1595 profile_source);
1513 pref_change_registrar_.Init(GetPrefs()); 1596 pref_change_registrar_.Init(GetPrefs());
1514 pref_change_registrar_.Add( 1597 pref_change_registrar_.Add(
1515 prefs::kSyncedDefaultSearchProviderGUID, 1598 prefs::kSyncedDefaultSearchProviderGUID,
1516 base::Bind( 1599 base::Bind(
1517 &TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged, 1600 &TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged,
1518 base::Unretained(this))); 1601 base::Unretained(this)));
1519 } 1602 }
1520 1603 notification_registrar_.Add(
1521 DefaultSearchManager::Source source = DefaultSearchManager::FROM_USER; 1604 this, chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED,
1522 TemplateURLData* dse = 1605 content::NotificationService::AllSources());
1523 default_search_manager_.GetDefaultSearchEngine(&source);
1524 ApplyDefaultSearchChange(dse, source);
1525 1606
1526 if (num_initializers > 0) { 1607 if (num_initializers > 0) {
1527 // This path is only hit by test code and is used to simulate a loaded 1608 // This path is only hit by test code and is used to simulate a loaded
1528 // TemplateURLService. 1609 // TemplateURLService.
1529 ChangeToLoadedState(); 1610 ChangeToLoadedState();
1530 1611
1531 // Add specific initializers, if any. 1612 // Add specific initializers, if any.
1532 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 1613 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1533 for (int i(0); i < num_initializers; ++i) { 1614 for (int i(0); i < num_initializers; ++i) {
1534 DCHECK(initializers[i].keyword); 1615 DCHECK(initializers[i].keyword);
1535 DCHECK(initializers[i].url); 1616 DCHECK(initializers[i].url);
1536 DCHECK(initializers[i].content); 1617 DCHECK(initializers[i].content);
1537 1618
1538 // TemplateURLService ends up owning the TemplateURL, don't try and free 1619 // TemplateURLService ends up owning the TemplateURL, don't try and free
1539 // it. 1620 // it.
1540 TemplateURLData data; 1621 TemplateURLData data;
1541 data.short_name = base::UTF8ToUTF16(initializers[i].content); 1622 data.short_name = base::UTF8ToUTF16(initializers[i].content);
1542 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword)); 1623 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword));
1543 data.SetURL(initializers[i].url); 1624 data.SetURL(initializers[i].url);
1544 TemplateURL* template_url = new TemplateURL(profile_, data); 1625 TemplateURL* template_url = new TemplateURL(profile_, data);
1545 AddNoNotify(template_url, true); 1626 AddNoNotify(template_url, true);
1546 1627
1547 // Set the first provided identifier to be the default. 1628 // Set the first provided identifier to be the default.
1548 if (i == 0) 1629 if (i == 0)
1549 default_search_manager_.SetUserSelectedDefaultSearchEngine(data); 1630 SetDefaultSearchProviderNoNotify(template_url);
1550 } 1631 }
1551 } 1632 }
1552 1633
1634 // Initialize default search.
1635 UpdateDefaultSearch();
1636
1553 // Request a server check for the correct Google URL if Google is the 1637 // Request a server check for the correct Google URL if Google is the
1554 // default search engine and not in headless mode. 1638 // default search engine and not in headless mode.
1555 TemplateURL* default_search_provider = GetDefaultSearchProvider(); 1639 if (profile_ && initial_default_search_provider_ &&
1556 if (profile_ && default_search_provider && 1640 initial_default_search_provider_->HasGoogleBaseURLs()) {
1557 default_search_provider->HasGoogleBaseURLs()) {
1558 scoped_ptr<base::Environment> env(base::Environment::Create()); 1641 scoped_ptr<base::Environment> env(base::Environment::Create());
1559 if (!env->HasVar(env_vars::kHeadless)) 1642 if (!env->HasVar(env_vars::kHeadless))
1560 GoogleURLTracker::RequestServerCheck(profile_, false); 1643 GoogleURLTracker::RequestServerCheck(profile_, false);
1561 } 1644 }
1562 } 1645 }
1563 1646
1564 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { 1647 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) {
1565 const base::string16& keyword = template_url->keyword(); 1648 const base::string16& keyword = template_url->keyword();
1566 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); 1649 DCHECK_NE(0U, keyword_to_template_map_.count(keyword));
1567 if (keyword_to_template_map_[keyword] == template_url) { 1650 if (keyword_to_template_map_[keyword] == template_url) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1660 // (possibly deleted) entry. 1743 // (possibly deleted) entry.
1661 urls->clear(); 1744 urls->clear();
1662 } 1745 }
1663 1746
1664 void TemplateURLService::ChangeToLoadedState() { 1747 void TemplateURLService::ChangeToLoadedState() {
1665 DCHECK(!loaded_); 1748 DCHECK(!loaded_);
1666 1749
1667 UIThreadSearchTermsData search_terms_data(profile_); 1750 UIThreadSearchTermsData search_terms_data(profile_);
1668 provider_map_->Init(template_urls_, search_terms_data); 1751 provider_map_->Init(template_urls_, search_terms_data);
1669 loaded_ = true; 1752 loaded_ = true;
1753 }
1670 1754
1671 // This will cause a call to NotifyObservers(). 1755 void TemplateURLService::ClearDefaultProviderFromPrefs() {
1672 ApplyDefaultSearchChange(initial_default_search_provider_ ? 1756 // We overwrite user preferences. If the default search engine is managed,
1673 &initial_default_search_provider_->data() : NULL, 1757 // there is no effect.
1674 default_search_provider_source_); 1758 SaveDefaultSearchProviderToPrefs(NULL, GetPrefs());
1675 initial_default_search_provider_.reset(); 1759 // Default value for kDefaultSearchProviderEnabled is true.
1676 on_loaded_callbacks_.Notify(); 1760 PrefService* prefs = GetPrefs();
1761 if (prefs)
1762 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, true);
1677 } 1763 }
1678 1764
1679 bool TemplateURLService::CanReplaceKeywordForHost( 1765 bool TemplateURLService::CanReplaceKeywordForHost(
1680 const std::string& host, 1766 const std::string& host,
1681 TemplateURL** to_replace) { 1767 TemplateURL** to_replace) {
1682 DCHECK(!to_replace || !*to_replace); 1768 DCHECK(!to_replace || !*to_replace);
1683 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); 1769 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host);
1684 if (!urls) 1770 if (!urls)
1685 return true; 1771 return true;
1686 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { 1772 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 } 1849 }
1764 } 1850 }
1765 } 1851 }
1766 if (!existing_turl->sync_guid().empty()) 1852 if (!existing_turl->sync_guid().empty())
1767 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; 1853 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl;
1768 1854
1769 if (service_) 1855 if (service_)
1770 service_->UpdateKeyword(existing_turl->data()); 1856 service_->UpdateKeyword(existing_turl->data());
1771 1857
1772 // Inform sync of the update. 1858 // Inform sync of the update.
1773 ProcessTemplateURLChange( 1859 ProcessTemplateURLChange(FROM_HERE,
1774 FROM_HERE, existing_turl, syncer::SyncChange::ACTION_UPDATE); 1860 existing_turl,
1861 syncer::SyncChange::ACTION_UPDATE);
1775 1862
1776 if (default_search_provider_ == existing_turl && 1863 if (default_search_provider_ == existing_turl) {
1777 default_search_provider_source_ == DefaultSearchManager::FROM_USER) { 1864 bool success = SetDefaultSearchProviderNoNotify(existing_turl);
1778 default_search_manager_.SetUserSelectedDefaultSearchEngine( 1865 DCHECK(success);
1779 default_search_provider_->data());
1780 } 1866 }
1781 return true; 1867 return true;
1782 } 1868 }
1783 1869
1784 // static 1870 // static
1785 void TemplateURLService::UpdateTemplateURLIfPrepopulated( 1871 void TemplateURLService::UpdateTemplateURLIfPrepopulated(
1786 TemplateURL* template_url, 1872 TemplateURL* template_url,
1787 Profile* profile) { 1873 Profile* profile) {
1788 int prepopulate_id = template_url->prepopulate_id(); 1874 int prepopulate_id = template_url->prepopulate_id();
1789 if (template_url->prepopulate_id() == 0) 1875 if (template_url->prepopulate_id() == 0)
1790 return; 1876 return;
1791 1877
1792 size_t default_search_index; 1878 size_t default_search_index;
1793 ScopedVector<TemplateURLData> prepopulated_urls = 1879 ScopedVector<TemplateURLData> prepopulated_urls =
1794 TemplateURLPrepopulateData::GetPrepopulatedEngines( 1880 TemplateURLPrepopulateData::GetPrepopulatedEngines(
1795 profile ? profile->GetPrefs() : NULL, &default_search_index); 1881 profile ? profile->GetPrefs() : NULL, &default_search_index);
1796 1882
1797 for (size_t i = 0; i < prepopulated_urls.size(); ++i) { 1883 for (size_t i = 0; i < prepopulated_urls.size(); ++i) {
1798 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) { 1884 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) {
1799 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]); 1885 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]);
1800 template_url->CopyFrom(TemplateURL(profile, *prepopulated_urls[i])); 1886 template_url->CopyFrom(TemplateURL(profile, *prepopulated_urls[i]));
1801 } 1887 }
1802 } 1888 }
1803 } 1889 }
1804 1890
1805 void TemplateURLService::MaybeUpdateDSEAfterSync(TemplateURL* synced_turl) {
1806 if (GetPrefs() &&
1807 (synced_turl->sync_guid() ==
1808 GetPrefs()->GetString(prefs::kSyncedDefaultSearchProviderGUID))) {
1809 default_search_manager_.SetUserSelectedDefaultSearchEngine(
1810 synced_turl->data());
1811 }
1812 }
1813
1814 PrefService* TemplateURLService::GetPrefs() { 1891 PrefService* TemplateURLService::GetPrefs() {
1815 return profile_ ? profile_->GetPrefs() : NULL; 1892 return profile_ ? profile_->GetPrefs() : NULL;
1816 } 1893 }
1817 1894
1818 void TemplateURLService::UpdateKeywordSearchTermsForURL( 1895 void TemplateURLService::UpdateKeywordSearchTermsForURL(
1819 const history::URLVisitedDetails& details) { 1896 const history::URLVisitedDetails& details) {
1820 const history::URLRow& row = details.row; 1897 const history::URLRow& row = details.row;
1821 if (!row.url().is_valid()) 1898 if (!row.url().is_valid())
1822 return; 1899 return;
1823 1900
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1901 // need to reset the keyword to an appropriate local value when this 1978 // need to reset the keyword to an appropriate local value when this
1902 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). 1979 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData().
1903 UpdateNoNotify(t_url, updated_turl, 1980 UpdateNoNotify(t_url, updated_turl,
1904 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec())); 1981 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec()));
1905 } 1982 }
1906 } 1983 }
1907 if (something_changed) 1984 if (something_changed)
1908 NotifyObservers(); 1985 NotifyObservers();
1909 } 1986 }
1910 1987
1911 void TemplateURLService::OnDefaultSearchChange( 1988 void TemplateURLService::UpdateDefaultSearch() {
1912 const TemplateURLData* data,
1913 DefaultSearchManager::Source source) {
1914 if (GetPrefs() && (source == DefaultSearchManager::FROM_USER) &&
1915 ((source != default_search_provider_source_) ||
1916 !IdenticalSyncGUIDs(data, GetDefaultSearchProvider()))) {
1917 GetPrefs()->SetString(prefs::kSyncedDefaultSearchProviderGUID,
1918 data->sync_guid);
1919 }
1920 ApplyDefaultSearchChange(data, source);
1921 }
1922
1923 void TemplateURLService::ApplyDefaultSearchChange(
1924 const TemplateURLData* data,
1925 DefaultSearchManager::Source source) {
1926 if (!loaded_) { 1989 if (!loaded_) {
1927 // Set |initial_default_search_provider_| from the preferences. This is 1990 // Set |initial_default_search_provider_| from the preferences. We use this
1928 // mainly so we can hold ownership until we get to the point where the list 1991 // value for default search provider until the database has been loaded.
1929 // of keywords from Web Data is the owner of everything including the 1992 scoped_ptr<TemplateURLData> data;
1930 // default. 1993 if (!LoadDefaultSearchProviderFromPrefs(
1994 GetPrefs(), &data, &is_default_search_managed_)) {
1995 // Prefs does not specify, so rely on the prepopulated engines. This
1996 // should happen only the first time Chrome is started.
1997 data =
1998 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs());
1999 is_default_search_managed_ = false;
2000 }
2001
1931 initial_default_search_provider_.reset( 2002 initial_default_search_provider_.reset(
1932 data ? new TemplateURL(profile_, *data) : NULL); 2003 data ? new TemplateURL(profile_, *data) : NULL);
1933 default_search_provider_source_ = source; 2004
1934 return; 2005 return;
1935 } 2006 }
1936 2007 // Load the default search specified in prefs.
1937 // Prevent recursion if we update the value stored in default_search_manager_. 2008 scoped_ptr<TemplateURLData> new_default_from_prefs;
1938 // Note that we exclude the case of data == NULL because that could cause a 2009 bool new_is_default_managed = false;
1939 // false positive for recursion when the initial_default_search_provider_ is 2010 // Load the default from prefs. It's possible that it won't succeed
1940 // NULL due to policy. We'll never actually get recursion with data == NULL. 2011 // because we are in the middle of doing SaveDefaultSearchProviderToPrefs()
1941 if (source == default_search_provider_source_ && data != NULL && 2012 // and all the preference items have not been saved. In that case, we
1942 TemplateURL::MatchesData(default_search_provider_, data)) 2013 // don't have yet a default. It would be much better if we could save
2014 // preferences in batches and trigger notifications at the end.
2015 LoadDefaultSearchProviderFromPrefs(
2016 GetPrefs(), &new_default_from_prefs, &new_is_default_managed);
2017 if (!is_default_search_managed_ && !new_is_default_managed) {
2018 // We're not interested in cases where the default was and remains
2019 // unmanaged. In that case, preferences have no impact on the default.
1943 return; 2020 return;
1944 2021 }
1945 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchChangeOrigin",
1946 dsp_change_origin_, DSP_CHANGE_MAX);
1947
1948 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 2022 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1949 if (default_search_provider_source_ == DefaultSearchManager::FROM_POLICY || 2023 if (is_default_search_managed_ && new_is_default_managed) {
1950 source == DefaultSearchManager::FROM_POLICY) { 2024 // The default was managed and remains managed. Update the default only
1951 // We do this both to remove any no-longer-applicable policy-defined DSE as 2025 // if it has changed; we don't want to respond to changes triggered by
1952 // well as to add the new one, if appropriate. 2026 // SaveDefaultSearchProviderToPrefs.
1953 UpdateProvidersCreatedByPolicy( 2027 if (TemplateURL::MatchesData(default_search_provider_,
1954 &template_urls_, 2028 new_default_from_prefs.get()))
1955 source == DefaultSearchManager::FROM_POLICY ? data : NULL); 2029 return;
1956 } 2030 if (!new_default_from_prefs) {
1957 2031 // |default_search_provider_| can't be NULL or MatchesData() would have
1958 if (!data) { 2032 // returned true. Remove this now invalid value.
1959 default_search_provider_ = NULL; 2033 TemplateURL* old_default = default_search_provider_;
1960 default_search_provider_source_ = source; 2034 bool success = SetDefaultSearchProviderNoNotify(NULL);
1961 NotifyObservers(); 2035 DCHECK(success);
1962 return; 2036 RemoveNoNotify(old_default);
1963 } 2037 } else if (default_search_provider_) {
1964 2038 new_default_from_prefs->created_by_policy = true;
1965 if (source == DefaultSearchManager::FROM_EXTENSION) { 2039 TemplateURL new_values(profile_, *new_default_from_prefs);
1966 default_search_provider_ = FindMatchingExtensionTemplateURL(
1967 *data, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
1968 }
1969
1970 if (source == DefaultSearchManager::FROM_FALLBACK) {
1971 default_search_provider_ =
1972 FindPrepopulatedTemplateURL(data->prepopulate_id);
1973 if (default_search_provider_) {
1974 TemplateURLData update_data(*data);
1975 update_data.sync_guid = default_search_provider_->sync_guid();
1976 if (!default_search_provider_->safe_for_autoreplace()) {
1977 update_data.safe_for_autoreplace = false;
1978 update_data.SetKeyword(default_search_provider_->keyword());
1979 update_data.short_name = default_search_provider_->short_name();
1980 }
1981 UIThreadSearchTermsData search_terms_data( 2040 UIThreadSearchTermsData search_terms_data(
1982 default_search_provider_->profile()); 2041 default_search_provider_->profile());
1983 UpdateNoNotify(default_search_provider_, 2042 UpdateNoNotify(default_search_provider_, new_values, search_terms_data);
1984 TemplateURL(profile_, update_data),
1985 search_terms_data);
1986 } else { 2043 } else {
1987 // Normally the prepopulated fallback should be present in 2044 TemplateURL* new_template = NULL;
1988 // |template_urls_|, but in a few cases it might not be: 2045 if (new_default_from_prefs) {
1989 // (1) Tests that initialize the TemplateURLService in peculiar ways. 2046 new_default_from_prefs->created_by_policy = true;
1990 // (2) If the user deleted the pre-populated default and we subsequently 2047 new_template = new TemplateURL(profile_, *new_default_from_prefs);
1991 // lost their user-selected value. 2048 if (!AddNoNotify(new_template, true))
1992 TemplateURL* new_dse = new TemplateURL(profile_, *data); 2049 return;
1993 if (AddNoNotify(new_dse, true)) 2050 }
1994 default_search_provider_ = new_dse; 2051 bool success = SetDefaultSearchProviderNoNotify(new_template);
1995 } 2052 DCHECK(success);
1996 } 2053 }
1997 if (source == DefaultSearchManager::FROM_USER) { 2054 } else if (!is_default_search_managed_ && new_is_default_managed) {
1998 default_search_provider_ = GetTemplateURLForGUID(data->sync_guid); 2055 // The default used to be unmanaged and is now managed. Add the new
1999 if (!default_search_provider_ && data->prepopulate_id) { 2056 // managed default to the list of URLs and set it as default.
2000 default_search_provider_ = 2057 is_default_search_managed_ = new_is_default_managed;
2001 FindPrepopulatedTemplateURL(data->prepopulate_id); 2058 TemplateURL* new_template = NULL;
2002 } 2059 if (new_default_from_prefs) {
2003 TemplateURLData new_data(*data); 2060 new_default_from_prefs->created_by_policy = true;
2004 new_data.show_in_default_list = true; 2061 new_template = new TemplateURL(profile_, *new_default_from_prefs);
2005 if (default_search_provider_) { 2062 if (!AddNoNotify(new_template, true))
2006 UIThreadSearchTermsData search_terms_data( 2063 return;
2007 default_search_provider_->profile()); 2064 }
2008 UpdateNoNotify(default_search_provider_, 2065 bool success = SetDefaultSearchProviderNoNotify(new_template);
2009 TemplateURL(profile_, new_data), 2066 DCHECK(success);
2010 search_terms_data); 2067 } else {
2068 // The default was managed and is no longer.
2069 DCHECK(is_default_search_managed_ && !new_is_default_managed);
2070 is_default_search_managed_ = new_is_default_managed;
2071 // If we had a default, delete the previous default if created by policy
2072 // and set a likely default.
2073 if ((default_search_provider_ != NULL) &&
2074 default_search_provider_->created_by_policy()) {
2075 TemplateURL* old_default = default_search_provider_;
2076 default_search_provider_ = NULL;
2077 RemoveNoNotify(old_default);
2078 }
2079
2080 // The likely default should be from Sync if we were waiting on Sync.
2081 // Otherwise, it should be FindNewDefaultSearchProvider.
2082 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
2083 if (synced_default) {
2084 pending_synced_default_search_ = false;
2085
2086 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2087 &dsp_change_origin_, DSP_CHANGE_SYNC_NOT_MANAGED);
2088 SetDefaultSearchProviderNoNotify(synced_default);
2011 } else { 2089 } else {
2012 new_data.id = kInvalidTemplateURLID; 2090 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
2013 TemplateURL* new_dse = new TemplateURL(profile_, new_data); 2091 }
2014 if (AddNoNotify(new_dse, true)) 2092 }
2015 default_search_provider_ = new_dse; 2093 NotifyObservers();
2016 } 2094 }
2017 if (default_search_provider_ && GetPrefs()) { 2095
2018 GetPrefs()->SetString( 2096 void TemplateURLService::SetDefaultSearchProvider(
2019 prefs::kSyncedDefaultSearchProviderGUID, 2097 TemplateURL* url) {
2020 default_search_provider_->sync_guid()); 2098 DCHECK(!is_default_search_managed_);
2021 } 2099 // Omnibox keywords cannot be made default. Extension-controlled search
2022 2100 // engines can be made default only by the extension itself because they
2023 } 2101 // aren't persisted.
2024 2102 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL));
2025 default_search_provider_source_ = source; 2103
2026 2104 // Always persist the setting in the database, that way if the backup
2027 if (default_search_provider_ && 2105 // signature has changed out from under us it gets reset correctly.
2028 default_search_provider_->HasGoogleBaseURLs()) { 2106 if (SetDefaultSearchProviderNoNotify(url))
2029 if (profile_) 2107 NotifyObservers();
2108 }
2109
2110 bool TemplateURLService::SetDefaultSearchProviderNoNotify(TemplateURL* url) {
2111 if (url) {
2112 if (std::find(template_urls_.begin(), template_urls_.end(), url) ==
2113 template_urls_.end())
2114 return false;
2115 // Omnibox keywords cannot be made default.
2116 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, url->GetType());
2117 }
2118
2119 // Only bother reassigning |url| if it has changed. Notice that we don't just
2120 // early exit if they are equal, because |url| may have had its fields
2121 // changed, and needs to be persisted below (for example, when this is called
2122 // from UpdateNoNotify).
2123 if (default_search_provider_ != url) {
2124 // Engines set by policy override extension-controlled engines, which
2125 // override other engines.
2126 DCHECK(!is_default_search_managed() || !url ||
2127 (url->GetType() == TemplateURL::NORMAL));
2128 if (is_default_search_managed() || !default_search_provider_ ||
2129 (default_search_provider_->GetType() == TemplateURL::NORMAL) ||
2130 (url &&
2131 (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION))){
2132 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchChangeOrigin",
2133 dsp_change_origin_, DSP_CHANGE_MAX);
2134 default_search_provider_ = url;
2135 }
2136 }
2137
2138 if (url) {
2139 // Don't mark the url as edited, otherwise we won't be able to rev the
2140 // template urls we ship with.
2141 url->data_.show_in_default_list = true;
2142 if (service_ && (url->GetType() == TemplateURL::NORMAL))
2143 service_->UpdateKeyword(url->data());
2144
2145 if (url->HasGoogleBaseURLs()) {
2030 GoogleURLTracker::RequestServerCheck(profile_, false); 2146 GoogleURLTracker::RequestServerCheck(profile_, false);
2031 #if defined(ENABLE_RLZ) 2147 #if defined(ENABLE_RLZ)
2032 RLZTracker::RecordProductEvent(rlz_lib::CHROME, 2148 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
2033 RLZTracker::CHROME_OMNIBOX, 2149 RLZTracker::CHROME_OMNIBOX,
2034 rlz_lib::SET_TO_GOOGLE); 2150 rlz_lib::SET_TO_GOOGLE);
2035 #endif 2151 #endif
2036 } 2152 }
2037 2153 }
2038 NotifyObservers(); 2154
2155 // Extension-controlled search engines shouldn't be persisted anywhere.
2156 if (url && (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION))
2157 return true;
2158
2159 if (!is_default_search_managed_) {
2160 SaveDefaultSearchProviderToPrefs(url, GetPrefs());
2161
2162 // If we are syncing, we want to set the synced pref that will notify other
2163 // instances to change their default to this new search provider.
2164 // Note: we don't update the pref if we're currently in the middle of
2165 // handling a sync operation. Sync operations from other clients are not
2166 // guaranteed to arrive together, and any client that deletes the default
2167 // needs to set a new default as well. If we update the default here, we're
2168 // likely to race with the update from the other client, resulting in
2169 // a possibly random default search provider.
2170 if (sync_processor_.get() && url && !url->sync_guid().empty() &&
2171 GetPrefs() && !processing_syncer_changes_) {
2172 GetPrefs()->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2173 url->sync_guid());
2174 }
2175 }
2176
2177 if (service_)
2178 service_->SetDefaultSearchProviderID(url ? url->id() : 0);
2179
2180 // Inform sync the change to the show_in_default_list flag.
2181 if (url)
2182 ProcessTemplateURLChange(FROM_HERE,
2183 url,
2184 syncer::SyncChange::ACTION_UPDATE);
2185 return true;
2039 } 2186 }
2040 2187
2041 bool TemplateURLService::AddNoNotify(TemplateURL* template_url, 2188 bool TemplateURLService::AddNoNotify(TemplateURL* template_url,
2042 bool newly_adding) { 2189 bool newly_adding) {
2043 DCHECK(template_url); 2190 DCHECK(template_url);
2044 2191
2045 if (newly_adding) { 2192 if (newly_adding) {
2046 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); 2193 DCHECK_EQ(kInvalidTemplateURLID, template_url->id());
2047 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), 2194 DCHECK(std::find(template_urls_.begin(), template_urls_.end(),
2048 template_url) == template_urls_.end()); 2195 template_url) == template_urls_.end());
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 TemplateURLData data(url->data()); 2290 TemplateURLData data(url->data());
2144 data.short_name = title; 2291 data.short_name = title;
2145 data.SetKeyword(keyword); 2292 data.SetKeyword(keyword);
2146 if (search_url != data.url()) { 2293 if (search_url != data.url()) {
2147 data.SetURL(search_url); 2294 data.SetURL(search_url);
2148 // The urls have changed, reset the favicon url. 2295 // The urls have changed, reset the favicon url.
2149 data.favicon_url = GURL(); 2296 data.favicon_url = GURL();
2150 } 2297 }
2151 data.safe_for_autoreplace = false; 2298 data.safe_for_autoreplace = false;
2152 data.last_modified = time_provider_(); 2299 data.last_modified = time_provider_();
2300 TemplateURL new_url(url->profile(), data);
2153 UIThreadSearchTermsData search_terms_data(url->profile()); 2301 UIThreadSearchTermsData search_terms_data(url->profile());
2154 return UpdateNoNotify(url, TemplateURL(profile_, data), search_terms_data); 2302 return UpdateNoNotify(url, new_url, search_terms_data);
2155 } 2303 }
2156 2304
2157 void TemplateURLService::NotifyObservers() { 2305 void TemplateURLService::NotifyObservers() {
2158 if (!loaded_) 2306 if (!loaded_)
2159 return; 2307 return;
2160 2308
2161 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_, 2309 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_,
2162 OnTemplateURLServiceChanged()); 2310 OnTemplateURLServiceChanged());
2163 } 2311 }
2164 2312
2165 // |template_urls| are the TemplateURLs loaded from the database. 2313 // |template_urls| are the TemplateURLs loaded from the database.
2166 // |default_from_prefs| is the default search provider from the preferences, or 2314 // |default_search_provider| points to one of them, if it was set in the db.
2167 // NULL if the DSE is not policy-defined. 2315 // |default_from_prefs| is the default search provider from the preferences.
2316 // Check |is_default_search_managed_| to determine if it was set by policy.
2168 // 2317 //
2169 // This function removes from the vector and the database all the TemplateURLs 2318 // This function removes from the vector and the database all the TemplateURLs
2170 // that were set by policy, unless it is the current default search provider, in 2319 // that were set by policy, unless it is the current default search provider
2171 // which case it is updated with the data from prefs. 2320 // and matches what is set by a managed preference.
2172 void TemplateURLService::UpdateProvidersCreatedByPolicy( 2321 void TemplateURLService::RemoveProvidersCreatedByPolicy(
2173 TemplateURLVector* template_urls, 2322 TemplateURLVector* template_urls,
2174 const TemplateURLData* default_from_prefs) { 2323 TemplateURL** default_search_provider,
2324 TemplateURLData* default_from_prefs) {
2175 DCHECK(template_urls); 2325 DCHECK(template_urls);
2176 2326 DCHECK(default_search_provider);
2177 for (TemplateURLVector::iterator i = template_urls->begin(); 2327 for (TemplateURLVector::iterator i = template_urls->begin();
2178 i != template_urls->end(); ) { 2328 i != template_urls->end(); ) {
2179 TemplateURL* template_url = *i; 2329 TemplateURL* template_url = *i;
2180 if (template_url->created_by_policy()) { 2330 if (template_url->created_by_policy()) {
2181 if (default_from_prefs && 2331 if (template_url == *default_search_provider &&
2332 is_default_search_managed_ &&
2182 TemplateURL::MatchesData(template_url, default_from_prefs)) { 2333 TemplateURL::MatchesData(template_url, default_from_prefs)) {
2183 // If the database specified a default search provider that was set 2334 // If the database specified a default search provider that was set
2184 // by policy, and the default search provider from the preferences 2335 // by policy, and the default search provider from the preferences
2185 // is also set by policy and they are the same, keep the entry in the 2336 // is also set by policy and they are the same, keep the entry in the
2186 // database and the |default_search_provider|. 2337 // database and the |default_search_provider|.
2187 default_search_provider_ = template_url;
2188 // Prevent us from saving any other entries, or creating a new one.
2189 default_from_prefs = NULL;
2190 ++i; 2338 ++i;
2191 continue; 2339 continue;
2192 } 2340 }
2193 2341
2194 RemoveFromMaps(template_url); 2342 // The database loaded a managed |default_search_provider|, but it has
2343 // been updated in the prefs. Remove it from the database, and update the
2344 // |default_search_provider| pointer here.
2345 if (*default_search_provider &&
2346 (*default_search_provider)->id() == template_url->id())
2347 *default_search_provider = NULL;
2348
2195 i = template_urls->erase(i); 2349 i = template_urls->erase(i);
2196 if (service_) 2350 if (service_)
2197 service_->RemoveKeyword(template_url->id()); 2351 service_->RemoveKeyword(template_url->id());
2198 delete template_url; 2352 delete template_url;
2199 } else { 2353 } else {
2200 ++i; 2354 ++i;
2201 } 2355 }
2202 } 2356 }
2203
2204 if (default_from_prefs) {
2205 default_search_provider_ = NULL;
2206 default_search_provider_source_ = DefaultSearchManager::FROM_POLICY;
2207 TemplateURLData new_data(*default_from_prefs);
2208 if (new_data.sync_guid.empty())
2209 new_data.sync_guid = base::GenerateGUID();
2210 new_data.created_by_policy = true;
2211 TemplateURL* new_dse = new TemplateURL(profile_, new_data);
2212 if (AddNoNotify(new_dse, true))
2213 default_search_provider_ = new_dse;
2214 }
2215 } 2357 }
2216 2358
2217 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, 2359 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url,
2218 const std::string& guid) { 2360 const std::string& guid) {
2219 DCHECK(loaded_); 2361 DCHECK(loaded_);
2220 DCHECK(!guid.empty()); 2362 DCHECK(!guid.empty());
2221 2363
2222 TemplateURLData data(url->data()); 2364 TemplateURLData data(url->data());
2223 data.sync_guid = guid; 2365 data.sync_guid = guid;
2366 TemplateURL new_url(url->profile(), data);
2224 UIThreadSearchTermsData search_terms_data(url->profile()); 2367 UIThreadSearchTermsData search_terms_data(url->profile());
2225 UpdateNoNotify(url, TemplateURL(profile_, data), search_terms_data); 2368 UpdateNoNotify(url, new_url, search_terms_data);
2226 } 2369 }
2227 2370
2228 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl, 2371 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl,
2229 bool force) { 2372 bool force) {
2230 if (!force) { 2373 if (!force) {
2231 // Already unique. 2374 // Already unique.
2232 if (!GetTemplateURLForKeyword(turl.keyword())) 2375 if (!GetTemplateURLForKeyword(turl.keyword()))
2233 return turl.keyword(); 2376 return turl.keyword();
2234 2377
2235 // First, try to return the generated keyword for the TemplateURL (except 2378 // First, try to return the generated keyword for the TemplateURL (except
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 base::string16 new_keyword = UniquifyKeyword(*loser, false); 2429 base::string16 new_keyword = UniquifyKeyword(*loser, false);
2287 DCHECK(!GetTemplateURLForKeyword(new_keyword)); 2430 DCHECK(!GetTemplateURLForKeyword(new_keyword));
2288 if (applied_turl_is_better) { 2431 if (applied_turl_is_better) {
2289 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible 2432 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible
2290 // for adding or updating unapplied_sync_turl in the local model. 2433 // for adding or updating unapplied_sync_turl in the local model.
2291 unapplied_sync_turl->data_.SetKeyword(new_keyword); 2434 unapplied_sync_turl->data_.SetKeyword(new_keyword);
2292 } else { 2435 } else {
2293 // Update |applied_sync_turl| in the local model with the new keyword. 2436 // Update |applied_sync_turl| in the local model with the new keyword.
2294 TemplateURLData data(applied_sync_turl->data()); 2437 TemplateURLData data(applied_sync_turl->data());
2295 data.SetKeyword(new_keyword); 2438 data.SetKeyword(new_keyword);
2439 TemplateURL new_turl(applied_sync_turl->profile(), data);
2296 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile()); 2440 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile());
2297 if (UpdateNoNotify( 2441 if (UpdateNoNotify(applied_sync_turl, new_turl, search_terms_data))
2298 applied_sync_turl, TemplateURL(profile_, data), search_terms_data))
2299 NotifyObservers(); 2442 NotifyObservers();
2300 } 2443 }
2301 // The losing TemplateURL should have their keyword updated. Send a change to 2444 // The losing TemplateURL should have their keyword updated. Send a change to
2302 // the server to reflect this change. 2445 // the server to reflect this change.
2303 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser); 2446 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser);
2304 change_list->push_back(syncer::SyncChange(FROM_HERE, 2447 change_list->push_back(syncer::SyncChange(FROM_HERE,
2305 syncer::SyncChange::ACTION_UPDATE, 2448 syncer::SyncChange::ACTION_UPDATE,
2306 sync_data)); 2449 sync_data));
2307 } 2450 }
2308 2451
(...skipping 28 matching lines...) Expand all
2337 // |conflicting_turl| is not yet known to Sync. If it is better, then we 2480 // |conflicting_turl| is not yet known to Sync. If it is better, then we
2338 // want to transfer its values up to sync. Otherwise, we remove it and 2481 // want to transfer its values up to sync. Otherwise, we remove it and
2339 // allow the entry from Sync to overtake it in the model. 2482 // allow the entry from Sync to overtake it in the model.
2340 const std::string guid = conflicting_turl->sync_guid(); 2483 const std::string guid = conflicting_turl->sync_guid();
2341 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) { 2484 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) {
2342 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid()); 2485 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid());
2343 syncer::SyncData sync_data = 2486 syncer::SyncData sync_data =
2344 CreateSyncDataFromTemplateURL(*conflicting_turl); 2487 CreateSyncDataFromTemplateURL(*conflicting_turl);
2345 change_list->push_back(syncer::SyncChange( 2488 change_list->push_back(syncer::SyncChange(
2346 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data)); 2489 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data));
2490 if (conflicting_turl == GetDefaultSearchProvider() &&
2491 !pending_synced_default_search_) {
2492 // If we're not waiting for the Synced default to come in, we should
2493 // override the pref with our new GUID. If we are waiting for the
2494 // arrival of a synced default, setting the pref here would cause us
2495 // to lose the GUID we are waiting on.
2496 PrefService* prefs = GetPrefs();
2497 if (prefs) {
2498 prefs->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2499 conflicting_turl->sync_guid());
2500 }
2501 }
2347 // Note that in this case we do not add the Sync TemplateURL to the 2502 // Note that in this case we do not add the Sync TemplateURL to the
2348 // local model, since we've effectively "merged" it in by updating the 2503 // local model, since we've effectively "merged" it in by updating the
2349 // local conflicting entry with its sync_guid. 2504 // local conflicting entry with its sync_guid.
2350 should_add_sync_turl = false; 2505 should_add_sync_turl = false;
2351 merge_result->set_num_items_modified( 2506 merge_result->set_num_items_modified(
2352 merge_result->num_items_modified() + 1); 2507 merge_result->num_items_modified() + 1);
2353 } else { 2508 } else {
2354 // We guarantee that this isn't the local search provider. Otherwise, 2509 // We guarantee that this isn't the local search provider. Otherwise,
2355 // local would have won. 2510 // local would have won.
2356 DCHECK(conflicting_turl != GetDefaultSearchProvider()); 2511 DCHECK(conflicting_turl != GetDefaultSearchProvider());
2357 Remove(conflicting_turl); 2512 Remove(conflicting_turl);
2358 merge_result->set_num_items_deleted( 2513 merge_result->set_num_items_deleted(
2359 merge_result->num_items_deleted() + 1); 2514 merge_result->num_items_deleted() + 1);
2360 } 2515 }
2361 // This TemplateURL was either removed or overwritten in the local model. 2516 // This TemplateURL was either removed or overwritten in the local model.
2362 // Remove the entry from the local data so it isn't pushed up to Sync. 2517 // Remove the entry from the local data so it isn't pushed up to Sync.
2363 local_data->erase(guid); 2518 local_data->erase(guid);
2364 } 2519 }
2365 } 2520 }
2366 2521
2367 if (should_add_sync_turl) { 2522 if (should_add_sync_turl) {
2368 // Force the local ID to kInvalidTemplateURLID so we can add it. 2523 // Force the local ID to kInvalidTemplateURLID so we can add it.
2369 TemplateURLData data(sync_turl->data()); 2524 TemplateURLData data(sync_turl->data());
2370 data.id = kInvalidTemplateURLID; 2525 data.id = kInvalidTemplateURLID;
2371 TemplateURL* added = new TemplateURL(profile_, data); 2526 Add(new TemplateURL(profile_, data));
2372 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2373 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
2374 if (Add(added))
2375 MaybeUpdateDSEAfterSync(added);
2376 merge_result->set_num_items_added( 2527 merge_result->set_num_items_added(
2377 merge_result->num_items_added() + 1); 2528 merge_result->num_items_added() + 1);
2378 } 2529 }
2379 } 2530 }
2380 2531
2532 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced(
2533 const std::string& guid) {
2534 // If we're not syncing or if default search is managed by policy, ignore.
2535 if (!sync_processor_.get() || is_default_search_managed_)
2536 return;
2537
2538 PrefService* prefs = GetPrefs();
2539 if (prefs && pending_synced_default_search_ &&
2540 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID) == guid) {
2541 // Make sure this actually exists. We should not be calling this unless we
2542 // really just added this TemplateURL.
2543 TemplateURL* turl_from_sync = GetTemplateURLForGUID(guid);
2544 if (turl_from_sync && turl_from_sync->SupportsReplacement()) {
2545 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2546 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
2547 SetDefaultSearchProvider(turl_from_sync);
2548 }
2549 pending_synced_default_search_ = false;
2550 }
2551 }
2552
2553 TemplateURL* TemplateURLService::GetPendingSyncedDefaultSearchProvider() {
2554 PrefService* prefs = GetPrefs();
2555 if (!prefs || !pending_synced_default_search_)
2556 return NULL;
2557
2558 // Could be NULL if no such thing exists.
2559 return GetTemplateURLForGUID(
2560 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID));
2561 }
2562
2381 void TemplateURLService::PatchMissingSyncGUIDs( 2563 void TemplateURLService::PatchMissingSyncGUIDs(
2382 TemplateURLVector* template_urls) { 2564 TemplateURLVector* template_urls) {
2383 DCHECK(template_urls); 2565 DCHECK(template_urls);
2384 for (TemplateURLVector::iterator i = template_urls->begin(); 2566 for (TemplateURLVector::iterator i = template_urls->begin();
2385 i != template_urls->end(); ++i) { 2567 i != template_urls->end(); ++i) {
2386 TemplateURL* template_url = *i; 2568 TemplateURL* template_url = *i;
2387 DCHECK(template_url); 2569 DCHECK(template_url);
2388 if (template_url->sync_guid().empty() && 2570 if (template_url->sync_guid().empty() &&
2389 (template_url->GetType() != 2571 (template_url->GetType() !=
2390 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) { 2572 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) {
2391 template_url->data_.sync_guid = base::GenerateGUID(); 2573 template_url->data_.sync_guid = base::GenerateGUID();
2392 if (service_) 2574 if (service_)
2393 service_->UpdateKeyword(template_url->data()); 2575 service_->UpdateKeyword(template_url->data());
2394 } 2576 }
2395 } 2577 }
2396 } 2578 }
2397 2579
2398 void TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged() { 2580 void TemplateURLService::AddTemplateURLsAndSetupDefaultEngine(
2399 base::AutoReset<DefaultSearchChangeOrigin> change_origin( 2581 TemplateURLVector* template_urls,
2400 &dsp_change_origin_, DSP_CHANGE_SYNC_PREF); 2582 TemplateURL* default_search_provider) {
2583 DCHECK(template_urls);
2584 is_default_search_managed_ = false;
2585 bool database_specified_a_default = (default_search_provider != NULL);
2401 2586
2402 std::string new_guid = 2587 // Check if default search provider is now managed.
2403 GetPrefs()->GetString(prefs::kSyncedDefaultSearchProviderGUID); 2588 scoped_ptr<TemplateURLData> default_from_prefs;
2404 if (new_guid.empty()) { 2589 LoadDefaultSearchProviderFromPrefs(
2405 default_search_manager_.ClearUserSelectedDefaultSearchEngine(); 2590 GetPrefs(), &default_from_prefs, &is_default_search_managed_);
2406 return; 2591
2592 // Remove entries that were created because of policy as they may have
2593 // changed since the database was saved.
2594 RemoveProvidersCreatedByPolicy(template_urls,
2595 &default_search_provider,
2596 default_from_prefs.get());
2597
2598 PatchMissingSyncGUIDs(template_urls);
2599
2600 if (is_default_search_managed_) {
2601 SetTemplateURLs(template_urls);
2602
2603 if (TemplateURL::MatchesData(default_search_provider,
2604 default_from_prefs.get())) {
2605 // The value from the preferences was previously stored in the database.
2606 // Reuse it.
2607 } else {
2608 // The value from the preferences takes over.
2609 default_search_provider = NULL;
2610 if (default_from_prefs) {
2611 default_from_prefs->created_by_policy = true;
2612 default_from_prefs->id = kInvalidTemplateURLID;
2613 default_search_provider =
2614 new TemplateURL(profile_, *default_from_prefs);
2615 if (!AddNoNotify(default_search_provider, true))
2616 default_search_provider = NULL;
2617 }
2618 }
2619 // Note that this saves the default search provider to prefs.
2620 if (!default_search_provider ||
2621 ((default_search_provider->GetType() !=
2622 TemplateURL::OMNIBOX_API_EXTENSION) &&
2623 default_search_provider->SupportsReplacement())) {
2624 bool success = SetDefaultSearchProviderNoNotify(default_search_provider);
2625 DCHECK(success);
2626 }
2627 } else {
2628 // If we had a managed default, replace it with the synced default if
2629 // applicable, or the first provider of the list.
2630 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
2631 if (synced_default) {
2632 default_search_provider = synced_default;
2633 pending_synced_default_search_ = false;
2634 } else if (database_specified_a_default &&
2635 default_search_provider == NULL) {
2636 UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
2637 FIRST_POTENTIAL_CALLSITE_ON_LOAD,
2638 FIRST_POTENTIAL_CALLSITE_MAX);
2639 default_search_provider = FirstPotentialDefaultEngine(*template_urls);
2640 }
2641
2642 // If the default search provider existed previously, then just
2643 // set the member variable. Otherwise, we'll set it using the method
2644 // to ensure that it is saved properly after its id is set.
2645 if (default_search_provider &&
2646 (default_search_provider->id() != kInvalidTemplateURLID)) {
2647 default_search_provider_ = default_search_provider;
2648 default_search_provider = NULL;
2649 }
2650 SetTemplateURLs(template_urls);
2651
2652 if (default_search_provider) {
2653 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2654 &dsp_change_origin_, default_from_prefs ?
2655 dsp_change_origin_ : DSP_CHANGE_NEW_ENGINE_NO_PREFS);
2656 // Note that this saves the default search provider to prefs.
2657 SetDefaultSearchProvider(default_search_provider);
2658 } else {
2659 // Always save the default search provider to prefs. That way we don't
2660 // have to worry about it being out of sync.
2661 if (default_search_provider_)
2662 SaveDefaultSearchProviderToPrefs(default_search_provider_, GetPrefs());
2663 }
2407 } 2664 }
2408
2409 TemplateURL* turl = GetTemplateURLForGUID(new_guid);
2410 if (turl)
2411 default_search_manager_.SetUserSelectedDefaultSearchEngine(turl->data());
2412 } 2665 }
2413 2666
2414 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL( 2667 void TemplateURLService::EnsureDefaultSearchProviderExists() {
2415 int prepopulated_id) { 2668 if (!is_default_search_managed()) {
2416 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2669 bool has_default_search_provider = default_search_provider_ &&
2417 i != template_urls_.end(); ++i) { 2670 default_search_provider_->SupportsReplacement();
2418 if ((*i)->prepopulate_id() == prepopulated_id) 2671 UMA_HISTOGRAM_BOOLEAN("Search.HasDefaultSearchProvider",
2419 return *i; 2672 has_default_search_provider);
2673 // Ensure that default search provider exists. See http://crbug.com/116952.
2674 if (!has_default_search_provider) {
2675 bool success =
2676 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
2677 DCHECK(success);
2678 }
2679 // Don't log anything if the user has a NULL default search provider.
2680 if (default_search_provider_) {
2681 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchProviderType",
2682 TemplateURLPrepopulateData::GetEngineType(*default_search_provider_),
2683 SEARCH_ENGINE_MAX);
2684 }
2420 } 2685 }
2421 return NULL;
2422 } 2686 }
2423 2687
2424 TemplateURL* TemplateURLService::CreateTemplateURLForExtension( 2688 TemplateURL* TemplateURLService::CreateTemplateURLForExtension(
2425 const ExtensionKeyword& extension_keyword) { 2689 const ExtensionKeyword& extension_keyword) {
2426 TemplateURLData data; 2690 TemplateURLData data;
2427 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name); 2691 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name);
2428 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword)); 2692 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword));
2429 // This URL is not actually used for navigation. It holds the extension's 2693 // This URL is not actually used for navigation. It holds the extension's
2430 // ID, as well as forcing the TemplateURL to be treated as a search keyword. 2694 // ID, as well as forcing the TemplateURL to be treated as a search keyword.
2431 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + 2695 data.SetURL(std::string(extensions::kExtensionScheme) + "://" +
2432 extension_keyword.extension_id + "/?q={searchTerms}"); 2696 extension_keyword.extension_id + "/?q={searchTerms}");
2433 return new TemplateURL(profile_, data); 2697 return new TemplateURL(profile_, data);
2434 } 2698 }
2435 2699
2436 TemplateURL* TemplateURLService::FindTemplateURLForExtension( 2700 TemplateURL* TemplateURLService::FindTemplateURLForExtension(
2437 const std::string& extension_id, 2701 const std::string& extension_id,
2438 TemplateURL::Type type) { 2702 TemplateURL::Type type) {
2439 DCHECK_NE(TemplateURL::NORMAL, type); 2703 DCHECK_NE(TemplateURL::NORMAL, type);
2440 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2704 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2441 i != template_urls_.end(); ++i) { 2705 i != template_urls_.end(); ++i) {
2442 if ((*i)->GetType() == type && 2706 if ((*i)->GetType() == type &&
2443 (*i)->GetExtensionId() == extension_id) 2707 (*i)->GetExtensionId() == extension_id)
2444 return *i; 2708 return *i;
2445 } 2709 }
2710
2446 return NULL; 2711 return NULL;
2447 } 2712 }
2448 2713
2449 TemplateURL* TemplateURLService::FindMatchingExtensionTemplateURL( 2714 TemplateURL* TemplateURLService::FindExtensionDefaultSearchEngine() const {
2450 const TemplateURLData& data,
2451 TemplateURL::Type type) {
2452 DCHECK_NE(TemplateURL::NORMAL, type);
2453 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2454 i != template_urls_.end(); ++i) {
2455 if ((*i)->GetType() == type && TemplateURL::MatchesData(*i, &data))
2456 return *i;
2457 }
2458 return NULL;
2459 }
2460
2461 void TemplateURLService::UpdateExtensionDefaultSearchEngine() {
2462 TemplateURL* most_recently_intalled_default = NULL; 2715 TemplateURL* most_recently_intalled_default = NULL;
2463 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2716 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2464 i != template_urls_.end(); ++i) { 2717 i != template_urls_.end(); ++i) {
2465 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) && 2718 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) &&
2466 (*i)->extension_info_->wants_to_be_default_engine && 2719 (*i)->extension_info_->wants_to_be_default_engine &&
2467 (*i)->SupportsReplacement() && 2720 (*i)->SupportsReplacement() &&
2468 (!most_recently_intalled_default || 2721 (!most_recently_intalled_default ||
2469 (most_recently_intalled_default->extension_info_->install_time < 2722 (most_recently_intalled_default->extension_info_->install_time <
2470 (*i)->extension_info_->install_time))) 2723 (*i)->extension_info_->install_time)))
2471 most_recently_intalled_default = *i; 2724 most_recently_intalled_default = *i;
2472 } 2725 }
2473 2726
2474 if (most_recently_intalled_default) { 2727 return most_recently_intalled_default;
2475 base::AutoReset<DefaultSearchChangeOrigin> change_origin( 2728 }
2476 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION); 2729
2477 default_search_manager_.SetExtensionControlledDefaultSearchEngine( 2730 void TemplateURLService::
2478 most_recently_intalled_default->data()); 2731 SetDefaultSearchProviderAfterRemovingDefaultExtension() {
2479 } else { 2732 DCHECK(!is_default_search_managed());
2480 default_search_manager_.ClearExtensionControlledDefaultSearchEngine(); 2733 TemplateURL* new_dse = FindExtensionDefaultSearchEngine();
2734 if (!new_dse) {
2735 scoped_ptr<TemplateURLData> default_provider;
2736 bool is_managed;
2737 if (LoadDefaultSearchProviderFromPrefs(
2738 GetPrefs(), &default_provider, &is_managed) &&
2739 default_provider) {
2740 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2741 i != template_urls_.end(); ++i) {
2742 if ((*i)->id() == default_provider->id) {
2743 new_dse = *i;
2744 break;
2745 }
2746 }
2747 }
2481 } 2748 }
2749 if (!new_dse)
2750 new_dse = FindNewDefaultSearchProvider();
2751 SetDefaultSearchProviderNoNotify(new_dse);
2482 } 2752 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698