Upload upstream chromium 85.0.4183.84
[platform/framework/web/chromium-efl.git] / components / search_engines / template_url.h
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_H_
6 #define COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_H_
7
8 #include <cstddef>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "base/gtest_prod_util.h"
15 #include "base/macros.h"
16 #include "base/time/time.h"
17 #include "components/search_engines/search_engine_type.h"
18 #include "components/search_engines/template_url_data.h"
19 #include "components/search_engines/template_url_id.h"
20 #include "third_party/metrics_proto/omnibox_event.pb.h"
21 #include "third_party/metrics_proto/omnibox_input_type.pb.h"
22 #include "ui/gfx/geometry/size.h"
23 #include "url/gurl.h"
24 #include "url/third_party/mozilla/url_parse.h"
25
26 class SearchTermsData;
27 class TemplateURL;
28
29
30 // TemplateURLRef -------------------------------------------------------------
31
32 // A TemplateURLRef represents a single URL within the larger TemplateURL class
33 // (which represents an entire "search engine", see below).  If
34 // SupportsReplacement() is true, this URL has placeholders in it, for which
35 // callers can substitute values to get a "real" URL using ReplaceSearchTerms().
36 //
37 // TemplateURLRefs always have a non-NULL |owner_| TemplateURL, which they
38 // access in order to get at important data like the underlying URL string or
39 // the associated Profile.
40 class TemplateURLRef {
41  public:
42   // Magic numbers to pass to ReplaceSearchTerms() for the |accepted_suggestion|
43   // parameter.  Most callers aren't using Suggest capabilities and should just
44   // pass NO_SUGGESTIONS_AVAILABLE.
45   // NOTE: Because positive values are meaningful, make sure these are negative!
46   enum AcceptedSuggestion {
47     NO_SUGGESTION_CHOSEN = -1,
48     NO_SUGGESTIONS_AVAILABLE = -2,
49   };
50
51   // Which kind of URL within our owner we are.  This allows us to get at the
52   // correct string field. Use |INDEXED| to indicate that the numerical
53   // |index_in_owner_| should be used instead.
54   enum Type {
55     SEARCH,
56     SUGGEST,
57     IMAGE,
58     NEW_TAB,
59     CONTEXTUAL_SEARCH,
60     INDEXED
61   };
62
63   // Type to store <content_type, post_data> pair for POST URLs.
64   // The |content_type|(first part of the pair) is the content-type of
65   // the |post_data|(second part of the pair) which is encoded in
66   // "multipart/form-data" format, it also contains the MIME boundary used in
67   // the |post_data|. See http://tools.ietf.org/html/rfc2046 for the details.
68   typedef std::pair<std::string, std::string> PostContent;
69
70   // This struct encapsulates arguments passed to
71   // TemplateURLRef::ReplaceSearchTerms methods.  By default, only search_terms
72   // is required and is passed in the constructor.
73   struct SearchTermsArgs {
74     SearchTermsArgs();
75     explicit SearchTermsArgs(const base::string16& search_terms);
76     SearchTermsArgs(const SearchTermsArgs& other);
77     ~SearchTermsArgs();
78
79     // If the search request is from the omnibox, this enum may specify details
80     // about how the user last interacted with the omnibox.
81     //
82     // These values are used as HTTP GET parameter values. Entries should not be
83     // renumbered and numeric values should never be reused.
84     enum class OmniboxFocusType {
85       // The default value. This is used for any search requests without any
86       // special interaction annotation, including: normal omnibox searches,
87       // as-you-type omnibox suggestions, as well as non-omnibox searches.
88       DEFAULT = 0,
89
90       // This search request is triggered by the user focusing the omnibox.
91       ON_FOCUS = 1,
92     };
93
94     struct ContextualSearchParams {
95       ContextualSearchParams();
96       // Modern constructor, used when the content is sent in the HTTP header
97       // instead of as CGI parameters.
98       // The |version| tell the server which version of the client is making
99       // this request.
100       // The |contextual_cards_version| tells the server which version of
101       // contextual cards integration is being used by the client.
102       // The |home_country| is an ISO country code for the country that the user
103       // considers their permanent home (which may be different from the country
104       // they are currently visiting).  Pass an empty string if none available.
105       // The |previous_event_id| is an identifier previously returned by the
106       // server to identify that user interaction.
107       // The |previous_event_results| are the results of the user-interaction of
108       // that previous request.
109       // The "previous_xyz" parameters are documented in go/cs-sanitized.
110       // The |is_exact_search| allows the search request to be narrowed down to
111       // an "exact" search only, meaning just search for X rather than X +
112       // whatever else is in the context.  The returned search term should not
113       // be expanded, and the server will honor this along with creating a
114       // narrow Search Term.
115       // The |source_lang| specifies a source language hint to apply for
116       // translation or to indicate that translation might be appropriate.
117       // This comes from CLD evaluating the selection and/or page content.
118       // The |target_lang| specifies the best language to translate into for
119       // the user, which also indicates when translation is appropriate or
120       // helpful.  This comes from the Chrome Language Model.
121       // The |fluent_languages| string specifies the languages the user
122       // is fluent in reading.  This acts as an alternate set of languages
123       // to consider translating into.  The languages are ordered by
124       // fluency, and encoded as a comma-separated list of BCP 47 languages.
125       ContextualSearchParams(int version,
126                              int contextual_cards_version,
127                              std::string home_country,
128                              int64_t previous_event_id,
129                              int previous_event_results,
130                              bool is_exact_search,
131                              std::string source_lang,
132                              std::string target_lang,
133                              std::string fluent_languages);
134       ContextualSearchParams(const ContextualSearchParams& other);
135       ~ContextualSearchParams();
136
137       // Estimates dynamic memory usage.
138       // See base/trace_event/memory_usage_estimator.h for more info.
139       size_t EstimateMemoryUsage() const;
140
141       // The version of contextual search.
142       int version = -1;
143
144       // The version of Contextual Cards data to request.
145       // A value of 0 indicates no data needed.
146       int contextual_cards_version = 0;
147
148       // The locale of the user's home country in an ISO country code format,
149       // or an empty string if not available.  This indicates where the user
150       // resides, not where they currently are.
151       std::string home_country;
152
153       // An EventID from a previous interaction (sent by server, recorded by
154       // client).
155       int64_t previous_event_id = 0l;
156
157       // An encoded set of booleans that represent the interaction results from
158       // the previous event.
159       int previous_event_results = 0;
160
161       // A flag that restricts the search to exactly match the selection rather
162       // than expanding the Search Term to include other words in the context.
163       bool is_exact_search = false;
164
165       // Source language string to translate from.
166       std::string source_lang;
167
168       // Target language string to be translated into.
169       std::string target_lang;
170
171       // Alternate target languages that the user is fluent in, encoded in a
172       // single string.
173       std::string fluent_languages;
174     };
175
176     // Estimates dynamic memory usage.
177     // See base/trace_event/memory_usage_estimator.h for more info.
178     size_t EstimateMemoryUsage() const;
179
180     // The search terms (query).
181     base::string16 search_terms;
182
183     // The original (input) query.
184     base::string16 original_query;
185
186     // The type the original input query was identified as.
187     metrics::OmniboxInputType input_type = metrics::OmniboxInputType::EMPTY;
188
189     // If the search request is from the omnibox, this may specify how the user
190     // last interacted with the omnibox.
191     OmniboxFocusType omnibox_focus_type = OmniboxFocusType::DEFAULT;
192
193     // The optional assisted query stats, aka AQS, used for logging purposes.
194     // This string contains impressions of all autocomplete matches shown
195     // at the query submission time.  For privacy reasons, we require the
196     // search provider to support HTTPS protocol in order to receive the AQS
197     // param.
198     // For more details, see http://goto.google.com/binary-clients-logging .
199     std::string assisted_query_stats;
200
201     // TODO: Remove along with "aq" CGI param.
202     int accepted_suggestion = NO_SUGGESTIONS_AVAILABLE;
203
204     // The 0-based position of the cursor within the query string at the time
205     // the request was issued.  Set to base::string16::npos if not used.
206     size_t cursor_position = base::string16::npos;
207
208     // The URL of the current webpage to be used for experimental zero-prefix
209     // suggestions.
210     std::string current_page_url;
211
212     // Which omnibox the user used to type the prefix.
213     metrics::OmniboxEventProto::PageClassification page_classification =
214         metrics::OmniboxEventProto::INVALID_SPEC;
215
216     // Optional session token.
217     std::string session_token;
218
219     // Prefetch query and type.
220     std::string prefetch_query;
221     std::string prefetch_query_type;
222
223     // Additional query params to append to the request.
224     std::string additional_query_params;
225
226     // If set, ReplaceSearchTerms() will automatically append any extra query
227     // params specified via the --extra-search-query-params command-line
228     // argument.  Generally, this should be set when dealing with the search
229     // TemplateURLRefs of the default search engine and the caller cares
230     // about the query portion of the URL.  Since neither TemplateURLRef nor
231     // indeed TemplateURL know whether a TemplateURL is the default search
232     // engine, callers instead must set this manually.
233     bool append_extra_query_params_from_command_line = false;
234
235     // The raw content of an image thumbnail that will be used as a query for
236     // search-by-image frontend.
237     std::string image_thumbnail_content;
238
239     // When searching for an image, the URL of the original image. Callers
240     // should leave this empty for images specified via data: URLs.
241     GURL image_url;
242
243     // When searching for an image, the original size of the image.
244     gfx::Size image_original_size;
245
246     // True if the search was made using the app list search box. Otherwise, the
247     // search was made using the omnibox.
248     bool from_app_list = false;
249
250     ContextualSearchParams contextual_search_params;
251   };
252
253   TemplateURLRef(const TemplateURL* owner, Type type);
254   TemplateURLRef(const TemplateURL* owner, size_t index_in_owner);
255   ~TemplateURLRef();
256
257   TemplateURLRef(const TemplateURLRef& source);
258   TemplateURLRef& operator=(const TemplateURLRef& source);
259
260   // Returns the raw URL. None of the parameters will have been replaced.
261   std::string GetURL() const;
262
263   // Returns the raw string of the post params. Please see comments in
264   // prepopulated_engines_schema.json for the format.
265   std::string GetPostParamsString() const;
266
267   // Returns true if this URL supports search term replacement.
268   bool SupportsReplacement(const SearchTermsData& search_terms_data) const;
269
270   // Returns a string that is the result of replacing the search terms in
271   // the url with the specified arguments.  We use our owner's input encoding.
272   //
273   // If this TemplateURLRef does not support replacement (SupportsReplacement
274   // returns false), an empty string is returned.
275   // If this TemplateURLRef uses POST, and |post_content| is not NULL, the
276   // |post_params_| will be replaced, encoded in "multipart/form-data" format
277   // and stored into |post_content|.
278   std::string ReplaceSearchTerms(const SearchTermsArgs& search_terms_args,
279                                  const SearchTermsData& search_terms_data,
280                                  PostContent* post_content) const;
281
282   // TODO(jnd): remove the following ReplaceSearchTerms definition which does
283   // not have |post_content| parameter once all reference callers pass
284   // |post_content| parameter.
285   std::string ReplaceSearchTerms(
286       const SearchTermsArgs& search_terms_args,
287       const SearchTermsData& search_terms_data) const {
288     return ReplaceSearchTerms(search_terms_args, search_terms_data, NULL);
289   }
290
291   // Returns true if the TemplateURLRef is valid. An invalid TemplateURLRef is
292   // one that contains unknown terms, or invalid characters.
293   bool IsValid(const SearchTermsData& search_terms_data) const;
294
295   // Returns a string representation of this TemplateURLRef suitable for
296   // display. The display format is the same as the format used by Firefox.
297   base::string16 DisplayURL(const SearchTermsData& search_terms_data) const;
298
299   // Converts a string as returned by DisplayURL back into a string as
300   // understood by TemplateURLRef.
301   static std::string DisplayURLToURLRef(const base::string16& display_url);
302
303   // If this TemplateURLRef is valid and contains one search term, this returns
304   // the host/path of the URL, otherwise this returns an empty string.
305   const std::string& GetHost(const SearchTermsData& search_terms_data) const;
306   std::string GetPath(const SearchTermsData& search_terms_data) const;
307
308   // If this TemplateURLRef is valid and contains one search term
309   // in its query or ref, this returns the key of the search term,
310   // otherwise this returns an empty string.
311   const std::string& GetSearchTermKey(
312       const SearchTermsData& search_terms_data) const;
313
314   // If this TemplateURLRef is valid and contains one search term,
315   // this returns the location of the search term,
316   // otherwise this returns url::Parsed::QUERY.
317   url::Parsed::ComponentType GetSearchTermKeyLocation(
318       const SearchTermsData& search_terms_data) const;
319
320   // If this TemplateURLRef is valid and contains one search term,
321   // this returns the fixed prefix before the search term,
322   // otherwise this returns an empty string.
323   const std::string& GetSearchTermValuePrefix(
324       const SearchTermsData& search_terms_data) const;
325
326   // If this TemplateURLRef is valid and contains one search term,
327   // this returns the fixed suffix after the search term,
328   // otherwise this returns an empty string.
329   const std::string& GetSearchTermValueSuffix(
330       const SearchTermsData& search_terms_data) const;
331
332   // Converts the specified term in our owner's encoding to a base::string16.
333   base::string16 SearchTermToString16(const base::StringPiece& term) const;
334
335   // Returns true if this TemplateURLRef has a replacement term of
336   // {google:baseURL} or {google:baseSuggestURL}.
337   bool HasGoogleBaseURLs(const SearchTermsData& search_terms_data) const;
338
339   // Use the pattern referred to by this TemplateURLRef to match the provided
340   // |url| and extract |search_terms| from it. Returns true if the pattern
341   // matches, even if |search_terms| is empty. In this case
342   // |search_term_component|, if not NULL, indicates whether the search terms
343   // were found in the query or the ref parameters; and |search_terms_position|,
344   // if not NULL, contains the position of the search terms in the query or the
345   // ref parameters. Returns false and an empty |search_terms| if the pattern
346   // does not match.
347   bool ExtractSearchTermsFromURL(
348       const GURL& url,
349       base::string16* search_terms,
350       const SearchTermsData& search_terms_data,
351       url::Parsed::ComponentType* search_term_component,
352       url::Component* search_terms_position) const;
353
354   // Whether the URL uses POST (as opposed to GET).
355   bool UsesPOSTMethod(const SearchTermsData& search_terms_data) const;
356
357   // Estimates dynamic memory usage.
358   // See base/trace_event/memory_usage_estimator.h for more info.
359   size_t EstimateMemoryUsage() const;
360
361  private:
362   friend class TemplateURL;
363   friend class TemplateURLTest;
364   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, SetPrepopulatedAndParse);
365   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterKnown);
366   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterUnknown);
367   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLEmpty);
368   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoTemplateEnd);
369   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoKnownParameters);
370   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLTwoParameters);
371   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNestedParameter);
372   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, URLRefTestImageURLWithPOST);
373
374   // Enumeration of the known types.
375   enum ReplacementType {
376     ENCODING,
377     GOOGLE_ASSISTED_QUERY_STATS,
378     GOOGLE_BASE_URL,
379     GOOGLE_BASE_SUGGEST_URL,
380     GOOGLE_CONTEXTUAL_SEARCH_VERSION,
381     GOOGLE_CONTEXTUAL_SEARCH_CONTEXT_DATA,
382     GOOGLE_CURRENT_PAGE_URL,
383     GOOGLE_CURSOR_POSITION,
384     GOOGLE_IMAGE_ORIGINAL_HEIGHT,
385     GOOGLE_IMAGE_ORIGINAL_WIDTH,
386     GOOGLE_IMAGE_SEARCH_SOURCE,
387     GOOGLE_IMAGE_THUMBNAIL,
388     GOOGLE_IMAGE_THUMBNAIL_BASE64,
389     GOOGLE_IMAGE_URL,
390     GOOGLE_INPUT_TYPE,
391     GOOGLE_IOS_SEARCH_LANGUAGE,
392     GOOGLE_NTP_IS_THEMED,
393     GOOGLE_OMNIBOX_FOCUS_TYPE,
394     GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION,
395     GOOGLE_PAGE_CLASSIFICATION,
396     GOOGLE_PREFETCH_QUERY,
397     GOOGLE_RLZ,
398     GOOGLE_SEARCH_CLIENT,
399     GOOGLE_SEARCH_FIELDTRIAL_GROUP,
400     GOOGLE_SEARCH_VERSION,
401     GOOGLE_SESSION_TOKEN,
402     GOOGLE_SUGGEST_CLIENT,
403     GOOGLE_SUGGEST_REQUEST_ID,
404     GOOGLE_UNESCAPED_SEARCH_TERMS,
405     LANGUAGE,
406     MAIL_RU_REFERRAL_ID,
407     SEARCH_TERMS,
408     YANDEX_REFERRAL_ID,
409   };
410
411   // Used to identify an element of the raw url that can be replaced.
412   struct Replacement {
413     Replacement(ReplacementType type, size_t index)
414         : type(type), index(index), is_post_param(false) {}
415     ReplacementType type;
416     size_t index;
417     // Indicates the location in where the replacement is replaced. If
418     // |is_post_param| is false, |index| indicates the byte position in
419     // |parsed_url_|. Otherwise, |index| is the index of |post_params_|.
420     bool is_post_param;
421   };
422
423   // Stores a single parameter for a POST.
424   struct PostParam {
425     std::string name;
426     std::string value;
427     std::string content_type;
428
429     // Estimates dynamic memory usage.
430     // See base/trace_event/memory_usage_estimator.h for more info.
431     size_t EstimateMemoryUsage() const;
432   };
433
434   // The list of elements to replace.
435   typedef std::vector<struct Replacement> Replacements;
436   typedef std::vector<PostParam> PostParams;
437
438   // TemplateURLRef internally caches values to make replacement quick. This
439   // method invalidates any cached values.
440   void InvalidateCachedValues() const;
441
442   // Parses the parameter in url at the specified offset. start/end specify the
443   // range of the parameter in the url, including the braces. If the parameter
444   // is valid, url is updated to reflect the appropriate parameter. If
445   // the parameter is one of the known parameters an element is added to
446   // replacements indicating the type and range of the element. The original
447   // parameter is erased from the url.
448   //
449   // If the parameter is not a known parameter, false is returned. If this is a
450   // prepopulated URL, the parameter is erased, otherwise it is left alone.
451   bool ParseParameter(size_t start,
452                       size_t end,
453                       std::string* url,
454                       Replacements* replacements) const;
455
456   // Parses the specified url, replacing parameters as necessary. If
457   // successful, valid is set to true, and the parsed url is returned. For all
458   // known parameters that are encountered an entry is added to replacements.
459   // If there is an error parsing the url, valid is set to false, and an empty
460   // string is returned.  If the URL has the POST parameters, they will be
461   // parsed into |post_params| which will be further replaced with real search
462   // terms data and encoded in "multipart/form-data" format to generate the
463   // POST data.
464   std::string ParseURL(const std::string& url,
465                        Replacements* replacements,
466                        PostParams* post_params,
467                        bool* valid) const;
468
469   // If the url has not yet been parsed, ParseURL is invoked.
470   // NOTE: While this is const, it modifies parsed_, valid_, parsed_url_ and
471   // search_offset_.
472   void ParseIfNecessary(const SearchTermsData& search_terms_data) const;
473
474   // Parses a wildcard out of |path|, putting the parsed path in |path_prefix_|
475   // and |path_suffix_| and setting |path_wildcard_present_| to true.
476   // In the absence of a wildcard, the full path will be contained in
477   // |path_prefix_| and |path_wildcard_present_| will be false.
478   void ParsePath(const std::string& path) const;
479
480   // Returns whether the path portion of this template URL is equal to the path
481   // in |url|, checking that URL is prefixed/suffixed by
482   // |path_prefix_|/|path_suffix_| if |path_wildcard_present_| is true, or equal
483   // to |path_prefix_| otherwise.
484   bool PathIsEqual(const GURL& url) const;
485
486   // Extracts the query key and host from the url.
487   void ParseHostAndSearchTermKey(
488       const SearchTermsData& search_terms_data) const;
489
490   // Encode post parameters in "multipart/form-data" format and store it
491   // inside |post_content|. Returns false if errors are encountered during
492   // encoding. This method is called each time ReplaceSearchTerms gets called.
493   bool EncodeFormData(const PostParams& post_params,
494                       PostContent* post_content) const;
495
496   // Handles a replacement by using real term data. If the replacement
497   // belongs to a PostParam, the PostParam will be replaced by the term data.
498   // Otherwise, the term data will be inserted at the place that the
499   // replacement points to.
500   void HandleReplacement(const std::string& name,
501                          const std::string& value,
502                          const Replacement& replacement,
503                          std::string* url) const;
504
505   // Replaces all replacements in |parsed_url_| with their actual values and
506   // returns the result.  This is the main functionality of
507   // ReplaceSearchTerms().
508   std::string HandleReplacements(
509       const SearchTermsArgs& search_terms_args,
510       const SearchTermsData& search_terms_data,
511       PostContent* post_content) const;
512
513   // The TemplateURL that contains us.  This should outlive us.
514   const TemplateURL* owner_;
515
516   // What kind of URL we are.
517   Type type_;
518
519   // If |type_| is |INDEXED|, this |index_in_owner_| is used instead to refer to
520   // a url within our owner.
521   size_t index_in_owner_ = 0;
522
523   // Whether the URL has been parsed.
524   mutable bool parsed_ = false;
525
526   // Whether the url was successfully parsed.
527   mutable bool valid_ = false;
528
529   // The parsed URL. All terms have been stripped out of this with
530   // replacements_ giving the index of the terms to replace.
531   mutable std::string parsed_url_;
532
533   // Do we support search term replacement?
534   mutable bool supports_replacements_ = false;
535
536   // The replaceable parts of url (parsed_url_). These are ordered by index
537   // into the string, and may be empty.
538   mutable Replacements replacements_;
539
540   // Whether the path contains a wildcard.
541   mutable bool path_wildcard_present_ = false;
542
543   // Host, port, path, key and location of the search term. These are only set
544   // if the url contains one search term.
545   mutable std::string host_;
546   mutable std::string port_;
547   mutable std::string path_prefix_;
548   mutable std::string path_suffix_;
549   mutable std::string search_term_key_;
550   mutable url::Parsed::ComponentType search_term_key_location_ =
551       url::Parsed::QUERY;
552   mutable std::string search_term_value_prefix_;
553   mutable std::string search_term_value_suffix_;
554
555   mutable PostParams post_params_;
556
557   // Whether the contained URL is a pre-populated URL.
558   bool prepopulated_ = false;
559 };
560
561
562 // TemplateURL ----------------------------------------------------------------
563
564 // A TemplateURL represents a single "search engine", defined primarily as a
565 // subset of the Open Search Description Document
566 // (http://www.opensearch.org/Specifications/OpenSearch) plus some extensions.
567 // One TemplateURL contains several TemplateURLRefs, which correspond to various
568 // different capabilities (e.g. doing searches or getting suggestions), as well
569 // as a TemplateURLData containing other details like the name, keyword, etc.
570 //
571 // TemplateURLs are intended to be read-only for most users.
572 // The TemplateURLService, which handles storing and manipulating TemplateURLs,
573 // is made a friend so that it can be the exception to this pattern.
574 class TemplateURL {
575  public:
576   using TemplateURLVector = std::vector<TemplateURL*>;
577   using OwnedTemplateURLVector = std::vector<std::unique_ptr<TemplateURL>>;
578
579   enum Type {
580     // Regular search engine.
581     NORMAL,
582     // Installed by extension through Override Settings API.
583     NORMAL_CONTROLLED_BY_EXTENSION,
584     // The keyword associated with an extension that uses the Omnibox API.
585     OMNIBOX_API_EXTENSION,
586     // Installed only on this device. Should not be synced.
587     LOCAL,
588   };
589
590   // An AssociatedExtensionInfo represents information about the extension that
591   // added the search engine.
592   struct AssociatedExtensionInfo {
593     AssociatedExtensionInfo(const std::string& extension_id,
594                             base::Time install_time,
595                             bool wants_to_be_default_engine);
596     ~AssociatedExtensionInfo();
597
598     // Estimates dynamic memory usage.
599     // See base/trace_event/memory_usage_estimator.h for more info.
600     size_t EstimateMemoryUsage() const;
601
602     std::string extension_id;
603
604     // Used to resolve conflicts when there are multiple extensions specifying
605     // the default search engine. The most recently-installed wins.
606     base::Time install_time;
607
608     // Whether the search engine is supposed to be default.
609     bool wants_to_be_default_engine;
610   };
611
612   explicit TemplateURL(const TemplateURLData& data, Type type = NORMAL);
613
614   // Constructor for extension controlled engine. |type| must be
615   // NORMAL_CONTROLLED_BY_EXTENSION or OMNIBOX_API_EXTENSION.
616   TemplateURL(const TemplateURLData& data,
617               Type type,
618               std::string extension_id,
619               base::Time install_time,
620               bool wants_to_be_default_engine);
621
622   ~TemplateURL();
623
624   // Generates a suitable keyword for the specified url, which must be valid.
625   // This is guaranteed not to return an empty string, since TemplateURLs should
626   // never have an empty keyword.
627   static base::string16 GenerateKeyword(const GURL& url);
628
629   // Generates a favicon URL from the specified url.
630   static GURL GenerateFaviconURL(const GURL& url);
631
632   // Returns true if |t_url| and |data| are equal in all meaningful respects.
633   // Static to allow either or both params to be NULL.
634   static bool MatchesData(const TemplateURL* t_url,
635                           const TemplateURLData* data,
636                           const SearchTermsData& search_terms_data);
637
638   const TemplateURLData& data() const { return data_; }
639
640   const base::string16& short_name() const { return data_.short_name(); }
641   // An accessor for the short_name, but adjusted so it can be appropriately
642   // displayed even if it is LTR and the UI is RTL.
643   base::string16 AdjustedShortNameForLocaleDirection() const;
644
645   const base::string16& keyword() const { return data_.keyword(); }
646
647   const std::string& url() const { return data_.url(); }
648   const std::string& suggestions_url() const { return data_.suggestions_url; }
649   const std::string& image_url() const { return data_.image_url; }
650   const std::string& new_tab_url() const { return data_.new_tab_url; }
651   const std::string& contextual_search_url() const {
652     return data_.contextual_search_url;
653   }
654   const std::string& search_url_post_params() const {
655     return data_.search_url_post_params;
656   }
657   const std::string& suggestions_url_post_params() const {
658     return data_.suggestions_url_post_params;
659   }
660   const std::string& image_url_post_params() const {
661     return data_.image_url_post_params;
662   }
663   const std::vector<std::string>& alternate_urls() const {
664     return data_.alternate_urls;
665   }
666   const GURL& favicon_url() const { return data_.favicon_url; }
667
668   const GURL& logo_url() const { return data_.logo_url; }
669
670   const GURL& doodle_url() const { return data_.doodle_url; }
671
672   const GURL& originating_url() const { return data_.originating_url; }
673
674   bool safe_for_autoreplace() const { return data_.safe_for_autoreplace; }
675
676   const std::vector<std::string>& input_encodings() const {
677     return data_.input_encodings;
678   }
679
680   TemplateURLID id() const { return data_.id; }
681
682   base::Time date_created() const { return data_.date_created; }
683   base::Time last_modified() const { return data_.last_modified; }
684   base::Time last_visited() const { return data_.last_visited; }
685
686   bool created_by_policy() const { return data_.created_by_policy; }
687   bool created_from_play_api() const { return data_.created_from_play_api; }
688
689   int usage_count() const { return data_.usage_count; }
690
691   int prepopulate_id() const { return data_.prepopulate_id; }
692
693   const std::string& sync_guid() const { return data_.sync_guid; }
694
695   const std::vector<TemplateURLRef>& url_refs() const { return url_refs_; }
696   const TemplateURLRef& url_ref() const {
697     // Sanity check for https://crbug.com/781703.
698     CHECK(!url_refs_.empty());
699     return url_refs_.back();
700   }
701   const TemplateURLRef& suggestions_url_ref() const {
702     return suggestions_url_ref_;
703   }
704   const TemplateURLRef& image_url_ref() const { return image_url_ref_; }
705   const TemplateURLRef& new_tab_url_ref() const { return new_tab_url_ref_; }
706   const TemplateURLRef& contextual_search_url_ref() const {
707     return contextual_search_url_ref_;
708   }
709
710   Type type() const { return type_; }
711
712   const AssociatedExtensionInfo* GetExtensionInfoForTesting() const {
713     return extension_info_.get();
714   }
715
716   // Returns true if |url| supports replacement.
717   bool SupportsReplacement(const SearchTermsData& search_terms_data) const;
718
719   // Returns true if any URLRefs use Googe base URLs.
720   bool HasGoogleBaseURLs(const SearchTermsData& search_terms_data) const;
721
722   // Returns true if this TemplateURL uses Google base URLs and has a keyword
723   // of "google.TLD".  We use this to decide whether we can automatically
724   // update the keyword to reflect the current Google base URL TLD.
725   bool IsGoogleSearchURLWithReplaceableKeyword(
726       const SearchTermsData& search_terms_data) const;
727
728   // Returns true if the keywords match or if
729   // IsGoogleSearchURLWithReplaceableKeyword() is true for both |this| and
730   // |other|.
731   bool HasSameKeywordAs(const TemplateURLData& other,
732                         const SearchTermsData& search_terms_data) const;
733
734   // Returns the id of the extension that added this search engine. Only call
735   // this for TemplateURLs of type NORMAL_CONTROLLED_BY_EXTENSION or
736   // OMNIBOX_API_EXTENSION.
737   std::string GetExtensionId() const;
738
739   // Returns the type of this search engine, or SEARCH_ENGINE_OTHER if no
740   // engines match.
741   SearchEngineType GetEngineType(
742       const SearchTermsData& search_terms_data) const;
743
744   // Use the alternate URLs and the search URL to match the provided |url|
745   // and extract |search_terms| from it. Returns false and an empty
746   // |search_terms| if no search terms can be matched. The URLs are matched in
747   // the order listed in |url_refs_| (see comment there).
748   bool ExtractSearchTermsFromURL(const GURL& url,
749                                  const SearchTermsData& search_terms_data,
750                                  base::string16* search_terms) const;
751
752   // Returns true if non-empty search terms could be extracted from |url| using
753   // ExtractSearchTermsFromURL(). In other words, this returns whether |url|
754   // could be the result of performing a search with |this|.
755   bool IsSearchURL(const GURL& url,
756                    const SearchTermsData& search_terms_data) const;
757
758   // Given a |url| corresponding to this TemplateURL, identifies the search
759   // terms and replaces them with the ones in |search_terms_args|, leaving the
760   // other parameters untouched. If the replacement fails, returns false and
761   // leaves |result| untouched. This is used by mobile ports to perform query
762   // refinement.
763   bool ReplaceSearchTermsInURL(
764       const GURL& url,
765       const TemplateURLRef::SearchTermsArgs& search_terms_args,
766       const SearchTermsData& search_terms_data,
767       GURL* result) const;
768
769   // Encodes the search terms from |search_terms_args| so that we know the
770   // |input_encoding|. Returns the |encoded_terms| and the
771   // |encoded_original_query|. |encoded_terms| may be escaped as path or query
772   // depending on |is_in_query|; |encoded_original_query| is always escaped as
773   // query.
774   void EncodeSearchTerms(
775       const TemplateURLRef::SearchTermsArgs& search_terms_args,
776       bool is_in_query,
777       std::string* input_encoding,
778       base::string16* encoded_terms,
779       base::string16* encoded_original_query) const;
780
781   // Returns the search url for this template URL.
782   // Returns an empty GURL if this template URL has no url().
783   GURL GenerateSearchURL(const SearchTermsData& search_terms_data) const;
784
785   // TemplateURL internally caches values derived from a passed SearchTermsData
786   // to make its functions quick. This method invalidates any cached values and
787   // it should be called after SearchTermsData has been changed.
788   void InvalidateCachedValues() const;
789
790   // Estimates dynamic memory usage.
791   // See base/trace_event/memory_usage_estimator.h for more info.
792   size_t EstimateMemoryUsage() const;
793
794  private:
795   friend class TemplateURLService;
796
797   void CopyFrom(const TemplateURL& other);
798
799   void SetURL(const std::string& url);
800   void SetPrepopulateId(int id);
801
802   // Resets the keyword if IsGoogleSearchURLWithReplaceableKeyword() or |force|.
803   // The |force| parameter is useful when the existing keyword is known to be
804   // a placeholder.  The resulting keyword is generated using
805   // GenerateSearchURL() and GenerateKeyword().
806   void ResetKeywordIfNecessary(const SearchTermsData& search_terms_data,
807                                bool force);
808
809   // Resizes the |url_refs_| vector, which always holds the search URL as the
810   // last item.
811   void ResizeURLRefVector();
812
813   // Uses the alternate URLs and the search URL to match the provided |url|
814   // and extract |search_terms| from it as well as the |search_terms_component|
815   // (either REF or QUERY) and |search_terms_component| at which the
816   // |search_terms| are found in |url|. See also ExtractSearchTermsFromURL().
817   bool FindSearchTermsInURL(const GURL& url,
818                             const SearchTermsData& search_terms_data,
819                             base::string16* search_terms,
820                             url::Parsed::ComponentType* search_terms_component,
821                             url::Component* search_terms_position) const;
822
823   TemplateURLData data_;
824
825   // Contains TemplateURLRefs corresponding to the alternate URLs and the search
826   // URL, in priority order: the URL at index 0 is treated as the highest
827   // priority and the primary search URL is treated as the lowest priority.  For
828   // example, if a TemplateURL has alternate URL "http://foo/#q={searchTerms}"
829   // and search URL "http://foo/?q={searchTerms}", and the URL to be decoded is
830   // "http://foo/?q=a#q=b", the alternate URL will match first and the decoded
831   // search term will be "b".  Note that since every TemplateURLRef has a
832   // primary search URL, this vector is never empty.
833   std::vector<TemplateURLRef> url_refs_;
834
835   TemplateURLRef suggestions_url_ref_;
836   TemplateURLRef image_url_ref_;
837   TemplateURLRef new_tab_url_ref_;
838   TemplateURLRef contextual_search_url_ref_;
839   std::unique_ptr<AssociatedExtensionInfo> extension_info_;
840
841   const Type type_;
842
843   // Caches the computed engine type across successive calls to GetEngineType().
844   mutable SearchEngineType engine_type_;
845
846   // TODO(sky): Add date last parsed OSD file.
847
848   DISALLOW_COPY_AND_ASSIGN(TemplateURL);
849 };
850
851 #endif  // COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_H_