Home | History | Annotate | Download | only in search_engines
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
      6 #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
      7 
      8 #include <list>
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "base/gtest_prod_util.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/observer_list.h"
     17 #include "base/prefs/pref_change_registrar.h"
     18 #include "chrome/browser/search_engines/template_url_id.h"
     19 #include "chrome/browser/webdata/web_data_service.h"
     20 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
     21 #include "content/public/browser/notification_observer.h"
     22 #include "content/public/browser/notification_registrar.h"
     23 #include "sync/api/sync_change.h"
     24 #include "sync/api/syncable_service.h"
     25 
     26 class GURL;
     27 class PrefService;
     28 class Profile;
     29 class SearchHostToURLsMap;
     30 class SearchTermsData;
     31 class TemplateURLServiceObserver;
     32 
     33 namespace syncer {
     34 class SyncData;
     35 class SyncErrorFactory;
     36 }
     37 
     38 namespace history {
     39 struct URLVisitedDetails;
     40 }
     41 
     42 // TemplateURLService is the backend for keywords. It's used by
     43 // KeywordAutocomplete.
     44 //
     45 // TemplateURLService stores a vector of TemplateURLs. The TemplateURLs are
     46 // persisted to the database maintained by WebDataService. *ALL* mutations
     47 // to the TemplateURLs must funnel through TemplateURLService. This allows
     48 // TemplateURLService to notify listeners of changes as well as keep the
     49 // database in sync.
     50 //
     51 // There is a TemplateURLService per Profile.
     52 //
     53 // TemplateURLService does not load the vector of TemplateURLs in its
     54 // constructor (except for testing). Use the Load method to trigger a load.
     55 // When TemplateURLService has completed loading, observers are notified via
     56 // OnTemplateURLServiceChanged as well as the TEMPLATE_URL_SERVICE_LOADED
     57 // notification message.
     58 //
     59 // TemplateURLService takes ownership of any TemplateURL passed to it. If there
     60 // is a WebDataService, deletion is handled by WebDataService, otherwise
     61 // TemplateURLService handles deletion.
     62 
     63 class TemplateURLService : public WebDataServiceConsumer,
     64                            public BrowserContextKeyedService,
     65                            public content::NotificationObserver,
     66                            public syncer::SyncableService {
     67  public:
     68   typedef std::map<std::string, std::string> QueryTerms;
     69   typedef std::vector<TemplateURL*> TemplateURLVector;
     70   // Type for a static function pointer that acts as a time source.
     71   typedef base::Time(TimeProvider)();
     72   typedef std::map<std::string, syncer::SyncData> SyncDataMap;
     73 
     74   // Struct used for initializing the data store with fake data.
     75   // Each initializer is mapped to a TemplateURL.
     76   struct Initializer {
     77     const char* const keyword;
     78     const char* const url;
     79     const char* const content;
     80   };
     81 
     82   // Struct describes a search engine added by an extension.
     83   struct ExtensionKeyword {
     84     ExtensionKeyword(const std::string& id,
     85                      const std::string& name,
     86                      const std::string& keyword);
     87     ~ExtensionKeyword();
     88 
     89     std::string extension_id;
     90     std::string extension_name;
     91     std::string extension_keyword;
     92   };
     93 
     94   explicit TemplateURLService(Profile* profile);
     95   // The following is for testing.
     96   TemplateURLService(const Initializer* initializers, const int count);
     97   virtual ~TemplateURLService();
     98 
     99   // Generates a suitable keyword for the specified url, which must be valid.
    100   // This is guaranteed not to return an empty string, since TemplateURLs should
    101   // never have an empty keyword.
    102   static string16 GenerateKeyword(const GURL& url);
    103 
    104   // Removes any unnecessary characters from a user input keyword.
    105   // This removes the leading scheme, "www." and any trailing slash.
    106   static string16 CleanUserInputKeyword(const string16& keyword);
    107 
    108   // Returns the search url for t_url.  Returns an empty GURL if t_url has no
    109   // url().
    110   // NOTE: |t_url| is non-const in this version because of the need to access
    111   // t_url->profile().
    112   static GURL GenerateSearchURL(TemplateURL* t_url);
    113 
    114   // Just like GenerateSearchURL except that it takes SearchTermsData to supply
    115   // the data for some search terms, e.g. so this can be used on threads other
    116   // than the UI thread.  See the various TemplateURLRef::XXXUsingTermsData()
    117   // functions.
    118   static GURL GenerateSearchURLUsingTermsData(
    119       const TemplateURL* t_url,
    120       const SearchTermsData& search_terms_data);
    121 
    122   // Returns true if there is no TemplateURL that conflicts with the
    123   // keyword/url pair, or there is one but it can be replaced. If there is an
    124   // existing keyword that can be replaced and template_url_to_replace is
    125   // non-NULL, template_url_to_replace is set to the keyword to replace.
    126   //
    127   // url gives the url of the search query. The url is used to avoid generating
    128   // a TemplateURL for an existing TemplateURL that shares the same host.
    129   bool CanReplaceKeyword(const string16& keyword,
    130                          const GURL& url,
    131                          TemplateURL** template_url_to_replace);
    132 
    133   // Returns (in |matches|) all TemplateURLs whose keywords begin with |prefix|,
    134   // sorted shortest keyword-first. If |support_replacement_only| is true, only
    135   // TemplateURLs that support replacement are returned.
    136   void FindMatchingKeywords(const string16& prefix,
    137                             bool support_replacement_only,
    138                             TemplateURLVector* matches) const;
    139 
    140   // Looks up |keyword| and returns the element it maps to.  Returns NULL if
    141   // the keyword was not found.
    142   // The caller should not try to delete the returned pointer; the data store
    143   // retains ownership of it.
    144   TemplateURL* GetTemplateURLForKeyword(const string16& keyword);
    145 
    146   // Returns that TemplateURL with the specified GUID, or NULL if not found.
    147   // The caller should not try to delete the returned pointer; the data store
    148   // retains ownership of it.
    149   TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid);
    150 
    151   // Returns the first TemplateURL found with a URL using the specified |host|,
    152   // or NULL if there are no such TemplateURLs
    153   TemplateURL* GetTemplateURLForHost(const std::string& host);
    154 
    155   // Takes ownership of |template_url| and adds it to this model.  For obvious
    156   // reasons, it is illegal to Add() the same |template_url| pointer twice.
    157   void Add(TemplateURL* template_url);
    158 
    159   // Like Add(), but overwrites the |template_url|'s values with the provided
    160   // ones.
    161   void AddAndSetProfile(TemplateURL* template_url, Profile* profile);
    162   void AddWithOverrides(TemplateURL* template_url,
    163                         const string16& short_name,
    164                         const string16& keyword,
    165                         const std::string& url);
    166 
    167   // Removes the keyword from the model. This deletes the supplied TemplateURL.
    168   // This fails if the supplied template_url is the default search provider.
    169   void Remove(TemplateURL* template_url);
    170 
    171   // Removes all auto-generated keywords that were created on or after the
    172   // date passed in.
    173   void RemoveAutoGeneratedSince(base::Time created_after);
    174 
    175   // Removes all auto-generated keywords that were created in the specified
    176   // range.
    177   void RemoveAutoGeneratedBetween(base::Time created_after,
    178                                   base::Time created_before);
    179 
    180   // Removes all auto-generated keywords that were created in the specified
    181   // range for a specified |origin|. If |origin| is empty, deletes all
    182   // auto-generated keywords in the range.
    183   void RemoveAutoGeneratedForOriginBetween(const GURL& origin,
    184                                            base::Time created_after,
    185                                            base::Time created_before);
    186 
    187   // Adds a TemplateURL for an extension with an omnibox keyword.
    188   // Only 1 keyword is allowed for a given extension. If a keyword
    189   // already exists for this extension, does nothing.
    190   void RegisterExtensionKeyword(const std::string& extension_id,
    191                                 const std::string& extension_name,
    192                                 const std::string& keyword);
    193 
    194   // Removes the TemplateURL containing the keyword for the extension with the
    195   // given ID, if any.
    196   void UnregisterExtensionKeyword(const std::string& extension_id);
    197 
    198   // Returns the TemplateURL associated with the keyword for this extension.
    199   // This will work even if the user changed the keyword.
    200   TemplateURL* GetTemplateURLForExtension(const std::string& extension_id);
    201 
    202   // Returns the set of URLs describing the keywords. The elements are owned
    203   // by TemplateURLService and should not be deleted.
    204   TemplateURLVector GetTemplateURLs();
    205 
    206   // Increment the usage count of a keyword.
    207   // Called when a URL is loaded that was generated from a keyword.
    208   void IncrementUsageCount(TemplateURL* url);
    209 
    210   // Resets the title, keyword and search url of the specified TemplateURL.
    211   // The TemplateURL is marked as not replaceable.
    212   void ResetTemplateURL(TemplateURL* url,
    213                         const string16& title,
    214                         const string16& keyword,
    215                         const std::string& search_url);
    216 
    217   // Return true if the given |url| can be made the default.
    218   bool CanMakeDefault(const TemplateURL* url);
    219 
    220   // Set the default search provider.  |url| may be null.
    221   // This will assert if the default search is managed; the UI should not be
    222   // invoking this method in that situation.
    223   void SetDefaultSearchProvider(TemplateURL* url);
    224 
    225   // Returns the default search provider. If the TemplateURLService hasn't been
    226   // loaded, the default search provider is pulled from preferences.
    227   //
    228   // NOTE: At least in unittest mode, this may return NULL.
    229   TemplateURL* GetDefaultSearchProvider();
    230 
    231   // Returns true if the |url| is a search results page from the default search
    232   // provider.
    233   bool IsSearchResultsPageFromDefaultSearchProvider(const GURL& url);
    234 
    235   // Returns true if the default search is managed through group policy.
    236   bool is_default_search_managed() const { return is_default_search_managed_; }
    237 
    238   // Returns the default search specified in the prepopulated data, if it
    239   // exists.  If not, returns first URL in |template_urls_|, or NULL if that's
    240   // empty. The returned object is owned by TemplateURLService and can be
    241   // destroyed at any time so should be used right after the call.
    242   TemplateURL* FindNewDefaultSearchProvider();
    243 
    244   // Resets the search providers to the prepopulated engines plus any keywords
    245   // from currently-installed extensions.  The user will lose all auto-added
    246   // keywords from webpages, all edits to both normal and extension keywords,
    247   // and any keywords belonging to no-longer-installed extensions.
    248   // Modifications will be synced later.
    249   void ResetURLs();
    250 
    251   // Observers used to listen for changes to the model.
    252   // TemplateURLService does NOT delete the observers when deleted.
    253   void AddObserver(TemplateURLServiceObserver* observer);
    254   void RemoveObserver(TemplateURLServiceObserver* observer);
    255 
    256   // Loads the keywords. This has no effect if the keywords have already been
    257   // loaded.
    258   // Observers are notified when loading completes via the method
    259   // OnTemplateURLServiceChanged.
    260   void Load();
    261 
    262 #if defined(UNIT_TEST)
    263   void set_loaded(bool value) { loaded_ = value; }
    264 #endif
    265 
    266   // Whether or not the keywords have been loaded.
    267   bool loaded() { return loaded_; }
    268 
    269   // Notification that the keywords have been loaded.
    270   // This is invoked from WebDataService, and should not be directly
    271   // invoked.
    272   virtual void OnWebDataServiceRequestDone(
    273       WebDataService::Handle h,
    274       const WDTypedResult* result) OVERRIDE;
    275 
    276   // Returns the locale-direction-adjusted short name for the given keyword.
    277   // Also sets the out param to indicate whether the keyword belongs to an
    278   // extension.
    279   string16 GetKeywordShortName(const string16& keyword,
    280                                bool* is_extension_keyword);
    281 
    282   // content::NotificationObserver implementation.
    283   virtual void Observe(int type,
    284                        const content::NotificationSource& source,
    285                        const content::NotificationDetails& details) OVERRIDE;
    286 
    287   // BrowserContextKeyedService implementation.
    288   virtual void Shutdown() OVERRIDE;
    289 
    290   // syncer::SyncableService implementation.
    291 
    292   // Returns all syncable TemplateURLs from this model as SyncData. This should
    293   // include every search engine and no Extension keywords.
    294   virtual syncer::SyncDataList GetAllSyncData(
    295       syncer::ModelType type) const OVERRIDE;
    296   // Process new search engine changes from Sync, merging them into our local
    297   // data. This may send notifications if local search engines are added,
    298   // updated or removed.
    299   virtual syncer::SyncError ProcessSyncChanges(
    300       const tracked_objects::Location& from_here,
    301       const syncer::SyncChangeList& change_list) OVERRIDE;
    302   // Merge initial search engine data from Sync and push any local changes up
    303   // to Sync. This may send notifications if local search engines are added,
    304   // updated or removed.
    305   virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
    306       syncer::ModelType type,
    307       const syncer::SyncDataList& initial_sync_data,
    308       scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
    309       scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) OVERRIDE;
    310   virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
    311 
    312   // Processes a local TemplateURL change for Sync. |turl| is the TemplateURL
    313   // that has been modified, and |type| is the Sync ChangeType that took place.
    314   // This may send a new SyncChange to the cloud. If our model has not yet been
    315   // associated with Sync, or if this is triggered by a Sync change, then this
    316   // does nothing.
    317   void ProcessTemplateURLChange(const tracked_objects::Location& from_here,
    318                                 const TemplateURL* turl,
    319                                 syncer::SyncChange::SyncChangeType type);
    320 
    321   Profile* profile() const { return profile_; }
    322 
    323   // Returns a SyncData with a sync representation of the search engine data
    324   // from |turl|.
    325   static syncer::SyncData CreateSyncDataFromTemplateURL(
    326       const TemplateURL& turl);
    327 
    328   // Creates a new heap-allocated TemplateURL* which is populated by overlaying
    329   // |sync_data| atop |existing_turl|.  |existing_turl| may be NULL; if not it
    330   // remains unmodified.  The caller owns the returned TemplateURL*.
    331   //
    332   // If the created TemplateURL is migrated in some way from out-of-date sync
    333   // data, an appropriate SyncChange is added to |change_list|.  If the sync
    334   // data is bad for some reason, an ACTION_DELETE change is added and the
    335   // function returns NULL.
    336   static TemplateURL* CreateTemplateURLFromTemplateURLAndSyncData(
    337       Profile* profile,
    338       TemplateURL* existing_turl,
    339       const syncer::SyncData& sync_data,
    340       syncer::SyncChangeList* change_list);
    341 
    342   // Returns a map mapping Sync GUIDs to pointers to syncer::SyncData.
    343   static SyncDataMap CreateGUIDToSyncDataMap(
    344       const syncer::SyncDataList& sync_data);
    345 
    346 #if defined(UNIT_TEST)
    347   // Set a different time provider function, such as
    348   // base::MockTimeProvider::StaticNow, when testing calls to base::Time::Now.
    349   void set_time_provider(TimeProvider* time_provider) {
    350     time_provider_ = time_provider;
    351   }
    352 #endif
    353 
    354  protected:
    355   // Cover method for the method of the same name on the HistoryService.
    356   // url is the one that was visited with the given search terms.
    357   //
    358   // This exists and is virtual for testing.
    359   virtual void SetKeywordSearchTermsForURL(const TemplateURL* t_url,
    360                                            const GURL& url,
    361                                            const string16& term);
    362 
    363  private:
    364   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch);
    365   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
    366                            UpdateKeywordSearchTermsForURL);
    367   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
    368                            DontUpdateKeywordSearchForNonReplaceable);
    369   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue);
    370   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders);
    371   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
    372                            CreateSyncDataFromTemplateURL);
    373   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
    374                            CreateTemplateURLFromSyncData);
    375   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, UniquifyKeyword);
    376   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
    377                            ResolveSyncKeywordConflict);
    378   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, PreSyncDeletes);
    379   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest,
    380                            IsLocalTemplateURLBetter);
    381   FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL);
    382 
    383   friend class TemplateURLServiceTestUtilBase;
    384 
    385   typedef std::map<string16, TemplateURL*> KeywordToTemplateMap;
    386   typedef std::map<std::string, TemplateURL*> GUIDToTemplateMap;
    387 
    388   // Declaration of values to be used in an enumerated histogram to tally
    389   // changes to the default search provider from various entry points. In
    390   // particular, we use this to see what proportion of changes are from Sync
    391   // entry points, to help spot erroneous Sync activity.
    392   enum DefaultSearchChangeOrigin {
    393     // Various known Sync entry points.
    394     DSP_CHANGE_SYNC_PREF,
    395     DSP_CHANGE_SYNC_ADD,
    396     DSP_CHANGE_SYNC_DELETE,
    397     DSP_CHANGE_SYNC_NOT_MANAGED,
    398     // "Other" origins. We differentiate between Sync and not Sync so we know if
    399     // certain changes were intentionally from the system, or possibly some
    400     // unintentional change from when we were Syncing.
    401     DSP_CHANGE_SYNC_UNINTENTIONAL,
    402     // All non-sync changes save PROFILE_RESET; we can't reorder the list for
    403     // clarity as this would screw up stat collection.
    404     DSP_CHANGE_OTHER,
    405     // Changed through "Profile Reset" feature.
    406     DSP_CHANGE_PROFILE_RESET,
    407     // Boundary value.
    408     DSP_CHANGE_MAX,
    409   };
    410 
    411   // Helper functor for FindMatchingKeywords(), for finding the range of
    412   // keywords which begin with a prefix.
    413   class LessWithPrefix;
    414 
    415   void Init(const Initializer* initializers, int num_initializers);
    416 
    417   void RemoveFromMaps(TemplateURL* template_url);
    418 
    419   // Removes the supplied template_url from the keyword maps. This searches
    420   // through all entries in the keyword map and does not generate the host or
    421   // keyword. This is used when the cached content of the TemplateURL changes.
    422   void RemoveFromKeywordMapByPointer(TemplateURL* template_url);
    423 
    424   void AddToMaps(TemplateURL* template_url);
    425 
    426   // Sets the keywords. This is used once the keywords have been loaded.
    427   // This does NOT notify the delegate or the database.
    428   //
    429   // This transfers ownership of the elements in |urls| to |this|, and may
    430   // delete some elements, so it's not safe for callers to access any elements
    431   // after calling; to reinforce this, this function clears |urls| on exit.
    432   void SetTemplateURLs(TemplateURLVector* urls);
    433 
    434   // Transitions to the loaded state.
    435   void ChangeToLoadedState();
    436 
    437   // If there is a notification service, sends TEMPLATE_URL_SERVICE_LOADED
    438   // notification.
    439   void NotifyLoaded();
    440 
    441   // Saves enough of url to preferences so that it can be loaded from
    442   // preferences on start up.
    443   void SaveDefaultSearchProviderToPrefs(const TemplateURL* url);
    444 
    445   // Creates a TemplateURL that was previously saved to prefs via
    446   // SaveDefaultSearchProviderToPrefs or set via policy.
    447   // Returns true if successful, false otherwise.
    448   // If the user or the policy has opted for no default search, this
    449   // returns true but default_provider is set to NULL.
    450   // |*is_managed| specifies whether the default is managed via policy.
    451   bool LoadDefaultSearchProviderFromPrefs(
    452       scoped_ptr<TemplateURL>* default_provider,
    453       bool* is_managed);
    454 
    455   // Clears user preferences describing the default search engine.
    456   void ClearDefaultProviderFromPrefs();
    457 
    458   // Returns true if there is no TemplateURL that has a search url with the
    459   // specified host, or the only TemplateURLs matching the specified host can
    460   // be replaced.
    461   bool CanReplaceKeywordForHost(const std::string& host,
    462                                 TemplateURL** to_replace);
    463 
    464   // Returns true if the TemplateURL is replaceable. This doesn't look at the
    465   // uniqueness of the keyword or host and is intended to be called after those
    466   // checks have been done. This returns true if the TemplateURL doesn't appear
    467   // in the default list and is marked as safe_for_autoreplace.
    468   bool CanReplace(const TemplateURL* t_url);
    469 
    470   // Like GetTemplateURLForKeyword(), but ignores extension-provided keywords.
    471   TemplateURL* FindNonExtensionTemplateURLForKeyword(const string16& keyword);
    472 
    473   // Updates the information in |existing_turl| using the information from
    474   // |new_values|, but the ID for |existing_turl| is retained.  Notifying
    475   // observers is the responsibility of the caller.  Returns whether
    476   // |existing_turl| was found in |template_urls_| and thus could be updated.
    477   // |old_search_terms_data| is passed to SearchHostToURLsMap::Remove().
    478   //
    479   // NOTE: This should not be called with an extension keyword as there are no
    480   // updates needed in that case.
    481   bool UpdateNoNotify(TemplateURL* existing_turl,
    482                       const TemplateURL& new_values,
    483                       const SearchTermsData& old_search_terms_data);
    484 
    485   // If the TemplateURL comes from a prepopulated URL available in the current
    486   // country, update all its fields save for the keyword, short name and id so
    487   // that they match the internal prepopulated URL. TemplateURLs not coming from
    488   // a prepopulated URL are not modified.
    489   static void UpdateTemplateURLIfPrepopulated(TemplateURL* existing_turl,
    490                                               Profile* profile);
    491 
    492   // Returns the preferences we use.
    493   PrefService* GetPrefs();
    494 
    495   // Iterates through the TemplateURLs to see if one matches the visited url.
    496   // For each TemplateURL whose url matches the visited url
    497   // SetKeywordSearchTermsForURL is invoked.
    498   void UpdateKeywordSearchTermsForURL(
    499       const history::URLVisitedDetails& details);
    500 
    501   // If necessary, generates a visit for the site http:// + t_url.keyword().
    502   void AddTabToSearchVisit(const TemplateURL& t_url);
    503 
    504   // Invoked when the Google base URL has changed. Updates the mapping for all
    505   // TemplateURLs that have a replacement term of {google:baseURL} or
    506   // {google:baseSuggestURL}.
    507   void GoogleBaseURLChanged(const GURL& old_base_url);
    508 
    509   // Update the default search.  Called at initialization or when a managed
    510   // preference has changed.
    511   void UpdateDefaultSearch();
    512 
    513   // Set the default search provider even if it is managed. |url| may be null.
    514   // Caller is responsible for notifying observers.  Returns whether |url| was
    515   // found in |template_urls_| and thus could be made default.
    516   bool SetDefaultSearchProviderNoNotify(TemplateURL* url);
    517 
    518   // Adds a new TemplateURL to this model. TemplateURLService will own the
    519   // reference, and delete it when the TemplateURL is removed.
    520   // If |newly_adding| is false, we assume that this TemplateURL was already
    521   // part of the model in the past, and therefore we don't need to do things
    522   // like assign it an ID or notify sync.
    523   // This function guarantees that on return the model will not have two
    524   // non-extension TemplateURLs with the same keyword.  If that means that it
    525   // cannot add the provided argument, it will delete it and return false.
    526   // Caller is responsible for notifying observers if this function returns
    527   // true.
    528   bool AddNoNotify(TemplateURL* template_url, bool newly_adding);
    529 
    530   // Removes the keyword from the model. This deletes the supplied TemplateURL.
    531   // This fails if the supplied template_url is the default search provider.
    532   // Caller is responsible for notifying observers.
    533   void RemoveNoNotify(TemplateURL* template_url);
    534 
    535   // Notify the observers that the model has changed.  This is done only if the
    536   // model is loaded.
    537   void NotifyObservers();
    538 
    539   // Removes from the vector any template URL that was created because of
    540   // policy.  These TemplateURLs are freed and removed from the database.
    541   // Sets default_search_provider to NULL if it was one of them, unless it is
    542   // the same as the current default from preferences and it is managed.
    543   void RemoveProvidersCreatedByPolicy(
    544       TemplateURLVector* template_urls,
    545       TemplateURL** default_search_provider,
    546       TemplateURL* default_from_prefs);
    547 
    548   // Resets the sync GUID of the specified TemplateURL and persists the change
    549   // to the database. This does not notify observers.
    550   void ResetTemplateURLGUID(TemplateURL* url, const std::string& guid);
    551 
    552   // Attempts to generate a unique keyword for |turl| based on its original
    553   // keyword. If its keyword is already unique, that is returned. Otherwise, it
    554   // tries to return the autogenerated keyword if that is unique to the Service,
    555   // and finally it repeatedly appends special characters to the keyword until
    556   // it is unique to the Service. If |force| is true, then this will only
    557   // execute the special character appending functionality.
    558   string16 UniquifyKeyword(const TemplateURL& turl, bool force);
    559 
    560   // Returns true iff |local_turl| is considered "better" than |sync_turl| for
    561   // the purposes of resolving conflicts. |local_turl| must be a TemplateURL
    562   // known to the local model (though it may already be synced), and |sync_turl|
    563   // is a new TemplateURL known to Sync but not yet known to the local model.
    564   // The criteria for if |local_turl| is better than |sync_turl| is whether any
    565   // of the following are true:
    566   //  * |local_turl|'s last_modified timestamp is newer than sync_turl.
    567   //  * |local_turl| is created by policy.
    568   //  * |local_turl| is the local default search provider.
    569   bool IsLocalTemplateURLBetter(const TemplateURL* local_turl,
    570                                 const TemplateURL* sync_turl);
    571 
    572   // Given two synced TemplateURLs with a conflicting keyword, one of which
    573   // needs to be added to or updated in the local model (|unapplied_sync_turl|)
    574   // and one which is already known to the local model (|applied_sync_turl|),
    575   // prepares the local model so that |unapplied_sync_turl| can be added to it,
    576   // or applied as an update to an existing TemplateURL.
    577   // Since both entries are known to Sync and one of their keywords will change,
    578   // an ACTION_UPDATE will be appended to |change_list| to reflect this change.
    579   // Note that |applied_sync_turl| must not be an extension keyword.
    580   void ResolveSyncKeywordConflict(TemplateURL* unapplied_sync_turl,
    581                                   TemplateURL* applied_sync_turl,
    582                                   syncer::SyncChangeList* change_list);
    583 
    584   // Adds |sync_turl| into the local model, possibly removing or updating a
    585   // local TemplateURL to make room for it. This expects |sync_turl| to be a new
    586   // entry from Sync, not currently known to the local model. |sync_data| should
    587   // be a SyncDataMap where the contents are entries initially known to Sync
    588   // during MergeDataAndStartSyncing.
    589   // Any necessary updates to Sync will be appended to |change_list|. This can
    590   // include updates on local TemplateURLs, if they are found in |sync_data|.
    591   // |initial_data| should be a SyncDataMap of the entries known to the local
    592   // model during MergeDataAndStartSyncing. If |sync_turl| replaces a local
    593   // entry, that entry is removed from |initial_data| to prevent it from being
    594   // sent up to Sync.
    595   // |merge_result| tracks the changes made to the local model. Added/modified/
    596   // deleted are updated depending on how the |sync_turl| is merged in.
    597   // This should only be called from MergeDataAndStartSyncing.
    598   void MergeInSyncTemplateURL(TemplateURL* sync_turl,
    599                               const SyncDataMap& sync_data,
    600                               syncer::SyncChangeList* change_list,
    601                               SyncDataMap* local_data,
    602                               syncer::SyncMergeResult* merge_result);
    603 
    604   // Checks a newly added TemplateURL from Sync by its sync_guid and sets it as
    605   // the default search provider if we were waiting for it.
    606   void SetDefaultSearchProviderIfNewlySynced(const std::string& guid);
    607 
    608   // Retrieve the pending default search provider according to Sync. Returns
    609   // NULL if there was no pending search provider from Sync.
    610   TemplateURL* GetPendingSyncedDefaultSearchProvider();
    611 
    612   // Goes through a vector of TemplateURLs and ensure that both the in-memory
    613   // and database copies have valid sync_guids. This is to fix crbug.com/102038,
    614   // where old entries were being pushed to Sync without a sync_guid.
    615   void PatchMissingSyncGUIDs(TemplateURLVector* template_urls);
    616 
    617   void OnSyncedDefaultSearchProviderGUIDChanged();
    618 
    619   // Adds |template_urls| to |template_urls_| and sets up the default search
    620   // provider.  If |default_search_provider| is non-NULL, it must refer to one
    621   // of the |template_urls|, and will be used as the new default.
    622   //
    623   // This transfers ownership of the elements in |template_urls| to |this|, and
    624   // may delete some elements, so it's not safe for callers to access any
    625   // elements after calling; to reinforce this, this function clears
    626   // |template_urls| on exit.
    627   void AddTemplateURLsAndSetupDefaultEngine(
    628       TemplateURLVector* template_urls,
    629       TemplateURL* default_search_provider);
    630 
    631   // If there is no current default search provider, sets the default to the
    632   // result of calling FindNewDefaultSearchProvider().
    633   void EnsureDefaultSearchProviderExists();
    634 
    635   // Returns a new TemplateURL for the given extension.
    636   TemplateURL* CreateTemplateURLForExtension(
    637       const ExtensionKeyword& extension_keyword) const;
    638 
    639   content::NotificationRegistrar notification_registrar_;
    640   PrefChangeRegistrar pref_change_registrar_;
    641 
    642   // Mapping from keyword to the TemplateURL.
    643   KeywordToTemplateMap keyword_to_template_map_;
    644 
    645   // Mapping from Sync GUIDs to the TemplateURL.
    646   GUIDToTemplateMap guid_to_template_map_;
    647 
    648   TemplateURLVector template_urls_;
    649 
    650   ObserverList<TemplateURLServiceObserver> model_observers_;
    651 
    652   // Maps from host to set of TemplateURLs whose search url host is host.
    653   // NOTE: This is always non-NULL; we use a scoped_ptr<> to avoid circular
    654   // header dependencies.
    655   scoped_ptr<SearchHostToURLsMap> provider_map_;
    656 
    657   // Used to obtain the WebDataService.
    658   // When Load is invoked, if we haven't yet loaded, the WebDataService is
    659   // obtained from the Profile. This allows us to lazily access the database.
    660   Profile* profile_;
    661 
    662   // Whether the keywords have been loaded.
    663   bool loaded_;
    664 
    665   // Did loading fail? This is only valid if loaded_ is true.
    666   bool load_failed_;
    667 
    668   // If non-zero, we're waiting on a load.
    669   WebDataService::Handle load_handle_;
    670 
    671   // Service used to store entries.
    672   scoped_refptr<WebDataService> service_;
    673 
    674   // All visits that occurred before we finished loading. Once loaded
    675   // UpdateKeywordSearchTermsForURL is invoked for each element of the vector.
    676   std::vector<history::URLVisitedDetails> visits_to_add_;
    677 
    678   // Once loaded, the default search provider.  This is a pointer to a
    679   // TemplateURL owned by template_urls_.
    680   TemplateURL* default_search_provider_;
    681 
    682   // The initial search provider extracted from preferences. This is only valid
    683   // if we haven't been loaded or loading failed.
    684   scoped_ptr<TemplateURL> initial_default_search_provider_;
    685 
    686   // Whether the default search is managed via policy.
    687   bool is_default_search_managed_;
    688 
    689   // ID assigned to next TemplateURL added to this model. This is an ever
    690   // increasing integer that is initialized from the database.
    691   TemplateURLID next_id_;
    692 
    693   // Function returning current time in base::Time units.
    694   TimeProvider* time_provider_;
    695 
    696   // Do we have an active association between the TemplateURLs and sync models?
    697   // Set in MergeDataAndStartSyncing, reset in StopSyncing. While this is not
    698   // set, we ignore any local search engine changes (when we start syncing we
    699   // will look up the most recent values anyways).
    700   bool models_associated_;
    701 
    702   // Whether we're currently processing changes from the syncer. While this is
    703   // true, we ignore any local search engine changes, since we triggered them.
    704   bool processing_syncer_changes_;
    705 
    706   // Sync's syncer::SyncChange handler. We push all our changes through this.
    707   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
    708 
    709   // Sync's error handler. We use it to create a sync error.
    710   scoped_ptr<syncer::SyncErrorFactory> sync_error_factory_;
    711 
    712   // Whether or not we are waiting on the default search provider to come in
    713   // from Sync. This is to facilitate the fact that changes to the value of
    714   // prefs::kSyncedDefaultSearchProviderGUID do not always come before the
    715   // TemplateURL entry it refers to, and to handle the case when we want to use
    716   // the Synced default when the default search provider becomes unmanaged.
    717   bool pending_synced_default_search_;
    718 
    719   // A set of sync GUIDs denoting TemplateURLs that have been removed from this
    720   // model or the underlying WebDataService prior to MergeDataAndStartSyncing.
    721   // This set is used to determine what entries from the server we want to
    722   // ignore locally and return a delete command for.
    723   std::set<std::string> pre_sync_deletes_;
    724 
    725   // This is used to log the origin of changes to the default search provider.
    726   // We set this value to increasingly specific values when we know what is the
    727   // cause/origin of a default search change.
    728   DefaultSearchChangeOrigin dsp_change_origin_;
    729 
    730   DISALLOW_COPY_AND_ASSIGN(TemplateURLService);
    731 };
    732 
    733 #endif  // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
    734