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