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

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

Issue 7670007: Revert 96969 - Implement SyncableServices in TemplateURLService. Add related unittests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "base/auto_reset.h"
8 #include "base/command_line.h" 7 #include "base/command_line.h"
9 #include "base/environment.h" 8 #include "base/environment.h"
10 #include "base/i18n/case_conversion.h" 9 #include "base/i18n/case_conversion.h"
11 #include "base/stl_util.h" 10 #include "base/stl_util.h"
12 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
13 #include "base/string_split.h" 12 #include "base/string_split.h"
14 #include "base/string_util.h" 13 #include "base/string_util.h"
15 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
16 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
17 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/google/google_url_tracker.h" 17 #include "chrome/browser/google/google_url_tracker.h"
19 #include "chrome/browser/history/history.h" 18 #include "chrome/browser/history/history.h"
20 #include "chrome/browser/history/history_notifications.h" 19 #include "chrome/browser/history/history_notifications.h"
21 #include "chrome/browser/net/url_fixer_upper.h" 20 #include "chrome/browser/net/url_fixer_upper.h"
22 #include "chrome/browser/prefs/pref_service.h" 21 #include "chrome/browser/prefs/pref_service.h"
23 #include "chrome/browser/prefs/pref_set_observer.h" 22 #include "chrome/browser/prefs/pref_set_observer.h"
24 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/rlz/rlz.h" 24 #include "chrome/browser/rlz/rlz.h"
26 #include "chrome/browser/search_engines/search_host_to_urls_map.h" 25 #include "chrome/browser/search_engines/search_host_to_urls_map.h"
27 #include "chrome/browser/search_engines/search_terms_data.h" 26 #include "chrome/browser/search_engines/search_terms_data.h"
28 #include "chrome/browser/search_engines/template_url.h" 27 #include "chrome/browser/search_engines/template_url.h"
29 #include "chrome/browser/search_engines/template_url_service_observer.h" 28 #include "chrome/browser/search_engines/template_url_service_observer.h"
30 #include "chrome/browser/search_engines/template_url_prepopulate_data.h" 29 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
31 #include "chrome/browser/search_engines/util.h" 30 #include "chrome/browser/search_engines/util.h"
32 #include "chrome/browser/sync/api/sync_change.h"
33 #include "chrome/browser/sync/protocol/search_engine_specifics.pb.h"
34 #include "chrome/common/chrome_notification_types.h" 31 #include "chrome/common/chrome_notification_types.h"
35 #include "chrome/common/chrome_switches.h" 32 #include "chrome/common/chrome_switches.h"
36 #include "chrome/common/env_vars.h" 33 #include "chrome/common/env_vars.h"
37 #include "chrome/common/extensions/extension.h" 34 #include "chrome/common/extensions/extension.h"
38 #include "chrome/common/guid.h"
39 #include "chrome/common/pref_names.h" 35 #include "chrome/common/pref_names.h"
40 #include "chrome/common/url_constants.h" 36 #include "chrome/common/url_constants.h"
41 #include "content/common/notification_service.h" 37 #include "content/common/notification_service.h"
42 #include "net/base/net_util.h" 38 #include "net/base/net_util.h"
43 #include "ui/base/l10n/l10n_util.h" 39 #include "ui/base/l10n/l10n_util.h"
44 40
41 using base::Time;
45 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet; 42 typedef SearchHostToURLsMap::TemplateURLSet TemplateURLSet;
46 typedef TemplateURLService::SyncDataMap SyncDataMap;
47 43
48 namespace { 44 namespace {
49 45
50 // String in the URL that is replaced by the search term. 46 // String in the URL that is replaced by the search term.
51 const char kSearchTermParameter[] = "{searchTerms}"; 47 const char kSearchTermParameter[] = "{searchTerms}";
52 48
53 // String in Initializer that is replaced with kSearchTermParameter. 49 // String in Initializer that is replaced with kSearchTermParameter.
54 const char kTemplateParameter[] = "%s"; 50 const char kTemplateParameter[] = "%s";
55 51
56 // Term used when generating a search url. Use something obscure so that on 52 // Term used when generating a search url. Use something obscure so that on
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 }; 97 };
102 98
103 TemplateURLService::TemplateURLService(Profile* profile) 99 TemplateURLService::TemplateURLService(Profile* profile)
104 : profile_(profile), 100 : profile_(profile),
105 loaded_(false), 101 loaded_(false),
106 load_failed_(false), 102 load_failed_(false),
107 load_handle_(0), 103 load_handle_(0),
108 default_search_provider_(NULL), 104 default_search_provider_(NULL),
109 is_default_search_managed_(false), 105 is_default_search_managed_(false),
110 next_id_(1), 106 next_id_(1),
111 time_provider_(&base::Time::Now), 107 time_provider_(&base::Time::Now) {
112 models_associated_(false),
113 processing_syncer_changes_(false),
114 sync_processor_(NULL) {
115 DCHECK(profile_); 108 DCHECK(profile_);
116 Init(NULL, 0); 109 Init(NULL, 0);
117 } 110 }
118 111
119 TemplateURLService::TemplateURLService(const Initializer* initializers, 112 TemplateURLService::TemplateURLService(const Initializer* initializers,
120 const int count) 113 const int count)
121 : profile_(NULL), 114 : profile_(NULL),
122 loaded_(false), 115 loaded_(false),
123 load_failed_(false), 116 load_failed_(false),
124 load_handle_(0), 117 load_handle_(0),
125 service_(NULL), 118 service_(NULL),
126 default_search_provider_(NULL), 119 default_search_provider_(NULL),
127 is_default_search_managed_(false), 120 is_default_search_managed_(false),
128 next_id_(1), 121 next_id_(1),
129 time_provider_(&base::Time::Now), 122 time_provider_(&base::Time::Now) {
130 models_associated_(false),
131 processing_syncer_changes_(false),
132 sync_processor_(NULL) {
133 Init(initializers, count); 123 Init(initializers, count);
134 } 124 }
135 125
136 TemplateURLService::~TemplateURLService() { 126 TemplateURLService::~TemplateURLService() {
137 if (load_handle_) { 127 if (load_handle_) {
138 DCHECK(service_.get()); 128 DCHECK(service_.get());
139 service_->CancelRequest(load_handle_); 129 service_->CancelRequest(load_handle_);
140 } 130 }
141 131
142 STLDeleteElements(&template_urls_); 132 STLDeleteElements(&template_urls_);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 } 279 }
290 } 280 }
291 281
292 const TemplateURL* TemplateURLService::GetTemplateURLForKeyword( 282 const TemplateURL* TemplateURLService::GetTemplateURLForKeyword(
293 const string16& keyword) const { 283 const string16& keyword) const {
294 KeywordToTemplateMap::const_iterator elem( 284 KeywordToTemplateMap::const_iterator elem(
295 keyword_to_template_map_.find(keyword)); 285 keyword_to_template_map_.find(keyword));
296 return (elem == keyword_to_template_map_.end()) ? NULL : elem->second; 286 return (elem == keyword_to_template_map_.end()) ? NULL : elem->second;
297 } 287 }
298 288
299 const TemplateURL* TemplateURLService::GetTemplateURLForGUID(
300 const std::string& sync_guid) const {
301 GUIDToTemplateMap::const_iterator elem(
302 guid_to_template_map_.find(sync_guid));
303 return (elem == guid_to_template_map_.end()) ? NULL : elem->second;
304 }
305
306 const TemplateURL* TemplateURLService::GetTemplateURLForHost( 289 const TemplateURL* TemplateURLService::GetTemplateURLForHost(
307 const std::string& host) const { 290 const std::string& host) const {
308 return provider_map_.GetTemplateURLForHost(host); 291 return provider_map_.GetTemplateURLForHost(host);
309 } 292 }
310 293
311 void TemplateURLService::Add(TemplateURL* template_url) { 294 void TemplateURLService::Add(TemplateURL* template_url) {
312 AddNoNotify(template_url); 295 AddNoNotify(template_url);
313 NotifyObservers(); 296 NotifyObservers();
314 } 297 }
315 298
316 void TemplateURLService::Remove(const TemplateURL* template_url) { 299 void TemplateURLService::Remove(const TemplateURL* template_url) {
317 RemoveNoNotify(template_url); 300 RemoveNoNotify(template_url);
318 NotifyObservers(); 301 NotifyObservers();
319 } 302 }
320 303
321 void TemplateURLService::RemoveAutoGeneratedBetween(base::Time created_after, 304 void TemplateURLService::RemoveAutoGeneratedBetween(Time created_after,
322 base::Time created_before) { 305 Time created_before) {
323 bool should_notify = false; 306 bool should_notify = false;
324 for (size_t i = 0; i < template_urls_.size();) { 307 for (size_t i = 0; i < template_urls_.size();) {
325 if (template_urls_[i]->date_created() >= created_after && 308 if (template_urls_[i]->date_created() >= created_after &&
326 (created_before.is_null() || 309 (created_before.is_null() ||
327 template_urls_[i]->date_created() < created_before) && 310 template_urls_[i]->date_created() < created_before) &&
328 CanReplace(template_urls_[i])) { 311 CanReplace(template_urls_[i])) {
329 RemoveNoNotify(template_urls_[i]); 312 RemoveNoNotify(template_urls_[i]);
330 should_notify = true; 313 should_notify = true;
331 } else { 314 } else {
332 ++i; 315 ++i;
333 } 316 }
334 } 317 }
335 if (should_notify) 318 if (should_notify)
336 NotifyObservers(); 319 NotifyObservers();
337 } 320 }
338 321
339 void TemplateURLService::RemoveAutoGeneratedSince(base::Time created_after) { 322 void TemplateURLService::RemoveAutoGeneratedSince(Time created_after) {
340 RemoveAutoGeneratedBetween(created_after, base::Time()); 323 RemoveAutoGeneratedBetween(created_after, Time());
341 } 324 }
342 325
343 void TemplateURLService::RegisterExtensionKeyword(const Extension* extension) { 326 void TemplateURLService::RegisterExtensionKeyword(const Extension* extension) {
344 // TODO(mpcomplete): disable the keyword when the extension is disabled. 327 // TODO(mpcomplete): disable the keyword when the extension is disabled.
345 if (extension->omnibox_keyword().empty()) 328 if (extension->omnibox_keyword().empty())
346 return; 329 return;
347 330
348 Load(); 331 Load();
349 if (!loaded_) { 332 if (!loaded_) {
350 pending_extension_ids_.push_back(extension->id()); 333 pending_extension_ids_.push_back(extension->id());
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 if (!pref_name || default_search_prefs_->IsObserved(*pref_name)) { 597 if (!pref_name || default_search_prefs_->IsObserved(*pref_name)) {
615 // A preference related to default search engine has changed. 598 // A preference related to default search engine has changed.
616 // Update the model if needed. 599 // Update the model if needed.
617 UpdateDefaultSearch(); 600 UpdateDefaultSearch();
618 } 601 }
619 } else { 602 } else {
620 NOTREACHED(); 603 NOTREACHED();
621 } 604 }
622 } 605 }
623 606
624 SyncDataList TemplateURLService::GetAllSyncData(
625 syncable::ModelType type) const {
626 DCHECK_EQ(syncable::SEARCH_ENGINES, type);
627
628 SyncDataList current_data;
629 for (TemplateURLVector::const_iterator iter = template_urls_.begin();
630 iter != template_urls_.end(); ++iter) {
631 // We don't sync extension keywords.
632 if ((*iter)->IsExtensionKeyword())
633 continue;
634 current_data.push_back(CreateSyncDataFromTemplateURL(**iter));
635 }
636
637 return current_data;
638 }
639
640 SyncError TemplateURLService::ProcessSyncChanges(
641 const tracked_objects::Location& from_here,
642 const SyncChangeList& change_list) {
643 if (!models_associated_) {
644 SyncError error(FROM_HERE, "Models not yet associated.",
645 syncable::SEARCH_ENGINES);
646 return error;
647 }
648
649 AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
650
651 SyncChangeList new_changes;
652 for (SyncChangeList::const_iterator iter = change_list.begin();
653 iter != change_list.end(); ++iter) {
654 DCHECK_EQ(syncable::SEARCH_ENGINES, iter->sync_data().GetDataType());
655
656 scoped_ptr<TemplateURL> turl(
657 CreateTemplateURLFromSyncData(iter->sync_data()));
658 if (!turl.get()) {
659 NOTREACHED() << "Failed to read search engine.";
660 continue;
661 }
662
663 const TemplateURL* existing_turl = GetTemplateURLForGUID(turl->sync_guid());
664 const TemplateURL* existing_keyword_turl =
665 GetTemplateURLForKeyword(turl->keyword());
666
667 if (iter->change_type() == SyncChange::ACTION_DELETE && existing_turl) {
668 Remove(existing_turl);
669 } else if (iter->change_type() == SyncChange::ACTION_ADD &&
670 !existing_turl) {
671 if (existing_keyword_turl)
672 ResolveSyncKeywordConflict(turl.get(), new_changes);
673 // Force the local ID to 0 so we can add it.
674 turl->set_id(0);
675 Add(turl.release());
676 } else if (iter->change_type() == SyncChange::ACTION_UPDATE &&
677 existing_turl) {
678 if (existing_keyword_turl)
679 ResolveSyncKeywordConflict(turl.get(), new_changes);
680 ResetTemplateURL(existing_turl, turl->short_name(), turl->keyword(),
681 turl->url() ? turl->url()->url() : std::string());
682 } else {
683 // Something really unexpected happened. Either we received an
684 // ACTION_INVALID, or Sync is in a crazy state:
685 // . Trying to DELETE or UPDATE a non-existent search engine.
686 // . Trying to ADD a search engine that already exists.
687 NOTREACHED() << "Unexpected sync change state.";
688 SyncError error(FROM_HERE, "ProcessSyncChanges failed on ChangeType " +
689 SyncChange::ChangeTypeToString(iter->change_type()),
690 syncable::SEARCH_ENGINES);
691 return error;
692 }
693 }
694
695 SyncError sync_error =
696 sync_processor_->ProcessSyncChanges(from_here, new_changes);
697
698 return sync_error;
699 }
700
701 SyncError TemplateURLService::MergeDataAndStartSyncing(
702 syncable::ModelType type,
703 const SyncDataList& initial_sync_data,
704 SyncChangeProcessor* sync_processor) {
705 DCHECK_EQ(type, syncable::SEARCH_ENGINES);
706 DCHECK(!sync_processor_);
707 sync_processor_ = sync_processor;
708
709 // We do a lot of calls to Add/Remove/ResetTemplateURL here, so ensure we
710 // don't step on our own toes.
711 AutoReset<bool> processing_changes(&processing_syncer_changes_, true);
712
713 SyncChangeList new_changes;
714
715 // Build maps of our sync GUIDs to SyncData.
716 SyncDataMap local_data_map = CreateGUIDToSyncDataMap(
717 GetAllSyncData(syncable::SEARCH_ENGINES));
718 SyncDataMap sync_data_map = CreateGUIDToSyncDataMap(initial_sync_data);
719
720 for (SyncDataMap::const_iterator iter = sync_data_map.begin();
721 iter != sync_data_map.end(); ++iter) {
722 TemplateURL* sync_turl = CreateTemplateURLFromSyncData(iter->second);
723 DCHECK(sync_turl);
724 const TemplateURL* local_turl = GetTemplateURLForGUID(iter->first);
725
726 if (local_turl) {
727 // This local search engine is already synced. If the timestamp differs
728 // from Sync, we need to update locally or to the cloud. Note that if the
729 // timestamps are equal, we touch neither.
730 if (sync_turl->last_modified() > local_turl->last_modified()) {
731 // TODO(stevet): For now we just reset the local TemplateURL with the
732 // more important Sync data fields. We may want to transfer over
733 // additional fields.
734 ResetTemplateURL(
735 local_turl,
736 sync_turl->short_name(),
737 sync_turl->keyword(),
738 sync_turl->url() ? sync_turl->url()->url() : std::string());
739 } else if (sync_turl->last_modified() < local_turl->last_modified()) {
740 new_changes.push_back(SyncChange(SyncChange::ACTION_UPDATE,
741 local_data_map[local_turl->sync_guid()]));
742 }
743 local_data_map.erase(iter->first);
744 } else {
745 // The search engine from the cloud has not been synced locally, but there
746 // might be a local search engine that is a duplicate that needs to be
747 // merged.
748 const TemplateURL* dupe_turl = FindDuplicateOfSyncTemplateURL(*sync_turl);
749 if (dupe_turl) {
750 // Merge duplicates and remove the processed local TURL from the map.
751 TemplateURL* modifiable_dupe_turl =
752 const_cast<TemplateURL*>(dupe_turl);
753 std::string old_guid = dupe_turl->sync_guid();
754 MergeSyncAndLocalURLDuplicates(sync_turl,
755 modifiable_dupe_turl,
756 new_changes);
757 local_data_map.erase(old_guid);
758 } else {
759 // Keyword conflict is possible in this case. Resolve it first before
760 // adding the new TemplateURL. Note that we don't remove the local TURL
761 // from local_data_map in this case as it may still need to be pushed to
762 // the cloud.
763 ResolveSyncKeywordConflict(sync_turl, new_changes);
764 // Force the local ID to 0 so we can add it.
765 sync_turl->set_id(0);
766 Add(sync_turl);
767 }
768 }
769 } // for
770
771 // The remaining SyncData in local_data_map should be everything that needs to
772 // be pushed as ADDs to sync.
773 for (SyncDataMap::const_iterator iter = local_data_map.begin();
774 iter != local_data_map.end(); ++iter) {
775 new_changes.push_back(SyncChange(SyncChange::ACTION_ADD, iter->second));
776 }
777
778 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes);
779 if (error.IsSet())
780 return error;
781
782 models_associated_ = true;
783 return SyncError();
784 }
785
786 void TemplateURLService::StopSyncing(syncable::ModelType type) {
787 DCHECK_EQ(type, syncable::SEARCH_ENGINES);
788 models_associated_ = false;
789 sync_processor_ = NULL;
790 }
791
792 void TemplateURLService::ProcessTemplateURLChange(
793 const TemplateURL* turl,
794 SyncChange::SyncChangeType type) {
795 DCHECK_NE(type, SyncChange::ACTION_INVALID);
796 DCHECK(turl);
797
798 if (!models_associated_)
799 return; // Not syncing.
800
801 if (processing_syncer_changes_)
802 return; // These are changes originating from us. Ignore.
803
804 // Avoid syncing Extension keywords.
805 if (turl->IsExtensionKeyword())
806 return;
807
808 SyncChangeList changes;
809
810 SyncData sync_data = CreateSyncDataFromTemplateURL(*turl);
811 changes.push_back(SyncChange(type, sync_data));
812
813 sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
814 }
815
816 // static 607 // static
817 void TemplateURLService::RegisterUserPrefs(PrefService* prefs) { 608 void TemplateURLService::RegisterUserPrefs(PrefService* prefs) {
818 prefs->RegisterBooleanPref(prefs::kDefaultSearchProviderEnabled, 609 prefs->RegisterBooleanPref(prefs::kDefaultSearchProviderEnabled,
819 true, 610 true,
820 PrefService::UNSYNCABLE_PREF); 611 PrefService::UNSYNCABLE_PREF);
821 prefs->RegisterStringPref(prefs::kDefaultSearchProviderName, 612 prefs->RegisterStringPref(prefs::kDefaultSearchProviderName,
822 std::string(), 613 std::string(),
823 PrefService::UNSYNCABLE_PREF); 614 PrefService::UNSYNCABLE_PREF);
824 prefs->RegisterStringPref(prefs::kDefaultSearchProviderID, 615 prefs->RegisterStringPref(prefs::kDefaultSearchProviderID,
825 std::string(), 616 std::string(),
(...skipping 14 matching lines...) Expand all
840 std::string(), 631 std::string(),
841 PrefService::UNSYNCABLE_PREF); 632 PrefService::UNSYNCABLE_PREF);
842 prefs->RegisterStringPref(prefs::kDefaultSearchProviderIconURL, 633 prefs->RegisterStringPref(prefs::kDefaultSearchProviderIconURL,
843 std::string(), 634 std::string(),
844 PrefService::UNSYNCABLE_PREF); 635 PrefService::UNSYNCABLE_PREF);
845 prefs->RegisterStringPref(prefs::kDefaultSearchProviderEncodings, 636 prefs->RegisterStringPref(prefs::kDefaultSearchProviderEncodings,
846 std::string(), 637 std::string(),
847 PrefService::UNSYNCABLE_PREF); 638 PrefService::UNSYNCABLE_PREF);
848 } 639 }
849 640
850 // static
851 SyncData TemplateURLService::CreateSyncDataFromTemplateURL(
852 const TemplateURL& turl) {
853 sync_pb::EntitySpecifics specifics;
854 sync_pb::SearchEngineSpecifics* se_specifics = specifics.MutableExtension(
855 sync_pb::search_engine);
856 se_specifics->set_short_name(UTF16ToUTF8(turl.short_name()));
857 se_specifics->set_keyword(UTF16ToUTF8(turl.keyword()));
858 se_specifics->set_favicon_url(turl.GetFaviconURL().spec());
859 se_specifics->set_url(turl.url() ? turl.url()->url() : std::string());
860 se_specifics->set_safe_for_autoreplace(turl.safe_for_autoreplace());
861 se_specifics->set_originating_url(turl.originating_url().spec());
862 se_specifics->set_date_created(turl.date_created().ToInternalValue());
863 se_specifics->set_input_encodings(JoinString(turl.input_encodings(), ';'));
864 se_specifics->set_show_in_default_list(turl.show_in_default_list());
865 se_specifics->set_suggestions_url(turl.suggestions_url() ?
866 turl.suggestions_url()->url() : std::string());
867 se_specifics->set_prepopulate_id(turl.prepopulate_id());
868 se_specifics->set_autogenerate_keyword(turl.autogenerate_keyword());
869 se_specifics->set_logo_id(turl.logo_id());
870 se_specifics->set_created_by_policy(turl.created_by_policy());
871 se_specifics->set_instant_url(turl.instant_url() ?
872 turl.instant_url()->url() : std::string());
873 se_specifics->set_id(turl.id());
874 se_specifics->set_last_modified(turl.last_modified().ToInternalValue());
875 se_specifics->set_sync_guid(turl.sync_guid());
876 return SyncData::CreateLocalData(se_specifics->sync_guid(),
877 se_specifics->keyword(),
878 specifics);
879 }
880
881 // static
882 TemplateURL* TemplateURLService::CreateTemplateURLFromSyncData(
883 const SyncData& sync_data) {
884 sync_pb::SearchEngineSpecifics specifics =
885 sync_data.GetSpecifics().GetExtension(sync_pb::search_engine);
886 TemplateURL* turl = new TemplateURL();
887 turl->set_short_name(UTF8ToUTF16(specifics.short_name()));
888 turl->set_keyword(UTF8ToUTF16(specifics.keyword()));
889 turl->SetFaviconURL(GURL(specifics.favicon_url()));
890 turl->SetURL(specifics.url(), 0, 0);
891 turl->set_safe_for_autoreplace(specifics.safe_for_autoreplace());
892 turl->set_originating_url(GURL(specifics.originating_url()));
893 turl->set_date_created(
894 base::Time::FromInternalValue(specifics.date_created()));
895 std::vector<std::string> input_encodings;
896 base::SplitString(specifics.input_encodings(), ';', &input_encodings);
897 turl->set_input_encodings(input_encodings);
898 turl->set_show_in_default_list(specifics.show_in_default_list());
899 turl->SetSuggestionsURL(specifics.suggestions_url(), 0, 0);
900 turl->SetPrepopulateId(specifics.prepopulate_id());
901 turl->set_autogenerate_keyword(specifics.autogenerate_keyword());
902 turl->set_logo_id(specifics.logo_id());
903 turl->set_created_by_policy(specifics.created_by_policy());
904 turl->SetInstantURL(specifics.instant_url(), 0, 0);
905 turl->set_id(specifics.id());
906 turl->set_last_modified(
907 base::Time::FromInternalValue(specifics.last_modified()));
908 turl->set_sync_guid(specifics.sync_guid());
909 return turl;
910 }
911
912 // static
913 SyncDataMap TemplateURLService::CreateGUIDToSyncDataMap(
914 const SyncDataList& sync_data) {
915 SyncDataMap data_map;
916 SyncDataList::const_iterator iter;
917 for (iter = sync_data.begin(); iter != sync_data.end(); ++iter) {
918 data_map[iter->GetSpecifics().GetExtension(
919 sync_pb::search_engine).sync_guid()] = *iter;
920 }
921 return data_map;
922 }
923
924 void TemplateURLService::SetKeywordSearchTermsForURL(const TemplateURL* t_url, 641 void TemplateURLService::SetKeywordSearchTermsForURL(const TemplateURL* t_url,
925 const GURL& url, 642 const GURL& url,
926 const string16& term) { 643 const string16& term) {
927 HistoryService* history = profile_ ? 644 HistoryService* history = profile_ ?
928 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS) : NULL; 645 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS) : NULL;
929 if (!history) 646 if (!history)
930 return; 647 return;
931 history->SetKeywordSearchTermsForURL(url, t_url->id(), term); 648 history->SetKeywordSearchTermsForURL(url, t_url->id(), term);
932 } 649 }
933 650
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 if (!env->HasVar(env_vars::kHeadless) && 706 if (!env->HasVar(env_vars::kHeadless) &&
990 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame)) 707 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeFrame))
991 GoogleURLTracker::RequestServerCheck(); 708 GoogleURLTracker::RequestServerCheck();
992 } 709 }
993 } 710 }
994 } 711 }
995 712
996 void TemplateURLService::RemoveFromMaps(const TemplateURL* template_url) { 713 void TemplateURLService::RemoveFromMaps(const TemplateURL* template_url) {
997 if (!template_url->keyword().empty()) 714 if (!template_url->keyword().empty())
998 keyword_to_template_map_.erase(template_url->keyword()); 715 keyword_to_template_map_.erase(template_url->keyword());
999 if (!template_url->sync_guid().empty())
1000 guid_to_template_map_.erase(template_url->sync_guid());
1001 if (loaded_) 716 if (loaded_)
1002 provider_map_.Remove(template_url); 717 provider_map_.Remove(template_url);
1003 } 718 }
1004 719
1005 void TemplateURLService::RemoveFromKeywordMapByPointer( 720 void TemplateURLService::RemoveFromKeywordMapByPointer(
1006 const TemplateURL* template_url) { 721 const TemplateURL* template_url) {
1007 DCHECK(template_url); 722 DCHECK(template_url);
1008 for (KeywordToTemplateMap::iterator i = keyword_to_template_map_.begin(); 723 for (KeywordToTemplateMap::iterator i = keyword_to_template_map_.begin();
1009 i != keyword_to_template_map_.end(); ++i) { 724 i != keyword_to_template_map_.end(); ++i) {
1010 if (i->second == template_url) { 725 if (i->second == template_url) {
1011 keyword_to_template_map_.erase(i); 726 keyword_to_template_map_.erase(i);
1012 // A given TemplateURL only occurs once in the map. As soon as we find the 727 // A given TemplateURL only occurs once in the map. As soon as we find the
1013 // entry, stop. 728 // entry, stop.
1014 break; 729 break;
1015 } 730 }
1016 } 731 }
1017 } 732 }
1018 733
1019 void TemplateURLService::AddToMaps(const TemplateURL* template_url) { 734 void TemplateURLService::AddToMaps(const TemplateURL* template_url) {
1020 if (!template_url->keyword().empty()) 735 if (!template_url->keyword().empty())
1021 keyword_to_template_map_[template_url->keyword()] = template_url; 736 keyword_to_template_map_[template_url->keyword()] = template_url;
1022 if (!template_url->sync_guid().empty())
1023 guid_to_template_map_[template_url->sync_guid()] = template_url;
1024 if (loaded_) { 737 if (loaded_) {
1025 UIThreadSearchTermsData search_terms_data; 738 UIThreadSearchTermsData search_terms_data;
1026 provider_map_.Add(template_url, search_terms_data); 739 provider_map_.Add(template_url, search_terms_data);
1027 } 740 }
1028 } 741 }
1029 742
1030 void TemplateURLService::SetTemplateURLs( 743 void TemplateURLService::SetTemplateURLs(
1031 const std::vector<TemplateURL*>& urls) { 744 const std::vector<TemplateURL*>& urls) {
1032 // Add mappings for the new items. 745 // Add mappings for the new items.
1033 746
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 926
1214 void TemplateURLService::UpdateNoNotify(const TemplateURL* existing_turl, 927 void TemplateURLService::UpdateNoNotify(const TemplateURL* existing_turl,
1215 const TemplateURL& new_values) { 928 const TemplateURL& new_values) {
1216 DCHECK(loaded_); 929 DCHECK(loaded_);
1217 DCHECK(existing_turl); 930 DCHECK(existing_turl);
1218 DCHECK(find(template_urls_.begin(), template_urls_.end(), existing_turl) != 931 DCHECK(find(template_urls_.begin(), template_urls_.end(), existing_turl) !=
1219 template_urls_.end()); 932 template_urls_.end());
1220 933
1221 if (!existing_turl->keyword().empty()) 934 if (!existing_turl->keyword().empty())
1222 keyword_to_template_map_.erase(existing_turl->keyword()); 935 keyword_to_template_map_.erase(existing_turl->keyword());
1223 if (!existing_turl->sync_guid().empty())
1224 guid_to_template_map_.erase(existing_turl->sync_guid());
1225 936
1226 // This call handles copying over the values (while retaining the id). 937 // This call handles copying over the values (while retaining the id).
1227 UIThreadSearchTermsData search_terms_data; 938 UIThreadSearchTermsData search_terms_data;
1228 provider_map_.Update(existing_turl, new_values, search_terms_data); 939 provider_map_.Update(existing_turl, new_values, search_terms_data);
1229 940
1230 if (!existing_turl->keyword().empty()) 941 if (!existing_turl->keyword().empty())
1231 keyword_to_template_map_[existing_turl->keyword()] = existing_turl; 942 keyword_to_template_map_[existing_turl->keyword()] = existing_turl;
1232 if (!existing_turl->sync_guid().empty())
1233 guid_to_template_map_[existing_turl->sync_guid()] = existing_turl;
1234 943
1235 if (service_.get()) 944 if (service_.get())
1236 service_->UpdateKeyword(*existing_turl); 945 service_->UpdateKeyword(*existing_turl);
1237 946
1238 // Inform sync of the update.
1239 ProcessTemplateURLChange(existing_turl, SyncChange::ACTION_UPDATE);
1240
1241 if (default_search_provider_ == existing_turl) 947 if (default_search_provider_ == existing_turl)
1242 SetDefaultSearchProviderNoNotify(existing_turl); 948 SetDefaultSearchProviderNoNotify(existing_turl);
1243 } 949 }
1244 950
1245 PrefService* TemplateURLService::GetPrefs() { 951 PrefService* TemplateURLService::GetPrefs() {
1246 return profile_ ? profile_->GetPrefs() : NULL; 952 return profile_ ? profile_->GetPrefs() : NULL;
1247 } 953 }
1248 954
1249 void TemplateURLService::UpdateKeywordSearchTermsForURL( 955 void TemplateURLService::UpdateKeywordSearchTermsForURL(
1250 const history::URLVisitedDetails& details) { 956 const history::URLVisitedDetails& details) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 DCHECK(template_url); 1233 DCHECK(template_url);
1528 DCHECK(template_url->id() == 0); 1234 DCHECK(template_url->id() == 0);
1529 DCHECK(find(template_urls_.begin(), template_urls_.end(), template_url) == 1235 DCHECK(find(template_urls_.begin(), template_urls_.end(), template_url) ==
1530 template_urls_.end()); 1236 template_urls_.end());
1531 template_url->set_id(++next_id_); 1237 template_url->set_id(++next_id_);
1532 template_urls_.push_back(template_url); 1238 template_urls_.push_back(template_url);
1533 AddToMaps(template_url); 1239 AddToMaps(template_url);
1534 1240
1535 if (service_.get()) 1241 if (service_.get())
1536 service_->AddKeyword(*template_url); 1242 service_->AddKeyword(*template_url);
1537
1538 // Inform sync of the addition. Note that this will assign a GUID to
1539 // template_url and add it to the guid_to_template_map_.
1540 ProcessTemplateURLChange(template_url, SyncChange::ACTION_ADD);
1541 } 1243 }
1542 1244
1543 void TemplateURLService::RemoveNoNotify(const TemplateURL* template_url) { 1245 void TemplateURLService::RemoveNoNotify(const TemplateURL* template_url) {
1544 TemplateURLVector::iterator i = find(template_urls_.begin(), 1246 TemplateURLVector::iterator i = find(template_urls_.begin(),
1545 template_urls_.end(), 1247 template_urls_.end(),
1546 template_url); 1248 template_url);
1547 if (i == template_urls_.end()) 1249 if (i == template_urls_.end())
1548 return; 1250 return;
1549 1251
1550 if (template_url == default_search_provider_) { 1252 if (template_url == default_search_provider_) {
1551 // Should never delete the default search provider. 1253 // Should never delete the default search provider.
1552 NOTREACHED(); 1254 NOTREACHED();
1553 return; 1255 return;
1554 } 1256 }
1555 1257
1556 RemoveFromMaps(template_url); 1258 RemoveFromMaps(template_url);
1557 1259
1558 // Remove it from the vector containing all TemplateURLs. 1260 // Remove it from the vector containing all TemplateURLs.
1559 template_urls_.erase(i); 1261 template_urls_.erase(i);
1560 1262
1561 if (service_.get()) 1263 if (service_.get())
1562 service_->RemoveKeyword(*template_url); 1264 service_->RemoveKeyword(*template_url);
1563 1265
1564 // Inform sync of the deletion.
1565 ProcessTemplateURLChange(template_url, SyncChange::ACTION_DELETE);
1566
1567 if (profile_) { 1266 if (profile_) {
1568 Source<Profile> source(profile_); 1267 Source<Profile> source(profile_);
1569 TemplateURLID id = template_url->id(); 1268 TemplateURLID id = template_url->id();
1570 NotificationService::current()->Notify( 1269 NotificationService::current()->Notify(
1571 chrome::NOTIFICATION_TEMPLATE_URL_REMOVED, 1270 chrome::NOTIFICATION_TEMPLATE_URL_REMOVED,
1572 source, 1271 source,
1573 Details<TemplateURLID>(&id)); 1272 Details<TemplateURLID>(&id));
1574 } 1273 }
1575 1274
1576 // We own the TemplateURL and need to delete it. 1275 // We own the TemplateURL and need to delete it.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 1323
1625 i = template_urls->erase(i); 1324 i = template_urls->erase(i);
1626 if (service_.get()) 1325 if (service_.get())
1627 service_->RemoveKeyword(*template_url); 1326 service_->RemoveKeyword(*template_url);
1628 delete template_url; 1327 delete template_url;
1629 } else { 1328 } else {
1630 ++i; 1329 ++i;
1631 } 1330 }
1632 } 1331 }
1633 } 1332 }
1634
1635 void TemplateURLService::ResetTemplateURLGUID(const TemplateURL* url,
1636 const std::string& guid) {
1637 DCHECK(!guid.empty());
1638
1639 TemplateURL new_url(*url);
1640 new_url.set_sync_guid(guid);
1641 UpdateNoNotify(url, new_url);
1642 }
1643
1644 string16 TemplateURLService::UniquifyKeyword(const TemplateURL& turl) const {
1645 // Already unique.
1646 if (!GetTemplateURLForKeyword(turl.keyword()))
1647 return turl.keyword();
1648
1649 // First, try to return the generated keyword for the TemplateURL.
1650 string16 keyword_candidate = GenerateKeyword(
1651 turl.url() ? GURL(turl.url()->url()) : GURL(), true);
1652 if (!GetTemplateURLForKeyword(keyword_candidate) &&
1653 !keyword_candidate.empty()) {
1654 return keyword_candidate;
1655 }
1656
1657 // We try to uniquify the keyword by appending a special character to the end.
1658 // This is a best-effort approach where we try to preserve the original
1659 // keyword and let the user do what they will after our attempt.
1660 keyword_candidate = turl.keyword();
1661 do {
1662 keyword_candidate.append(UTF8ToUTF16("_"));
1663 } while (GetTemplateURLForKeyword(keyword_candidate));
1664
1665 return keyword_candidate;
1666 }
1667
1668 bool TemplateURLService::ResolveSyncKeywordConflict(
1669 TemplateURL* sync_turl,
1670 SyncChangeList& change_list) {
1671 DCHECK(sync_turl);
1672
1673 const TemplateURL* existing_turl =
1674 GetTemplateURLForKeyword(sync_turl->keyword());
1675 if (!existing_turl)
1676 return false;
1677
1678 string16 new_keyword;
1679 if (existing_turl->last_modified() > sync_turl->last_modified()) {
1680 new_keyword = UniquifyKeyword(*sync_turl);
1681 DCHECK(!GetTemplateURLForKeyword(new_keyword));
1682 sync_turl->set_keyword(new_keyword);
1683 // If we update the cloud TURL, we need to push an update back to sync
1684 // informing it that something has changed.
1685 SyncData sync_data = CreateSyncDataFromTemplateURL(*sync_turl);
1686 change_list.push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data));
1687 } else {
1688 new_keyword = UniquifyKeyword(*existing_turl);
1689 ResetTemplateURL(existing_turl, existing_turl->short_name(), new_keyword,
1690 existing_turl->url() ? existing_turl->url()->url() : std::string());
1691 }
1692 return true;
1693 }
1694
1695 const TemplateURL* TemplateURLService::FindDuplicateOfSyncTemplateURL(
1696 const TemplateURL& sync_turl) {
1697 const TemplateURL* existing_turl =
1698 GetTemplateURLForKeyword(sync_turl.keyword());
1699 if (!existing_turl)
1700 return NULL;
1701
1702 if (existing_turl->url() && sync_turl.url() &&
1703 existing_turl->url()->url() == sync_turl.url()->url()) {
1704 return existing_turl;
1705 }
1706 return NULL;
1707 }
1708
1709 void TemplateURLService::MergeSyncAndLocalURLDuplicates(
1710 TemplateURL* sync_turl,
1711 TemplateURL* local_turl,
1712 SyncChangeList& change_list) {
1713 DCHECK(sync_turl);
1714 DCHECK(local_turl);
1715
1716 if (sync_turl->last_modified() > local_turl->last_modified()) {
1717 // Fully replace local_url with Sync's copy. Note that because use Add
1718 // rather than ResetTemplateURL, |sync_url| is added with a fresh
1719 // TemplateURLID. We don't need to sync the new ID back to the server since
1720 // it's only relevant locally.
1721 Remove(local_turl);
1722 // Force the local ID to 0 so we can add it.
1723 sync_turl->set_id(0);
1724 Add(sync_turl);
1725 } else {
1726 // Change the local TURL's GUID to the server's GUID and push an update to
1727 // Sync. This ensures that the rest of local_url's fields are sync'd up to
1728 // the server, and the next time local_url is synced, it is recognized by
1729 // having the same GUID.
1730 ResetTemplateURLGUID(local_turl, sync_turl->sync_guid());
1731 SyncData sync_data = CreateSyncDataFromTemplateURL(*local_turl);
1732 change_list.push_back(SyncChange(SyncChange::ACTION_UPDATE, sync_data));
1733 }
1734 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698