1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
6 #define COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
17 #include "base/callback_list.h"
18 #include "base/functional/callback.h"
19 #include "base/gtest_prod_util.h"
20 #include "base/memory/raw_ptr.h"
21 #include "base/memory/raw_ptr_exclusion.h"
22 #include "base/observer_list.h"
23 #include "base/time/default_clock.h"
24 #include "base/time/time.h"
25 #include "build/build_config.h"
26 #include "components/keyed_service/core/keyed_service.h"
27 #include "components/prefs/pref_change_registrar.h"
28 #include "components/search_engines/default_search_manager.h"
29 #include "components/search_engines/keyword_web_data_service.h"
30 #include "components/search_engines/search_host_to_urls_map.h"
31 #include "components/search_engines/search_terms_data.h"
32 #include "components/search_engines/template_url.h"
33 #include "components/sync/model/sync_change.h"
34 #include "components/sync/model/syncable_service.h"
35 #include "components/sync/protocol/search_engine_specifics.pb.h"
36 #include "components/webdata/common/web_data_service_consumer.h"
37 #if BUILDFLAG(IS_ANDROID)
38 #include "base/android/scoped_java_ref.h"
43 class TemplateURLServiceClient;
44 class TemplateURLServiceObserver;
45 struct TemplateURLData;
46 #if BUILDFLAG(IS_ANDROID)
47 class TemplateUrlServiceAndroid;
54 namespace user_prefs {
55 class PrefRegistrySyncable;
58 // TemplateURLService is the backend for keywords. It's used by
59 // KeywordAutocomplete.
61 // TemplateURLService stores a vector of TemplateURLs. The TemplateURLs are
62 // persisted to the database maintained by KeywordWebDataService.
63 // *ALL* mutations to the TemplateURLs must funnel through TemplateURLService.
64 // This allows TemplateURLService to notify listeners of changes as well as keep
65 // the database in sync.
67 // TemplateURLService does not load the vector of TemplateURLs in its
68 // constructor (except for testing). Use the Load method to trigger a load.
69 // When TemplateURLService has completed loading, observers are notified via
70 // OnTemplateURLServiceChanged, or by a callback registered prior to calling
73 // TemplateURLService takes ownership of any TemplateURL passed to it. If there
74 // is a KeywordWebDataService, deletion is handled by KeywordWebDataService,
75 // otherwise TemplateURLService handles deletion.
77 class TemplateURLService : public WebDataServiceConsumer,
79 public syncer::SyncableService {
81 using QueryTerms = std::map<std::string, std::string>;
82 using TemplateURLVector = TemplateURL::TemplateURLVector;
83 using OwnedTemplateURLVector = TemplateURL::OwnedTemplateURLVector;
84 using SyncDataMap = std::map<std::string, syncer::SyncData>;
86 // We may want to treat the keyword in a TemplateURL as being a different
87 // length than it actually is. For example, for keywords that end in a
88 // registry, e.g., '.com', we want to consider the registry characters as not
89 // a meaningful part of the keyword and not penalize for the user not typing
91 using TURLAndMeaningfulLength = std::pair<TemplateURL*, size_t>;
92 using TURLsAndMeaningfulLengths = std::vector<TURLAndMeaningfulLength>;
94 // Struct used for initializing the data store with fake data.
95 // Each initializer is mapped to a TemplateURL.
97 const char* const keyword;
98 const char* const url;
99 const char* const content;
102 struct URLVisitedDetails {
104 bool is_keyword_transition;
107 // Search metadata that's often used to persist into History.
108 struct SearchMetadata {
109 // This field is not a raw_ptr<> because it was filtered by the rewriter
111 RAW_PTR_EXCLUSION const TemplateURL* template_url;
113 std::u16string search_terms;
116 // Values for an enumerated histogram used to track TemplateURL edge cases.
117 // These are persisted. Do not re-number.
118 enum SearchTemplateURLEvent {
119 SYNC_DELETE_SUCCESS = 0,
120 SYNC_DELETE_FAIL_NONEXISTENT_ENGINE = 1,
121 SYNC_DELETE_FAIL_DEFAULT_SEARCH_PROVIDER = 2,
122 SYNC_ADD_SUCCESS = 3,
123 SYNC_ADD_CONVERTED_TO_UPDATE = 4,
124 SYNC_ADD_FAIL_OTHER_ERROR = 5,
125 SYNC_UPDATE_SUCCESS = 6,
126 SYNC_UPDATE_CONVERTED_TO_ADD = 7,
127 MIGRATE_SAFE_FOR_AUTOREPLACE_PLAY_API_ENGINE = 8,
128 SEARCH_TEMPLATE_URL_EVENT_MAX,
133 std::unique_ptr<SearchTermsData> search_terms_data,
134 const scoped_refptr<KeywordWebDataService>& web_data_service,
135 std::unique_ptr<TemplateURLServiceClient> client,
136 const base::RepeatingClosure& dsp_change_callback);
137 // The following is for testing.
138 TemplateURLService(const Initializer* initializers, const int count);
140 TemplateURLService(const TemplateURLService&) = delete;
141 TemplateURLService& operator=(const TemplateURLService&) = delete;
143 ~TemplateURLService() override;
145 // Log a SearchTemplateURLEvent.
146 static void LogSearchTemplateURLEvent(SearchTemplateURLEvent event);
148 // Register Profile preferences in |registry|.
149 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
151 #if BUILDFLAG(IS_ANDROID)
152 base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
155 // Returns true if there is no TemplateURL that conflicts with the
156 // keyword/url pair, or there is one but it can be replaced.
158 // |url| is the URL of the search query. This is used to prevent auto-adding
159 // a keyword for hosts already associated with a manually-edited keyword.
160 bool CanAddAutogeneratedKeyword(const std::u16string& keyword,
163 // Returns whether the engine is a "pre-existing" engine, either from the
164 // prepopulate list or created by policy.
165 bool IsPrepopulatedOrCreatedByPolicy(const TemplateURL* template_url) const;
167 // Returns whether |template_url| should be shown in the list of engines
168 // most likely to be selected as a default engine. This is meant to highlight
169 // the current default, as well as the other most likely choices of default
170 // engine, separately from a full list of all TemplateURLs (which might be
172 bool ShowInDefaultList(const TemplateURL* template_url) const;
174 // Adds to |matches| all TemplateURLs whose keywords begin with |prefix|,
175 // sorted shortest-keyword-first. If |supports_replacement_only| is true, only
176 // TemplateURLs that support replacement are returned. This method must be
177 // efficient, since it's run roughly once per omnibox keystroke.
178 void AddMatchingKeywords(const std::u16string& prefix,
179 bool supports_replacement_only,
180 TURLsAndMeaningfulLengths* matches);
182 // Looks up |keyword| and returns the best TemplateURL for it. Returns
183 // nullptr if the keyword was not found. The caller should not try to delete
184 // the returned pointer; the data store retains ownership of it.
185 TemplateURL* GetTemplateURLForKeyword(const std::u16string& keyword);
186 const TemplateURL* GetTemplateURLForKeyword(
187 const std::u16string& keyword) const;
189 // Returns that TemplateURL with the specified GUID, or NULL if not found.
190 // The caller should not try to delete the returned pointer; the data store
191 // retains ownership of it.
192 TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid);
193 const TemplateURL* GetTemplateURLForGUID(const std::string& sync_guid) const;
195 // Returns the best TemplateURL found with a URL using the specified |host|,
196 // or nullptr if there are no such TemplateURLs.
197 TemplateURL* GetTemplateURLForHost(const std::string& host);
198 const TemplateURL* GetTemplateURLForHost(const std::string& host) const;
200 // Returns the number of TemplateURLs that match `host`. Used for logging.
201 // Caller must ensure TemplateURLService is loaded before calling this.
202 // TODO(crbug.com/1322216): Delete after bug is fixed.
203 size_t GetTemplateURLCountForHostForLogging(const std::string& host) const;
205 // Adds a new TemplateURL to this model.
207 // This function guarantees that on return the model will not have two non-
208 // extension TemplateURLs with the same keyword. If that means that it cannot
209 // add the provided argument, it will return null. Otherwise it will return
210 // the raw pointer to the TemplateURL.
212 // Returns a raw pointer to |template_url| if the addition succeeded, or null
213 // on failure. (Many callers need still need a raw pointer to the TemplateURL
214 // so they can access it later.)
215 TemplateURL* Add(std::unique_ptr<TemplateURL> template_url);
217 // Like Add(), but overwrites the |template_url|'s values with the provided
219 TemplateURL* AddWithOverrides(std::unique_ptr<TemplateURL> template_url,
220 const std::u16string& short_name,
221 const std::u16string& keyword,
222 const std::string& url);
224 // Removes the keyword from the model. This deletes the supplied TemplateURL.
225 // This fails if the supplied template_url is the default search provider.
226 void Remove(const TemplateURL* template_url);
228 // Removes any TemplateURL of the specified |type| associated with
229 // |extension_id|. Unlike with Remove(), this can be called when the
230 // TemplateURL in question is the current default search provider.
231 void RemoveExtensionControlledTURL(const std::string& extension_id,
232 TemplateURL::Type type);
234 // Removes all auto-generated keywords that were created in the specified
236 void RemoveAutoGeneratedBetween(base::Time created_after,
237 base::Time created_before);
239 // Removes all auto-generated keywords that were created in the specified
240 // range and match |url_filter|. If |url_filter| is_null(), deletes all
241 // auto-generated keywords in the range.
242 void RemoveAutoGeneratedForUrlsBetween(
243 const base::RepeatingCallback<bool(const GURL&)>& url_filter,
244 base::Time created_after,
245 base::Time created_before);
247 // Adds a TemplateURL for an extension with an omnibox keyword.
248 // Only 1 keyword is allowed for a given extension. If a keyword
249 // already exists for this extension, does nothing.
250 void RegisterOmniboxKeyword(const std::string& extension_id,
251 const std::string& extension_name,
252 const std::string& keyword,
253 const std::string& template_url_string,
254 const base::Time& extension_install_time);
256 // Returns the set of URLs describing the keywords. The elements are owned
257 // by TemplateURLService and should not be deleted.
258 TemplateURLVector GetTemplateURLs();
260 // Increment the usage count of a keyword.
261 // Called when a URL is loaded that was generated from a keyword.
262 void IncrementUsageCount(TemplateURL* url);
264 // Resets the title, keyword and search url of the specified TemplateURL.
265 // The TemplateURL is marked as not replaceable.
266 void ResetTemplateURL(TemplateURL* url,
267 const std::u16string& title,
268 const std::u16string& keyword,
269 const std::string& search_url);
271 // Sets the `is_active` field of the specified TemplateURL to `kTrue` or
272 // `kFalse`. Called when a user explicitly activates/deactivates the search
274 void SetIsActiveTemplateURL(TemplateURL* url, bool is_active);
276 // Creates a TemplateURL for |keyword| marked with created_from_play_api().
277 // Returns the newly created engine.
279 // This method must NOT be called multiple times for the same |keyword|,
280 // because that would create duplicate engines. Caller is responsible for
281 // verifying there are no existing |keyword| created_from_play_api() engines.
282 TemplateURL* CreatePlayAPISearchEngine(const std::u16string& title,
283 const std::u16string& keyword,
284 const std::string& search_url,
285 const std::string& suggestions_url,
286 const std::string& favicon_url);
288 // Updates any search providers matching |potential_search_url| with the new
289 // favicon location |favicon_url|.
290 void UpdateProviderFavicons(const GURL& potential_search_url,
291 const GURL& favicon_url);
293 // Return true if the given |url| can be made the default. This returns false
294 // regardless of |url| if the default search provider is managed by policy or
295 // controlled by an extension.
296 bool CanMakeDefault(const TemplateURL* url) const;
298 // Set the default search provider. |url| may be null.
299 // This will assert if the default search is managed; the UI should not be
300 // invoking this method in that situation.
301 void SetUserSelectedDefaultSearchProvider(TemplateURL* url);
303 // Returns the default search provider. If the TemplateURLService hasn't been
304 // loaded, the default search provider is pulled from preferences.
306 // NOTE: This may return null in certain circumstances such as:
307 // 1.) Unit test mode
308 // 2.) The default search engine is disabled by policy.
309 const TemplateURL* GetDefaultSearchProvider() const;
311 // Returns the default search provider, ignoring any that were provided by an
313 const TemplateURL* GetDefaultSearchProviderIgnoringExtensions() const;
315 // Returns true if the |url| is a search results page from the default search
317 bool IsSearchResultsPageFromDefaultSearchProvider(const GURL& url) const;
319 // Generates a search results page URL for the default search provider with
320 // the given search terms. Returns an empty GURL if the default search
321 // provider is not available.
322 GURL GenerateSearchURLForDefaultSearchProvider(
323 const std::u16string& search_terms) const;
325 // Returns search metadata if |url| is a valid Search URL.
326 absl::optional<SearchMetadata> ExtractSearchMetadata(const GURL& url) const;
328 // Returns true if the default search provider supports the side search
330 bool IsSideSearchSupportedForDefaultSearchProvider() const;
332 // Returns true if the default search provider supports the opening
333 // image search requests in the side panel.
334 bool IsSideImageSearchSupportedForDefaultSearchProvider() const;
336 // Generates a side search URL for the default search provider's search url.
337 GURL GenerateSideSearchURLForDefaultSearchProvider(
338 const GURL& search_url,
339 const std::string& version) const;
341 // Takes a search URL that belongs to this side search in the side panel and
342 // removes the side search param from the URL.
343 GURL RemoveSideSearchParamFromURL(const GURL& side_search_url) const;
345 // Generates a side image search URL for the default search provider's image
347 GURL GenerateSideImageSearchURLForDefaultSearchProvider(
348 const GURL& image_search_url,
349 const std::string& version) const;
351 // Takes a search URL that belongs to this image search in the side panel and
352 // removes the side image search param from the URL.
353 GURL RemoveSideImageSearchParamFromURL(const GURL& image_search_url) const;
355 // Returns true if the default search is managed through group policy.
356 bool is_default_search_managed() const {
357 return default_search_provider_source_ == DefaultSearchManager::FROM_POLICY;
360 // Returns true if the default search provider is controlled by an extension.
361 bool IsExtensionControlledDefaultSearch() const;
363 // Returns the default search specified in the prepopulated data, if it
364 // exists. If not, returns first URL in |template_urls_|, or NULL if that's
365 // empty. The returned object is owned by TemplateURLService and can be
366 // destroyed at any time so should be used right after the call.
367 TemplateURL* FindNewDefaultSearchProvider();
369 // Performs the same actions that happen when the prepopulate data version is
370 // revved: all existing prepopulated entries are checked against the current
371 // prepopulate data, any now-extraneous safe_for_autoreplace() entries are
372 // removed, any existing engines are reset to the provided data (except for
373 // user-edited names or keywords), and any new prepopulated engines are
376 // After this, the default search engine is reset to the default entry in the
378 void RepairPrepopulatedSearchEngines();
380 // Performs the same actions that happen when the starter pack data version is
381 // revved: all existing starter pack entries are checked against the current
382 // starter pack data, any now-extraneous safe_for_autoreplace() entries are
383 // removed, any existing engines are reset to the provided data (except for
384 // user-edited names or keywords), and any new starter pack engines are
385 // added. Unlike `RepairPrepopulatedSearchEngines()`, this does not modify
386 // the default search engine entry.
387 void RepairStarterPackEngines();
389 // Observers used to listen for changes to the model.
390 // TemplateURLService does NOT delete the observers when deleted.
391 void AddObserver(TemplateURLServiceObserver* observer);
392 void RemoveObserver(TemplateURLServiceObserver* observer);
394 // Loads the keywords. This has no effect if the keywords have already been
396 // Observers are notified when loading completes via the method
397 // OnTemplateURLServiceChanged.
400 // Registers a callback to be called when the service has loaded.
402 // If the service has already loaded, this function does nothing.
403 base::CallbackListSubscription RegisterOnLoadedCallback(
404 base::OnceClosure callback);
406 #if defined(UNIT_TEST)
407 void set_loaded(bool value) { loaded_ = value; }
409 // Turns Load() into a no-op.
410 void set_disable_load(bool value) { disable_load_ = value; }
413 // Whether or not the keywords have been loaded.
414 bool loaded() const { return loaded_; }
416 // Notification that the keywords have been loaded.
417 // This is invoked from WebDataService, and should not be directly
419 void OnWebDataServiceRequestDone(
420 KeywordWebDataService::Handle h,
421 std::unique_ptr<WDTypedResult> result) override;
423 // Returns the locale-direction-adjusted short name for the given keyword.
424 // Also sets the out param to indicate whether the keyword belongs to an
425 // Omnibox extension.
426 std::u16string GetKeywordShortName(
427 const std::u16string& keyword,
428 bool* is_omnibox_api_extension_keyword) const;
430 // Called by the history service when a URL is visited.
431 void OnHistoryURLVisited(const URLVisitedDetails& details);
433 // KeyedService implementation.
434 void Shutdown() override;
436 // syncer::SyncableService implementation.
438 // Waits until keywords have been loaded.
439 void WaitUntilReadyToSync(base::OnceClosure done) override;
441 // Returns all syncable TemplateURLs from this model as SyncData. This should
442 // include every search engine and no Extension keywords.
443 syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const;
444 // Process new search engine changes from Sync, merging them into our local
445 // data. This may send notifications if local search engines are added,
446 // updated or removed.
447 absl::optional<syncer::ModelError> ProcessSyncChanges(
448 const base::Location& from_here,
449 const syncer::SyncChangeList& change_list) override;
450 // Merge initial search engine data from Sync and push any local changes up
451 // to Sync. This may send notifications if local search engines are added,
452 // updated or removed.
453 absl::optional<syncer::ModelError> MergeDataAndStartSyncing(
454 syncer::ModelType type,
455 const syncer::SyncDataList& initial_sync_data,
456 std::unique_ptr<syncer::SyncChangeProcessor> sync_processor) override;
457 void StopSyncing(syncer::ModelType type) override;
459 // Processes a local TemplateURL change for Sync. |turl| is the TemplateURL
460 // that has been modified, and |type| is the Sync ChangeType that took place.
461 // This may send a new SyncChange to the cloud. If our model has not yet been
462 // associated with Sync, or if this is triggered by a Sync change, then this
464 void ProcessTemplateURLChange(const base::Location& from_here,
465 const TemplateURL* turl,
466 syncer::SyncChange::SyncChangeType type);
468 // Returns a SearchTermsData which can be used to call TemplateURL methods.
469 const SearchTermsData& search_terms_data() const {
470 return *search_terms_data_;
473 // Obtains a session token, regenerating if necessary.
474 std::string GetSessionToken();
476 // Clears the session token. Should be called when the user clears browsing
478 void ClearSessionToken();
480 // Explicitly converts from ActiveStatus enum in sync protos to enum in
482 static TemplateURLData::ActiveStatus ActiveStatusFromSync(
483 sync_pb::SearchEngineSpecifics_ActiveStatus is_active);
485 // Explicitly converts from ActiveStatus enum in TemplateURLData to enum in
487 static sync_pb::SearchEngineSpecifics_ActiveStatus ActiveStatusToSync(
488 TemplateURLData::ActiveStatus is_active);
490 // Returns a SyncData with a sync representation of the search engine data
492 static syncer::SyncData CreateSyncDataFromTemplateURL(
493 const TemplateURL& turl);
495 // Creates a new heap-allocated TemplateURL* which is populated by overlaying
496 // |sync_data| atop |existing_turl|. |existing_turl| may be NULL; if not it
497 // remains unmodified. The caller owns the returned TemplateURL*.
499 // If the created TemplateURL is migrated in some way from out-of-date sync
500 // data, an appropriate SyncChange is added to |change_list|. If the sync
501 // data is bad for some reason, an ACTION_DELETE change is added and the
502 // function returns NULL.
503 static std::unique_ptr<TemplateURL>
504 CreateTemplateURLFromTemplateURLAndSyncData(
505 TemplateURLServiceClient* client,
507 const SearchTermsData& search_terms_data,
508 const TemplateURL* existing_turl,
509 const syncer::SyncData& sync_data,
510 syncer::SyncChangeList* change_list);
512 // Returns a map mapping Sync GUIDs to pointers to syncer::SyncData.
513 static SyncDataMap CreateGUIDToSyncDataMap(
514 const syncer::SyncDataList& sync_data);
516 #if defined(UNIT_TEST)
517 void set_clock(std::unique_ptr<base::Clock> clock) {
518 clock_ = std::move(clock);
523 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch);
524 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
525 UpdateKeywordSearchTermsForURL);
526 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
527 DontUpdateKeywordSearchForNonReplaceable);
528 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue);
529 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders);
530 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, AddOmniboxExtensionKeyword);
531 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ExtensionsWithSameKeywords);
532 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
533 KeywordConflictNonReplaceableEngines);
534 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, LastVisitedTimeUpdate);
535 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
536 RepairPrepopulatedSearchEngines);
537 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, RepairStarterPackEngines);
538 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, PreSyncDeletes);
539 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL);
540 FRIEND_TEST_ALL_PREFIXES(LocationBarModelTest, GoogleBaseURL);
541 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceUnitTest, SessionToken);
543 friend class InstantUnitTestBase;
545 friend class TemplateURLServiceTestUtil;
546 friend class TemplateUrlServiceAndroid;
548 using GUIDToTURL = std::map<std::string, TemplateURL*>;
550 // A mapping from keywords to the corresponding TemplateURLs and their
551 // meaningful keyword lengths. This is a multimap, so the system can
552 // efficiently tolerate multiple engines with the same keyword, like from
555 // The values for any given keyword are not sorted. Users that want the best
556 // value for each key must traverse through all matching items. The vast
557 // majority of keywords should only have one item.
558 using KeywordToTURLAndMeaningfulLength =
559 std::multimap<std::u16string, TURLAndMeaningfulLength>;
561 // Declaration of values to be used in an enumerated histogram to tally
562 // changes to the default search provider from various entry points. In
563 // particular, we use this to see what proportion of changes are from Sync
564 // entry points, to help spot erroneous Sync activity.
565 enum DefaultSearchChangeOrigin {
566 // Various known Sync entry points.
567 DSP_CHANGE_SYNC_PREF,
569 DSP_CHANGE_SYNC_DELETE,
570 DSP_CHANGE_SYNC_NOT_MANAGED,
571 // "Other" origins. We differentiate between Sync and not Sync so we know if
572 // certain changes were intentionally from the system, or possibly some
573 // unintentional change from when we were Syncing.
574 DSP_CHANGE_SYNC_UNINTENTIONAL,
575 // All changes that don't fall into another category; we can't reorder the
576 // list for clarity as this would screw up stat collection.
578 // Changed through "Profile Reset" feature.
579 DSP_CHANGE_PROFILE_RESET,
580 // Changed by an extension through the Override Settings API.
581 DSP_CHANGE_OVERRIDE_SETTINGS_EXTENSION,
582 // New DSP during database/prepopulate data load, which was not previously
583 // in the known engine set, and with no previous value in prefs. The
584 // typical time to see this is during first run.
585 DSP_CHANGE_NEW_ENGINE_NO_PREFS,
590 // Helper functor for FindMatchingKeywords(), for finding the range of
591 // keywords which begin with a prefix.
592 class LessWithPrefix;
594 // Used to defer notifications until the last Scoper is destroyed by leaving
595 // the scope of a code block.
598 void Init(const Initializer* initializers, int num_initializers);
600 // Removes |template_url| from various internal maps
601 // (|keyword_to_turl_and_length_|, |guid_to_turl_|, |provider_map_|).
602 void RemoveFromMaps(const TemplateURL* template_url);
604 // Adds |template_url| to various internal maps
605 // (|keyword_to_turl_and_length_|, |guid_to_turl_|, |provider_map_|) if
606 // appropriate. (It might not be appropriate if, for instance,
607 // |template_url|'s keyword conflicts with the keyword of a custom search
608 // engine already existing in the maps that is not allowed to be replaced.)
609 void AddToMaps(TemplateURL* template_url);
611 // Helper function for adding an element to |keyword_to_turl_and_length_|.
612 void AddToMap(TemplateURL* template_url);
614 // Sets the keywords. This is used once the keywords have been loaded.
615 // This does NOT notify the delegate or the database.
616 void SetTemplateURLs(std::unique_ptr<OwnedTemplateURLVector> urls);
618 // Transitions to the loaded state.
619 void ChangeToLoadedState();
621 // Applies a DSE change and reports metrics if appropriate.
622 void ApplyDefaultSearchChange(const TemplateURLData* new_dse_data,
623 DefaultSearchManager::Source source);
625 // Applies a DSE change. May be called at startup or after transitioning to
626 // the loaded state. Returns true if a change actually occurred.
627 bool ApplyDefaultSearchChangeNoMetrics(const TemplateURLData* new_dse_data,
628 DefaultSearchManager::Source source);
630 // Returns false if there is a TemplateURL that has a search url with the
631 // specified host and that TemplateURL has been manually modified.
632 bool CanAddAutogeneratedKeywordForHost(const std::string& host) const;
634 // Updates the information in |existing_turl| using the information from
635 // |new_values|, but the ID for |existing_turl| is retained. Returns whether
636 // |existing_turl| was found in |template_urls_| and thus could be updated.
638 // NOTE: This should not be called with an extension keyword as there are no
639 // updates needed in that case.
640 bool Update(TemplateURL* existing_turl, const TemplateURL& new_values);
642 // If the TemplateURL comes from a prepopulated URL available in the current
643 // country, update all its fields save for the keyword, short name and id so
644 // that they match the internal prepopulated URL. TemplateURLs not coming from
645 // a prepopulated URL are not modified.
646 static void UpdateTemplateURLIfPrepopulated(TemplateURL* existing_turl,
649 // If the TemplateURL's sync GUID matches the kSyncedDefaultSearchProviderGUID
650 // preference it will be used to update the DSE in prefs.
651 // OnDefaultSearchChange may be triggered as a result.
652 void MaybeUpdateDSEViaPrefs(TemplateURL* synced_turl);
654 // Iterates through the TemplateURLs to see if one matches the visited url.
655 // For each TemplateURL whose url matches the visited url
656 // SetKeywordSearchTermsForURL is invoked.
657 void UpdateKeywordSearchTermsForURL(const URLVisitedDetails& details);
659 // Updates the last_visited time of |url| to the current time.
660 void UpdateTemplateURLVisitTime(TemplateURL* url);
662 // If necessary, generates a visit for the site http:// + t_url.keyword().
663 void AddTabToSearchVisit(const TemplateURL& t_url);
665 // Adds a new TemplateURL to this model.
667 // If |newly_adding| is false, we assume that this TemplateURL was already
668 // part of the model in the past, and therefore we don't need to do things
669 // like assign it an ID or notify sync.
671 // This function guarantees that on return the model will not have two non-
672 // extension TemplateURLs with the same keyword. If that means that it cannot
673 // add the provided argument, it will return null. Otherwise it will return
674 // the raw pointer to the TemplateURL.
676 // Returns a raw pointer to |template_url| if the addition succeeded, or null
677 // on failure. (Many callers need still need a raw pointer to the TemplateURL
678 // so they can access it later.)
679 TemplateURL* Add(std::unique_ptr<TemplateURL> template_url,
682 // Updates |template_urls| so that the only "created by policy" entry is
683 // |default_from_prefs|. |default_from_prefs| may be NULL if there is no
684 // policy-defined DSE in effect.
685 void UpdateProvidersCreatedByPolicy(OwnedTemplateURLVector* template_urls,
686 const TemplateURLData* default_from_prefs,
689 // Resets the sync GUID of the specified TemplateURL and persists the change
690 // to the database. This does not notify observers.
691 void ResetTemplateURLGUID(TemplateURL* url, const std::string& guid);
693 // Adds |sync_turl| into the local model, possibly removing or updating a
694 // local TemplateURL to make room for it. This expects |sync_turl| to be a new
695 // entry from Sync, not currently known to the local model. |sync_data| should
696 // be a SyncDataMap where the contents are entries initially known to Sync
697 // during MergeDataAndStartSyncing.
698 // Any necessary updates to Sync will be appended to |change_list|. This can
699 // include updates on local TemplateURLs, if they are found in |sync_data|.
700 // |initial_data| should be a SyncDataMap of the entries known to the local
701 // model during MergeDataAndStartSyncing. If |sync_turl| replaces a local
702 // entry, that entry is removed from |initial_data| to prevent it from being
704 // This should only be called from MergeDataAndStartSyncing.
705 void MergeInSyncTemplateURL(TemplateURL* sync_turl,
706 const SyncDataMap& sync_data,
707 syncer::SyncChangeList* change_list,
708 SyncDataMap* local_data);
710 // Goes through a vector of TemplateURLs and ensure that both the in-memory
711 // and database copies have valid sync_guids. This is to fix crbug.com/102038,
712 // where old entries were being pushed to Sync without a sync_guid.
713 void PatchMissingSyncGUIDs(OwnedTemplateURLVector* template_urls);
715 void OnSyncedDefaultSearchProviderGUIDChanged();
717 // Goes through a vector of TemplateURLs and sets is_active to true if it was
718 // not previously set (currently kUnspecified) and has been interacted with
720 void MaybeSetIsActiveSearchEngines(OwnedTemplateURLVector* template_urls);
722 // Adds to |matches| all TemplateURLs stored in |keyword_to_turl_and_length|
723 // whose keywords begin with |prefix|, sorted shortest-keyword-first. If
724 // |supports_replacement_only| is true, only TemplateURLs that support
725 // replacement are returned.
726 template <typename Container>
727 void AddMatchingKeywordsHelper(const Container& keyword_to_turl_and_length,
728 const std::u16string& prefix,
729 bool supports_replacement_only,
730 TURLsAndMeaningfulLengths* matches);
732 // Returns the TemplateURL corresponding to |prepopulated_id|, if any.
733 TemplateURL* FindPrepopulatedTemplateURL(int prepopulated_id);
735 // Returns the TemplateURL corresponding to |starter_pack_id|, if any.
736 TemplateURL* FindStarterPackTemplateURL(int starter_pack_id);
738 // Returns the TemplateURL associated with |extension_id|, if any.
739 TemplateURL* FindTemplateURLForExtension(const std::string& extension_id,
740 TemplateURL::Type type);
742 // Finds any NORMAL_CONTROLLED_BY_EXTENSION engine that matches |data| and
743 // wants to be default. Returns nullptr if not found.
744 TemplateURL* FindMatchingDefaultExtensionTemplateURL(
745 const TemplateURLData& data);
747 // This method removes all TemplateURLs that meet all three criteria:
748 // - Duplicate: Shares the same keyword as |candidate|.
749 // - Replaceable: Engine is eligible for automatic removal. See CanReplace().
750 // - Worse: There exists a better engine with the same keyword.
752 // This method must run BEFORE |candidate| is added to the engine list / map.
753 // It would be simpler to run the algorithm AFTER |candidate| is added, but
754 // that makes extra sync updates, observer notifications, and database churn.
756 // This method returns true if |candidate| ITSELF is rendundant.
757 // But notably, this method NEVER calls Remove() on |candidate|, leaving the
758 // correct handling to its caller.
759 bool RemoveDuplicateReplaceableEnginesOf(TemplateURL* candidate);
761 // Returns true if |turl| matches the default search provider. This method
762 // does both a GUID comparison, because while the model is being loaded, the
763 // DSE may be sourced from prefs, and we still want to consider the
764 // corresponding database entry a match. https://crbug.com/1164024
765 bool MatchesDefaultSearchProvider(TemplateURL* turl) const;
767 // Emits the UMA Histogram for the number of search engines that are active
768 // and inactive at load time.
769 void EmitTemplateURLActiveOnStartupHistogram(
770 OwnedTemplateURLVector* template_urls);
772 // ---------- Browser state related members ---------------------------------
773 raw_ptr<PrefService> prefs_ = nullptr;
775 std::unique_ptr<SearchTermsData> search_terms_data_ =
776 std::make_unique<SearchTermsData>();
778 // ---------- Dependencies on other components ------------------------------
779 // Service used to store entries.
780 scoped_refptr<KeywordWebDataService> web_data_service_;
782 std::unique_ptr<TemplateURLServiceClient> client_;
784 // This closure is run when the default search provider is set to Google.
785 base::RepeatingClosure dsp_change_callback_;
787 PrefChangeRegistrar pref_change_registrar_;
789 // Mapping from keyword to the TemplateURL.
790 KeywordToTURLAndMeaningfulLength keyword_to_turl_and_length_;
792 // Mapping from Sync GUIDs to the TemplateURL.
793 GUIDToTURL guid_to_turl_;
795 OwnedTemplateURLVector template_urls_;
797 base::ObserverList<TemplateURLServiceObserver> model_observers_;
799 // Maps from host to set of TemplateURLs whose search url host is host.
800 std::unique_ptr<SearchHostToURLsMap> provider_map_ =
801 std::make_unique<SearchHostToURLsMap>();
803 // Whether the keywords have been loaded.
804 bool loaded_ = false;
806 // Set when the web data service fails to load properly. This prevents
807 // further communication with sync or writing to prefs, so we don't persist
808 // inconsistent state data anywhere.
809 bool load_failed_ = false;
811 // Whether Load() is disabled. True only in testing contexts.
812 bool disable_load_ = false;
814 // If non-zero, we're waiting on a load.
815 KeywordWebDataService::Handle load_handle_ = 0;
817 // All visits that occurred before we finished loading. Once loaded
818 // UpdateKeywordSearchTermsForURL is invoked for each element of the vector.
819 std::vector<URLVisitedDetails> visits_to_add_;
821 // Once loaded, the default search provider. This is a pointer to a
822 // TemplateURL owned by |template_urls_|.
824 // TODO(tommycli): Can we combine this with initial_default_search_provider_?
825 // Essentially all direct usages of this variable need to first check that
826 // |loading_| is true, and should call GetDefaultSearchProvider() instead.
827 // Example of a regression due to this mistake: https://crbug.com/1164024.
828 raw_ptr<TemplateURL, DanglingUntriaged> default_search_provider_ = nullptr;
830 // A temporary location for the DSE until Web Data has been loaded and it can
831 // be merged into |template_urls_|.
832 std::unique_ptr<TemplateURL> initial_default_search_provider_;
834 // Source of the default search provider.
835 DefaultSearchManager::Source default_search_provider_source_;
837 // ID assigned to next TemplateURL added to this model. This is an ever
838 // increasing integer that is initialized from the database.
839 TemplateURLID next_id_ = kInvalidTemplateURLID + 1;
841 // Used to retrieve the current time, in base::Time units.
842 std::unique_ptr<base::Clock> clock_ = std::make_unique<base::DefaultClock>();
844 // Do we have an active association between the TemplateURLs and sync models?
845 // Set in MergeDataAndStartSyncing, reset in StopSyncing. While this is not
846 // set, we ignore any local search engine changes (when we start syncing we
847 // will look up the most recent values anyways).
848 bool models_associated_ = false;
850 // Whether we're currently processing changes from the syncer. While this is
851 // true, we ignore any local search engine changes, since we triggered them.
852 bool processing_syncer_changes_ = false;
854 // We never want reentrancy while applying a default search engine change.
855 // This can happen when deleting keyword conflicts. crbug.com/1031506
856 bool applying_default_search_engine_change_ = false;
858 // Sync's syncer::SyncChange handler. We push all our changes through this.
859 std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_;
861 // A set of sync GUIDs denoting TemplateURLs that have been removed from this
862 // model or the underlying KeywordWebDataService prior to
863 // MergeDataAndStartSyncing.
864 // This set is used to determine what entries from the server we want to
865 // ignore locally and return a delete command for.
866 std::set<std::string> pre_sync_deletes_;
868 // This is used to log the origin of changes to the default search provider.
869 // We set this value to increasingly specific values when we know what is the
870 // cause/origin of a default search change.
871 DefaultSearchChangeOrigin dsp_change_origin_ = DSP_CHANGE_OTHER;
873 // Stores a list of callbacks to be run after TemplateURLService has loaded.
874 base::OnceClosureList on_loaded_callbacks_;
876 // Similar to |on_loaded_callbacks_| but used for WaitUntilReadyToSync().
877 base::OnceClosure on_loaded_callback_for_sync_;
879 // Helper class to manage the default search engine.
880 DefaultSearchManager default_search_manager_;
882 // This tracks how many Scoper handles exist. When the number of handles drops
883 // to zero, a notification is made to observers if
884 // |model_mutated_notification_pending_| is true.
885 int outstanding_scoper_handles_ = 0;
887 // Used to track if a notification is necessary due to the model being
888 // mutated. The outermost Scoper handles, can be used to defer notifications,
889 // but if no model mutation occurs, the deferred notification can be skipped.
890 bool model_mutated_notification_pending_ = false;
892 // Session token management.
893 std::string current_token_;
894 base::TimeTicks token_expiration_time_;
896 #if BUILDFLAG(IS_ANDROID)
897 // Manage and fetch the java object that wraps this TemplateURLService on
899 std::unique_ptr<TemplateUrlServiceAndroid> template_url_service_android_;
903 #endif // COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_