Print Preview: Changing displayed error message when PDF Viewer is missing.
[chromium-blink-merge.git] / chrome / browser / search_engines / template_url_service.h
blobf5c62642db5749180de43f395198e64f89a4cbad
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
6 #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_
7 #pragma once
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <vector>
14 #include "base/gtest_prod_util.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/observer_list.h"
17 #include "chrome/browser/profiles/profile_keyed_service.h"
18 #include "chrome/browser/search_engines/search_host_to_urls_map.h"
19 #include "chrome/browser/search_engines/template_url_id.h"
20 #include "chrome/browser/webdata/web_data_service.h"
21 #include "content/common/notification_observer.h"
22 #include "content/common/notification_registrar.h"
24 class GURL;
25 class Extension;
26 class PrefService;
27 class Profile;
28 class PrefSetObserver;
29 class SearchHostToURLsMap;
30 class SearchTermsData;
31 class TemplateURLServiceObserver;
32 class TemplateURLRef;
34 namespace history {
35 struct URLVisitedDetails;
38 // TemplateURLService is the backend for keywords. It's used by
39 // KeywordAutocomplete.
41 // TemplateURLService stores a vector of TemplateURLs. The TemplateURLs are
42 // persisted to the database maintained by WebDataService. *ALL* mutations
43 // to the TemplateURLs must funnel through TemplateURLService. This allows
44 // TemplateURLService to notify listeners of changes as well as keep the
45 // database in sync.
47 // There is a TemplateURLService per Profile.
49 // TemplateURLService does not load the vector of TemplateURLs in its
50 // constructor (except for testing). Use the Load method to trigger a load.
51 // When TemplateURLService has completed loading, observers are notified via
52 // OnTemplateURLServiceChanged as well as the TEMPLATE_URL_SERVICE_LOADED
53 // notification message.
55 // TemplateURLService takes ownership of any TemplateURL passed to it. If there
56 // is a WebDataService, deletion is handled by WebDataService, otherwise
57 // TemplateURLService handles deletion.
59 class TemplateURLService : public WebDataServiceConsumer,
60 public ProfileKeyedService,
61 public NotificationObserver {
62 public:
63 typedef std::map<std::string, std::string> QueryTerms;
64 typedef std::vector<const TemplateURL*> TemplateURLVector;
66 // Struct used for initializing the data store with fake data.
67 // Each initializer is mapped to a TemplateURL.
68 struct Initializer {
69 const char* const keyword;
70 const char* const url;
71 const char* const content;
74 explicit TemplateURLService(Profile* profile);
75 // The following is for testing.
76 TemplateURLService(const Initializer* initializers, const int count);
77 virtual ~TemplateURLService();
79 // Generates a suitable keyword for the specified url. Returns an empty
80 // string if a keyword couldn't be generated. If |autodetected| is true, we
81 // don't generate keywords for a variety of situations where we would probably
82 // not want to auto-add keywords, such as keywords for searches on pages that
83 // themselves come from form submissions.
84 static string16 GenerateKeyword(const GURL& url, bool autodetected);
86 // Removes any unnecessary characters from a user input keyword.
87 // This removes the leading scheme, "www." and any trailing slash.
88 static string16 CleanUserInputKeyword(const string16& keyword);
90 // Returns the search url for t_url. Returns an empty GURL if t_url has no
91 // url().
92 static GURL GenerateSearchURL(const TemplateURL* t_url);
94 // Just like GenerateSearchURL except that it takes SearchTermsData to supply
95 // the data for some search terms. Most of the time GenerateSearchURL should
96 // be called.
97 static GURL GenerateSearchURLUsingTermsData(
98 const TemplateURL* t_url,
99 const SearchTermsData& search_terms_data);
101 // Returns true if there is no TemplateURL that conflicts with the
102 // keyword/url pair, or there is one but it can be replaced. If there is an
103 // existing keyword that can be replaced and template_url_to_replace is
104 // non-NULL, template_url_to_replace is set to the keyword to replace.
106 // url gives the url of the search query. The url is used to avoid generating
107 // a TemplateURL for an existing TemplateURL that shares the same host.
108 bool CanReplaceKeyword(const string16& keyword,
109 const GURL& url,
110 const TemplateURL** template_url_to_replace);
112 // Returns (in |matches|) all keywords beginning with |prefix|, sorted
113 // shortest-first. If support_replacement_only is true, only keywords that
114 // support replacement are returned.
115 void FindMatchingKeywords(const string16& prefix,
116 bool support_replacement_only,
117 std::vector<string16>* matches) const;
119 // Looks up |keyword| and returns the element it maps to. Returns NULL if
120 // the keyword was not found.
121 // The caller should not try to delete the returned pointer; the data store
122 // retains ownership of it.
123 const TemplateURL* GetTemplateURLForKeyword(const string16& keyword) const;
125 // Returns the first TemplateURL found with a URL using the specified |host|,
126 // or NULL if there are no such TemplateURLs
127 const TemplateURL* GetTemplateURLForHost(const std::string& host) const;
129 // Adds a new TemplateURL to this model. TemplateURLService will own the
130 // reference, and delete it when the TemplateURL is removed.
131 void Add(TemplateURL* template_url);
133 // Removes the keyword from the model. This deletes the supplied TemplateURL.
134 // This fails if the supplied template_url is the default search provider.
135 void Remove(const TemplateURL* template_url);
137 // Removes all auto-generated keywords that were created in the specified
138 // range.
139 void RemoveAutoGeneratedBetween(base::Time created_after,
140 base::Time created_before);
142 // Removes all auto-generated keywords that were created on or after the
143 // date passed in.
144 void RemoveAutoGeneratedSince(base::Time created_after);
146 // If the given extension has an omnibox keyword, adds a TemplateURL for that
147 // keyword. Only 1 keyword is allowed for a given extension. If the keyword
148 // already exists for this extension, does nothing.
149 void RegisterExtensionKeyword(const Extension* extension);
151 // Removes the TemplateURL containing the keyword for the given extension,
152 // if any.
153 void UnregisterExtensionKeyword(const Extension* extension);
155 // Returns the TemplateURL associated with the keyword for this extension.
156 // This works by checking the extension ID, not the keyword, so it will work
157 // even if the user changed the keyword.
158 const TemplateURL* GetTemplateURLForExtension(
159 const Extension* extension) const;
161 // Returns the set of URLs describing the keywords. The elements are owned
162 // by TemplateURLService and should not be deleted.
163 TemplateURLVector GetTemplateURLs() const;
165 // Increment the usage count of a keyword.
166 // Called when a URL is loaded that was generated from a keyword.
167 void IncrementUsageCount(const TemplateURL* url);
169 // Resets the title, keyword and search url of the specified TemplateURL.
170 // The TemplateURL is marked as not replaceable.
171 void ResetTemplateURL(const TemplateURL* url,
172 const string16& title,
173 const string16& keyword,
174 const std::string& search_url);
176 // Return true if the given |url| can be made the default.
177 bool CanMakeDefault(const TemplateURL* url);
179 // Set the default search provider. |url| may be null.
180 // This will assert if the default search is managed; the UI should not be
181 // invoking this method in that situation.
182 void SetDefaultSearchProvider(const TemplateURL* url);
184 // Returns the default search provider. If the TemplateURLService hasn't been
185 // loaded, the default search provider is pulled from preferences.
187 // NOTE: At least in unittest mode, this may return NULL.
188 const TemplateURL* GetDefaultSearchProvider();
190 // Returns true if the default search is managed through group policy.
191 bool is_default_search_managed() const { return is_default_search_managed_; }
193 // Observers used to listen for changes to the model.
194 // TemplateURLService does NOT delete the observers when deleted.
195 void AddObserver(TemplateURLServiceObserver* observer);
196 void RemoveObserver(TemplateURLServiceObserver* observer);
198 // Loads the keywords. This has no effect if the keywords have already been
199 // loaded.
200 // Observers are notified when loading completes via the method
201 // OnTemplateURLServiceChanged.
202 void Load();
204 // Whether or not the keywords have been loaded.
205 bool loaded() { return loaded_; }
207 // Notification that the keywords have been loaded.
208 // This is invoked from WebDataService, and should not be directly
209 // invoked.
210 virtual void OnWebDataServiceRequestDone(WebDataService::Handle h,
211 const WDTypedResult* result);
213 // Returns the locale-direction-adjusted short name for the given keyword.
214 // Also sets the out param to indicate whether the keyword belongs to an
215 // extension.
216 string16 GetKeywordShortName(const string16& keyword,
217 bool* is_extension_keyword);
219 // NotificationObserver method. TemplateURLService listens for three
220 // notification types:
221 // . NOTIFY_HISTORY_URL_VISITED: adds keyword search terms if the visit
222 // corresponds to a keyword.
223 // . NOTIFY_GOOGLE_URL_UPDATED: updates mapping for any keywords containing
224 // a google base url replacement term.
225 // . PREF_CHANGED: checks whether the default search engine has changed.
226 virtual void Observe(NotificationType type,
227 const NotificationSource& source,
228 const NotificationDetails& details);
230 Profile* profile() const { return profile_; }
232 void SetSearchEngineDialogSlot(int slot) {
233 search_engine_dialog_chosen_slot_ = slot;
236 int GetSearchEngineDialogSlot() const {
237 return search_engine_dialog_chosen_slot_;
240 // Registers the preferences used to save a TemplateURL to prefs.
241 static void RegisterUserPrefs(PrefService* prefs);
243 protected:
244 // Cover method for the method of the same name on the HistoryService.
245 // url is the one that was visited with the given search terms.
247 // This exists and is virtual for testing.
248 virtual void SetKeywordSearchTermsForURL(const TemplateURL* t_url,
249 const GURL& url,
250 const string16& term);
252 private:
253 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, BuildQueryTerms);
254 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, TestManagedDefaultSearch);
255 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
256 UpdateKeywordSearchTermsForURL);
257 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest,
258 DontUpdateKeywordSearchForNonReplaceable);
259 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, ChangeGoogleBaseValue);
260 FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceTest, MergeDeletesUnusedProviders);
261 friend class TemplateURLServiceTestUtil;
263 typedef std::map<string16, const TemplateURL*> KeywordToTemplateMap;
265 // Helper functor for FindMatchingKeywords(), for finding the range of
266 // keywords which begin with a prefix.
267 class LessWithPrefix;
269 void Init(const Initializer* initializers, int num_initializers);
271 void RemoveFromMaps(const TemplateURL* template_url);
273 // Removes the supplied template_url from the keyword maps. This searches
274 // through all entries in the keyword map and does not generate the host or
275 // keyword. This is used when the cached content of the TemplateURL changes.
276 void RemoveFromKeywordMapByPointer(const TemplateURL* template_url);
278 void AddToMaps(const TemplateURL* template_url);
280 // Sets the keywords. This is used once the keywords have been loaded.
281 // This does NOT notify the delegate or the database.
282 void SetTemplateURLs(const std::vector<TemplateURL*>& urls);
284 // Transitions to the loaded state.
285 void ChangeToLoadedState();
287 // If there is a notification service, sends TEMPLATE_URL_SERVICE_LOADED
288 // notification.
289 void NotifyLoaded();
291 // Saves enough of url to preferences so that it can be loaded from
292 // preferences on start up.
293 void SaveDefaultSearchProviderToPrefs(const TemplateURL* url);
295 // Creates a TemplateURL that was previously saved to prefs via
296 // SaveDefaultSearchProviderToPrefs or set via policy.
297 // Returns true if successful, false otherwise.
298 // If the user or the policy has opted for no default search, this
299 // returns true but default_provider is set to NULL.
300 // |*is_managed| specifies whether the default is managed via policy.
301 bool LoadDefaultSearchProviderFromPrefs(
302 scoped_ptr<TemplateURL>* default_provider,
303 bool* is_managed);
305 // Returns true if there is no TemplateURL that has a search url with the
306 // specified host, or the only TemplateURLs matching the specified host can
307 // be replaced.
308 bool CanReplaceKeywordForHost(const std::string& host,
309 const TemplateURL** to_replace);
311 // Returns true if the TemplateURL is replaceable. This doesn't look at the
312 // uniqueness of the keyword or host and is intended to be called after those
313 // checks have been done. This returns true if the TemplateURL doesn't appear
314 // in the default list and is marked as safe_for_autoreplace.
315 bool CanReplace(const TemplateURL* t_url);
317 // Updates the information in |existing_turl| using the information from
318 // |new_values|, but the ID for |existing_turl| is retained.
319 // Notifying observers is the responsibility of the caller.
320 void UpdateNoNotify(const TemplateURL* existing_turl,
321 const TemplateURL& new_values);
323 // Returns the preferences we use.
324 PrefService* GetPrefs();
326 // Iterates through the TemplateURLs to see if one matches the visited url.
327 // For each TemplateURL whose url matches the visited url
328 // SetKeywordSearchTermsForURL is invoked.
329 void UpdateKeywordSearchTermsForURL(
330 const history::URLVisitedDetails& details);
332 // If necessary, generates a visit for the site http:// + t_url.keyword().
333 void AddTabToSearchVisit(const TemplateURL& t_url);
335 // Adds each of the query terms in the specified url whose key and value are
336 // non-empty to query_terms. If a query key appears multiple times, the value
337 // is set to an empty string. Returns true if there is at least one key that
338 // does not occur multiple times.
339 static bool BuildQueryTerms(
340 const GURL& url,
341 std::map<std::string,std::string>* query_terms);
343 // Invoked when the Google base URL has changed. Updates the mapping for all
344 // TemplateURLs that have a replacement term of {google:baseURL} or
345 // {google:baseSuggestURL}.
346 void GoogleBaseURLChanged();
348 // Update the default search. Called at initialization or when a managed
349 // preference has changed.
350 void UpdateDefaultSearch();
352 // Returns the default search specified in the prepopulated data, if it
353 // exists. If not, returns first URL in |template_urls_|, or NULL if that's
354 // empty.
355 const TemplateURL* FindNewDefaultSearchProvider();
357 // Set the default search provider even if it is managed. |url| may be null.
358 // Caller is responsible for notifying observers.
359 void SetDefaultSearchProviderNoNotify(const TemplateURL* url);
361 // Adds a new TemplateURL to this model. TemplateURLService will own the
362 // reference, and delete it when the TemplateURL is removed.
363 // Caller is responsible for notifying observers.
364 void AddNoNotify(TemplateURL* template_url);
366 // Removes the keyword from the model. This deletes the supplied TemplateURL.
367 // This fails if the supplied template_url is the default search provider.
368 // Caller is responsible for notifying observers.
369 void RemoveNoNotify(const TemplateURL* template_url);
371 // Notify the observers that the model has changed. This is done only if the
372 // model is loaded.
373 void NotifyObservers();
375 // Removes from the vector any template URL that was created because of
376 // policy. These TemplateURLs are freed and removed from the database.
377 // Sets default_search_provider to NULL if it was one of them, unless it is
378 // the same as the current default from preferences and it is managed.
379 void RemoveProvidersCreatedByPolicy(
380 std::vector<TemplateURL*>* template_urls,
381 const TemplateURL** default_search_provider,
382 const TemplateURL* default_from_prefs);
384 NotificationRegistrar registrar_;
386 // Mapping from keyword to the TemplateURL.
387 KeywordToTemplateMap keyword_to_template_map_;
389 TemplateURLVector template_urls_;
391 ObserverList<TemplateURLServiceObserver> model_observers_;
393 // Maps from host to set of TemplateURLs whose search url host is host.
394 SearchHostToURLsMap provider_map_;
396 // Used to obtain the WebDataService.
397 // When Load is invoked, if we haven't yet loaded, the WebDataService is
398 // obtained from the Profile. This allows us to lazily access the database.
399 Profile* profile_;
401 // Whether the keywords have been loaded.
402 bool loaded_;
404 // Did loading fail? This is only valid if loaded_ is true.
405 bool load_failed_;
407 // If non-zero, we're waiting on a load.
408 WebDataService::Handle load_handle_;
410 // Service used to store entries.
411 scoped_refptr<WebDataService> service_;
413 // All visits that occurred before we finished loading. Once loaded
414 // UpdateKeywordSearchTermsForURL is invoked for each element of the vector.
415 std::vector<history::URLVisitedDetails> visits_to_add_;
417 // Once loaded, the default search provider. This is a pointer to a
418 // TemplateURL owned by template_urls_.
419 const TemplateURL* default_search_provider_;
421 // Used for UX testing. Gives the slot in the search engine dialog that was
422 // chosen as the default search engine.
423 int search_engine_dialog_chosen_slot_;
425 // The initial search provider extracted from preferences. This is only valid
426 // if we haven't been loaded or loading failed.
427 scoped_ptr<TemplateURL> initial_default_search_provider_;
429 // Whether the default search is managed via policy.
430 bool is_default_search_managed_;
432 // The set of preferences observer we use to find if the default search
433 // preferences have changed.
434 scoped_ptr<PrefSetObserver> default_search_prefs_;
436 // ID assigned to next TemplateURL added to this model. This is an ever
437 // increasing integer that is initialized from the database.
438 TemplateURLID next_id_;
440 // List of extension IDs waiting for Load to have keywords registered.
441 std::vector<std::string> pending_extension_ids_;
443 DISALLOW_COPY_AND_ASSIGN(TemplateURLService);
446 #endif // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_SERVICE_H_