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