| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ |
| #define COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ |
| |
| #include <stddef.h> |
| |
| #include <map> |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/callback.h" |
| #include "base/callback_list.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/time/default_clock.h" |
| #include "build/build_config.h" |
| #include "components/keyed_service/core/keyed_service.h" |
| #include "components/prefs/pref_change_registrar.h" |
| #include "components/search_engines/default_search_manager.h" |
| #include "components/search_engines/keyword_web_data_service.h" |
| #include "components/search_engines/search_host_to_urls_map.h" |
| #include "components/search_engines/search_terms_data.h" |
| #include "components/search_engines/template_url.h" |
| #include "components/sync/model/sync_change.h" |
| #include "components/sync/model/syncable_service.h" |
| #include "components/sync/protocol/search_engine_specifics.pb.h" |
| #include "components/webdata/common/web_data_service_consumer.h" |
| #if BUILDFLAG(IS_ANDROID) |
| #include "base/android/scoped_java_ref.h" |
| #endif |
| |
| class GURL; |
| class PrefService; |
| class TemplateURLServiceClient; |
| class TemplateURLServiceObserver; |
| struct TemplateURLData; |
| #if BUILDFLAG(IS_ANDROID) |
| class TemplateUrlServiceAndroid; |
| #endif |
| |
| namespace syncer { |
| class SyncData; |
| class SyncErrorFactory; |
| } |
| |
| namespace user_prefs { |
| class PrefRegistrySyncable; |
| } |
| |
| // TemplateURLService is the backend for keywords. It's used by |
| // KeywordAutocomplete. |
| // |
| // TemplateURLService stores a vector of TemplateURLs. The TemplateURLs are |
| // persisted to the database maintained by KeywordWebDataService. |
| // *ALL* mutations to the TemplateURLs must funnel through TemplateURLService. |
| // This allows TemplateURLService to notify listeners of changes as well as keep |
| // the database in sync. |
| // |
| // TemplateURLService does not load the vector of TemplateURLs in its |
| // constructor (except for testing). Use the Load method to trigger a load. |
| // When TemplateURLService has completed loading, observers are notified via |
| // OnTemplateURLServiceChanged, or by a callback registered prior to calling |
| // the Load method. |
| // |
| // TemplateURLService takes ownership of any TemplateURL passed to it. If there |
| // is a KeywordWebDataService, deletion is handled by KeywordWebDataService, |
| // otherwise TemplateURLService handles deletion. |
| |
| class TemplateURLService : public WebDataServiceConsumer, |
| public KeyedService, |
| public syncer::SyncableService { |
| public: |
| using QueryTerms = std::map<std::string, std::string>; |
| using TemplateURLVector = TemplateURL::TemplateURLVector; |
| using OwnedTemplateURLVector = TemplateURL::OwnedTemplateURLVector; |
| using SyncDataMap = std::map<std::string, syncer::SyncData>; |
| |
| // We may want to treat the keyword in a TemplateURL as being a different |
| // length than it actually is. For example, for keywords that end in a |
| // registry, e.g., '.com', we want to consider the registry characters as not |
| // a meaningful part of the keyword and not penalize for the user not typing |
| // those.) |
| using TURLAndMeaningfulLength = std::pair<TemplateURL*, size_t>; |
| using TURLsAndMeaningfulLengths = std::vector<TURLAndMeaningfulLength>; |
| |
| // Struct used for initializing the data store with fake data. |
| // Each initializer is mapped to a TemplateURL. |
| struct Initializer { |
| const char* const keyword; |
| const char* const url; |
| const char* const content; |
| }; |
| |
| struct URLVisitedDetails { |
| GURL url; |
| bool is_keyword_transition; |
| }; |
| |
| // Values for an enumerated histogram used to track TemplateURL edge cases. |
| // These are persisted. Do not re-number. |
| enum SearchTemplateURLEvent { |
| SYNC_DELETE_SUCCESS = 0, |
| SYNC_DELETE_FAIL_NONEXISTENT_ENGINE = 1, |
| SYNC_DELETE_FAIL_DEFAULT_SEARCH_PROVIDER = 2, |
| SYNC_ADD_SUCCESS = 3, |
| SYNC_ADD_CONVERTED_TO_UPDATE = 4, |
| SYNC_ADD_FAIL_OTHER_ERROR = 5, |
| SYNC_UPDATE_SUCCESS = 6, |
| SYNC_UPDATE_CONVERTED_TO_ADD = 7, |
| MIGRATE_SAFE_FOR_AUTOREPLACE_PLAY_API_ENGINE = 8, |
| SEARCH_TEMPLATE_URL_EVENT_MAX, |
| }; |
| |
| TemplateURLService( |
| PrefService* prefs, |
| std::unique_ptr<SearchTermsData> search_terms_data, |
| const scoped_refptr<KeywordWebDataService>& web_data_service, |
| std::unique_ptr<TemplateURLServiceClient> client, |
| const base::RepeatingClosure& dsp_change_callback); |
| // The following is for testing. |
| TemplateURLService(const Initializer* initializers, const int count); |
| |
| TemplateURLService(const TemplateURLService&) = delete; |
| TemplateURLService& operator=(const TemplateURLService&) = delete; |
| |
| ~TemplateURLService() override; |
| |
| // Log a SearchTemplateURLEvent. |
| static void LogSearchTemplateURLEvent(SearchTemplateURLEvent event); |
| |
| // Register Profile preferences in |registry|. |
| static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); |
| |
| #if BUILDFLAG(IS_ANDROID) |
| base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); |
| #endif |
| |
| // Returns true if there is no TemplateURL that conflicts with the |
| // keyword/url pair, or there is one but it can be replaced. |
| // |
| // |url| is the URL of the search query. This is used to prevent auto-adding |
| // a keyword for hosts already associated with a manually-edited keyword. |
| bool CanAddAutogeneratedKeyword(const std::u16string& keyword, |
| const GURL& url); |
| |
| // Returns whether the engine is a "pre-existing" engine, either from the |
| // prepopulate list or created by policy. |
| bool IsPrepopulatedOrCreatedByPolicy(const TemplateURL* template_url) const; |
| |
| // Returns whether |template_url| should be shown in the list of engines |
| // most likely to be selected as a default engine. This is meant to highlight |
| // the current default, as well as the other most likely choices of default |
| // engine, separately from a full list of all TemplateURLs (which might be |
| // very long). |
| bool ShowInDefaultList(const TemplateURL* template_url) const; |
| |
| // Adds to |matches| all TemplateURLs whose keywords begin with |prefix|, |
| // sorted shortest-keyword-first. If |supports_replacement_only| is true, only |
| // TemplateURLs that support replacement are returned. This method must be |
| // efficient, since it's run roughly once per omnibox keystroke. |
| void AddMatchingKeywords(const std::u16string& prefix, |
| bool supports_replacement_only, |
| TURLsAndMeaningfulLengths* matches); |
| |
| // Looks up |keyword| and returns the element it maps to. Returns NULL if |
| // the keyword was not found. |
| // The caller should not try to delete the returned pointer; the data store |
| // retains ownership of it. |
| TemplateURL* GetTemplateURLForKeyword(const std::u16string& keyword); |
| const TemplateURL* GetTemplateURLForKeyword( |
| const std::u16string& keyword) const; |
| |
| // Returns that TemplateURL with the specified GUID, or NULL if not found. |
| // The caller should not try to delete the returned pointer; the data store |
| // retains ownership of it. |
| TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid); |
| const TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid) const; |
| |
| // Returns the first TemplateURL found with a URL using the specified |host|, |
| // or NULL if there are no such TemplateURLs |
| TemplateURL* GetTemplateURLForHost(const std::string& host); |
| const TemplateURL* GetTemplateURLForHost(const std::string& host) const; |
| |
| // Adds a new TemplateURL to this model. |
| // |
| // This function guarantees that on return the model will not have two non- |
| // extension TemplateURLs with the same keyword. If that means that it cannot |
| // add the provided argument, it will return null. Otherwise it will return |
| // the raw pointer to the TemplateURL. |
| // |
| // Returns a raw pointer to |template_url| if the addition succeeded, or null |
| // on failure. (Many callers need still need a raw pointer to the TemplateURL |
| // so they can access it later.) |
| TemplateURL* Add(std::unique_ptr<TemplateURL> template_url); |
| |
| // Like Add(), but overwrites the |template_url|'s values with the provided |
| // ones. |
| TemplateURL* AddWithOverrides(std::unique_ptr<TemplateURL> template_url, |
| const std::u16string& short_name, |
| const std::u16string& keyword, |
| const std::string& url); |
| |
| // Removes the keyword from the model. This deletes the supplied TemplateURL. |
| // This fails if the supplied template_url is the default search provider. |
| void Remove(const TemplateURL* template_url); |
| |
| // Removes any TemplateURL of the specified |type| associated with |
| // |extension_id|. Unlike with Remove(), this can be called when the |
| // TemplateURL in question is the current default search provider. |
| void RemoveExtensionControlledTURL(const std::string& extension_id, |
| TemplateURL::Type type); |
| |
| // Removes all auto-generated keywords that were created in the specified |
| // range. |
| void RemoveAutoGeneratedBetween(base::Time created_after, |
| base::Time created_before); |
| |
| // Removes all auto-generated keywords that were created in the specified |
| // range and match |url_filter|. If |url_filter| is_null(), deletes all |
| // auto-generated keywords in the range. |
| void RemoveAutoGeneratedForUrlsBetween( |
| const base::RepeatingCallback<bool(const GURL&)>& url_filter, |
| base::Time created_after, |
| base::Time created_before); |
| |
| // Adds a TemplateURL for an extension with an omnibox keyword. |
| // Only 1 keyword is allowed for a given extension. If a keyword |
| // already exists for this extension, does nothing. |
| void RegisterOmniboxKeyword(const std::string& extension_id, |
| const std::string& extension_name, |
| const std::string& keyword, |
| const std::string& template_url_string, |
| const base::Time& extension_install_time); |
| |
| // Returns the set of URLs describing the keywords. The elements are owned |
| // by TemplateURLService and should not be deleted. |
| TemplateURLVector GetTemplateURLs(); |
| |
| // Increment the usage count of a keyword. |
| // Called when a URL is loaded that was generated from a keyword. |
| void IncrementUsageCount(TemplateURL* url); |
| |
| // Resets the title, keyword and search url of the specified TemplateURL. |
| // The TemplateURL is marked as not replaceable. |
| void ResetTemplateURL(TemplateURL* url, |
| const std::u16string& title, |
| const std::u16string& keyword, |
| const std::string& search_url); |
| |
| // Sets the `is_active` field of the specified TemplateURL to `kTrue` or |
| // `kFalse`. Called when a user explicitly activates/deactivates the search |
| // engine. |
| void SetIsActiveTemplateURL(TemplateURL* url, bool is_active); |
| |
| // Creates a TemplateURL for |keyword| marked with created_from_play_api(). |
| // Returns the newly created engine. |
| // |
| // This method must NOT be called multiple times for the same |keyword|, |
| // because that would create duplicate engines. Caller is responsible for |
| // verifying there are no existing |keyword| created_from_play_api() engines. |
| TemplateURL* CreatePlayAPISearchEngine(const std::u16string& title, |
| const std::u16string& keyword, |
| const std::string& search_url, |
| const std::string& suggestions_url, |
| const std::string& favicon_url); |
| |
| // Updates any search providers matching |potential_search_url| with the new |
| // favicon location |favicon_url|. |
| void UpdateProviderFavicons(const GURL& potential_search_url, |
| const GURL& favicon_url); |
| |
| // Return true if the given |url| can be made the default. This returns false |
| // regardless of |url| if the default search provider is managed by policy or |
| // controlled by an extension. |
| bool CanMakeDefault(const TemplateURL* url) const; |
| |
| // Set the default search provider. |url| may be null. |
| // This will assert if the default search is managed; the UI should not be |
| // invoking this method in that situation. |
| void SetUserSelectedDefaultSearchProvider(TemplateURL* url); |
| |
| // Returns the default search provider. If the TemplateURLService hasn't been |
| // loaded, the default search provider is pulled from preferences. |
| // |
| // NOTE: This may return null in certain circumstances such as: |
| // 1.) Unit test mode |
| // 2.) The default search engine is disabled by policy. |
| const TemplateURL* GetDefaultSearchProvider() const; |
| |
| // Returns the default search provider, ignoring any that were provided by an |
| // extension. |
| const TemplateURL* GetDefaultSearchProviderIgnoringExtensions() const; |
| |
| // Returns true if the |url| is a search results page from the default search |
| // provider. |
| bool IsSearchResultsPageFromDefaultSearchProvider(const GURL& url) const; |
| |
| // Returns true if the default search is managed through group policy. |
| bool is_default_search_managed() const { |
| return default_search_provider_source_ == DefaultSearchManager::FROM_POLICY; |
| } |
| |
| // Returns true if the default search provider is controlled by an extension. |
| bool IsExtensionControlledDefaultSearch() const; |
| |
| // Returns the default search specified in the prepopulated data, if it |
| // exists. If not, returns first URL in |template_urls_|, or NULL if that's |
| // empty. The returned object is owned by TemplateURLService and can be |
| // destroyed at any time so should be used right after the call. |
| TemplateURL* FindNewDefaultSearchProvider(); |
| |
| // Performs the same actions that happen when the prepopulate data version is |
| // revved: all existing prepopulated entries are checked against the current |
| // prepopulate data, any now-extraneous safe_for_autoreplace() entries are |
| // removed, any existing engines are reset to the provided data (except for |
| // user-edited names or keywords), and any new prepopulated engines are |
| // added. |
| // |
| // After this, the default search engine is reset to the default entry in the |
| // prepopulate data. |
| void RepairPrepopulatedSearchEngines(); |
| |
| // Observers used to listen for changes to the model. |
| // TemplateURLService does NOT delete the observers when deleted. |
| void AddObserver(TemplateURLServiceObserver* observer); |
| void RemoveObserver(TemplateURLServiceObserver* observer); |
| |
| // Loads the keywords. This has no effect if the keywords have already been |
| // loaded. |
| // Observers are notified when loading completes via the method |
| // OnTemplateURLServiceChanged. |
| void Load(); |
| |
| // Registers a callback to be called when the service has loaded. |
| // |
| // If the service has already loaded, this function does nothing. |
| base::CallbackListSubscription RegisterOnLoadedCallback( |
| base::OnceClosure callback); |
| |
| #if defined(UNIT_TEST) |
| void set_loaded(bool value) { loaded_ = value; } |
| |
| // Turns Load() into a no-op. |
| void set_disable_load(bool value) { disable_load_ = value; } |
| #endif |
| |
| // Whether or not the keywords have been loaded. |
| bool loaded() { return loaded_; } |
| |
| // Notification that the keywords have been loaded. |
| // This is invoked from WebDataService, and should not be directly |
| // invoked. |
| void OnWebDataServiceRequestDone( |
| KeywordWebDataService::Handle h, |
| std::unique_ptr<WDTypedResult> result) override; |
| |
| // Returns the locale-direction-adjusted short name for the given keyword. |
| // Also sets the out param to indicate whether the keyword belongs to an |
| // Omnibox extension. |
| std::u16string GetKeywordShortName( |
| const std::u16string& keyword, |
| bool* is_omnibox_api_extension_keyword) const; |
| |
| // Called by the history service when a URL is visited. |
| void OnHistoryURLVisited(const URLVisitedDetails& details); |
| |
| // KeyedService implementation. |
| void Shutdown() override; |
| |
| // syncer::SyncableService implementation. |
| |
| // Waits until keywords have been loaded. |
| void WaitUntilReadyToSync(base::OnceClosure done) override; |
| |
| // Returns all syncable TemplateURLs from this model as SyncData. This should |
| // include every search engine and no Extension keywords. |
| syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const; |
| // Process new search engine changes from Sync, merging them into our local |
| // data. This may send notifications if local search engines are added, |
| // updated or removed. |
| absl::optional<syncer::ModelError> ProcessSyncChanges( |
| const base::Location& from_here, |
| const syncer::SyncChangeList& change_list) override; |
| // Merge initial search engine data from Sync and push any local changes up |
| // to Sync. This may send notifications if local search engines are added, |
| // updated or removed. |
| absl::optional<syncer::ModelError> MergeDataAndStartSyncing( |
| syncer::ModelType type, |
| const syncer::SyncDataList& initial_sync_data, |
| std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, |
| std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) override; |
| void StopSyncing(syncer::ModelType type) override; |
| |
| // Processes a local TemplateURL change for Sync. |turl| is the TemplateURL |
| // that has been modified, and |type| is the Sync ChangeType that took place. |
| // This may send a new SyncChange to the cloud. If our model has not yet been |
| // associated with Sync, or if this is triggered by a Sync change, then this |
| // does nothing. |
| void ProcessTemplateURLChange(const base::Location& from_here, |
| const TemplateURL* turl, |
| syncer::SyncChange::SyncChangeType type); |
| |
| // Returns a SearchTermsData which can be used to call TemplateURL methods. |
| const SearchTermsData& search_terms_data() const { |
| return *search_terms_data_; |
| } |
| |
| // Obtains a session token, regenerating if necessary. |
| std::string GetSessionToken(); |
| |
| // Clears the session token. Should be called when the user clears browsing |
| // data. |
| void ClearSessionToken(); |
| |
| // Explicitly converts from ActiveStatus enum in sync protos to enum in |
| // TemplateURLData. |
| static TemplateURLData::ActiveStatus ActiveStatusFromSync( |
| sync_pb::SearchEngineSpecifics_ActiveStatus is_active); |
| |
| // Explicitly converts from ActiveStatus enum in TemplateURLData to enum in |
| // sync protos. |
| static sync_pb::SearchEngineSpecifics_ActiveStatus ActiveStatusToSync( |
| TemplateURLData::ActiveStatus is_active); |
| |
| // Returns a SyncData with a sync representation of the search engine data |
| // from |turl|. |
| static syncer::SyncData CreateSyncDataFromTemplateURL( |
| const TemplateURL& turl); |
| |
| // Creates a new heap-allocated TemplateURL* which is populated by overlaying |
| // |sync_data| atop |existing_turl|. |existing_turl| may be NULL; if not it |
| // remains unmodified. The caller owns the returned TemplateURL*. |
| // |
| // If the created TemplateURL is migrated in some way from out-of-date sync |
| // data, an appropriate SyncChange is added to |change_list|. If the sync |
| // data is bad for some reason, an ACTION_DELETE change is added and the |
| // function returns NULL. |
| static std::unique_ptr<TemplateURL> |
| CreateTemplateURLFromTemplateURLAndSyncData( |
| TemplateURLServiceClient* client, |
| PrefService* prefs, |
| const SearchTermsData& search_terms_data, |
| const TemplateURL* existing_turl, |
| const syncer::SyncData& sync_data, |
| syncer::SyncChangeList* change_list); |
| |
| // Returns a map mapping Sync GUIDs to pointers to syncer::SyncData. |
| static SyncDataMap CreateGUIDToSyncDataMap( |
| const syncer::SyncDataList& sync_data); |
| |
| #if defined(UNIT_TEST) |
| void set_clock(std::unique_ptr<base::Clock> clock) { |
| clock_ = std::move(clock); |
| } |
| #endif |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
| UpdateKeywordSearchTermsForURL); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
| DontUpdateKeywordSearchForNonReplaceable); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, AddOmniboxExtensionKeyword); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ExtensionsWithSameKeywords); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
| KeywordConflictNonReplaceableEngines); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, LastVisitedTimeUpdate); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, |
| RepairPrepopulatedSearchEngines); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, PreSyncDeletes); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL); |
| FRIEND_TEST_ALL_PREFIXES(LocationBarModelTest, GoogleBaseURL); |
| FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceUnitTest, SessionToken); |
| |
| friend class InstantUnitTestBase; |
| friend class Scoper; |
| friend class TemplateURLServiceTestUtil; |
| friend class TemplateUrlServiceAndroid; |
| |
| using GUIDToTURL = std::map<std::string, TemplateURL*>; |
| |
| // A mapping from keywords to the corresponding TemplateURLs and their |
| // meaningful keyword lengths. This is a multimap, so the system can |
| // efficiently tolerate multiple engines with the same keyword, like from |
| // extensions. |
| // |
| // The values for any given keyword are not sorted. Users that want the best |
| // value for each key must traverse through all matching items. The vast |
| // majority of keywords should only have one item. |
| using KeywordToTURLAndMeaningfulLength = |
| std::multimap<std::u16string, TURLAndMeaningfulLength>; |
| |
| // Declaration of values to be used in an enumerated histogram to tally |
| // changes to the default search provider from various entry points. In |
| // particular, we use this to see what proportion of changes are from Sync |
| // entry points, to help spot erroneous Sync activity. |
| enum DefaultSearchChangeOrigin { |
| // Various known Sync entry points. |
| DSP_CHANGE_SYNC_PREF, |
| DSP_CHANGE_SYNC_ADD, |
| DSP_CHANGE_SYNC_DELETE, |
| DSP_CHANGE_SYNC_NOT_MANAGED, |
| // "Other" origins. We differentiate between Sync and not Sync so we know if |
| // certain changes were intentionally from the system, or possibly some |
| // unintentional change from when we were Syncing. |
| DSP_CHANGE_SYNC_UNINTENTIONAL, |
| // All changes that don't fall into another category; we can't reorder the |
| // list for clarity as this would screw up stat collection. |
| DSP_CHANGE_OTHER, |
| // Changed through "Profile Reset" feature. |
| DSP_CHANGE_PROFILE_RESET, |
| // Changed by an extension through the Override Settings API. |
| DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION, |
| // New DSP during database/prepopulate data load, which was not previously |
| // in the known engine set, and with no previous value in prefs. The |
| // typical time to see this is during first run. |
| DSP_CHANGE_NEW_ENGINE_NO_PREFS, |
| // Boundary value. |
| DSP_CHANGE_MAX, |
| }; |
| |
| // Helper functor for FindMatchingKeywords(), for finding the range of |
| // keywords which begin with a prefix. |
| class LessWithPrefix; |
| |
| // Used to defer notifications until the last Scoper is destroyed by leaving |
| // the scope of a code block. |
| class Scoper; |
| |
| void Init(const Initializer* initializers, int num_initializers); |
| |
| // Removes |template_url| from various internal maps |
| // (|keyword_to_turl_and_length_|, |guid_to_turl_|, |provider_map_|). |
| void RemoveFromMaps(const TemplateURL* template_url); |
| |
| // Adds |template_url| to various internal maps |
| // (|keyword_to_turl_and_length_|, |guid_to_turl_|, |provider_map_|) if |
| // appropriate. (It might not be appropriate if, for instance, |
| // |template_url|'s keyword conflicts with the keyword of a custom search |
| // engine already existing in the maps that is not allowed to be replaced.) |
| void AddToMaps(TemplateURL* template_url); |
| |
| // Helper function for adding an element to |keyword_to_turl_and_length_|. |
| void AddToMap(TemplateURL* template_url); |
| |
| // Sets the keywords. This is used once the keywords have been loaded. |
| // This does NOT notify the delegate or the database. |
| void SetTemplateURLs(std::unique_ptr<OwnedTemplateURLVector> urls); |
| |
| // Transitions to the loaded state. |
| void ChangeToLoadedState(); |
| |
| // Applies a DSE change and reports metrics if appropriate. |
| void ApplyDefaultSearchChange(const TemplateURLData* new_dse_data, |
| DefaultSearchManager::Source source); |
| |
| // Applies a DSE change. May be called at startup or after transitioning to |
| // the loaded state. Returns true if a change actually occurred. |
| bool ApplyDefaultSearchChangeNoMetrics(const TemplateURLData* new_dse_data, |
| DefaultSearchManager::Source source); |
| |
| // Returns false if there is a TemplateURL that has a search url with the |
| // specified host and that TemplateURL has been manually modified. |
| bool CanAddAutogeneratedKeywordForHost(const std::string& host) const; |
| |
| // Updates the information in |existing_turl| using the information from |
| // |new_values|, but the ID for |existing_turl| is retained. Returns whether |
| // |existing_turl| was found in |template_urls_| and thus could be updated. |
| // |
| // NOTE: This should not be called with an extension keyword as there are no |
| // updates needed in that case. |
| bool Update(TemplateURL* existing_turl, const TemplateURL& new_values); |
| |
| // If the TemplateURL comes from a prepopulated URL available in the current |
| // country, update all its fields save for the keyword, short name and id so |
| // that they match the internal prepopulated URL. TemplateURLs not coming from |
| // a prepopulated URL are not modified. |
| static void UpdateTemplateURLIfPrepopulated(TemplateURL* existing_turl, |
| PrefService* prefs); |
| |
| // If the TemplateURL's sync GUID matches the kSyncedDefaultSearchProviderGUID |
| // preference it will be used to update the DSE in prefs. |
| // OnDefaultSearchChange may be triggered as a result. |
| void MaybeUpdateDSEViaPrefs(TemplateURL* synced_turl); |
| |
| // Iterates through the TemplateURLs to see if one matches the visited url. |
| // For each TemplateURL whose url matches the visited url |
| // SetKeywordSearchTermsForURL is invoked. |
| void UpdateKeywordSearchTermsForURL(const URLVisitedDetails& details); |
| |
| // Updates the last_visited time of |url| to the current time. |
| void UpdateTemplateURLVisitTime(TemplateURL* url); |
| |
| // If necessary, generates a visit for the site http:// + t_url.keyword(). |
| void AddTabToSearchVisit(const TemplateURL& t_url); |
| |
| // Adds a new TemplateURL to this model. |
| // |
| // If |newly_adding| is false, we assume that this TemplateURL was already |
| // part of the model in the past, and therefore we don't need to do things |
| // like assign it an ID or notify sync. |
| // |
| // This function guarantees that on return the model will not have two non- |
| // extension TemplateURLs with the same keyword. If that means that it cannot |
| // add the provided argument, it will return null. Otherwise it will return |
| // the raw pointer to the TemplateURL. |
| // |
| // Returns a raw pointer to |template_url| if the addition succeeded, or null |
| // on failure. (Many callers need still need a raw pointer to the TemplateURL |
| // so they can access it later.) |
| TemplateURL* Add(std::unique_ptr<TemplateURL> template_url, |
| bool newly_adding); |
| |
| // Updates |template_urls| so that the only "created by policy" entry is |
| // |default_from_prefs|. |default_from_prefs| may be NULL if there is no |
| // policy-defined DSE in effect. |
| void UpdateProvidersCreatedByPolicy( |
| OwnedTemplateURLVector* template_urls, |
| const TemplateURLData* default_from_prefs); |
| |
| // Resets the sync GUID of the specified TemplateURL and persists the change |
| // to the database. This does not notify observers. |
| void ResetTemplateURLGUID(TemplateURL* url, const std::string& guid); |
| |
| // Adds |sync_turl| into the local model, possibly removing or updating a |
| // local TemplateURL to make room for it. This expects |sync_turl| to be a new |
| // entry from Sync, not currently known to the local model. |sync_data| should |
| // be a SyncDataMap where the contents are entries initially known to Sync |
| // during MergeDataAndStartSyncing. |
| // Any necessary updates to Sync will be appended to |change_list|. This can |
| // include updates on local TemplateURLs, if they are found in |sync_data|. |
| // |initial_data| should be a SyncDataMap of the entries known to the local |
| // model during MergeDataAndStartSyncing. If |sync_turl| replaces a local |
| // entry, that entry is removed from |initial_data| to prevent it from being |
| // sent up to Sync. |
| // This should only be called from MergeDataAndStartSyncing. |
| void MergeInSyncTemplateURL(TemplateURL* sync_turl, |
| const SyncDataMap& sync_data, |
| syncer::SyncChangeList* change_list, |
| SyncDataMap* local_data); |
| |
| // Goes through a vector of TemplateURLs and ensure that both the in-memory |
| // and database copies have valid sync_guids. This is to fix crbug.com/102038, |
| // where old entries were being pushed to Sync without a sync_guid. |
| void PatchMissingSyncGUIDs(OwnedTemplateURLVector* template_urls); |
| |
| void OnSyncedDefaultSearchProviderGUIDChanged(); |
| |
| // Goes through a vector of TemplateURLs and sets is_active to true if it was |
| // not previously set (currently kUnspecified) and has been interacted with |
| // by the user. |
| void MaybeSetIsActiveSearchEngines(OwnedTemplateURLVector* template_urls); |
| |
| // Adds to |matches| all TemplateURLs stored in |keyword_to_turl_and_length| |
| // whose keywords begin with |prefix|, sorted shortest-keyword-first. If |
| // |supports_replacement_only| is true, only TemplateURLs that support |
| // replacement are returned. |
| template <typename Container> |
| void AddMatchingKeywordsHelper(const Container& keyword_to_turl_and_length, |
| const std::u16string& prefix, |
| bool supports_replacement_only, |
| TURLsAndMeaningfulLengths* matches); |
| |
| // Returns the TemplateURL corresponding to |prepopulated_id|, if any. |
| TemplateURL* FindPrepopulatedTemplateURL(int prepopulated_id); |
| |
| // Returns the TemplateURL associated with |extension_id|, if any. |
| TemplateURL* FindTemplateURLForExtension(const std::string& extension_id, |
| TemplateURL::Type type); |
| |
| // Finds any NORMAL_CONTROLLED_BY_EXTENSION engine that matches |data| and |
| // wants to be default. Returns nullptr if not found. |
| TemplateURL* FindMatchingDefaultExtensionTemplateURL( |
| const TemplateURLData& data); |
| |
| // This method removes all TemplateURLs that meet all three criteria: |
| // - Duplicate: Shares the same keyword as |candidate|. |
| // - Replaceable: Engine is eligible for automatic removal. See CanReplace(). |
| // - Worse: There exists a better engine with the same keyword. |
| // |
| // This method must run BEFORE |candidate| is added to the engine list / map. |
| // It would be simpler to run the algorithm AFTER |candidate| is added, but |
| // that makes extra sync updates, observer notifications, and database churn. |
| // |
| // This method returns true if |candidate| ITSELF is rendundant. |
| // But notably, this method NEVER calls Remove() on |candidate|, leaving the |
| // correct handling to its caller. |
| bool RemoveDuplicateReplaceableEnginesOf(TemplateURL* candidate); |
| |
| // Returns true if |turl| matches the default search provider. This method |
| // does both a GUID comparison, because while the model is being loaded, the |
| // DSE may be sourced from prefs, and we still want to consider the |
| // corresponding database entry a match. https://crbug.com/1164024 |
| bool MatchesDefaultSearchProvider(TemplateURL* turl) const; |
| |
| // ---------- Browser state related members --------------------------------- |
| raw_ptr<PrefService> prefs_ = nullptr; |
| |
| std::unique_ptr<SearchTermsData> search_terms_data_ = |
| std::make_unique<SearchTermsData>(); |
| |
| // ---------- Dependencies on other components ------------------------------ |
| // Service used to store entries. |
| scoped_refptr<KeywordWebDataService> web_data_service_; |
| |
| std::unique_ptr<TemplateURLServiceClient> client_; |
| |
| // This closure is run when the default search provider is set to Google. |
| base::RepeatingClosure dsp_change_callback_; |
| |
| PrefChangeRegistrar pref_change_registrar_; |
| |
| // Mapping from keyword to the TemplateURL. |
| KeywordToTURLAndMeaningfulLength keyword_to_turl_and_length_; |
| |
| // Mapping from Sync GUIDs to the TemplateURL. |
| GUIDToTURL guid_to_turl_; |
| |
| OwnedTemplateURLVector template_urls_; |
| |
| base::ObserverList<TemplateURLServiceObserver> model_observers_; |
| |
| // Maps from host to set of TemplateURLs whose search url host is host. |
| std::unique_ptr<SearchHostToURLsMap> provider_map_ = |
| std::make_unique<SearchHostToURLsMap>(); |
| |
| // Whether the keywords have been loaded. |
| bool loaded_ = false; |
| |
| // Set when the web data service fails to load properly. This prevents |
| // further communication with sync or writing to prefs, so we don't persist |
| // inconsistent state data anywhere. |
| bool load_failed_ = false; |
| |
| // Whether Load() is disabled. True only in testing contexts. |
| bool disable_load_ = false; |
| |
| // If non-zero, we're waiting on a load. |
| KeywordWebDataService::Handle load_handle_ = 0; |
| |
| // All visits that occurred before we finished loading. Once loaded |
| // UpdateKeywordSearchTermsForURL is invoked for each element of the vector. |
| std::vector<URLVisitedDetails> visits_to_add_; |
| |
| // Once loaded, the default search provider. This is a pointer to a |
| // TemplateURL owned by |template_urls_|. |
| // |
| // TODO(tommycli): Can we combine this with initial_default_search_provider_? |
| // Essentially all direct usages of this variable need to first check that |
| // |loading_| is true, and should call GetDefaultSearchProvider() instead. |
| // Example of a regression due to this mistake: https://crbug.com/1164024. |
| raw_ptr<TemplateURL> default_search_provider_ = nullptr; |
| |
| // A temporary location for the DSE until Web Data has been loaded and it can |
| // be merged into |template_urls_|. |
| std::unique_ptr<TemplateURL> initial_default_search_provider_; |
| |
| // Source of the default search provider. |
| DefaultSearchManager::Source default_search_provider_source_; |
| |
| // ID assigned to next TemplateURL added to this model. This is an ever |
| // increasing integer that is initialized from the database. |
| TemplateURLID next_id_ = kInvalidTemplateURLID + 1; |
| |
| // Used to retrieve the current time, in base::Time units. |
| std::unique_ptr<base::Clock> clock_ = std::make_unique<base::DefaultClock>(); |
| |
| // Do we have an active association between the TemplateURLs and sync models? |
| // Set in MergeDataAndStartSyncing, reset in StopSyncing. While this is not |
| // set, we ignore any local search engine changes (when we start syncing we |
| // will look up the most recent values anyways). |
| bool models_associated_ = false; |
| |
| // Whether we're currently processing changes from the syncer. While this is |
| // true, we ignore any local search engine changes, since we triggered them. |
| bool processing_syncer_changes_ = false; |
| |
| // We never want reentrancy while applying a default search engine change. |
| // This can happen when deleting keyword conflicts. crbug.com/1031506 |
| bool applying_default_search_engine_change_ = false; |
| |
| // Sync's syncer::SyncChange handler. We push all our changes through this. |
| std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_; |
| |
| // Sync's error handler. We use it to create a sync error. |
| std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory_; |
| |
| // A set of sync GUIDs denoting TemplateURLs that have been removed from this |
| // model or the underlying KeywordWebDataService prior to |
| // MergeDataAndStartSyncing. |
| // This set is used to determine what entries from the server we want to |
| // ignore locally and return a delete command for. |
| std::set<std::string> pre_sync_deletes_; |
| |
| // This is used to log the origin of changes to the default search provider. |
| // We set this value to increasingly specific values when we know what is the |
| // cause/origin of a default search change. |
| DefaultSearchChangeOrigin dsp_change_origin_ = DSP_CHANGE_OTHER; |
| |
| // Stores a list of callbacks to be run after TemplateURLService has loaded. |
| base::OnceClosureList on_loaded_callbacks_; |
| |
| // Similar to |on_loaded_callbacks_| but used for WaitUntilReadyToSync(). |
| base::OnceClosure on_loaded_callback_for_sync_; |
| |
| // Helper class to manage the default search engine. |
| DefaultSearchManager default_search_manager_; |
| |
| // This tracks how many Scoper handles exist. When the number of handles drops |
| // to zero, a notification is made to observers if |
| // |model_mutated_notification_pending_| is true. |
| int outstanding_scoper_handles_ = 0; |
| |
| // Used to track if a notification is necessary due to the model being |
| // mutated. The outermost Scoper handles, can be used to defer notifications, |
| // but if no model mutation occurs, the deferred notification can be skipped. |
| bool model_mutated_notification_pending_ = false; |
| |
| // Session token management. |
| std::string current_token_; |
| base::TimeTicks token_expiration_time_; |
| |
| #if BUILDFLAG(IS_ANDROID) |
| // Manage and fetch the java object that wraps this TemplateURLService on |
| // android. |
| std::unique_ptr<TemplateUrlServiceAndroid> template_url_service_android_; |
| #endif |
| }; |
| |
| #endif // COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_ |