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

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

Issue 268643002: Use the DefaultSearchManager as the exclusive authority on DSE, ignoring Web Data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Nearly all non-sync tests pass. 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 (url1->image_url_post_params() == url2->image_url_post_params) && 76 (url1->image_url_post_params() == url2->image_url_post_params) &&
77 (url1->favicon_url() == url2->favicon_url) && 77 (url1->favicon_url() == url2->favicon_url) &&
78 (url1->safe_for_autoreplace() == url2->safe_for_autoreplace) && 78 (url1->safe_for_autoreplace() == url2->safe_for_autoreplace) &&
79 (url1->show_in_default_list() == url2->show_in_default_list) && 79 (url1->show_in_default_list() == url2->show_in_default_list) &&
80 (url1->input_encodings() == url2->input_encodings) && 80 (url1->input_encodings() == url2->input_encodings) &&
81 (url1->alternate_urls() == url2->alternate_urls) && 81 (url1->alternate_urls() == url2->alternate_urls) &&
82 (url1->search_terms_replacement_key() == 82 (url1->search_terms_replacement_key() ==
83 url2->search_terms_replacement_key); 83 url2->search_terms_replacement_key);
84 } 84 }
85 85
86 const char kFirstPotentialEngineHistogramName[] =
erikwright (departed) 2014/05/02 16:35:56 Is this metric still meaningful/relevant?
87 "Search.FirstPotentialEngineCalled";
88
89 // Values for an enumerated histogram used to track whenever
90 // FirstPotentialDefaultEngine is called, and from where.
91 enum FirstPotentialEngineCaller {
92 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP,
93 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_PROCESSING_SYNC_CHANGES,
94 FIRST_POTENTIAL_CALLSITE_ON_LOAD,
95 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_SYNCING,
96 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_NOT_SYNCING,
97 FIRST_POTENTIAL_CALLSITE_MAX,
98 };
99
100 const char kDeleteSyncedEngineHistogramName[] = 86 const char kDeleteSyncedEngineHistogramName[] =
101 "Search.DeleteSyncedSearchEngine"; 87 "Search.DeleteSyncedSearchEngine";
102 88
103 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is 89 // Values for an enumerated histogram used to track whenever an ACTION_DELETE is
104 // sent to the server for search engines. 90 // sent to the server for search engines.
105 enum DeleteSyncedSearchEngineEvent { 91 enum DeleteSyncedSearchEngineEvent {
106 DELETE_ENGINE_USER_ACTION, 92 DELETE_ENGINE_USER_ACTION,
107 DELETE_ENGINE_PRE_SYNC, 93 DELETE_ENGINE_PRE_SYNC,
108 DELETE_ENGINE_EMPTY_FIELD, 94 DELETE_ENGINE_EMPTY_FIELD,
109 DELETE_ENGINE_MAX, 95 DELETE_ENGINE_MAX,
110 }; 96 };
111 97
112 TemplateURL* FirstPotentialDefaultEngine(
113 const TemplateURLService::TemplateURLVector& template_urls) {
114 for (TemplateURLService::TemplateURLVector::const_iterator i(
115 template_urls.begin()); i != template_urls.end(); ++i) {
116 if ((*i)->ShowInDefaultList() &&
117 ((*i)->GetType() == TemplateURL::NORMAL))
118 return *i;
119 }
120 return NULL;
121 }
122
123 // 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
124 // 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
125 // to changes after it in |change_list|. 100 // to changes after it in |change_list|.
126 // The criteria is: 101 // The criteria is:
127 // 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
128 // 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
129 // entries that were originally from the Sync server. 104 // entries that were originally from the Sync server.
130 // 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
131 // |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.
132 // 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 251
277 // TemplateURLService --------------------------------------------------------- 252 // TemplateURLService ---------------------------------------------------------
278 253
279 TemplateURLService::TemplateURLService(Profile* profile) 254 TemplateURLService::TemplateURLService(Profile* profile)
280 : provider_map_(new SearchHostToURLsMap), 255 : provider_map_(new SearchHostToURLsMap),
281 profile_(profile), 256 profile_(profile),
282 loaded_(false), 257 loaded_(false),
283 load_failed_(false), 258 load_failed_(false),
284 load_handle_(0), 259 load_handle_(0),
285 default_search_provider_(NULL), 260 default_search_provider_(NULL),
286 is_default_search_managed_(false),
287 next_id_(kInvalidTemplateURLID + 1), 261 next_id_(kInvalidTemplateURLID + 1),
288 time_provider_(&base::Time::Now), 262 time_provider_(&base::Time::Now),
289 models_associated_(false), 263 models_associated_(false),
290 processing_syncer_changes_(false), 264 processing_syncer_changes_(false),
291 pending_synced_default_search_(false), 265 default_search_manager_(new DefaultSearchManager(
erikwright (departed) 2014/05/02 16:35:56 TODO: make this a data member instead of pointer n
292 dsp_change_origin_(DSP_CHANGE_OTHER), 266 GetPrefs(),
293 default_search_manager_(new DefaultSearchManager(GetPrefs())) { 267 base::Bind(&TemplateURLService::OnDefaultSearchChange,
268 base::Unretained(this)))) {
294 DCHECK(profile_); 269 DCHECK(profile_);
295 Init(NULL, 0); 270 Init(NULL, 0);
296 } 271 }
297 272
298 TemplateURLService::TemplateURLService(const Initializer* initializers, 273 TemplateURLService::TemplateURLService(const Initializer* initializers,
299 const int count) 274 const int count)
300 : provider_map_(new SearchHostToURLsMap), 275 : provider_map_(new SearchHostToURLsMap),
301 profile_(NULL), 276 profile_(NULL),
302 loaded_(false), 277 loaded_(false),
303 load_failed_(false), 278 load_failed_(false),
304 load_handle_(0), 279 load_handle_(0),
305 service_(NULL), 280 service_(NULL),
306 default_search_provider_(NULL), 281 default_search_provider_(NULL),
307 is_default_search_managed_(false),
308 next_id_(kInvalidTemplateURLID + 1), 282 next_id_(kInvalidTemplateURLID + 1),
309 time_provider_(&base::Time::Now), 283 time_provider_(&base::Time::Now),
310 models_associated_(false), 284 models_associated_(false),
311 processing_syncer_changes_(false), 285 processing_syncer_changes_(false),
312 pending_synced_default_search_(false), 286 default_search_manager_(new DefaultSearchManager(
313 dsp_change_origin_(DSP_CHANGE_OTHER) { 287 GetPrefs(),
288 base::Bind(&TemplateURLService::OnDefaultSearchChange,
289 base::Unretained(this)))) {
314 Init(initializers, count); 290 Init(initializers, count);
315 } 291 }
316 292
317 TemplateURLService::~TemplateURLService() { 293 TemplateURLService::~TemplateURLService() {
318 // |service_| should be deleted during Shutdown(). 294 // |service_| should be deleted during Shutdown().
319 DCHECK(!service_); 295 DCHECK(!service_);
320 STLDeleteElements(&template_urls_); 296 STLDeleteElements(&template_urls_);
321 } 297 }
322 298
323 // static 299 // static
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 DCHECK(info); 499 DCHECK(info);
524 DCHECK_EQ(info->wants_to_be_default_engine, 500 DCHECK_EQ(info->wants_to_be_default_engine,
525 template_url->show_in_default_list()); 501 template_url->show_in_default_list());
526 template_url->extension_info_.swap(info); 502 template_url->extension_info_.swap(info);
527 DCHECK(!FindTemplateURLForExtension( 503 DCHECK(!FindTemplateURLForExtension(
528 template_url->GetExtensionId(), 504 template_url->GetExtensionId(),
529 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)); 505 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION));
530 506
531 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 507 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
532 if (AddNoNotify(template_url, true)) { 508 if (AddNoNotify(template_url, true)) {
533 // Note that we can't call CanMakeDefault() here, since it would return 509 if (template_url->extension_info_->wants_to_be_default_engine) {
534 // false when another extension is already controlling the default search 510 UpdateExtensionDefaultSearchEngine();
535 // engine, and we want to allow new extensions to take over.
536 if (template_url->extension_info_->wants_to_be_default_engine &&
537 !is_default_search_managed()) {
538 TemplateURL* default_candidate = FindExtensionDefaultSearchEngine();
539 if (default_candidate == template_url) {
540 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
541 &dsp_change_origin_, DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION);
542 SetDefaultSearchProviderNoNotify(template_url);
543 }
544 } 511 }
545 NotifyObservers(); 512 NotifyObservers();
546 } 513 }
547 } 514 }
548 515
549 void TemplateURLService::Remove(TemplateURL* template_url) { 516 void TemplateURLService::Remove(TemplateURL* template_url) {
550 RemoveNoNotify(template_url); 517 RemoveNoNotify(template_url);
551 NotifyObservers(); 518 NotifyObservers();
552 } 519 }
553 520
554 void TemplateURLService::RemoveExtensionControlledTURL( 521 void TemplateURLService::RemoveExtensionControlledTURL(
555 const std::string& extension_id) { 522 const std::string& extension_id) {
556 DCHECK(loaded_); 523 DCHECK(loaded_);
557 TemplateURL* url = FindTemplateURLForExtension( 524 TemplateURL* url = FindTemplateURLForExtension(
558 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION); 525 extension_id, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
559 if (!url) 526 if (!url)
560 return; 527 return;
561 bool restore_dse = (url == GetDefaultSearchProvider()); 528 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
562 if (restore_dse) { 529 // NULL this out so that we can call RemoveNoNotify. The subsequent
563 DCHECK(!is_default_search_managed()); 530 // UpdateExtensionDefaultSearchEngine will cause it to be reset.
531 if (default_search_provider_ == url)
564 default_search_provider_ = NULL; 532 default_search_provider_ = NULL;
565 }
566 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
567 RemoveNoNotify(url); 533 RemoveNoNotify(url);
568 if (restore_dse) 534 UpdateExtensionDefaultSearchEngine();
569 SetDefaultSearchProviderAfterRemovingDefaultExtension();
570 NotifyObservers(); 535 NotifyObservers();
571 } 536 }
572 537
573 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) { 538 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) {
574 RemoveAutoGeneratedBetween(created_after, base::Time()); 539 RemoveAutoGeneratedBetween(created_after, base::Time());
575 } 540 }
576 541
577 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after, 542 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after,
578 base::Time created_before) { 543 base::Time created_before) {
579 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before); 544 RemoveAutoGeneratedForOriginBetween(GURL(), created_after, created_before);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 TemplateURLData data(url->data()); 620 TemplateURLData data(url->data());
656 data.short_name = title; 621 data.short_name = title;
657 data.SetKeyword(keyword); 622 data.SetKeyword(keyword);
658 if (search_url != data.url()) { 623 if (search_url != data.url()) {
659 data.SetURL(search_url); 624 data.SetURL(search_url);
660 // The urls have changed, reset the favicon url. 625 // The urls have changed, reset the favicon url.
661 data.favicon_url = GURL(); 626 data.favicon_url = GURL();
662 } 627 }
663 data.safe_for_autoreplace = false; 628 data.safe_for_autoreplace = false;
664 data.last_modified = time_provider_(); 629 data.last_modified = time_provider_();
665 TemplateURL new_url(url->profile(), data); 630
666 UIThreadSearchTermsData search_terms_data(url->profile()); 631 UIThreadSearchTermsData search_terms_data(url->profile());
667 if (UpdateNoNotify(url, new_url, search_terms_data)) 632 if (UpdateNoNotify(url, data, search_terms_data))
668 NotifyObservers(); 633 NotifyObservers();
669 } 634 }
670 635
671 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) { 636 bool TemplateURLService::CanMakeDefault(const TemplateURL* url) {
672 return !is_default_search_managed() && 637 return default_search_provider_source_ == DefaultSearchManager::FROM_USER &&
673 !IsExtensionControlledDefaultSearch() &&
674 (url != GetDefaultSearchProvider()) && 638 (url != GetDefaultSearchProvider()) &&
675 url->url_ref().SupportsReplacement() && 639 url->url_ref().SupportsReplacement() &&
676 (url->GetType() == TemplateURL::NORMAL); 640 (url->GetType() == TemplateURL::NORMAL);
677 } 641 }
678 642
679 void TemplateURLService::SetUserSelectedDefaultSearchProvider( 643 void TemplateURLService::SetUserSelectedDefaultSearchProvider(
680 TemplateURL* url) { 644 TemplateURL* url) {
681 SetDefaultSearchProvider(url); 645 // Omnibox keywords cannot be made default. Extension-controlled search
682 if (default_search_manager_) { 646 // engines can be made default only by the extension itself because they
683 if (url) 647 // aren't persisted.
684 default_search_manager_->SetUserSelectedDefaultSearchEngine(url->data()); 648 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL));
685 else 649 // We rely on the DefaultSearchManager to push this back to us if, in fact,
686 default_search_manager_->ClearUserSelectedDefaultSearchEngine(); 650 // the effective DSE changes.
687 } 651 if (url)
652 default_search_manager_->SetUserSelectedDefaultSearchEngine(url->data());
653 else
654 default_search_manager_->ClearUserSelectedDefaultSearchEngine();
688 } 655 }
689 656
690 TemplateURL* TemplateURLService::GetDefaultSearchProvider() { 657 TemplateURL* TemplateURLService::GetDefaultSearchProvider() {
691 if (loaded_ && !load_failed_) 658 if (loaded_)
692 return default_search_provider_; 659 return default_search_provider_;
693 // We're not loaded, rely on the default search provider stored in prefs. 660 // We're not loaded, rely on the default search provider stored in prefs.
694 return initial_default_search_provider_.get(); 661 return initial_default_search_provider_.get();
695 } 662 }
696 663
697 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider( 664 bool TemplateURLService::IsSearchResultsPageFromDefaultSearchProvider(
698 const GURL& url) { 665 const GURL& url) {
699 TemplateURL* default_provider = GetDefaultSearchProvider(); 666 TemplateURL* default_provider = GetDefaultSearchProvider();
700 return default_provider && default_provider->IsSearchURL(url); 667 return default_provider && default_provider->IsSearchURL(url);
701 } 668 }
702 669
703 bool TemplateURLService::IsExtensionControlledDefaultSearch() { 670 bool TemplateURLService::IsExtensionControlledDefaultSearch() {
704 const TemplateURL* default_provider = GetDefaultSearchProvider(); 671 return default_search_provider_source_ ==
705 return default_provider && (default_provider->GetType() == 672 DefaultSearchManager::FROM_EXTENSION;
706 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
707 }
708
709 TemplateURL* TemplateURLService::FindNewDefaultSearchProvider() {
710 // See if the prepopulated default still exists.
711 scoped_ptr<TemplateURLData> prepopulated_default =
712 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs());
713
714 for (TemplateURLVector::iterator i = template_urls_.begin();
715 i != template_urls_.end(); ++i) {
716 if ((*i)->prepopulate_id() == prepopulated_default->prepopulate_id)
717 return *i;
718 }
719 // If not, use the first non-extension keyword of the templates that supports
720 // search term replacement.
721 if (processing_syncer_changes_) {
722 UMA_HISTOGRAM_ENUMERATION(
723 kFirstPotentialEngineHistogramName,
724 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_PROCESSING_SYNC_CHANGES,
725 FIRST_POTENTIAL_CALLSITE_MAX);
726 } else {
727 if (sync_processor_.get()) {
728 // We're not currently in a sync cycle, but we're syncing.
729 UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
730 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_SYNCING,
731 FIRST_POTENTIAL_CALLSITE_MAX);
732 } else {
733 // We're not syncing at all.
734 UMA_HISTOGRAM_ENUMERATION(
735 kFirstPotentialEngineHistogramName,
736 FIRST_POTENTIAL_CALLSITE_FIND_NEW_DSP_NOT_SYNCING,
737 FIRST_POTENTIAL_CALLSITE_MAX);
738 }
739 }
740 return FirstPotentialDefaultEngine(template_urls_);
741 } 673 }
742 674
743 void TemplateURLService::RepairPrepopulatedSearchEngines() { 675 void TemplateURLService::RepairPrepopulatedSearchEngines() {
744 // Can't clean DB if it hasn't been loaded. 676 // Can't clean DB if it hasn't been loaded.
745 DCHECK(loaded()); 677 DCHECK(loaded());
746 678
747 size_t default_search_provider_index = 0; 679 size_t default_search_provider_index = 0;
748 ScopedVector<TemplateURLData> prepopulated_urls = 680 ScopedVector<TemplateURLData> prepopulated_urls =
749 TemplateURLPrepopulateData::GetPrepopulatedEngines( 681 TemplateURLPrepopulateData::GetPrepopulatedEngines(
750 GetPrefs(), &default_search_provider_index); 682 GetPrefs(), &default_search_provider_index);
751 DCHECK(!prepopulated_urls.empty()); 683 DCHECK(!prepopulated_urls.empty());
752 int default_search_engine_id =
753 prepopulated_urls[default_search_provider_index]->prepopulate_id;
754 TemplateURL* current_dse = default_search_provider_;
755 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData( 684 ActionsFromPrepopulateData actions(CreateActionsFromCurrentPrepopulateData(
756 &prepopulated_urls, template_urls_, current_dse)); 685 &prepopulated_urls, template_urls_, default_search_provider_));
757 686
758 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 687 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
759 688
760 // Remove items. 689 // Remove items.
761 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin(); 690 for (std::vector<TemplateURL*>::iterator i = actions.removed_engines.begin();
762 i < actions.removed_engines.end(); ++i) 691 i < actions.removed_engines.end(); ++i)
763 RemoveNoNotify(*i); 692 RemoveNoNotify(*i);
764 693
765 // Edit items. 694 // Edit items.
766 for (EditedEngines::iterator i(actions.edited_engines.begin()); 695 for (EditedEngines::iterator i(actions.edited_engines.begin());
767 i < actions.edited_engines.end(); ++i) { 696 i < actions.edited_engines.end(); ++i) {
768 UIThreadSearchTermsData search_terms_data(profile()); 697 UIThreadSearchTermsData search_terms_data(profile());
769 TemplateURL new_values(profile(), i->second); 698 UpdateNoNotify(i->first, i->second, search_terms_data);
770 UpdateNoNotify(i->first, new_values, search_terms_data);
771 } 699 }
772 700
773 // Add items. 701 // Add items.
774 for (std::vector<TemplateURLData>::const_iterator i = 702 for (std::vector<TemplateURLData>::const_iterator i =
775 actions.added_engines.begin(); 703 actions.added_engines.begin();
776 i < actions.added_engines.end(); 704 i < actions.added_engines.end();
777 ++i) { 705 ++i) {
778 AddNoNotify(new TemplateURL(profile_, *i), true); 706 AddNoNotify(new TemplateURL(profile_, *i), true);
779 } 707 }
780 708
781 // Change the DSE.
782 TemplateURL* new_dse = FindURLByPrepopulateID(template_urls_,
783 default_search_engine_id);
784 DCHECK(new_dse);
785 if (CanMakeDefault(new_dse)) {
786 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
787 &dsp_change_origin_, DSP_CHANGE_PROFILE_RESET);
788 SetDefaultSearchProviderNoNotify(new_dse);
789 }
790 NotifyObservers(); 709 NotifyObservers();
791 } 710 }
792 711
793 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) { 712 void TemplateURLService::AddObserver(TemplateURLServiceObserver* observer) {
794 model_observers_.AddObserver(observer); 713 model_observers_.AddObserver(observer);
795 } 714 }
796 715
797 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) { 716 void TemplateURLService::RemoveObserver(TemplateURLServiceObserver* observer) {
798 model_observers_.RemoveObserver(observer); 717 model_observers_.RemoveObserver(observer);
799 } 718 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 750
832 if (!result) { 751 if (!result) {
833 // Results are null if the database went away or (most likely) wasn't 752 // Results are null if the database went away or (most likely) wasn't
834 // loaded. 753 // loaded.
835 load_failed_ = true; 754 load_failed_ = true;
836 ChangeToLoadedState(); 755 ChangeToLoadedState();
837 on_loaded_callbacks_.Notify(); 756 on_loaded_callbacks_.Notify();
838 return; 757 return;
839 } 758 }
840 759
841 // initial_default_search_provider_ is only needed before we've finished
842 // loading. Now that we've loaded we can nuke it.
843 initial_default_search_provider_.reset();
844
845 TemplateURLVector template_urls; 760 TemplateURLVector template_urls;
846 TemplateURL* default_search_provider = NULL;
847 int new_resource_keyword_version = 0; 761 int new_resource_keyword_version = 0;
848 GetSearchProvidersUsingKeywordResult(*result, service_.get(), profile_, 762 GetSearchProvidersUsingKeywordResult(
849 &template_urls, &default_search_provider, &new_resource_keyword_version, 763 *result,
764 service_.get(),
765 profile_,
766 &template_urls,
767 default_search_provider_source_ == DefaultSearchManager::FROM_USER
768 ? initial_default_search_provider_.get()
769 : NULL,
770 &new_resource_keyword_version,
850 &pre_sync_deletes_); 771 &pre_sync_deletes_);
851 772
852 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 773 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
853 774
854 AddTemplateURLsAndSetupDefaultEngine(&template_urls, default_search_provider); 775 PatchMissingSyncGUIDs(&template_urls);
776 SetTemplateURLs(&template_urls);
855 777
856 // This initializes provider_map_ which should be done before 778 // This initializes provider_map_ which should be done before
857 // calling UpdateKeywordSearchTermsForURL. 779 // calling UpdateKeywordSearchTermsForURL.
780 // This also calls NotifyObservers.
858 ChangeToLoadedState(); 781 ChangeToLoadedState();
859 782
860 // Index any visits that occurred before we finished loading. 783 // Index any visits that occurred before we finished loading.
861 for (size_t i = 0; i < visits_to_add_.size(); ++i) 784 for (size_t i = 0; i < visits_to_add_.size(); ++i)
862 UpdateKeywordSearchTermsForURL(visits_to_add_[i]); 785 UpdateKeywordSearchTermsForURL(visits_to_add_[i]);
863 visits_to_add_.clear(); 786 visits_to_add_.clear();
864 787
865 if (new_resource_keyword_version) 788 if (new_resource_keyword_version)
866 service_->SetBuiltinKeywordVersion(new_resource_keyword_version); 789 service_->SetBuiltinKeywordVersion(new_resource_keyword_version);
867 790
868 EnsureDefaultSearchProviderExists();
869
870 NotifyObservers();
871 on_loaded_callbacks_.Notify(); 791 on_loaded_callbacks_.Notify();
872 } 792 }
873 793
874 base::string16 TemplateURLService::GetKeywordShortName( 794 base::string16 TemplateURLService::GetKeywordShortName(
875 const base::string16& keyword, 795 const base::string16& keyword,
876 bool* is_omnibox_api_extension_keyword) { 796 bool* is_omnibox_api_extension_keyword) {
877 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword); 797 const TemplateURL* template_url = GetTemplateURLForKeyword(keyword);
878 798
879 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService 799 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLService
880 // to track changes to the model, this should become a DCHECK. 800 // to track changes to the model, this should become a DCHECK.
881 if (template_url) { 801 if (template_url) {
882 *is_omnibox_api_extension_keyword = 802 *is_omnibox_api_extension_keyword =
883 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION; 803 template_url->GetType() == TemplateURL::OMNIBOX_API_EXTENSION;
884 return template_url->AdjustedShortNameForLocaleDirection(); 804 return template_url->AdjustedShortNameForLocaleDirection();
885 } 805 }
886 *is_omnibox_api_extension_keyword = false; 806 *is_omnibox_api_extension_keyword = false;
887 return base::string16(); 807 return base::string16();
888 } 808 }
889 809
890 void TemplateURLService::Observe(int type, 810 void TemplateURLService::Observe(int type,
891 const content::NotificationSource& source, 811 const content::NotificationSource& source,
892 const content::NotificationDetails& details) { 812 const content::NotificationDetails& details) {
893 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) { 813 if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED) {
894 content::Details<history::URLVisitedDetails> visit_details(details); 814 content::Details<history::URLVisitedDetails> visit_details(details);
895 if (!loaded_) 815 if (!loaded_)
896 visits_to_add_.push_back(*visit_details.ptr()); 816 visits_to_add_.push_back(*visit_details.ptr());
897 else 817 else
898 UpdateKeywordSearchTermsForURL(*visit_details.ptr()); 818 UpdateKeywordSearchTermsForURL(*visit_details.ptr());
899 } else if (type == chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED) {
900 // Policy has been updated, so the default search prefs may be different.
901 // Reload the default search provider from them.
902 // TODO(pkasting): Rather than communicating via prefs, we should eventually
903 // observe policy changes directly.
904 UpdateDefaultSearch();
905 } else { 819 } else {
906 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type); 820 DCHECK_EQ(chrome::NOTIFICATION_GOOGLE_URL_UPDATED, type);
907 if (loaded_) { 821 if (loaded_) {
908 GoogleBaseURLChanged( 822 GoogleBaseURLChanged(
909 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first); 823 content::Details<GoogleURLTracker::UpdatedDetails>(details)->first);
910 } 824 }
911 } 825 }
912 } 826 }
913 827
914 void TemplateURLService::Shutdown() { 828 void TemplateURLService::Shutdown() {
915 // This check has to be done at Shutdown() instead of in the dtor to ensure 829 // This check has to be done at Shutdown() instead of in the dtor to ensure
916 // that no clients of WebDataService are holding ptrs to it after the first 830 // that no clients of WebDataService are holding ptrs to it after the first
917 // phase of the KeyedService Shutdown() process. 831 // phase of the KeyedService Shutdown() process.
918 if (load_handle_) { 832 if (load_handle_) {
919 DCHECK(service_.get()); 833 DCHECK(service_.get());
920 service_->CancelRequest(load_handle_); 834 service_->CancelRequest(load_handle_);
921 } 835 }
922 service_ = NULL; 836 service_ = NULL;
923 } 837 }
924 838
925 void TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged() {
926 // Listen for changes to the default search from Sync.
927 PrefService* prefs = GetPrefs();
928 TemplateURL* new_default_search = GetTemplateURLForGUID(
929 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID));
930 if (new_default_search && !is_default_search_managed_) {
931 if (new_default_search != GetDefaultSearchProvider()) {
932 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
933 &dsp_change_origin_, DSP_CHANGE_SYNC_PREF);
934 SetUserSelectedDefaultSearchProvider(new_default_search);
935 pending_synced_default_search_ = false;
936 }
937 } else {
938 // If it's not there, or if default search is currently managed, set a
939 // flag to indicate that we waiting on the search engine entry to come
940 // in through Sync.
941 pending_synced_default_search_ = true;
942 }
943 UpdateDefaultSearch();
944 }
945
946 syncer::SyncDataList TemplateURLService::GetAllSyncData( 839 syncer::SyncDataList TemplateURLService::GetAllSyncData(
947 syncer::ModelType type) const { 840 syncer::ModelType type) const {
948 DCHECK_EQ(syncer::SEARCH_ENGINES, type); 841 DCHECK_EQ(syncer::SEARCH_ENGINES, type);
949 842
950 syncer::SyncDataList current_data; 843 syncer::SyncDataList current_data;
951 for (TemplateURLVector::const_iterator iter = template_urls_.begin(); 844 for (TemplateURLVector::const_iterator iter = template_urls_.begin();
952 iter != template_urls_.end(); ++iter) { 845 iter != template_urls_.end(); ++iter) {
953 // We don't sync keywords managed by policy. 846 // We don't sync keywords managed by policy.
954 if ((*iter)->created_by_policy()) 847 if ((*iter)->created_by_policy())
955 continue; 848 continue;
(...skipping 13 matching lines...) Expand all
969 syncer::SyncError error(FROM_HERE, 862 syncer::SyncError error(FROM_HERE,
970 syncer::SyncError::DATATYPE_ERROR, 863 syncer::SyncError::DATATYPE_ERROR,
971 "Models not yet associated.", 864 "Models not yet associated.",
972 syncer::SEARCH_ENGINES); 865 syncer::SEARCH_ENGINES);
973 return error; 866 return error;
974 } 867 }
975 DCHECK(loaded_); 868 DCHECK(loaded_);
976 869
977 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 870 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
978 871
979 // We've started syncing, so set our origin member to the base Sync value.
980 // As we move through Sync Code, we may set this to increasingly specific
981 // origins so we can tell what exactly caused a DSP change.
982 base::AutoReset<DefaultSearchChangeOrigin> change_origin(&dsp_change_origin_,
983 DSP_CHANGE_SYNC_UNINTENTIONAL);
984
985 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 872 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
986 873
987 syncer::SyncChangeList new_changes; 874 syncer::SyncChangeList new_changes;
988 syncer::SyncError error; 875 syncer::SyncError error;
989 for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); 876 for (syncer::SyncChangeList::const_iterator iter = change_list.begin();
990 iter != change_list.end(); ++iter) { 877 iter != change_list.end(); ++iter) {
991 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType()); 878 DCHECK_EQ(syncer::SEARCH_ENGINES, iter->sync_data().GetDataType());
992 879
993 std::string guid = 880 std::string guid =
994 iter->sync_data().GetSpecifics().search_engine().sync_guid(); 881 iter->sync_data().GetSpecifics().search_engine().sync_guid();
(...skipping 11 matching lines...) Expand all
1006 TemplateURL* existing_keyword_turl = 893 TemplateURL* existing_keyword_turl =
1007 FindNonExtensionTemplateURLForKeyword(turl->keyword()); 894 FindNonExtensionTemplateURLForKeyword(turl->keyword());
1008 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { 895 if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) {
1009 if (!existing_turl) { 896 if (!existing_turl) {
1010 error = sync_error_factory_->CreateAndUploadError( 897 error = sync_error_factory_->CreateAndUploadError(
1011 FROM_HERE, 898 FROM_HERE,
1012 "ProcessSyncChanges failed on ChangeType ACTION_DELETE"); 899 "ProcessSyncChanges failed on ChangeType ACTION_DELETE");
1013 continue; 900 continue;
1014 } 901 }
1015 if (existing_turl == GetDefaultSearchProvider()) { 902 if (existing_turl == GetDefaultSearchProvider()) {
1016 // The only way Sync can attempt to delete the default search provider 903 // TODO(erikwright): This could happen if the user changes the default
1017 // is if we had changed the kSyncedDefaultSearchProviderGUID 904 // and then deletes the former default. If we receive the keyword sync
1018 // preference, but perhaps it has not yet been received. To avoid 905 // before the pref sync we end up here. For now we will just fail to
1019 // situations where this has come in erroneously, we will un-delete 906 // delete the local record. The user can always correct it later if they
1020 // the current default search from the Sync data. If the pref really 907 // so choose.
1021 // does arrive later, then default search will change to the correct
1022 // entry, but we'll have this extra entry sitting around. The result is
1023 // not ideal, but it prevents a far more severe bug where the default is
1024 // unexpectedly swapped to something else. The user can safely delete
1025 // the extra entry again later, if they choose. Most users who do not
1026 // look at the search engines UI will not notice this.
1027 // Note that we append a special character to the end of the keyword in
1028 // an attempt to avoid a ping-poinging situation where receiving clients
1029 // may try to continually delete the resurrected entry.
1030 base::string16 updated_keyword = UniquifyKeyword(*existing_turl, true);
1031 TemplateURLData data(existing_turl->data());
1032 data.SetKeyword(updated_keyword);
1033 TemplateURL new_turl(existing_turl->profile(), data);
1034 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1035 if (UpdateNoNotify(existing_turl, new_turl, search_terms_data))
1036 NotifyObservers();
1037
1038 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(new_turl);
1039 new_changes.push_back(syncer::SyncChange(FROM_HERE,
1040 syncer::SyncChange::ACTION_ADD,
1041 sync_data));
1042 // Ignore the delete attempt. This means we never end up reseting the
1043 // default search provider due to an ACTION_DELETE from sync.
1044 continue; 908 continue;
1045 } 909 }
1046 910
1047 Remove(existing_turl); 911 Remove(existing_turl);
1048 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { 912 } else if (iter->change_type() == syncer::SyncChange::ACTION_ADD) {
1049 if (existing_turl) { 913 if (existing_turl) {
1050 error = sync_error_factory_->CreateAndUploadError( 914 error = sync_error_factory_->CreateAndUploadError(
1051 FROM_HERE, 915 FROM_HERE,
1052 "ProcessSyncChanges failed on ChangeType ACTION_ADD"); 916 "ProcessSyncChanges failed on ChangeType ACTION_ADD");
1053 continue; 917 continue;
1054 } 918 }
1055 const std::string guid = turl->sync_guid(); 919 const std::string guid = turl->sync_guid();
1056 if (existing_keyword_turl) { 920 if (existing_keyword_turl) {
1057 // Resolve any conflicts so we can safely add the new entry. 921 // Resolve any conflicts so we can safely add the new entry.
1058 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 922 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1059 &new_changes); 923 &new_changes);
1060 } 924 }
1061 // Force the local ID to kInvalidTemplateURLID so we can add it. 925 // Force the local ID to kInvalidTemplateURLID so we can add it.
1062 TemplateURLData data(turl->data()); 926 TemplateURLData data(turl->data());
1063 data.id = kInvalidTemplateURLID; 927 data.id = kInvalidTemplateURLID;
1064 Add(new TemplateURL(profile_, data)); 928 Add(new TemplateURL(profile_, data));
1065
1066 // Possibly set the newly added |turl| as the default search provider.
1067 SetDefaultSearchProviderIfNewlySynced(guid);
1068 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { 929 } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) {
1069 if (!existing_turl) { 930 if (!existing_turl) {
1070 error = sync_error_factory_->CreateAndUploadError( 931 error = sync_error_factory_->CreateAndUploadError(
1071 FROM_HERE, 932 FROM_HERE,
1072 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE"); 933 "ProcessSyncChanges failed on ChangeType ACTION_UPDATE");
1073 continue; 934 continue;
1074 } 935 }
1075 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) { 936 if (existing_keyword_turl && (existing_keyword_turl != existing_turl)) {
1076 // Resolve any conflicts with other entries so we can safely update the 937 // Resolve any conflicts with other entries so we can safely update the
1077 // keyword. 938 // keyword.
1078 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl, 939 ResolveSyncKeywordConflict(turl.get(), existing_keyword_turl,
1079 &new_changes); 940 &new_changes);
1080 } 941 }
1081 UIThreadSearchTermsData search_terms_data(existing_turl->profile()); 942 UIThreadSearchTermsData search_terms_data(existing_turl->profile());
1082 if (UpdateNoNotify(existing_turl, *turl, search_terms_data)) 943 if (UpdateNoNotify(existing_turl, turl->data(), search_terms_data))
1083 NotifyObservers(); 944 NotifyObservers();
1084 } else { 945 } else {
1085 // We've unexpectedly received an ACTION_INVALID. 946 // We've unexpectedly received an ACTION_INVALID.
1086 error = sync_error_factory_->CreateAndUploadError( 947 error = sync_error_factory_->CreateAndUploadError(
1087 FROM_HERE, 948 FROM_HERE,
1088 "ProcessSyncChanges received an ACTION_INVALID"); 949 "ProcessSyncChanges received an ACTION_INVALID");
1089 } 950 }
1090 } 951 }
1091 952
1092 // If something went wrong, we want to prematurely exit to avoid pushing 953 // If something went wrong, we want to prematurely exit to avoid pushing
(...skipping 13 matching lines...) Expand all
1106 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { 967 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
1107 DCHECK(loaded_); 968 DCHECK(loaded_);
1108 DCHECK_EQ(type, syncer::SEARCH_ENGINES); 969 DCHECK_EQ(type, syncer::SEARCH_ENGINES);
1109 DCHECK(!sync_processor_.get()); 970 DCHECK(!sync_processor_.get());
1110 DCHECK(sync_processor.get()); 971 DCHECK(sync_processor.get());
1111 DCHECK(sync_error_factory.get()); 972 DCHECK(sync_error_factory.get());
1112 syncer::SyncMergeResult merge_result(type); 973 syncer::SyncMergeResult merge_result(type);
1113 sync_processor_ = sync_processor.Pass(); 974 sync_processor_ = sync_processor.Pass();
1114 sync_error_factory_ = sync_error_factory.Pass(); 975 sync_error_factory_ = sync_error_factory.Pass();
1115 976
1116 // We just started syncing, so set our wait-for-default flag if we are
1117 // expecting a default from Sync.
1118 if (GetPrefs()) {
1119 std::string default_guid = GetPrefs()->GetString(
1120 prefs::kSyncedDefaultSearchProviderGUID);
1121 const TemplateURL* current_default = GetDefaultSearchProvider();
1122
1123 if (!default_guid.empty() &&
1124 (!current_default || current_default->sync_guid() != default_guid))
1125 pending_synced_default_search_ = true;
1126 }
1127
1128 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we 977 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we
1129 // don't step on our own toes. 978 // don't step on our own toes.
1130 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); 979 base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
1131 980
1132 // We've started syncing, so set our origin member to the base Sync value.
1133 // As we move through Sync Code, we may set this to increasingly specific
1134 // origins so we can tell what exactly caused a DSP change.
1135 base::AutoReset<DefaultSearchChangeOrigin> change_origin(&dsp_change_origin_,
1136 DSP_CHANGE_SYNC_UNINTENTIONAL);
1137
1138 syncer::SyncChangeList new_changes; 981 syncer::SyncChangeList new_changes;
1139 982
1140 // Build maps of our sync GUIDs to syncer::SyncData. 983 // Build maps of our sync GUIDs to syncer::SyncData.
1141 SyncDataMap local_data_map = CreateGUIDToSyncDataMap( 984 SyncDataMap local_data_map = CreateGUIDToSyncDataMap(
1142 GetAllSyncData(syncer::SEARCH_ENGINES)); 985 GetAllSyncData(syncer::SEARCH_ENGINES));
1143 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data); 986 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data);
1144 987
1145 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 988 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1146 989
1147 merge_result.set_num_items_before_association(local_data_map.size()); 990 merge_result.set_num_items_before_association(local_data_map.size());
(...skipping 25 matching lines...) Expand all
1173 // This local search engine is already synced. If the timestamp differs 1016 // This local search engine is already synced. If the timestamp differs
1174 // from Sync, we need to update locally or to the cloud. Note that if the 1017 // from Sync, we need to update locally or to the cloud. Note that if the
1175 // timestamps are equal, we touch neither. 1018 // timestamps are equal, we touch neither.
1176 if (sync_turl->last_modified() > local_turl->last_modified()) { 1019 if (sync_turl->last_modified() > local_turl->last_modified()) {
1177 // We've received an update from Sync. We should replace all synced 1020 // We've received an update from Sync. We should replace all synced
1178 // fields in the local TemplateURL. Note that this includes the 1021 // fields in the local TemplateURL. Note that this includes the
1179 // TemplateURLID and the TemplateURL may have to be reparsed. This 1022 // TemplateURLID and the TemplateURL may have to be reparsed. This
1180 // also makes the local data's last_modified timestamp equal to Sync's, 1023 // also makes the local data's last_modified timestamp equal to Sync's,
1181 // avoiding an Update on the next MergeData call. 1024 // avoiding an Update on the next MergeData call.
1182 UIThreadSearchTermsData search_terms_data(local_turl->profile()); 1025 UIThreadSearchTermsData search_terms_data(local_turl->profile());
1183 if (UpdateNoNotify(local_turl, *sync_turl, search_terms_data)) 1026 if (UpdateNoNotify(local_turl, sync_turl->data(), search_terms_data))
1184 NotifyObservers(); 1027 NotifyObservers();
1185 merge_result.set_num_items_modified( 1028 merge_result.set_num_items_modified(
1186 merge_result.num_items_modified() + 1); 1029 merge_result.num_items_modified() + 1);
1187 } else if (sync_turl->last_modified() < local_turl->last_modified()) { 1030 } else if (sync_turl->last_modified() < local_turl->last_modified()) {
1188 // Otherwise, we know we have newer data, so update Sync with our 1031 // Otherwise, we know we have newer data, so update Sync with our
1189 // data fields. 1032 // data fields.
1190 new_changes.push_back( 1033 new_changes.push_back(
1191 syncer::SyncChange(FROM_HERE, 1034 syncer::SyncChange(FROM_HERE,
1192 syncer::SyncChange::ACTION_UPDATE, 1035 syncer::SyncChange::ACTION_UPDATE,
1193 local_data_map[local_turl->sync_guid()])); 1036 local_data_map[local_turl->sync_guid()]));
1194 } 1037 }
1195 local_data_map.erase(iter->first); 1038 local_data_map.erase(iter->first);
1196 } else { 1039 } else {
1197 // The search engine from the cloud has not been synced locally. Merge it 1040 // The search engine from the cloud has not been synced locally. Merge it
1198 // into our local model. This will handle any conflicts with local (and 1041 // into our local model. This will handle any conflicts with local (and
1199 // already-synced) TemplateURLs. It will prefer to keep entries from Sync 1042 // already-synced) TemplateURLs. It will prefer to keep entries from Sync
1200 // over not-yet-synced TemplateURLs. 1043 // over not-yet-synced TemplateURLs.
1201 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes, 1044 MergeInSyncTemplateURL(sync_turl.get(), sync_data_map, &new_changes,
1202 &local_data_map, &merge_result); 1045 &local_data_map, &merge_result);
1203 } 1046 }
1204 } 1047 }
1205 1048
1206 // If there is a pending synced default search provider that was processed
1207 // above, set it now.
1208 TemplateURL* pending_default = GetPendingSyncedDefaultSearchProvider();
1209 if (pending_default) {
1210 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
1211 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
1212 SetUserSelectedDefaultSearchProvider(pending_default);
1213 }
1214
1215 // The remaining SyncData in local_data_map should be everything that needs to 1049 // The remaining SyncData in local_data_map should be everything that needs to
1216 // be pushed as ADDs to sync. 1050 // be pushed as ADDs to sync.
1217 for (SyncDataMap::const_iterator iter = local_data_map.begin(); 1051 for (SyncDataMap::const_iterator iter = local_data_map.begin();
1218 iter != local_data_map.end(); ++iter) { 1052 iter != local_data_map.end(); ++iter) {
1219 new_changes.push_back( 1053 new_changes.push_back(
1220 syncer::SyncChange(FROM_HERE, 1054 syncer::SyncChange(FROM_HERE,
1221 syncer::SyncChange::ACTION_ADD, 1055 syncer::SyncChange::ACTION_ADD,
1222 iter->second)); 1056 iter->second));
1223 } 1057 }
1224 1058
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 if (profile_) { 1283 if (profile_) {
1450 // TODO(sky): bug 1166191. The keywords should be moved into the history 1284 // TODO(sky): bug 1166191. The keywords should be moved into the history
1451 // db, which will mean we no longer need this notification and the history 1285 // db, which will mean we no longer need this notification and the history
1452 // backend can handle automatically adding the search terms as the user 1286 // backend can handle automatically adding the search terms as the user
1453 // navigates. 1287 // navigates.
1454 content::Source<Profile> profile_source(profile_->GetOriginalProfile()); 1288 content::Source<Profile> profile_source(profile_->GetOriginalProfile());
1455 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, 1289 notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED,
1456 profile_source); 1290 profile_source);
1457 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED, 1291 notification_registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_URL_UPDATED,
1458 profile_source); 1292 profile_source);
1459 pref_change_registrar_.Init(GetPrefs());
1460 pref_change_registrar_.Add(
1461 prefs::kSyncedDefaultSearchProviderGUID,
1462 base::Bind(
1463 &TemplateURLService::OnSyncedDefaultSearchProviderGUIDChanged,
1464 base::Unretained(this)));
1465 } 1293 }
1466 notification_registrar_.Add( 1294
1467 this, chrome::NOTIFICATION_DEFAULT_SEARCH_POLICY_CHANGED, 1295 DefaultSearchManager::Source source = DefaultSearchManager::FROM_USER;
1468 content::NotificationService::AllSources()); 1296 TemplateURLData* dse =
1297 default_search_manager_->GetDefaultSearchEngine(&source);
1298 OnDefaultSearchChange(dse, source);
1469 1299
1470 if (num_initializers > 0) { 1300 if (num_initializers > 0) {
1471 // This path is only hit by test code and is used to simulate a loaded 1301 // This path is only hit by test code and is used to simulate a loaded
1472 // TemplateURLService. 1302 // TemplateURLService.
1473 ChangeToLoadedState(); 1303 ChangeToLoadedState();
1474 1304
1475 // Add specific initializers, if any. 1305 // Add specific initializers, if any.
1476 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get()); 1306 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1477 for (int i(0); i < num_initializers; ++i) { 1307 for (int i(0); i < num_initializers; ++i) {
1478 DCHECK(initializers[i].keyword); 1308 DCHECK(initializers[i].keyword);
1479 DCHECK(initializers[i].url); 1309 DCHECK(initializers[i].url);
1480 DCHECK(initializers[i].content); 1310 DCHECK(initializers[i].content);
1481 1311
1482 // TemplateURLService ends up owning the TemplateURL, don't try and free 1312 // TemplateURLService ends up owning the TemplateURL, don't try and free
1483 // it. 1313 // it.
1484 TemplateURLData data; 1314 TemplateURLData data;
1485 data.short_name = base::UTF8ToUTF16(initializers[i].content); 1315 data.short_name = base::UTF8ToUTF16(initializers[i].content);
1486 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword)); 1316 data.SetKeyword(base::UTF8ToUTF16(initializers[i].keyword));
1487 data.SetURL(initializers[i].url); 1317 data.SetURL(initializers[i].url);
1488 TemplateURL* template_url = new TemplateURL(profile_, data); 1318 TemplateURL* template_url = new TemplateURL(profile_, data);
1489 AddNoNotify(template_url, true); 1319 AddNoNotify(template_url, true);
1490 1320
1491 // Set the first provided identifier to be the default. 1321 // Set the first provided identifier to be the default.
1492 if (i == 0) 1322 if (i == 0)
1493 SetDefaultSearchProviderNoNotify(template_url); 1323 default_search_manager_->SetUserSelectedDefaultSearchEngine(data);
1494 } 1324 }
1495 } 1325 }
1496 1326
1497 // Initialize default search.
1498 UpdateDefaultSearch();
1499
1500 // Request a server check for the correct Google URL if Google is the 1327 // Request a server check for the correct Google URL if Google is the
1501 // default search engine and not in headless mode. 1328 // default search engine and not in headless mode.
1502 if (profile_ && initial_default_search_provider_.get() && 1329 TemplateURL* default_search_provider = GetDefaultSearchProvider();
1503 initial_default_search_provider_->url_ref().HasGoogleBaseURLs()) { 1330 if (profile_ && default_search_provider &&
1331 default_search_provider->url_ref().HasGoogleBaseURLs()) {
1504 scoped_ptr<base::Environment> env(base::Environment::Create()); 1332 scoped_ptr<base::Environment> env(base::Environment::Create());
1505 if (!env->HasVar(env_vars::kHeadless)) 1333 if (!env->HasVar(env_vars::kHeadless))
1506 GoogleURLTracker::RequestServerCheck(profile_, false); 1334 GoogleURLTracker::RequestServerCheck(profile_, false);
1507 } 1335 }
1508 } 1336 }
1509 1337
1510 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) { 1338 void TemplateURLService::RemoveFromMaps(TemplateURL* template_url) {
1511 const base::string16& keyword = template_url->keyword(); 1339 const base::string16& keyword = template_url->keyword();
1512 DCHECK_NE(0U, keyword_to_template_map_.count(keyword)); 1340 DCHECK_NE(0U, keyword_to_template_map_.count(keyword));
1513 if (keyword_to_template_map_[keyword] == template_url) { 1341 if (keyword_to_template_map_[keyword] == template_url) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 // (possibly deleted) entry. 1434 // (possibly deleted) entry.
1607 urls->clear(); 1435 urls->clear();
1608 } 1436 }
1609 1437
1610 void TemplateURLService::ChangeToLoadedState() { 1438 void TemplateURLService::ChangeToLoadedState() {
1611 DCHECK(!loaded_); 1439 DCHECK(!loaded_);
1612 1440
1613 UIThreadSearchTermsData search_terms_data(profile_); 1441 UIThreadSearchTermsData search_terms_data(profile_);
1614 provider_map_->Init(template_urls_, search_terms_data); 1442 provider_map_->Init(template_urls_, search_terms_data);
1615 loaded_ = true; 1443 loaded_ = true;
1444
1445 // This will cause a call to NotifyObservers().
1446 OnDefaultSearchChange(initial_default_search_provider_
1447 ? &initial_default_search_provider_->data()
1448 : NULL,
1449 default_search_provider_source_);
1450 initial_default_search_provider_.reset();
1616 } 1451 }
1617 1452
1618 void TemplateURLService::SaveDefaultSearchProviderToPrefs( 1453 // static
1619 const TemplateURL* t_url) { 1454 void TemplateURLService::SaveDefaultSearchProviderToLegacyPrefs(
1620 PrefService* prefs = GetPrefs(); 1455 const TemplateURL* t_url, PrefService* prefs) {
1621 if (!prefs) 1456 if (!prefs)
1622 return; 1457 return;
1623 1458
1624 bool enabled = false; 1459 bool enabled = false;
1625 std::string search_url; 1460 std::string search_url;
1626 std::string suggest_url; 1461 std::string suggest_url;
1627 std::string instant_url; 1462 std::string instant_url;
1628 std::string image_url; 1463 std::string image_url;
1629 std::string new_tab_url; 1464 std::string new_tab_url;
1630 std::string search_url_post_params; 1465 std::string search_url_post_params;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings); 1516 prefs->SetString(prefs::kDefaultSearchProviderEncodings, encodings);
1682 prefs->SetString(prefs::kDefaultSearchProviderName, short_name); 1517 prefs->SetString(prefs::kDefaultSearchProviderName, short_name);
1683 prefs->SetString(prefs::kDefaultSearchProviderKeyword, keyword); 1518 prefs->SetString(prefs::kDefaultSearchProviderKeyword, keyword);
1684 prefs->SetString(prefs::kDefaultSearchProviderID, id_string); 1519 prefs->SetString(prefs::kDefaultSearchProviderID, id_string);
1685 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, prepopulate_id); 1520 prefs->SetString(prefs::kDefaultSearchProviderPrepopulateID, prepopulate_id);
1686 prefs->Set(prefs::kDefaultSearchProviderAlternateURLs, alternate_urls); 1521 prefs->Set(prefs::kDefaultSearchProviderAlternateURLs, alternate_urls);
1687 prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey, 1522 prefs->SetString(prefs::kDefaultSearchProviderSearchTermsReplacementKey,
1688 search_terms_replacement_key); 1523 search_terms_replacement_key);
1689 } 1524 }
1690 1525
1691 bool TemplateURLService::LoadDefaultSearchProviderFromPrefs( 1526 // static
1527 bool TemplateURLService::LoadDefaultSearchProviderFromLegacyPrefs(
1528 PrefService* prefs,
1692 scoped_ptr<TemplateURLData>* default_provider_data, 1529 scoped_ptr<TemplateURLData>* default_provider_data,
1693 bool* is_managed) { 1530 bool* is_managed) {
1694 PrefService* prefs = GetPrefs();
1695 if (!prefs || !prefs->HasPrefPath(prefs::kDefaultSearchProviderSearchURL) || 1531 if (!prefs || !prefs->HasPrefPath(prefs::kDefaultSearchProviderSearchURL) ||
1696 !prefs->HasPrefPath(prefs::kDefaultSearchProviderKeyword)) 1532 !prefs->HasPrefPath(prefs::kDefaultSearchProviderKeyword))
1697 return false; 1533 return false;
1698 1534
1699 const PrefService::Preference* pref = 1535 const PrefService::Preference* pref =
1700 prefs->FindPreference(prefs::kDefaultSearchProviderSearchURL); 1536 prefs->FindPreference(prefs::kDefaultSearchProviderSearchURL);
1701 *is_managed = pref && pref->IsManaged(); 1537 *is_managed = pref && pref->IsManaged();
1702 1538
1703 if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) { 1539 if (!prefs->GetBoolean(prefs::kDefaultSearchProviderEnabled)) {
1704 // The user doesn't want a default search provider. 1540 // The user doesn't want a default search provider.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1777 (*default_provider_data)->id = value; 1613 (*default_provider_data)->id = value;
1778 } 1614 }
1779 if (!prepopulate_id.empty() && !*is_managed) { 1615 if (!prepopulate_id.empty() && !*is_managed) {
1780 int value; 1616 int value;
1781 base::StringToInt(prepopulate_id, &value); 1617 base::StringToInt(prepopulate_id, &value);
1782 (*default_provider_data)->prepopulate_id = value; 1618 (*default_provider_data)->prepopulate_id = value;
1783 } 1619 }
1784 return true; 1620 return true;
1785 } 1621 }
1786 1622
1787 void TemplateURLService::ClearDefaultProviderFromPrefs() {
1788 // We overwrite user preferences. If the default search engine is managed,
1789 // there is no effect.
1790 SaveDefaultSearchProviderToPrefs(NULL);
1791 // Default value for kDefaultSearchProviderEnabled is true.
1792 PrefService* prefs = GetPrefs();
1793 if (prefs)
1794 prefs->SetBoolean(prefs::kDefaultSearchProviderEnabled, true);
1795 }
1796
1797 bool TemplateURLService::CanReplaceKeywordForHost( 1623 bool TemplateURLService::CanReplaceKeywordForHost(
1798 const std::string& host, 1624 const std::string& host,
1799 TemplateURL** to_replace) { 1625 TemplateURL** to_replace) {
1800 DCHECK(!to_replace || !*to_replace); 1626 DCHECK(!to_replace || !*to_replace);
1801 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host); 1627 const TemplateURLSet* urls = provider_map_->GetURLsForHost(host);
1802 if (!urls) 1628 if (!urls)
1803 return true; 1629 return true;
1804 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) { 1630 for (TemplateURLSet::const_iterator i(urls->begin()); i != urls->end(); ++i) {
1805 if (CanReplace(*i)) { 1631 if (CanReplace(*i)) {
1806 if (to_replace) 1632 if (to_replace)
(...skipping 20 matching lines...) Expand all
1827 i != template_urls_.end(); ++i) { 1653 i != template_urls_.end(); ++i) {
1828 if (((*i)->GetType() == TemplateURL::NORMAL) && 1654 if (((*i)->GetType() == TemplateURL::NORMAL) &&
1829 ((*i)->keyword() == keyword)) 1655 ((*i)->keyword() == keyword))
1830 return *i; 1656 return *i;
1831 } 1657 }
1832 return NULL; 1658 return NULL;
1833 } 1659 }
1834 1660
1835 bool TemplateURLService::UpdateNoNotify( 1661 bool TemplateURLService::UpdateNoNotify(
1836 TemplateURL* existing_turl, 1662 TemplateURL* existing_turl,
1837 const TemplateURL& new_values, 1663 const TemplateURLData& new_values,
1838 const SearchTermsData& old_search_terms_data) { 1664 const SearchTermsData& old_search_terms_data) {
1839 DCHECK(loaded_); 1665 DCHECK(loaded_);
1840 DCHECK(existing_turl); 1666 DCHECK(existing_turl);
1841 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) == 1667 if (std::find(template_urls_.begin(), template_urls_.end(), existing_turl) ==
1842 template_urls_.end()) 1668 template_urls_.end())
1843 return false; 1669 return false;
1844 1670
1845 base::string16 old_keyword(existing_turl->keyword()); 1671 base::string16 old_keyword(existing_turl->keyword());
1846 keyword_to_template_map_.erase(old_keyword); 1672 keyword_to_template_map_.erase(old_keyword);
1847 if (!existing_turl->sync_guid().empty()) 1673 if (!existing_turl->sync_guid().empty())
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1885 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl; 1711 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl;
1886 1712
1887 if (service_.get()) 1713 if (service_.get())
1888 service_->UpdateKeyword(existing_turl->data()); 1714 service_->UpdateKeyword(existing_turl->data());
1889 1715
1890 // Inform sync of the update. 1716 // Inform sync of the update.
1891 ProcessTemplateURLChange(FROM_HERE, 1717 ProcessTemplateURLChange(FROM_HERE,
1892 existing_turl, 1718 existing_turl,
1893 syncer::SyncChange::ACTION_UPDATE); 1719 syncer::SyncChange::ACTION_UPDATE);
1894 1720
1895 if (default_search_provider_ == existing_turl) { 1721 if (default_search_provider_ == existing_turl &&
1896 bool success = SetDefaultSearchProviderNoNotify(existing_turl); 1722 default_search_provider_source_ == DefaultSearchManager::FROM_USER) {
1897 DCHECK(success); 1723 default_search_manager_->SetUserSelectedDefaultSearchEngine(
1724 default_search_provider_->data());
1898 } 1725 }
1899 return true; 1726 return true;
1900 } 1727 }
1901 1728
1902 // static 1729 // static
1903 void TemplateURLService::UpdateTemplateURLIfPrepopulated( 1730 void TemplateURLService::UpdateTemplateURLIfPrepopulated(
1904 TemplateURL* template_url, 1731 TemplateURL* template_url,
1905 Profile* profile) { 1732 Profile* profile) {
1906 int prepopulate_id = template_url->prepopulate_id(); 1733 int prepopulate_id = template_url->prepopulate_id();
1907 if (template_url->prepopulate_id() == 0) 1734 if (template_url->prepopulate_id() == 0)
1908 return; 1735 return;
1909 1736
1910 size_t default_search_index; 1737 size_t default_search_index;
1911 ScopedVector<TemplateURLData> prepopulated_urls = 1738 ScopedVector<TemplateURLData> prepopulated_urls =
1912 TemplateURLPrepopulateData::GetPrepopulatedEngines( 1739 TemplateURLPrepopulateData::GetPrepopulatedEngines(
1913 profile ? profile->GetPrefs() : NULL, &default_search_index); 1740 profile ? profile->GetPrefs() : NULL, &default_search_index);
1914 1741
1915 for (size_t i = 0; i < prepopulated_urls.size(); ++i) { 1742 for (size_t i = 0; i < prepopulated_urls.size(); ++i) {
1916 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) { 1743 if (prepopulated_urls[i]->prepopulate_id == prepopulate_id) {
1917 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]); 1744 MergeIntoPrepopulatedEngineData(template_url, prepopulated_urls[i]);
1918 template_url->CopyFrom(TemplateURL(profile, *prepopulated_urls[i])); 1745 template_url->CopyFrom(*prepopulated_urls[i]);
1919 } 1746 }
1920 } 1747 }
1921 } 1748 }
1922 1749
1923 PrefService* TemplateURLService::GetPrefs() { 1750 PrefService* TemplateURLService::GetPrefs() {
1924 return profile_ ? profile_->GetPrefs() : NULL; 1751 return profile_ ? profile_->GetPrefs() : NULL;
1925 } 1752 }
1926 1753
1927 void TemplateURLService::UpdateKeywordSearchTermsForURL( 1754 void TemplateURLService::UpdateKeywordSearchTermsForURL(
1928 const history::URLVisitedDetails& details) { 1755 const history::URLVisitedDetails& details) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2003 // |provider_map_| will not be updated correctly. 1830 // |provider_map_| will not be updated correctly.
2004 if (CanReplace(existing_entry->second)) 1831 if (CanReplace(existing_entry->second))
2005 RemoveNoNotify(existing_entry->second); 1832 RemoveNoNotify(existing_entry->second);
2006 else 1833 else
2007 updated_turl.data_.SetKeyword(t_url->keyword()); 1834 updated_turl.data_.SetKeyword(t_url->keyword());
2008 } 1835 }
2009 something_changed = true; 1836 something_changed = true;
2010 // This will send the keyword change to sync. Note that other clients 1837 // This will send the keyword change to sync. Note that other clients
2011 // need to reset the keyword to an appropriate local value when this 1838 // need to reset the keyword to an appropriate local value when this
2012 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData(). 1839 // change arrives; see CreateTemplateURLFromTemplateURLAndSyncData().
2013 UpdateNoNotify(t_url, updated_turl, 1840 UpdateNoNotify(t_url, updated_turl.data(),
2014 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec())); 1841 OldBaseURLSearchTermsData(t_url->profile(), old_base_url.spec()));
2015 } 1842 }
2016 } 1843 }
2017 if (something_changed) 1844 if (something_changed)
2018 NotifyObservers(); 1845 NotifyObservers();
2019 } 1846 }
2020 1847
2021 void TemplateURLService::UpdateDefaultSearch() { 1848 void TemplateURLService::OnDefaultSearchChange(
1849 const TemplateURLData* data,
1850 DefaultSearchManager::Source source) {
2022 if (!loaded_) { 1851 if (!loaded_) {
2023 // Set |initial_default_search_provider_| from the preferences. We use this 1852 // Set |initial_default_search_provider_| from the preferences. This is
2024 // value for default search provider until the database has been loaded. 1853 // mainly so we can hold ownership until we get to the point where the list
2025 scoped_ptr<TemplateURLData> data; 1854 // of keywords from Web Data is the owner of everything including the
2026 if (!LoadDefaultSearchProviderFromPrefs(&data, 1855 // default.
2027 &is_default_search_managed_)) { 1856 initial_default_search_provider_.reset(
2028 // Prefs does not specify, so rely on the prepopulated engines. This 1857 data ? new TemplateURL(profile_, *data) : NULL);
2029 // should happen only the first time Chrome is started. 1858 default_search_provider_source_ = source;
2030 data = 1859 return;
2031 TemplateURLPrepopulateData::GetPrepopulatedDefaultSearch(GetPrefs()); 1860 }
2032 is_default_search_managed_ = false; 1861
1862 // Prevent recursion if we update the value stored in default_search_manager_.
1863 // Note that we exclude if data == NULL because that could cause a false
1864 // positive for recursion when the initial_default_search_provider_ is NULL
1865 // due to policy. No recursion case could lead to recursion with NULL.
1866 if (source == default_search_provider_source_ && data != NULL &&
1867 TemplateURLMatchesData(default_search_provider_, data))
1868 return;
1869
1870 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
1871 if (default_search_provider_source_ == DefaultSearchManager::FROM_POLICY ||
1872 source == DefaultSearchManager::FROM_POLICY) {
1873 // We do this both to clear up removed policy-defined DSE as well as to add
1874 // the new one, if appropriate.
1875 UpdateProvidersCreatedByPolicy(
1876 &template_urls_,
1877 source == DefaultSearchManager::FROM_POLICY ? data : NULL);
1878 }
1879
1880 if (!data) {
1881 default_search_provider_ = NULL;
1882 default_search_provider_source_ = source;
1883 NotifyObservers();
1884 return;
1885 }
1886
1887 if (source == DefaultSearchManager::FROM_EXTENSION) {
1888 default_search_provider_ = FindMatchingExtensionTemplateURL(
1889 *data, TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION);
1890 }
1891
1892 if (source == DefaultSearchManager::FROM_FALLBACK) {
1893 default_search_provider_ =
1894 FindPrepopulatedTemplateURL(data->prepopulate_id);
1895 if (default_search_provider_) {
1896 TemplateURLData update_data(*data);
1897 update_data.sync_guid = default_search_provider_->sync_guid();
1898 UIThreadSearchTermsData search_terms_data(
1899 default_search_provider_->profile());
1900 UpdateNoNotify(default_search_provider_, update_data, search_terms_data);
1901 } else {
1902 // TODO(erikwright): AFAIU something ought to have inserted all of the
1903 // pre-populated DSEs in web data by now.. Maybe it isn't done in tests^
1904 TemplateURL* new_dse = new TemplateURL(profile_, *data);
1905 if (AddNoNotify(new_dse, true))
1906 default_search_provider_ = new_dse;
1907 else
1908 delete new_dse;
1909 }
1910 }
1911 if (source == DefaultSearchManager::FROM_USER) {
1912 default_search_provider_ = GetTemplateURLForGUID(data->sync_guid);
1913 if (default_search_provider_) {
1914 TemplateURLData new_data(*data);
1915 new_data.show_in_default_list = true;
1916 UIThreadSearchTermsData search_terms_data(
1917 default_search_provider_->profile());
1918 UpdateNoNotify(default_search_provider_, new_data, search_terms_data);
1919 } else {
1920 TemplateURL* new_dse = new TemplateURL(profile_, *data);
1921 new_dse->data_.show_in_default_list = true;
1922 new_dse->data_.id = kInvalidTemplateURLID;
1923 if (!AddNoNotify(new_dse, true))
1924 delete new_dse;
1925 else
1926 default_search_provider_ = new_dse;
2033 } 1927 }
2034 1928
2035 initial_default_search_provider_.reset(
2036 data ? new TemplateURL(profile_, *data) : NULL);
2037
2038 return;
2039 }
2040 // Load the default search specified in prefs.
2041 scoped_ptr<TemplateURLData> new_default_from_prefs;
2042 bool new_is_default_managed = false;
2043 // Load the default from prefs. It's possible that it won't succeed
2044 // because we are in the middle of doing SaveDefaultSearchProviderToPrefs()
2045 // and all the preference items have not been saved. In that case, we
2046 // don't have yet a default. It would be much better if we could save
2047 // preferences in batches and trigger notifications at the end.
2048 LoadDefaultSearchProviderFromPrefs(&new_default_from_prefs,
2049 &new_is_default_managed);
2050 if (!is_default_search_managed_ && !new_is_default_managed) {
2051 // We're not interested in cases where the default was and remains
2052 // unmanaged. In that case, preferences have no impact on the default.
2053 return;
2054 }
2055 WebDataService::KeywordBatchModeScoper keyword_scoper(service_.get());
2056 if (is_default_search_managed_ && new_is_default_managed) {
2057 // The default was managed and remains managed. Update the default only
2058 // if it has changed; we don't want to respond to changes triggered by
2059 // SaveDefaultSearchProviderToPrefs.
2060 if (TemplateURLMatchesData(default_search_provider_,
2061 new_default_from_prefs.get()))
2062 return;
2063 if (!new_default_from_prefs) {
2064 // default_search_provider_ can't be NULL otherwise
2065 // TemplateURLMatchesData would have returned true. Remove this now
2066 // invalid value.
2067 TemplateURL* old_default = default_search_provider_;
2068 bool success = SetDefaultSearchProviderNoNotify(NULL);
2069 DCHECK(success);
2070 RemoveNoNotify(old_default);
2071 } else if (default_search_provider_) {
2072 new_default_from_prefs->created_by_policy = true;
2073 TemplateURL new_values(profile_, *new_default_from_prefs);
2074 UIThreadSearchTermsData search_terms_data(
2075 default_search_provider_->profile());
2076 UpdateNoNotify(default_search_provider_, new_values, search_terms_data);
2077 } else {
2078 TemplateURL* new_template = NULL;
2079 if (new_default_from_prefs) {
2080 new_default_from_prefs->created_by_policy = true;
2081 new_template = new TemplateURL(profile_, *new_default_from_prefs);
2082 if (!AddNoNotify(new_template, true))
2083 return;
2084 }
2085 bool success = SetDefaultSearchProviderNoNotify(new_template);
2086 DCHECK(success);
2087 }
2088 } else if (!is_default_search_managed_ && new_is_default_managed) {
2089 // The default used to be unmanaged and is now managed. Add the new
2090 // managed default to the list of URLs and set it as default.
2091 is_default_search_managed_ = new_is_default_managed;
2092 TemplateURL* new_template = NULL;
2093 if (new_default_from_prefs) {
2094 new_default_from_prefs->created_by_policy = true;
2095 new_template = new TemplateURL(profile_, *new_default_from_prefs);
2096 if (!AddNoNotify(new_template, true))
2097 return;
2098 }
2099 bool success = SetDefaultSearchProviderNoNotify(new_template);
2100 DCHECK(success);
2101 } else {
2102 // The default was managed and is no longer.
2103 DCHECK(is_default_search_managed_ && !new_is_default_managed);
2104 is_default_search_managed_ = new_is_default_managed;
2105 // If we had a default, delete the previous default if created by policy
2106 // and set a likely default.
2107 if ((default_search_provider_ != NULL) &&
2108 default_search_provider_->created_by_policy()) {
2109 TemplateURL* old_default = default_search_provider_;
2110 default_search_provider_ = NULL;
2111 RemoveNoNotify(old_default);
2112 }
2113
2114 // The likely default should be from Sync if we were waiting on Sync.
2115 // Otherwise, it should be FindNewDefaultSearchProvider.
2116 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
2117 if (synced_default) {
2118 pending_synced_default_search_ = false;
2119
2120 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2121 &dsp_change_origin_, DSP_CHANGE_SYNC_NOT_MANAGED);
2122 SetDefaultSearchProviderNoNotify(synced_default);
2123 } else {
2124 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
2125 }
2126 }
2127 NotifyObservers();
2128 }
2129
2130 void TemplateURLService::SetDefaultSearchProvider(
2131 TemplateURL* url) {
2132 DCHECK(!is_default_search_managed_);
2133 // Omnibox keywords cannot be made default. Extension-controlled search
2134 // engines can be made default only by the extension itself because they
2135 // aren't persisted.
2136 DCHECK(!url || (url->GetType() == TemplateURL::NORMAL));
2137
2138 // Always persist the setting in the database, that way if the backup
2139 // signature has changed out from under us it gets reset correctly.
2140 if (SetDefaultSearchProviderNoNotify(url))
2141 NotifyObservers();
2142 }
2143
2144 bool TemplateURLService::SetDefaultSearchProviderNoNotify(TemplateURL* url) {
2145 if (url) {
2146 if (std::find(template_urls_.begin(), template_urls_.end(), url) ==
2147 template_urls_.end())
2148 return false;
2149 // Omnibox keywords cannot be made default.
2150 DCHECK_NE(TemplateURL::OMNIBOX_API_EXTENSION, url->GetType());
2151 } 1929 }
2152 1930
2153 // Only bother reassigning |url| if it has changed. Notice that we don't just 1931 default_search_provider_source_ = source;
2154 // early exit if they are equal, because |url| may have had its fields
2155 // changed, and needs to be persisted below (for example, when this is called
2156 // from UpdateNoNotify).
2157 if (default_search_provider_ != url) {
2158 // Engines set by policy override extension-controlled engines, which
2159 // override other engines.
2160 DCHECK(!is_default_search_managed() || !url ||
2161 (url->GetType() == TemplateURL::NORMAL));
2162 if (is_default_search_managed() || !default_search_provider_ ||
2163 (default_search_provider_->GetType() == TemplateURL::NORMAL) ||
2164 (url &&
2165 (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION))){
2166 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchChangeOrigin",
2167 dsp_change_origin_, DSP_CHANGE_MAX);
2168 default_search_provider_ = url;
2169 }
2170 }
2171 1932
2172 if (url) { 1933 if (default_search_provider_ &&
2173 // Don't mark the url as edited, otherwise we won't be able to rev the 1934 default_search_provider_->url_ref().HasGoogleBaseURLs()) {
2174 // template urls we ship with.
2175 url->data_.show_in_default_list = true;
2176 if (service_.get() && (url->GetType() == TemplateURL::NORMAL))
2177 service_->UpdateKeyword(url->data());
2178
2179 if (url->url_ref().HasGoogleBaseURLs()) {
2180 GoogleURLTracker::RequestServerCheck(profile_, false); 1935 GoogleURLTracker::RequestServerCheck(profile_, false);
2181 #if defined(ENABLE_RLZ) 1936 #if defined(ENABLE_RLZ)
1937 // TODO(erikwright): should this only be if user-selected?
2182 RLZTracker::RecordProductEvent(rlz_lib::CHROME, 1938 RLZTracker::RecordProductEvent(rlz_lib::CHROME,
2183 RLZTracker::CHROME_OMNIBOX, 1939 RLZTracker::CHROME_OMNIBOX,
2184 rlz_lib::SET_TO_GOOGLE); 1940 rlz_lib::SET_TO_GOOGLE);
2185 #endif 1941 #endif
2186 }
2187 } 1942 }
2188 1943
2189 // Extension-controlled search engines shouldn't be persisted anywhere. 1944 NotifyObservers();
2190 if (url && (url->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION))
2191 return true;
2192
2193 if (!is_default_search_managed_) {
2194 SaveDefaultSearchProviderToPrefs(url);
2195
2196 // If we are syncing, we want to set the synced pref that will notify other
2197 // instances to change their default to this new search provider.
2198 // Note: we don't update the pref if we're currently in the middle of
2199 // handling a sync operation. Sync operations from other clients are not
2200 // guaranteed to arrive together, and any client that deletes the default
2201 // needs to set a new default as well. If we update the default here, we're
2202 // likely to race with the update from the other client, resulting in
2203 // a possibly random default search provider.
2204 if (sync_processor_.get() && url && !url->sync_guid().empty() &&
2205 GetPrefs() && !processing_syncer_changes_) {
2206 GetPrefs()->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2207 url->sync_guid());
2208 }
2209 }
2210
2211 if (service_.get())
2212 service_->SetDefaultSearchProviderID(url ? url->id() : 0);
2213
2214 // Inform sync the change to the show_in_default_list flag.
2215 if (url)
2216 ProcessTemplateURLChange(FROM_HERE,
2217 url,
2218 syncer::SyncChange::ACTION_UPDATE);
2219 return true;
2220 } 1945 }
2221 1946
2222 bool TemplateURLService::AddNoNotify(TemplateURL* template_url, 1947 bool TemplateURLService::AddNoNotify(TemplateURL* template_url,
2223 bool newly_adding) { 1948 bool newly_adding) {
2224 DCHECK(template_url); 1949 DCHECK(template_url);
2225 1950
2226 if (newly_adding) { 1951 if (newly_adding) {
2227 DCHECK_EQ(kInvalidTemplateURLID, template_url->id()); 1952 DCHECK_EQ(kInvalidTemplateURLID, template_url->id());
2228 DCHECK(std::find(template_urls_.begin(), template_urls_.end(), 1953 DCHECK(std::find(template_urls_.begin(), template_urls_.end(),
2229 template_url) == template_urls_.end()); 1954 template_url) == template_urls_.end());
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 2039
2315 void TemplateURLService::NotifyObservers() { 2040 void TemplateURLService::NotifyObservers() {
2316 if (!loaded_) 2041 if (!loaded_)
2317 return; 2042 return;
2318 2043
2319 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_, 2044 FOR_EACH_OBSERVER(TemplateURLServiceObserver, model_observers_,
2320 OnTemplateURLServiceChanged()); 2045 OnTemplateURLServiceChanged());
2321 } 2046 }
2322 2047
2323 // |template_urls| are the TemplateURLs loaded from the database. 2048 // |template_urls| are the TemplateURLs loaded from the database.
2324 // |default_search_provider| points to one of them, if it was set in the db. 2049 // |default_from_prefs| is the default search provider from the preferences, or
2325 // |default_from_prefs| is the default search provider from the preferences. 2050 // NULL if the DSE is not policy-defined.
2326 // Check |is_default_search_managed_| to determine if it was set by policy.
2327 // 2051 //
2328 // This function removes from the vector and the database all the TemplateURLs 2052 // This function removes from the vector and the database all the TemplateURLs
2329 // that were set by policy, unless it is the current default search provider 2053 // that were set by policy, unless it is the current default search provider, in
2330 // and matches what is set by a managed preference. 2054 // which case it is updated with the data from prefs.
2331 void TemplateURLService::RemoveProvidersCreatedByPolicy( 2055 void TemplateURLService::UpdateProvidersCreatedByPolicy(
2332 TemplateURLVector* template_urls, 2056 TemplateURLVector* template_urls,
2333 TemplateURL** default_search_provider, 2057 const TemplateURLData* default_from_prefs) {
2334 TemplateURLData* default_from_prefs) {
2335 DCHECK(template_urls); 2058 DCHECK(template_urls);
2336 DCHECK(default_search_provider); 2059
2337 for (TemplateURLVector::iterator i = template_urls->begin(); 2060 for (TemplateURLVector::iterator i = template_urls->begin();
2338 i != template_urls->end(); ) { 2061 i != template_urls->end(); ) {
2339 TemplateURL* template_url = *i; 2062 TemplateURL* template_url = *i;
2340 if (template_url->created_by_policy()) { 2063 if (template_url->created_by_policy()) {
2341 if (template_url == *default_search_provider && 2064 if (default_from_prefs &&
2342 is_default_search_managed_ &&
2343 TemplateURLMatchesData(template_url, default_from_prefs)) { 2065 TemplateURLMatchesData(template_url, default_from_prefs)) {
2344 // If the database specified a default search provider that was set 2066 // If the database specified a default search provider that was set
2345 // by policy, and the default search provider from the preferences 2067 // by policy, and the default search provider from the preferences
2346 // is also set by policy and they are the same, keep the entry in the 2068 // is also set by policy and they are the same, keep the entry in the
2347 // database and the |default_search_provider|. 2069 // database and the |default_search_provider|.
2070 default_search_provider_ = template_url;
2071 // Prevent us from saving any other entries, or creating a new one.
2072 default_from_prefs = NULL;
2348 ++i; 2073 ++i;
2349 continue; 2074 continue;
2350 } 2075 }
2351 2076
2352 // The database loaded a managed |default_search_provider|, but it has 2077 RemoveFromMaps(template_url);
2353 // been updated in the prefs. Remove it from the database, and update the
2354 // |default_search_provider| pointer here.
2355 if (*default_search_provider &&
2356 (*default_search_provider)->id() == template_url->id())
2357 *default_search_provider = NULL;
2358
2359 i = template_urls->erase(i); 2078 i = template_urls->erase(i);
2360 if (service_.get()) 2079 if (service_.get())
2361 service_->RemoveKeyword(template_url->id()); 2080 service_->RemoveKeyword(template_url->id());
2362 delete template_url; 2081 delete template_url;
2363 } else { 2082 } else {
2364 ++i; 2083 ++i;
2365 } 2084 }
2366 } 2085 }
2086
2087 if (default_from_prefs) {
2088 default_search_provider_ = NULL;
2089 default_search_provider_source_ = DefaultSearchManager::FROM_POLICY;
2090 TemplateURLData new_data(*default_from_prefs);
2091 new_data.created_by_policy = true;
2092 TemplateURL* new_dse = new TemplateURL(profile_, new_data);
2093 if (!AddNoNotify(new_dse, true))
2094 delete new_dse;
2095 else
2096 default_search_provider_ = new_dse;
2097 }
2367 } 2098 }
2368 2099
2369 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url, 2100 void TemplateURLService::ResetTemplateURLGUID(TemplateURL* url,
2370 const std::string& guid) { 2101 const std::string& guid) {
2371 DCHECK(loaded_); 2102 DCHECK(loaded_);
2372 DCHECK(!guid.empty()); 2103 DCHECK(!guid.empty());
2373 2104
2374 TemplateURLData data(url->data()); 2105 TemplateURLData data(url->data());
2375 data.sync_guid = guid; 2106 data.sync_guid = guid;
2376 TemplateURL new_url(url->profile(), data);
2377 UIThreadSearchTermsData search_terms_data(url->profile()); 2107 UIThreadSearchTermsData search_terms_data(url->profile());
2378 UpdateNoNotify(url, new_url, search_terms_data); 2108 UpdateNoNotify(url, data, search_terms_data);
2379 } 2109 }
2380 2110
2381 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl, 2111 base::string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl,
2382 bool force) { 2112 bool force) {
2383 if (!force) { 2113 if (!force) {
2384 // Already unique. 2114 // Already unique.
2385 if (!GetTemplateURLForKeyword(turl.keyword())) 2115 if (!GetTemplateURLForKeyword(turl.keyword()))
2386 return turl.keyword(); 2116 return turl.keyword();
2387 2117
2388 // First, try to return the generated keyword for the TemplateURL (except 2118 // First, try to return the generated keyword for the TemplateURL (except
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 base::string16 new_keyword = UniquifyKeyword(*loser, false); 2169 base::string16 new_keyword = UniquifyKeyword(*loser, false);
2440 DCHECK(!GetTemplateURLForKeyword(new_keyword)); 2170 DCHECK(!GetTemplateURLForKeyword(new_keyword));
2441 if (applied_turl_is_better) { 2171 if (applied_turl_is_better) {
2442 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible 2172 // Just set the keyword of |unapplied_sync_turl|. The caller is responsible
2443 // for adding or updating unapplied_sync_turl in the local model. 2173 // for adding or updating unapplied_sync_turl in the local model.
2444 unapplied_sync_turl->data_.SetKeyword(new_keyword); 2174 unapplied_sync_turl->data_.SetKeyword(new_keyword);
2445 } else { 2175 } else {
2446 // Update |applied_sync_turl| in the local model with the new keyword. 2176 // Update |applied_sync_turl| in the local model with the new keyword.
2447 TemplateURLData data(applied_sync_turl->data()); 2177 TemplateURLData data(applied_sync_turl->data());
2448 data.SetKeyword(new_keyword); 2178 data.SetKeyword(new_keyword);
2449 TemplateURL new_turl(applied_sync_turl->profile(), data);
2450 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile()); 2179 UIThreadSearchTermsData search_terms_data(applied_sync_turl->profile());
2451 if (UpdateNoNotify(applied_sync_turl, new_turl, search_terms_data)) 2180 if (UpdateNoNotify(applied_sync_turl, data, search_terms_data))
2452 NotifyObservers(); 2181 NotifyObservers();
2453 } 2182 }
2454 // The losing TemplateURL should have their keyword updated. Send a change to 2183 // The losing TemplateURL should have their keyword updated. Send a change to
2455 // the server to reflect this change. 2184 // the server to reflect this change.
2456 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser); 2185 syncer::SyncData sync_data = CreateSyncDataFromTemplateURL(*loser);
2457 change_list->push_back(syncer::SyncChange(FROM_HERE, 2186 change_list->push_back(syncer::SyncChange(FROM_HERE,
2458 syncer::SyncChange::ACTION_UPDATE, 2187 syncer::SyncChange::ACTION_UPDATE,
2459 sync_data)); 2188 sync_data));
2460 } 2189 }
2461 2190
(...skipping 28 matching lines...) Expand all
2490 // |conflicting_turl| is not yet known to Sync. If it is better, then we 2219 // |conflicting_turl| is not yet known to Sync. If it is better, then we
2491 // want to transfer its values up to sync. Otherwise, we remove it and 2220 // want to transfer its values up to sync. Otherwise, we remove it and
2492 // allow the entry from Sync to overtake it in the model. 2221 // allow the entry from Sync to overtake it in the model.
2493 const std::string guid = conflicting_turl->sync_guid(); 2222 const std::string guid = conflicting_turl->sync_guid();
2494 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) { 2223 if (IsLocalTemplateURLBetter(conflicting_turl, sync_turl)) {
2495 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid()); 2224 ResetTemplateURLGUID(conflicting_turl, sync_turl->sync_guid());
2496 syncer::SyncData sync_data = 2225 syncer::SyncData sync_data =
2497 CreateSyncDataFromTemplateURL(*conflicting_turl); 2226 CreateSyncDataFromTemplateURL(*conflicting_turl);
2498 change_list->push_back(syncer::SyncChange( 2227 change_list->push_back(syncer::SyncChange(
2499 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data)); 2228 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, sync_data));
2500 if (conflicting_turl == GetDefaultSearchProvider() &&
2501 !pending_synced_default_search_) {
2502 // If we're not waiting for the Synced default to come in, we should
2503 // override the pref with our new GUID. If we are waiting for the
2504 // arrival of a synced default, setting the pref here would cause us
2505 // to lose the GUID we are waiting on.
2506 PrefService* prefs = GetPrefs();
2507 if (prefs) {
2508 prefs->SetString(prefs::kSyncedDefaultSearchProviderGUID,
2509 conflicting_turl->sync_guid());
2510 }
2511 }
2512 // Note that in this case we do not add the Sync TemplateURL to the 2229 // Note that in this case we do not add the Sync TemplateURL to the
2513 // local model, since we've effectively "merged" it in by updating the 2230 // local model, since we've effectively "merged" it in by updating the
2514 // local conflicting entry with its sync_guid. 2231 // local conflicting entry with its sync_guid.
2515 should_add_sync_turl = false; 2232 should_add_sync_turl = false;
2516 merge_result->set_num_items_modified( 2233 merge_result->set_num_items_modified(
2517 merge_result->num_items_modified() + 1); 2234 merge_result->num_items_modified() + 1);
2518 } else { 2235 } else {
2519 // We guarantee that this isn't the local search provider. Otherwise, 2236 // We guarantee that this isn't the local search provider. Otherwise,
2520 // local would have won. 2237 // local would have won.
2521 DCHECK(conflicting_turl != GetDefaultSearchProvider()); 2238 DCHECK(conflicting_turl != GetDefaultSearchProvider());
(...skipping 10 matching lines...) Expand all
2532 if (should_add_sync_turl) { 2249 if (should_add_sync_turl) {
2533 // Force the local ID to kInvalidTemplateURLID so we can add it. 2250 // Force the local ID to kInvalidTemplateURLID so we can add it.
2534 TemplateURLData data(sync_turl->data()); 2251 TemplateURLData data(sync_turl->data());
2535 data.id = kInvalidTemplateURLID; 2252 data.id = kInvalidTemplateURLID;
2536 Add(new TemplateURL(profile_, data)); 2253 Add(new TemplateURL(profile_, data));
2537 merge_result->set_num_items_added( 2254 merge_result->set_num_items_added(
2538 merge_result->num_items_added() + 1); 2255 merge_result->num_items_added() + 1);
2539 } 2256 }
2540 } 2257 }
2541 2258
2542 void TemplateURLService::SetDefaultSearchProviderIfNewlySynced(
2543 const std::string& guid) {
2544 // If we're not syncing or if default search is managed by policy, ignore.
2545 if (!sync_processor_.get() || is_default_search_managed_)
2546 return;
2547
2548 PrefService* prefs = GetPrefs();
2549 if (prefs && pending_synced_default_search_ &&
2550 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID) == guid) {
2551 // Make sure this actually exists. We should not be calling this unless we
2552 // really just added this TemplateURL.
2553 TemplateURL* turl_from_sync = GetTemplateURLForGUID(guid);
2554 if (turl_from_sync && turl_from_sync->SupportsReplacement()) {
2555 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2556 &dsp_change_origin_, DSP_CHANGE_SYNC_ADD);
2557 SetDefaultSearchProvider(turl_from_sync);
2558 }
2559 pending_synced_default_search_ = false;
2560 }
2561 }
2562
2563 TemplateURL* TemplateURLService::GetPendingSyncedDefaultSearchProvider() {
2564 PrefService* prefs = GetPrefs();
2565 if (!prefs || !pending_synced_default_search_)
2566 return NULL;
2567
2568 // Could be NULL if no such thing exists.
2569 return GetTemplateURLForGUID(
2570 prefs->GetString(prefs::kSyncedDefaultSearchProviderGUID));
2571 }
2572
2573 void TemplateURLService::PatchMissingSyncGUIDs( 2259 void TemplateURLService::PatchMissingSyncGUIDs(
2574 TemplateURLVector* template_urls) { 2260 TemplateURLVector* template_urls) {
2575 DCHECK(template_urls); 2261 DCHECK(template_urls);
2576 for (TemplateURLVector::iterator i = template_urls->begin(); 2262 for (TemplateURLVector::iterator i = template_urls->begin();
2577 i != template_urls->end(); ++i) { 2263 i != template_urls->end(); ++i) {
2578 TemplateURL* template_url = *i; 2264 TemplateURL* template_url = *i;
2579 DCHECK(template_url); 2265 DCHECK(template_url);
2580 if (template_url->sync_guid().empty() && 2266 if (template_url->sync_guid().empty() &&
2581 (template_url->GetType() != 2267 (template_url->GetType() !=
2582 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) { 2268 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION)) {
2583 template_url->data_.sync_guid = base::GenerateGUID(); 2269 template_url->data_.sync_guid = base::GenerateGUID();
2584 if (service_.get()) 2270 if (service_.get())
2585 service_->UpdateKeyword(template_url->data()); 2271 service_->UpdateKeyword(template_url->data());
2586 } 2272 }
2587 } 2273 }
2588 } 2274 }
2589 2275
2590 void TemplateURLService::AddTemplateURLsAndSetupDefaultEngine( 2276 TemplateURL* TemplateURLService::FindPrepopulatedTemplateURL(
2591 TemplateURLVector* template_urls, 2277 int prepopulated_id) const {
2592 TemplateURL* default_search_provider) { 2278 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2593 DCHECK(template_urls); 2279 i != template_urls_.end(); ++i) {
2594 is_default_search_managed_ = false; 2280 if ((*i)->prepopulate_id() == prepopulated_id)
2595 bool database_specified_a_default = (default_search_provider != NULL); 2281 return *i;
2282 }
2596 2283
2597 // Check if default search provider is now managed. 2284 return NULL;
2598 scoped_ptr<TemplateURLData> default_from_prefs;
2599 LoadDefaultSearchProviderFromPrefs(&default_from_prefs,
2600 &is_default_search_managed_);
2601
2602 // Remove entries that were created because of policy as they may have
2603 // changed since the database was saved.
2604 RemoveProvidersCreatedByPolicy(template_urls,
2605 &default_search_provider,
2606 default_from_prefs.get());
2607
2608 PatchMissingSyncGUIDs(template_urls);
2609
2610 if (is_default_search_managed_) {
2611 SetTemplateURLs(template_urls);
2612
2613 if (TemplateURLMatchesData(default_search_provider,
2614 default_from_prefs.get())) {
2615 // The value from the preferences was previously stored in the database.
2616 // Reuse it.
2617 } else {
2618 // The value from the preferences takes over.
2619 default_search_provider = NULL;
2620 if (default_from_prefs) {
2621 default_from_prefs->created_by_policy = true;
2622 default_from_prefs->id = kInvalidTemplateURLID;
2623 default_search_provider =
2624 new TemplateURL(profile_, *default_from_prefs);
2625 if (!AddNoNotify(default_search_provider, true))
2626 default_search_provider = NULL;
2627 }
2628 }
2629 // Note that this saves the default search provider to prefs.
2630 if (!default_search_provider ||
2631 ((default_search_provider->GetType() !=
2632 TemplateURL::OMNIBOX_API_EXTENSION) &&
2633 default_search_provider->SupportsReplacement())) {
2634 bool success = SetDefaultSearchProviderNoNotify(default_search_provider);
2635 DCHECK(success);
2636 }
2637 } else {
2638 // If we had a managed default, replace it with the synced default if
2639 // applicable, or the first provider of the list.
2640 TemplateURL* synced_default = GetPendingSyncedDefaultSearchProvider();
2641 if (synced_default) {
2642 default_search_provider = synced_default;
2643 pending_synced_default_search_ = false;
2644 } else if (database_specified_a_default &&
2645 default_search_provider == NULL) {
2646 UMA_HISTOGRAM_ENUMERATION(kFirstPotentialEngineHistogramName,
2647 FIRST_POTENTIAL_CALLSITE_ON_LOAD,
2648 FIRST_POTENTIAL_CALLSITE_MAX);
2649 default_search_provider = FirstPotentialDefaultEngine(*template_urls);
2650 }
2651
2652 // If the default search provider existed previously, then just
2653 // set the member variable. Otherwise, we'll set it using the method
2654 // to ensure that it is saved properly after its id is set.
2655 if (default_search_provider &&
2656 (default_search_provider->id() != kInvalidTemplateURLID)) {
2657 default_search_provider_ = default_search_provider;
2658 default_search_provider = NULL;
2659 }
2660 SetTemplateURLs(template_urls);
2661
2662 if (default_search_provider) {
2663 base::AutoReset<DefaultSearchChangeOrigin> change_origin(
2664 &dsp_change_origin_, default_from_prefs ?
2665 dsp_change_origin_ : DSP_CHANGE_NEW_ENGINE_NO_PREFS);
2666 // Note that this saves the default search provider to prefs.
2667 SetDefaultSearchProvider(default_search_provider);
2668 } else {
2669 // Always save the default search provider to prefs. That way we don't
2670 // have to worry about it being out of sync.
2671 if (default_search_provider_)
2672 SaveDefaultSearchProviderToPrefs(default_search_provider_);
2673 }
2674 }
2675 }
2676
2677 void TemplateURLService::EnsureDefaultSearchProviderExists() {
2678 if (!is_default_search_managed()) {
2679 bool has_default_search_provider = default_search_provider_ &&
2680 default_search_provider_->SupportsReplacement();
2681 UMA_HISTOGRAM_BOOLEAN("Search.HasDefaultSearchProvider",
2682 has_default_search_provider);
2683 // Ensure that default search provider exists. See http://crbug.com/116952.
2684 if (!has_default_search_provider) {
2685 bool success =
2686 SetDefaultSearchProviderNoNotify(FindNewDefaultSearchProvider());
2687 DCHECK(success);
2688 }
2689 // Don't log anything if the user has a NULL default search provider.
2690 if (default_search_provider_) {
2691 UMA_HISTOGRAM_ENUMERATION("Search.DefaultSearchProviderType",
2692 TemplateURLPrepopulateData::GetEngineType(*default_search_provider_),
2693 SEARCH_ENGINE_MAX);
2694 }
2695 }
2696 } 2285 }
2697 2286
2698 TemplateURL* TemplateURLService::CreateTemplateURLForExtension( 2287 TemplateURL* TemplateURLService::CreateTemplateURLForExtension(
2699 const ExtensionKeyword& extension_keyword) const { 2288 const ExtensionKeyword& extension_keyword) const {
2700 TemplateURLData data; 2289 TemplateURLData data;
2701 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name); 2290 data.short_name = base::UTF8ToUTF16(extension_keyword.extension_name);
2702 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword)); 2291 data.SetKeyword(base::UTF8ToUTF16(extension_keyword.extension_keyword));
2703 // This URL is not actually used for navigation. It holds the extension's 2292 // This URL is not actually used for navigation. It holds the extension's
2704 // ID, as well as forcing the TemplateURL to be treated as a search keyword. 2293 // ID, as well as forcing the TemplateURL to be treated as a search keyword.
2705 data.SetURL(std::string(extensions::kExtensionScheme) + "://" + 2294 data.SetURL(std::string(extensions::kExtensionScheme) + "://" +
2706 extension_keyword.extension_id + "/?q={searchTerms}"); 2295 extension_keyword.extension_id + "/?q={searchTerms}");
2707 return new TemplateURL(profile_, data); 2296 return new TemplateURL(profile_, data);
2708 } 2297 }
2709 2298
2710 TemplateURL* TemplateURLService::FindTemplateURLForExtension( 2299 TemplateURL* TemplateURLService::FindTemplateURLForExtension(
2711 const std::string& extension_id, 2300 const std::string& extension_id,
2712 TemplateURL::Type type) const { 2301 TemplateURL::Type type) const {
2713 DCHECK_NE(TemplateURL::NORMAL, type); 2302 DCHECK_NE(TemplateURL::NORMAL, type);
2714 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2303 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2715 i != template_urls_.end(); ++i) { 2304 i != template_urls_.end(); ++i) {
2716 if ((*i)->GetType() == type && 2305 if ((*i)->GetType() == type &&
2717 (*i)->GetExtensionId() == extension_id) 2306 (*i)->GetExtensionId() == extension_id)
2718 return *i; 2307 return *i;
2719 } 2308 }
2720 2309
2721 return NULL; 2310 return NULL;
2722 } 2311 }
2723 2312
2724 TemplateURL* TemplateURLService::FindExtensionDefaultSearchEngine() const { 2313 TemplateURL* TemplateURLService::FindMatchingExtensionTemplateURL(
2314 const TemplateURLData& data,
2315 TemplateURL::Type type) const {
2316 DCHECK_NE(TemplateURL::NORMAL, type);
2317 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2318 i != template_urls_.end(); ++i) {
2319 if ((*i)->GetType() == type && TemplateURLMatchesData(*i, &data))
2320 return *i;
2321 }
2322
2323 return NULL;
2324 }
2325
2326 void TemplateURLService::UpdateExtensionDefaultSearchEngine() {
2725 TemplateURL* most_recently_intalled_default = NULL; 2327 TemplateURL* most_recently_intalled_default = NULL;
2726 for (TemplateURLVector::const_iterator i = template_urls_.begin(); 2328 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2727 i != template_urls_.end(); ++i) { 2329 i != template_urls_.end(); ++i) {
2728 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) && 2330 if (((*i)->GetType() == TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION) &&
2729 (*i)->extension_info_->wants_to_be_default_engine && 2331 (*i)->extension_info_->wants_to_be_default_engine &&
2730 (*i)->SupportsReplacement() && 2332 (*i)->SupportsReplacement() &&
2731 (!most_recently_intalled_default || 2333 (!most_recently_intalled_default ||
2732 (most_recently_intalled_default->extension_info_->install_time < 2334 (most_recently_intalled_default->extension_info_->install_time <
2733 (*i)->extension_info_->install_time))) 2335 (*i)->extension_info_->install_time)))
2734 most_recently_intalled_default = *i; 2336 most_recently_intalled_default = *i;
2735 } 2337 }
2736 2338
2737 return most_recently_intalled_default; 2339 if (most_recently_intalled_default) {
2340 default_search_manager_->SetExtensionControlledDefaultSearchEngine(
2341 new TemplateURLData(most_recently_intalled_default->data()));
2342 } else {
2343 default_search_manager_->ClearExtensionControlledDefaultSearchEngine();
2344 }
2738 } 2345 }
2739
2740 void TemplateURLService::
2741 SetDefaultSearchProviderAfterRemovingDefaultExtension() {
2742 DCHECK(!is_default_search_managed());
2743 TemplateURL* new_dse = FindExtensionDefaultSearchEngine();
2744 if (!new_dse) {
2745 scoped_ptr<TemplateURLData> default_provider;
2746 bool is_managed;
2747 if (LoadDefaultSearchProviderFromPrefs(&default_provider, &is_managed) &&
2748 default_provider) {
2749 for (TemplateURLVector::const_iterator i = template_urls_.begin();
2750 i != template_urls_.end(); ++i) {
2751 if ((*i)->id() == default_provider->id) {
2752 new_dse = *i;
2753 break;
2754 }
2755 }
2756 }
2757 }
2758 if (!new_dse)
2759 new_dse = FindNewDefaultSearchProvider();
2760 SetDefaultSearchProviderNoNotify(new_dse);
2761 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698