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 #ifndef CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ | 5 #ifndef CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ |
6 #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ | 6 #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
11 #include <string> | 11 #include <string> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
16 #include "base/observer_list.h" | 16 #include "base/observer_list.h" |
17 #include "chrome/browser/profiles/profile_keyed_service.h" | 17 #include "chrome/browser/profiles/profile_keyed_service.h" |
18 #include "chrome/browser/search_engines/search_host_to_urls_map.h" | 18 #include "chrome/browser/search_engines/search_host_to_urls_map.h" |
19 #include "chrome/browser/search_engines/template_url_id.h" | 19 #include "chrome/browser/search_engines/template_url_id.h" |
| 20 #include "chrome/browser/sync/api/sync_change.h" |
| 21 #include "chrome/browser/sync/api/syncable_service.h" |
20 #include "chrome/browser/webdata/web_data_service.h" | 22 #include "chrome/browser/webdata/web_data_service.h" |
21 #include "content/common/notification_observer.h" | 23 #include "content/common/notification_observer.h" |
22 #include "content/common/notification_registrar.h" | 24 #include "content/common/notification_registrar.h" |
23 | 25 |
24 class GURL; | 26 class GURL; |
25 class Extension; | 27 class Extension; |
26 class PrefService; | 28 class PrefService; |
27 class Profile; | 29 class Profile; |
28 class PrefSetObserver; | 30 class PrefSetObserver; |
29 class SearchHostToURLsMap; | 31 class SearchHostToURLsMap; |
30 class SearchTermsData; | 32 class SearchTermsData; |
| 33 class SyncData; |
31 class TemplateURLServiceObserver; | 34 class TemplateURLServiceObserver; |
32 class TemplateURLRef; | 35 class TemplateURLRef; |
33 | 36 |
34 namespace history { | 37 namespace history { |
35 struct URLVisitedDetails; | 38 struct URLVisitedDetails; |
36 } | 39 } |
37 | 40 |
38 // TemplateURLService is the backend for keywords. It's used by | 41 // TemplateURLService is the backend for keywords. It's used by |
39 // KeywordAutocomplete. | 42 // KeywordAutocomplete. |
40 // | 43 // |
(...skipping 10 matching lines...) Expand all Loading... |
51 // When TemplateURLService has completed loading, observers are notified via | 54 // When TemplateURLService has completed loading, observers are notified via |
52 // OnTemplateURLServiceChanged as well as the TEMPLATE_URL_SERVICE_LOADED | 55 // OnTemplateURLServiceChanged as well as the TEMPLATE_URL_SERVICE_LOADED |
53 // notification message. | 56 // notification message. |
54 // | 57 // |
55 // TemplateURLService takes ownership of any TemplateURL passed to it. If there | 58 // TemplateURLService takes ownership of any TemplateURL passed to it. If there |
56 // is a WebDataService, deletion is handled by WebDataService, otherwise | 59 // is a WebDataService, deletion is handled by WebDataService, otherwise |
57 // TemplateURLService handles deletion. | 60 // TemplateURLService handles deletion. |
58 | 61 |
59 class TemplateURLService : public WebDataServiceConsumer, | 62 class TemplateURLService : public WebDataServiceConsumer, |
60 public ProfileKeyedService, | 63 public ProfileKeyedService, |
61 public NotificationObserver { | 64 public NotificationObserver, |
| 65 public SyncableService { |
62 public: | 66 public: |
63 typedef std::map<std::string, std::string> QueryTerms; | 67 typedef std::map<std::string, std::string> QueryTerms; |
64 typedef std::vector<const TemplateURL*> TemplateURLVector; | 68 typedef std::vector<const TemplateURL*> TemplateURLVector; |
65 // Type for a static function pointer that acts as a time source. | 69 // Type for a static function pointer that acts as a time source. |
66 typedef base::Time(TimeProvider)(); | 70 typedef base::Time(TimeProvider)(); |
| 71 typedef std::map<std::string, SyncData> SyncDataMap; |
67 | 72 |
68 // Struct used for initializing the data store with fake data. | 73 // Struct used for initializing the data store with fake data. |
69 // Each initializer is mapped to a TemplateURL. | 74 // Each initializer is mapped to a TemplateURL. |
70 struct Initializer { | 75 struct Initializer { |
71 const char* const keyword; | 76 const char* const keyword; |
72 const char* const url; | 77 const char* const url; |
73 const char* const content; | 78 const char* const content; |
74 }; | 79 }; |
75 | 80 |
76 explicit TemplateURLService(Profile* profile); | 81 explicit TemplateURLService(Profile* profile); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 void FindMatchingKeywords(const string16& prefix, | 122 void FindMatchingKeywords(const string16& prefix, |
118 bool support_replacement_only, | 123 bool support_replacement_only, |
119 std::vector<string16>* matches) const; | 124 std::vector<string16>* matches) const; |
120 | 125 |
121 // Looks up |keyword| and returns the element it maps to. Returns NULL if | 126 // Looks up |keyword| and returns the element it maps to. Returns NULL if |
122 // the keyword was not found. | 127 // the keyword was not found. |
123 // The caller should not try to delete the returned pointer; the data store | 128 // The caller should not try to delete the returned pointer; the data store |
124 // retains ownership of it. | 129 // retains ownership of it. |
125 const TemplateURL* GetTemplateURLForKeyword(const string16& keyword) const; | 130 const TemplateURL* GetTemplateURLForKeyword(const string16& keyword) const; |
126 | 131 |
| 132 // Looks up |sync_guid| and returns the element it maps to. Returns NULL if |
| 133 // the guid was not found. |
| 134 // The caller should not try to delete the returned pointer; the data store |
| 135 // retains ownership of it. |
| 136 const TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid) const; |
| 137 |
127 // Returns the first TemplateURL found with a URL using the specified |host|, | 138 // Returns the first TemplateURL found with a URL using the specified |host|, |
128 // or NULL if there are no such TemplateURLs | 139 // or NULL if there are no such TemplateURLs |
129 const TemplateURL* GetTemplateURLForHost(const std::string& host) const; | 140 const TemplateURL* GetTemplateURLForHost(const std::string& host) const; |
130 | 141 |
131 // Adds a new TemplateURL to this model. TemplateURLService will own the | 142 // Adds a new TemplateURL to this model. TemplateURLService will own the |
132 // reference, and delete it when the TemplateURL is removed. | 143 // reference, and delete it when the TemplateURL is removed. |
133 void Add(TemplateURL* template_url); | 144 void Add(TemplateURL* template_url); |
134 | 145 |
135 // Removes the keyword from the model. This deletes the supplied TemplateURL. | 146 // Removes the keyword from the model. This deletes the supplied TemplateURL. |
136 // This fails if the supplied template_url is the default search provider. | 147 // This fails if the supplied template_url is the default search provider. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 // notification types: | 237 // notification types: |
227 // . NOTIFY_HISTORY_URL_VISITED: adds keyword search terms if the visit | 238 // . NOTIFY_HISTORY_URL_VISITED: adds keyword search terms if the visit |
228 // corresponds to a keyword. | 239 // corresponds to a keyword. |
229 // . NOTIFY_GOOGLE_URL_UPDATED: updates mapping for any keywords containing | 240 // . NOTIFY_GOOGLE_URL_UPDATED: updates mapping for any keywords containing |
230 // a google base url replacement term. | 241 // a google base url replacement term. |
231 // . PREF_CHANGED: checks whether the default search engine has changed. | 242 // . PREF_CHANGED: checks whether the default search engine has changed. |
232 virtual void Observe(int type, | 243 virtual void Observe(int type, |
233 const NotificationSource& source, | 244 const NotificationSource& source, |
234 const NotificationDetails& details); | 245 const NotificationDetails& details); |
235 | 246 |
| 247 // SyncableService implementation. |
| 248 |
| 249 // Returns all syncable TemplateURLs from this model as SyncData. This should |
| 250 // include every search engine and no Extension keywords. |
| 251 virtual SyncDataList GetAllSyncData(syncable::ModelType type) const OVERRIDE; |
| 252 // Process new search engine changes from Sync, merging them into our local |
| 253 // data. This may send notifications if local search engines are added, |
| 254 // updated or removed. |
| 255 virtual SyncError ProcessSyncChanges( |
| 256 const tracked_objects::Location& from_here, |
| 257 const SyncChangeList& change_list) OVERRIDE; |
| 258 // Merge initial search engine data from Sync and push any local changes up |
| 259 // to Sync. This may send notifications if local search engines are added, |
| 260 // updated or removed. |
| 261 virtual SyncError MergeDataAndStartSyncing( |
| 262 syncable::ModelType type, |
| 263 const SyncDataList& initial_sync_data, |
| 264 SyncChangeProcessor* sync_processor) OVERRIDE; |
| 265 virtual void StopSyncing(syncable::ModelType type) OVERRIDE; |
| 266 |
| 267 // Processes a local TemplateURL change for Sync. |turl| is the TemplateURL |
| 268 // that has been modified, and |type| is the Sync ChangeType that took place. |
| 269 // This may send a new SyncChange to the cloud. If our model has not yet been |
| 270 // associated with Sync, or if this is triggered by a Sync change, then this |
| 271 // does nothing. |
| 272 void ProcessTemplateURLChange(const TemplateURL* turl, |
| 273 SyncChange::SyncChangeType type); |
| 274 |
236 Profile* profile() const { return profile_; } | 275 Profile* profile() const { return profile_; } |
237 | 276 |
238 void SetSearchEngineDialogSlot(int slot) { | 277 void SetSearchEngineDialogSlot(int slot) { |
239 search_engine_dialog_chosen_slot_ = slot; | 278 search_engine_dialog_chosen_slot_ = slot; |
240 } | 279 } |
241 | 280 |
242 int GetSearchEngineDialogSlot() const { | 281 int GetSearchEngineDialogSlot() const { |
243 return search_engine_dialog_chosen_slot_; | 282 return search_engine_dialog_chosen_slot_; |
244 } | 283 } |
245 | 284 |
246 // Registers the preferences used to save a TemplateURL to prefs. | 285 // Registers the preferences used to save a TemplateURL to prefs. |
247 static void RegisterUserPrefs(PrefService* prefs); | 286 static void RegisterUserPrefs(PrefService* prefs); |
248 | 287 |
| 288 // Returns a SyncData with a sync representation of the search engine data |
| 289 // from |turl|. |
| 290 static SyncData CreateSyncDataFromTemplateURL(const TemplateURL& turl); |
| 291 |
| 292 // Returns a heap-allocated TemplateURL, populated by |sync_data|'s fields. |
| 293 // This does the opposite of CreateSyncDataFromTemplateURL. The caller owns |
| 294 // the returned TemplateURL*. |
| 295 static TemplateURL* CreateTemplateURLFromSyncData(const SyncData& sync_data); |
| 296 |
| 297 // Returns a map mapping Sync GUIDs to pointers to SyncData. |
| 298 static SyncDataMap CreateGUIDToSyncDataMap(const SyncDataList& sync_data); |
| 299 |
249 #if defined(UNIT_TEST) | 300 #if defined(UNIT_TEST) |
250 // Set a different time provider function, such as | 301 // Set a different time provider function, such as |
251 // base::MockTimeProvider::StaticNow, when testing calls to base::Time::Now. | 302 // base::MockTimeProvider::StaticNow, when testing calls to base::Time::Now. |
252 void set_time_provider(TimeProvider* time_provider) { | 303 void set_time_provider(TimeProvider* time_provider) { |
253 time_provider_ = time_provider; | 304 time_provider_ = time_provider; |
254 } | 305 } |
255 #endif | 306 #endif |
256 | 307 |
257 protected: | 308 protected: |
258 // Cover method for the method of the same name on the HistoryService. | 309 // Cover method for the method of the same name on the HistoryService. |
259 // url is the one that was visited with the given search terms. | 310 // url is the one that was visited with the given search terms. |
260 // | 311 // |
261 // This exists and is virtual for testing. | 312 // This exists and is virtual for testing. |
262 virtual void SetKeywordSearchTermsForURL(const TemplateURL* t_url, | 313 virtual void SetKeywordSearchTermsForURL(const TemplateURL* t_url, |
263 const GURL& url, | 314 const GURL& url, |
264 const string16& term); | 315 const string16& term); |
265 | 316 |
266 private: | 317 private: |
267 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, BuildQueryTerms); | 318 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, BuildQueryTerms); |
268 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch); | 319 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch); |
269 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, | 320 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
270 UpdateKeywordSearchTermsForURL); | 321 UpdateKeywordSearchTermsForURL); |
271 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, | 322 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
272 DontUpdateKeywordSearchForNonReplaceable); | 323 DontUpdateKeywordSearchForNonReplaceable); |
273 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue); | 324 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue); |
274 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders); | 325 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders); |
| 326 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, |
| 327 CreateSyncDataFromTemplateURL); |
| 328 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, |
| 329 CreateTemplateURLFromSyncData); |
| 330 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, UniquifyKeyword); |
| 331 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, |
| 332 ResolveSyncKeywordConflict); |
| 333 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, |
| 334 FindDuplicateOfSyncTemplateURL); |
| 335 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, |
| 336 MergeSyncAndLocalURLDuplicates); |
| 337 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, |
| 338 CreateGUIDToSyncDataMap); |
| 339 |
275 friend class TemplateURLServiceTestUtil; | 340 friend class TemplateURLServiceTestUtil; |
276 | 341 |
277 typedef std::map<string16, const TemplateURL*> KeywordToTemplateMap; | 342 typedef std::map<string16, const TemplateURL*> KeywordToTemplateMap; |
| 343 typedef std::map<std::string, const TemplateURL*> GUIDToTemplateMap; |
278 | 344 |
279 // Helper functor for FindMatchingKeywords(), for finding the range of | 345 // Helper functor for FindMatchingKeywords(), for finding the range of |
280 // keywords which begin with a prefix. | 346 // keywords which begin with a prefix. |
281 class LessWithPrefix; | 347 class LessWithPrefix; |
282 | 348 |
283 void Init(const Initializer* initializers, int num_initializers); | 349 void Init(const Initializer* initializers, int num_initializers); |
284 | 350 |
285 void RemoveFromMaps(const TemplateURL* template_url); | 351 void RemoveFromMaps(const TemplateURL* template_url); |
286 | 352 |
287 // Removes the supplied template_url from the keyword maps. This searches | 353 // Removes the supplied template_url from the keyword maps. This searches |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 | 454 |
389 // Removes from the vector any template URL that was created because of | 455 // Removes from the vector any template URL that was created because of |
390 // policy. These TemplateURLs are freed and removed from the database. | 456 // policy. These TemplateURLs are freed and removed from the database. |
391 // Sets default_search_provider to NULL if it was one of them, unless it is | 457 // Sets default_search_provider to NULL if it was one of them, unless it is |
392 // the same as the current default from preferences and it is managed. | 458 // the same as the current default from preferences and it is managed. |
393 void RemoveProvidersCreatedByPolicy( | 459 void RemoveProvidersCreatedByPolicy( |
394 std::vector<TemplateURL*>* template_urls, | 460 std::vector<TemplateURL*>* template_urls, |
395 const TemplateURL** default_search_provider, | 461 const TemplateURL** default_search_provider, |
396 const TemplateURL* default_from_prefs); | 462 const TemplateURL* default_from_prefs); |
397 | 463 |
| 464 // Resets the sync GUID of the specified TemplateURL and persists the change |
| 465 // to the database. This does not notify observers. |
| 466 void ResetTemplateURLGUID(const TemplateURL* url, const std::string& guid); |
| 467 |
| 468 // Attempts to generate a unique keyword for |turl| based on its original |
| 469 // keyword. If its keyword is already unique, that is returned. Otherwise, it |
| 470 // tries to return the autogenerated keyword if that is unique to the Service, |
| 471 // and finally it repeatedly appends special characters to the keyword until |
| 472 // it is unique to the Service. |
| 473 string16 UniquifyKeyword(const TemplateURL& turl) const; |
| 474 |
| 475 // Given a TemplateURL from Sync, resolves any keyword conflicts by checking |
| 476 // the local keywords and uniquifying either the cloud keyword or a |
| 477 // conflicting local keyword (whichever is older). If the cloud TURL is |
| 478 // changed, then an appropriate SyncChange is appended to |change_list|. If |
| 479 // a local TURL is changed, the service is updated with the new keyword. If |
| 480 // there was no conflict to begin with, this does nothing. In the case of tied |
| 481 // last_modified dates, |sync_turl| wins. Returns true iff there was a |
| 482 // conflict. |
| 483 bool ResolveSyncKeywordConflict(TemplateURL* sync_turl, |
| 484 SyncChangeList& change_list); |
| 485 |
| 486 // Returns a TemplateURL from the service that has the same keyword and search |
| 487 // URL as |sync_turl|, if it exists. |
| 488 const TemplateURL* FindDuplicateOfSyncTemplateURL( |
| 489 const TemplateURL& sync_turl); |
| 490 |
| 491 // Given a TemplateURL from the cloud and a local matching duplicate found by |
| 492 // FindDuplcateOfSyncTemplateURL, merges the two. If |sync_url| is newer, this |
| 493 // replaces |local_url| with |sync_url| using the service's Remove and Add. |
| 494 // If |local_url| is newer, this copies the GUID from |sync_url| over to |
| 495 // |local_url| and adds an update to change_list to notify the server of the |
| 496 // change. |
| 497 void MergeSyncAndLocalURLDuplicates(TemplateURL* sync_url, |
| 498 TemplateURL* local_url, |
| 499 SyncChangeList& change_list); |
| 500 |
398 NotificationRegistrar registrar_; | 501 NotificationRegistrar registrar_; |
399 | 502 |
400 // Mapping from keyword to the TemplateURL. | 503 // Mapping from keyword to the TemplateURL. |
401 KeywordToTemplateMap keyword_to_template_map_; | 504 KeywordToTemplateMap keyword_to_template_map_; |
402 | 505 |
| 506 // Mapping from Sync GUIDs to the TemplateURL. |
| 507 GUIDToTemplateMap guid_to_template_map_; |
| 508 |
403 TemplateURLVector template_urls_; | 509 TemplateURLVector template_urls_; |
404 | 510 |
405 ObserverList<TemplateURLServiceObserver> model_observers_; | 511 ObserverList<TemplateURLServiceObserver> model_observers_; |
406 | 512 |
407 // Maps from host to set of TemplateURLs whose search url host is host. | 513 // Maps from host to set of TemplateURLs whose search url host is host. |
408 SearchHostToURLsMap provider_map_; | 514 SearchHostToURLsMap provider_map_; |
409 | 515 |
410 // Used to obtain the WebDataService. | 516 // Used to obtain the WebDataService. |
411 // When Load is invoked, if we haven't yet loaded, the WebDataService is | 517 // When Load is invoked, if we haven't yet loaded, the WebDataService is |
412 // obtained from the Profile. This allows us to lazily access the database. | 518 // obtained from the Profile. This allows us to lazily access the database. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 // ID assigned to next TemplateURL added to this model. This is an ever | 556 // ID assigned to next TemplateURL added to this model. This is an ever |
451 // increasing integer that is initialized from the database. | 557 // increasing integer that is initialized from the database. |
452 TemplateURLID next_id_; | 558 TemplateURLID next_id_; |
453 | 559 |
454 // List of extension IDs waiting for Load to have keywords registered. | 560 // List of extension IDs waiting for Load to have keywords registered. |
455 std::vector<std::string> pending_extension_ids_; | 561 std::vector<std::string> pending_extension_ids_; |
456 | 562 |
457 // Function returning current time in base::Time units. | 563 // Function returning current time in base::Time units. |
458 TimeProvider* time_provider_; | 564 TimeProvider* time_provider_; |
459 | 565 |
| 566 // Do we have an active association between the TemplateURLs and sync models? |
| 567 // Set in MergeDataAndStartSyncing, reset in StopSyncing. While this is not |
| 568 // set, we ignore any local search engine changes (when we start syncing we |
| 569 // will look up the most recent values anyways). |
| 570 bool models_associated_; |
| 571 |
| 572 // Whether we're currently processing changes from the syncer. While this is |
| 573 // true, we ignore any local search engine changes, since we triggered them. |
| 574 bool processing_syncer_changes_; |
| 575 |
| 576 // Sync's SyncChange handler. We push all our changes through this. |
| 577 SyncChangeProcessor* sync_processor_; |
| 578 |
460 DISALLOW_COPY_AND_ASSIGN(TemplateURLService); | 579 DISALLOW_COPY_AND_ASSIGN(TemplateURLService); |
461 }; | 580 }; |
462 | 581 |
463 #endif // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ | 582 #endif // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ |
OLD | NEW |