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" | |
22 #include "chrome/browser/webdata/web_data_service.h" | 20 #include "chrome/browser/webdata/web_data_service.h" |
23 #include "content/common/notification_observer.h" | 21 #include "content/common/notification_observer.h" |
24 #include "content/common/notification_registrar.h" | 22 #include "content/common/notification_registrar.h" |
25 | 23 |
26 class GURL; | 24 class GURL; |
27 class Extension; | 25 class Extension; |
28 class PrefService; | 26 class PrefService; |
29 class Profile; | 27 class Profile; |
30 class PrefSetObserver; | 28 class PrefSetObserver; |
31 class SearchHostToURLsMap; | 29 class SearchHostToURLsMap; |
32 class SearchTermsData; | 30 class SearchTermsData; |
33 class SyncData; | |
34 class TemplateURLServiceObserver; | 31 class TemplateURLServiceObserver; |
35 class TemplateURLRef; | 32 class TemplateURLRef; |
36 | 33 |
37 namespace history { | 34 namespace history { |
38 struct URLVisitedDetails; | 35 struct URLVisitedDetails; |
39 } | 36 } |
40 | 37 |
41 // TemplateURLService is the backend for keywords. It's used by | 38 // TemplateURLService is the backend for keywords. It's used by |
42 // KeywordAutocomplete. | 39 // KeywordAutocomplete. |
43 // | 40 // |
(...skipping 10 matching lines...) Expand all Loading... |
54 // When TemplateURLService has completed loading, observers are notified via | 51 // When TemplateURLService has completed loading, observers are notified via |
55 // OnTemplateURLServiceChanged as well as the TEMPLATE_URL_SERVICE_LOADED | 52 // OnTemplateURLServiceChanged as well as the TEMPLATE_URL_SERVICE_LOADED |
56 // notification message. | 53 // notification message. |
57 // | 54 // |
58 // TemplateURLService takes ownership of any TemplateURL passed to it. If there | 55 // TemplateURLService takes ownership of any TemplateURL passed to it. If there |
59 // is a WebDataService, deletion is handled by WebDataService, otherwise | 56 // is a WebDataService, deletion is handled by WebDataService, otherwise |
60 // TemplateURLService handles deletion. | 57 // TemplateURLService handles deletion. |
61 | 58 |
62 class TemplateURLService : public WebDataServiceConsumer, | 59 class TemplateURLService : public WebDataServiceConsumer, |
63 public ProfileKeyedService, | 60 public ProfileKeyedService, |
64 public NotificationObserver, | 61 public NotificationObserver { |
65 public SyncableService { | |
66 public: | 62 public: |
67 typedef std::map<std::string, std::string> QueryTerms; | 63 typedef std::map<std::string, std::string> QueryTerms; |
68 typedef std::vector<const TemplateURL*> TemplateURLVector; | 64 typedef std::vector<const TemplateURL*> TemplateURLVector; |
69 // Type for a static function pointer that acts as a time source. | 65 // Type for a static function pointer that acts as a time source. |
70 typedef base::Time(TimeProvider)(); | 66 typedef base::Time(TimeProvider)(); |
71 typedef std::map<std::string, SyncData> SyncDataMap; | |
72 | 67 |
73 // Struct used for initializing the data store with fake data. | 68 // Struct used for initializing the data store with fake data. |
74 // Each initializer is mapped to a TemplateURL. | 69 // Each initializer is mapped to a TemplateURL. |
75 struct Initializer { | 70 struct Initializer { |
76 const char* const keyword; | 71 const char* const keyword; |
77 const char* const url; | 72 const char* const url; |
78 const char* const content; | 73 const char* const content; |
79 }; | 74 }; |
80 | 75 |
81 explicit TemplateURLService(Profile* profile); | 76 explicit TemplateURLService(Profile* profile); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 void FindMatchingKeywords(const string16& prefix, | 117 void FindMatchingKeywords(const string16& prefix, |
123 bool support_replacement_only, | 118 bool support_replacement_only, |
124 std::vector<string16>* matches) const; | 119 std::vector<string16>* matches) const; |
125 | 120 |
126 // Looks up |keyword| and returns the element it maps to. Returns NULL if | 121 // Looks up |keyword| and returns the element it maps to. Returns NULL if |
127 // the keyword was not found. | 122 // the keyword was not found. |
128 // The caller should not try to delete the returned pointer; the data store | 123 // The caller should not try to delete the returned pointer; the data store |
129 // retains ownership of it. | 124 // retains ownership of it. |
130 const TemplateURL* GetTemplateURLForKeyword(const string16& keyword) const; | 125 const TemplateURL* GetTemplateURLForKeyword(const string16& keyword) const; |
131 | 126 |
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 | |
138 // Returns the first TemplateURL found with a URL using the specified |host|, | 127 // Returns the first TemplateURL found with a URL using the specified |host|, |
139 // or NULL if there are no such TemplateURLs | 128 // or NULL if there are no such TemplateURLs |
140 const TemplateURL* GetTemplateURLForHost(const std::string& host) const; | 129 const TemplateURL* GetTemplateURLForHost(const std::string& host) const; |
141 | 130 |
142 // Adds a new TemplateURL to this model. TemplateURLService will own the | 131 // Adds a new TemplateURL to this model. TemplateURLService will own the |
143 // reference, and delete it when the TemplateURL is removed. | 132 // reference, and delete it when the TemplateURL is removed. |
144 void Add(TemplateURL* template_url); | 133 void Add(TemplateURL* template_url); |
145 | 134 |
146 // Removes the keyword from the model. This deletes the supplied TemplateURL. | 135 // Removes the keyword from the model. This deletes the supplied TemplateURL. |
147 // This fails if the supplied template_url is the default search provider. | 136 // 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... |
237 // notification types: | 226 // notification types: |
238 // . NOTIFY_HISTORY_URL_VISITED: adds keyword search terms if the visit | 227 // . NOTIFY_HISTORY_URL_VISITED: adds keyword search terms if the visit |
239 // corresponds to a keyword. | 228 // corresponds to a keyword. |
240 // . NOTIFY_GOOGLE_URL_UPDATED: updates mapping for any keywords containing | 229 // . NOTIFY_GOOGLE_URL_UPDATED: updates mapping for any keywords containing |
241 // a google base url replacement term. | 230 // a google base url replacement term. |
242 // . PREF_CHANGED: checks whether the default search engine has changed. | 231 // . PREF_CHANGED: checks whether the default search engine has changed. |
243 virtual void Observe(int type, | 232 virtual void Observe(int type, |
244 const NotificationSource& source, | 233 const NotificationSource& source, |
245 const NotificationDetails& details); | 234 const NotificationDetails& details); |
246 | 235 |
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 | |
275 Profile* profile() const { return profile_; } | 236 Profile* profile() const { return profile_; } |
276 | 237 |
277 void SetSearchEngineDialogSlot(int slot) { | 238 void SetSearchEngineDialogSlot(int slot) { |
278 search_engine_dialog_chosen_slot_ = slot; | 239 search_engine_dialog_chosen_slot_ = slot; |
279 } | 240 } |
280 | 241 |
281 int GetSearchEngineDialogSlot() const { | 242 int GetSearchEngineDialogSlot() const { |
282 return search_engine_dialog_chosen_slot_; | 243 return search_engine_dialog_chosen_slot_; |
283 } | 244 } |
284 | 245 |
285 // Registers the preferences used to save a TemplateURL to prefs. | 246 // Registers the preferences used to save a TemplateURL to prefs. |
286 static void RegisterUserPrefs(PrefService* prefs); | 247 static void RegisterUserPrefs(PrefService* prefs); |
287 | 248 |
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 | |
300 #if defined(UNIT_TEST) | 249 #if defined(UNIT_TEST) |
301 // Set a different time provider function, such as | 250 // Set a different time provider function, such as |
302 // base::MockTimeProvider::StaticNow, when testing calls to base::Time::Now. | 251 // base::MockTimeProvider::StaticNow, when testing calls to base::Time::Now. |
303 void set_time_provider(TimeProvider* time_provider) { | 252 void set_time_provider(TimeProvider* time_provider) { |
304 time_provider_ = time_provider; | 253 time_provider_ = time_provider; |
305 } | 254 } |
306 #endif | 255 #endif |
307 | 256 |
308 protected: | 257 protected: |
309 // Cover method for the method of the same name on the HistoryService. | 258 // Cover method for the method of the same name on the HistoryService. |
310 // url is the one that was visited with the given search terms. | 259 // url is the one that was visited with the given search terms. |
311 // | 260 // |
312 // This exists and is virtual for testing. | 261 // This exists and is virtual for testing. |
313 virtual void SetKeywordSearchTermsForURL(const TemplateURL* t_url, | 262 virtual void SetKeywordSearchTermsForURL(const TemplateURL* t_url, |
314 const GURL& url, | 263 const GURL& url, |
315 const string16& term); | 264 const string16& term); |
316 | 265 |
317 private: | 266 private: |
318 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, BuildQueryTerms); | 267 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, BuildQueryTerms); |
319 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch); | 268 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch); |
320 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, | 269 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
321 UpdateKeywordSearchTermsForURL); | 270 UpdateKeywordSearchTermsForURL); |
322 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, | 271 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
323 DontUpdateKeywordSearchForNonReplaceable); | 272 DontUpdateKeywordSearchForNonReplaceable); |
324 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue); | 273 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue); |
325 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders); | 274 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 | |
340 friend class TemplateURLServiceTestUtil; | 275 friend class TemplateURLServiceTestUtil; |
341 | 276 |
342 typedef std::map<string16, const TemplateURL*> KeywordToTemplateMap; | 277 typedef std::map<string16, const TemplateURL*> KeywordToTemplateMap; |
343 typedef std::map<std::string, const TemplateURL*> GUIDToTemplateMap; | |
344 | 278 |
345 // Helper functor for FindMatchingKeywords(), for finding the range of | 279 // Helper functor for FindMatchingKeywords(), for finding the range of |
346 // keywords which begin with a prefix. | 280 // keywords which begin with a prefix. |
347 class LessWithPrefix; | 281 class LessWithPrefix; |
348 | 282 |
349 void Init(const Initializer* initializers, int num_initializers); | 283 void Init(const Initializer* initializers, int num_initializers); |
350 | 284 |
351 void RemoveFromMaps(const TemplateURL* template_url); | 285 void RemoveFromMaps(const TemplateURL* template_url); |
352 | 286 |
353 // Removes the supplied template_url from the keyword maps. This searches | 287 // Removes the supplied template_url from the keyword maps. This searches |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 | 388 |
455 // Removes from the vector any template URL that was created because of | 389 // Removes from the vector any template URL that was created because of |
456 // policy. These TemplateURLs are freed and removed from the database. | 390 // policy. These TemplateURLs are freed and removed from the database. |
457 // Sets default_search_provider to NULL if it was one of them, unless it is | 391 // Sets default_search_provider to NULL if it was one of them, unless it is |
458 // the same as the current default from preferences and it is managed. | 392 // the same as the current default from preferences and it is managed. |
459 void RemoveProvidersCreatedByPolicy( | 393 void RemoveProvidersCreatedByPolicy( |
460 std::vector<TemplateURL*>* template_urls, | 394 std::vector<TemplateURL*>* template_urls, |
461 const TemplateURL** default_search_provider, | 395 const TemplateURL** default_search_provider, |
462 const TemplateURL* default_from_prefs); | 396 const TemplateURL* default_from_prefs); |
463 | 397 |
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 | |
501 NotificationRegistrar registrar_; | 398 NotificationRegistrar registrar_; |
502 | 399 |
503 // Mapping from keyword to the TemplateURL. | 400 // Mapping from keyword to the TemplateURL. |
504 KeywordToTemplateMap keyword_to_template_map_; | 401 KeywordToTemplateMap keyword_to_template_map_; |
505 | 402 |
506 // Mapping from Sync GUIDs to the TemplateURL. | |
507 GUIDToTemplateMap guid_to_template_map_; | |
508 | |
509 TemplateURLVector template_urls_; | 403 TemplateURLVector template_urls_; |
510 | 404 |
511 ObserverList<TemplateURLServiceObserver> model_observers_; | 405 ObserverList<TemplateURLServiceObserver> model_observers_; |
512 | 406 |
513 // Maps from host to set of TemplateURLs whose search url host is host. | 407 // Maps from host to set of TemplateURLs whose search url host is host. |
514 SearchHostToURLsMap provider_map_; | 408 SearchHostToURLsMap provider_map_; |
515 | 409 |
516 // Used to obtain the WebDataService. | 410 // Used to obtain the WebDataService. |
517 // When Load is invoked, if we haven't yet loaded, the WebDataService is | 411 // When Load is invoked, if we haven't yet loaded, the WebDataService is |
518 // obtained from the Profile. This allows us to lazily access the database. | 412 // 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... |
556 // ID assigned to next TemplateURL added to this model. This is an ever | 450 // ID assigned to next TemplateURL added to this model. This is an ever |
557 // increasing integer that is initialized from the database. | 451 // increasing integer that is initialized from the database. |
558 TemplateURLID next_id_; | 452 TemplateURLID next_id_; |
559 | 453 |
560 // List of extension IDs waiting for Load to have keywords registered. | 454 // List of extension IDs waiting for Load to have keywords registered. |
561 std::vector<std::string> pending_extension_ids_; | 455 std::vector<std::string> pending_extension_ids_; |
562 | 456 |
563 // Function returning current time in base::Time units. | 457 // Function returning current time in base::Time units. |
564 TimeProvider* time_provider_; | 458 TimeProvider* time_provider_; |
565 | 459 |
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 | |
579 DISALLOW_COPY_AND_ASSIGN(TemplateURLService); | 460 DISALLOW_COPY_AND_ASSIGN(TemplateURLService); |
580 }; | 461 }; |
581 | 462 |
582 #endif // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ | 463 #endif // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ |
OLD | NEW |