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