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