Home | History | Annotate | Download | only in search_engines
      1 // Copyright (c) 2012 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 CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
      6 #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
      7 
      8 #include <string>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/gtest_prod_util.h"
     13 #include "base/time/time.h"
     14 #include "chrome/browser/autocomplete/autocomplete_input.h"
     15 #include "chrome/browser/search_engines/template_url_id.h"
     16 #include "url/gurl.h"
     17 #include "url/url_parse.h"
     18 
     19 class Profile;
     20 class SearchTermsData;
     21 class TemplateURL;
     22 
     23 
     24 // TemplateURLRef -------------------------------------------------------------
     25 
     26 // A TemplateURLRef represents a single URL within the larger TemplateURL class
     27 // (which represents an entire "search engine", see below).  If
     28 // SupportsReplacement() is true, this URL has placeholders in it, for which
     29 // callers can substitute values to get a "real" URL using ReplaceSearchTerms().
     30 //
     31 // TemplateURLRefs always have a non-NULL |owner_| TemplateURL, which they
     32 // access in order to get at important data like the underlying URL string or
     33 // the associated Profile.
     34 class TemplateURLRef {
     35  public:
     36   // Magic numbers to pass to ReplaceSearchTerms() for the |accepted_suggestion|
     37   // parameter.  Most callers aren't using Suggest capabilities and should just
     38   // pass NO_SUGGESTIONS_AVAILABLE.
     39   // NOTE: Because positive values are meaningful, make sure these are negative!
     40   enum AcceptedSuggestion {
     41     NO_SUGGESTION_CHOSEN = -1,
     42     NO_SUGGESTIONS_AVAILABLE = -2,
     43   };
     44 
     45   // Which kind of URL within our owner we are.  This allows us to get at the
     46   // correct string field. Use |INDEXED| to indicate that the numerical
     47   // |index_in_owner_| should be used instead.
     48   enum Type {
     49     SEARCH,
     50     SUGGEST,
     51     INSTANT,
     52     IMAGE,
     53     INDEXED
     54   };
     55 
     56   // Type to store <content_type, post_data> pair for POST URLs.
     57   // The |content_type|(first part of the pair) is the content-type of
     58   // the |post_data|(second part of the pair) which is encoded in
     59   // "multipart/form-data" format, it also contains the MIME boundary used in
     60   // the |post_data|. See http://tools.ietf.org/html/rfc2046 for the details.
     61   typedef std::pair<std::string, std::string> PostContent;
     62 
     63   // This struct encapsulates arguments passed to
     64   // TemplateURLRef::ReplaceSearchTerms methods.  By default, only search_terms
     65   // is required and is passed in the constructor.
     66   struct SearchTermsArgs {
     67     explicit SearchTermsArgs(const string16& search_terms);
     68     ~SearchTermsArgs();
     69 
     70     // The search terms (query).
     71     string16 search_terms;
     72 
     73     // The original (input) query.
     74     string16 original_query;
     75 
     76     // The optional assisted query stats, aka AQS, used for logging purposes.
     77     // This string contains impressions of all autocomplete matches shown
     78     // at the query submission time.  For privacy reasons, we require the
     79     // search provider to support HTTPS protocol in order to receive the AQS
     80     // param.
     81     // For more details, see http://goto.google.com/binary-clients-logging .
     82     std::string assisted_query_stats;
     83 
     84     // TODO: Remove along with "aq" CGI param.
     85     int accepted_suggestion;
     86 
     87     // The 0-based position of the cursor within the query string at the time
     88     // the request was issued.  Set to string16::npos if not used.
     89     size_t cursor_position;
     90 
     91     // The start-edge margin of the omnibox in pixels, used in extended Instant
     92     // to align the preview contents with the omnibox.
     93     int omnibox_start_margin;
     94 
     95     // The URL of the current webpage to be used for experimental zero-prefix
     96     // suggestions.
     97     std::string zero_prefix_url;
     98 
     99     // Which omnibox the user used to type the prefix.
    100     AutocompleteInput::PageClassification page_classification;
    101 
    102     // If set, ReplaceSearchTerms() will automatically append any extra query
    103     // params specified via the --extra-search-query-params command-line
    104     // argument.  Generally, this should be set when dealing with the search or
    105     // instant TemplateURLRefs of the default search engine and the caller cares
    106     // about the query portion of the URL.  Since neither TemplateURLRef nor
    107     // indeed TemplateURL know whether a TemplateURL is the default search
    108     // engine, callers instead must set this manually.
    109     bool append_extra_query_params;
    110 
    111     // The raw content of an image thumbnail that will be used as a query for
    112     // search-by-image frontend.
    113     std::string image_thumbnail_content;
    114 
    115     // When searching for an image, the URL of the original image. Callers
    116     // should leave this empty for images specified via data: URLs.
    117     GURL image_url;
    118   };
    119 
    120   TemplateURLRef(TemplateURL* owner, Type type);
    121   TemplateURLRef(TemplateURL* owner, size_t index_in_owner);
    122   ~TemplateURLRef();
    123 
    124   // Returns the raw URL. None of the parameters will have been replaced.
    125   std::string GetURL() const;
    126 
    127   // Returns the raw string of the post params. Please see comments in
    128   // prepopulated_engines_schema.json for the format.
    129   std::string GetPostParamsString() const;
    130 
    131   // Returns true if this URL supports search term replacement.
    132   bool SupportsReplacement() const;
    133 
    134   // Like SupportsReplacement but usable on threads other than the UI thread.
    135   bool SupportsReplacementUsingTermsData(
    136       const SearchTermsData& search_terms_data) const;
    137 
    138   // Returns a string that is the result of replacing the search terms in
    139   // the url with the specified arguments.  We use our owner's input encoding.
    140   //
    141   // If this TemplateURLRef does not support replacement (SupportsReplacement
    142   // returns false), an empty string is returned.
    143   // If this TemplateURLRef uses POST, and |post_content| is not NULL, the
    144   // |post_params_| will be replaced, encoded in "multipart/form-data" format
    145   // and stored into |post_content|.
    146   std::string ReplaceSearchTerms(
    147       const SearchTermsArgs& search_terms_args,
    148       PostContent* post_content) const;
    149   // TODO(jnd): remove the following ReplaceSearchTerms definition which does
    150   // not have |post_content| parameter once all reference callers pass
    151   // |post_content| parameter.
    152   std::string ReplaceSearchTerms(
    153       const SearchTermsArgs& search_terms_args) const {
    154     return ReplaceSearchTerms(search_terms_args, NULL);
    155   }
    156 
    157   // Just like ReplaceSearchTerms except that it takes SearchTermsData to supply
    158   // the data for some search terms. Most of the time ReplaceSearchTerms should
    159   // be called.
    160   std::string ReplaceSearchTermsUsingTermsData(
    161       const SearchTermsArgs& search_terms_args,
    162       const SearchTermsData& search_terms_data,
    163       PostContent* post_content) const;
    164 
    165   // Returns true if the TemplateURLRef is valid. An invalid TemplateURLRef is
    166   // one that contains unknown terms, or invalid characters.
    167   bool IsValid() const;
    168 
    169   // Like IsValid but usable on threads other than the UI thread.
    170   bool IsValidUsingTermsData(const SearchTermsData& search_terms_data) const;
    171 
    172   // Returns a string representation of this TemplateURLRef suitable for
    173   // display. The display format is the same as the format used by Firefox.
    174   string16 DisplayURL() const;
    175 
    176   // Converts a string as returned by DisplayURL back into a string as
    177   // understood by TemplateURLRef.
    178   static std::string DisplayURLToURLRef(const string16& display_url);
    179 
    180   // If this TemplateURLRef is valid and contains one search term, this returns
    181   // the host/path of the URL, otherwise this returns an empty string.
    182   const std::string& GetHost() const;
    183   const std::string& GetPath() const;
    184 
    185   // If this TemplateURLRef is valid and contains one search term, this returns
    186   // the key of the search term, otherwise this returns an empty string.
    187   const std::string& GetSearchTermKey() const;
    188 
    189   // Converts the specified term in our owner's encoding to a string16.
    190   string16 SearchTermToString16(const std::string& term) const;
    191 
    192   // Returns true if this TemplateURLRef has a replacement term of
    193   // {google:baseURL} or {google:baseSuggestURL}.
    194   bool HasGoogleBaseURLs() const;
    195 
    196   // Use the pattern referred to by this TemplateURLRef to match the provided
    197   // |url| and extract |search_terms| from it. Returns true if the pattern
    198   // matches, even if |search_terms| is empty. In this case
    199   // |search_term_component|, if not NULL, indicates whether the search terms
    200   // were found in the query or the ref parameters; and |search_terms_position|,
    201   // if not NULL, contains the position of the search terms in the query or the
    202   // ref parameters. Returns false and an empty |search_terms| if the pattern
    203   // does not match.
    204   bool ExtractSearchTermsFromURL(
    205       const GURL& url,
    206       string16* search_terms,
    207       const SearchTermsData& search_terms_data,
    208       url_parse::Parsed::ComponentType* search_term_component,
    209       url_parse::Component* search_terms_position) const;
    210 
    211   // Whether the URL uses POST (as opposed to GET).
    212   bool UsesPOSTMethodUsingTermsData(
    213       const SearchTermsData* search_terms_data) const;
    214   bool UsesPOSTMethod() const {
    215     return UsesPOSTMethodUsingTermsData(NULL);
    216   }
    217 
    218  private:
    219   friend class TemplateURL;
    220   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, SetPrepopulatedAndParse);
    221   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterKnown);
    222   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterUnknown);
    223   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLEmpty);
    224   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoTemplateEnd);
    225   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoKnownParameters);
    226   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLTwoParameters);
    227   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNestedParameter);
    228   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, URLRefTestImageURLWithPOST);
    229 
    230   // Enumeration of the known types.
    231   enum ReplacementType {
    232     ENCODING,
    233     GOOGLE_ASSISTED_QUERY_STATS,
    234     GOOGLE_BASE_URL,
    235     GOOGLE_BASE_SUGGEST_URL,
    236     GOOGLE_CURSOR_POSITION,
    237     GOOGLE_IMAGE_SEARCH_SOURCE,
    238     GOOGLE_IMAGE_THUMBNAIL,
    239     GOOGLE_IMAGE_URL,
    240     GOOGLE_INSTANT_ENABLED,
    241     GOOGLE_INSTANT_EXTENDED_ENABLED,
    242     GOOGLE_NTP_IS_THEMED,
    243     GOOGLE_OMNIBOX_START_MARGIN,
    244     GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION,
    245     GOOGLE_PAGE_CLASSIFICATION,
    246     GOOGLE_RLZ,
    247     GOOGLE_SEARCH_CLIENT,
    248     GOOGLE_SEARCH_FIELDTRIAL_GROUP,
    249     GOOGLE_SUGGEST_CLIENT,
    250     GOOGLE_UNESCAPED_SEARCH_TERMS,
    251     GOOGLE_ZERO_PREFIX_URL,
    252     LANGUAGE,
    253     SEARCH_TERMS,
    254   };
    255 
    256   // Used to identify an element of the raw url that can be replaced.
    257   struct Replacement {
    258     Replacement(ReplacementType type, size_t index)
    259         : type(type), index(index), is_post_param(false) {}
    260     ReplacementType type;
    261     size_t index;
    262     // Indicates the location in where the replacement is replaced. If
    263     // |is_post_param| is false, |index| indicates the byte position in
    264     // |parsed_url_|. Otherwise, |index| is the index of |post_params_|.
    265     bool is_post_param;
    266   };
    267 
    268   // The list of elements to replace.
    269   typedef std::vector<struct Replacement> Replacements;
    270   // Type to store <key, value> pairs for POST URLs.
    271   typedef std::pair<std::string, std::string> PostParam;
    272   typedef std::vector<PostParam> PostParams;
    273 
    274   // TemplateURLRef internally caches values to make replacement quick. This
    275   // method invalidates any cached values.
    276   void InvalidateCachedValues() const;
    277 
    278   // Parses the parameter in url at the specified offset. start/end specify the
    279   // range of the parameter in the url, including the braces. If the parameter
    280   // is valid, url is updated to reflect the appropriate parameter. If
    281   // the parameter is one of the known parameters an element is added to
    282   // replacements indicating the type and range of the element. The original
    283   // parameter is erased from the url.
    284   //
    285   // If the parameter is not a known parameter, false is returned. If this is a
    286   // prepopulated URL, the parameter is erased, otherwise it is left alone.
    287   bool ParseParameter(size_t start,
    288                       size_t end,
    289                       std::string* url,
    290                       Replacements* replacements) const;
    291 
    292   // Parses the specified url, replacing parameters as necessary. If
    293   // successful, valid is set to true, and the parsed url is returned. For all
    294   // known parameters that are encountered an entry is added to replacements.
    295   // If there is an error parsing the url, valid is set to false, and an empty
    296   // string is returned.  If the URL has the POST parameters, they will be
    297   // parsed into |post_params| which will be further replaced with real search
    298   // terms data and encoded in "multipart/form-data" format to generate the
    299   // POST data.
    300   std::string ParseURL(const std::string& url,
    301                        Replacements* replacements,
    302                        PostParams* post_params,
    303                        bool* valid) const;
    304 
    305   // If the url has not yet been parsed, ParseURL is invoked.
    306   // NOTE: While this is const, it modifies parsed_, valid_, parsed_url_ and
    307   // search_offset_.
    308   void ParseIfNecessary() const;
    309 
    310   // Like ParseIfNecessary but usable on threads other than the UI thread.
    311   void ParseIfNecessaryUsingTermsData(
    312       const SearchTermsData& search_terms_data) const;
    313 
    314   // Extracts the query key and host from the url.
    315   void ParseHostAndSearchTermKey(
    316       const SearchTermsData& search_terms_data) const;
    317 
    318   // Encode post parameters in "multipart/form-data" format and store it
    319   // inside |post_content|. Returns false if errors are encountered during
    320   // encoding. This method is called each time ReplaceSearchTerms gets called.
    321   bool EncodeFormData(const PostParams& post_params,
    322                       PostContent* post_content) const;
    323 
    324   // Handles a replacement by using real term data. If the replacement
    325   // belongs to a PostParam, the PostParam will be replaced by the term data.
    326   // Otherwise, the term data will be inserted at the place that the
    327   // replacement points to.
    328   void HandleReplacement(const std::string& name,
    329                          const std::string& value,
    330                          const Replacement& replacement,
    331                          std::string* url) const;
    332 
    333   // Replaces all replacements in |parsed_url_| with their actual values and
    334   // returns the result.  This is the main functionality of
    335   // ReplaceSearchTermsUsingTermsData().
    336   std::string HandleReplacements(
    337       const SearchTermsArgs& search_terms_args,
    338       const SearchTermsData& search_terms_data,
    339       PostContent* post_content) const;
    340 
    341   // The TemplateURL that contains us.  This should outlive us.
    342   TemplateURL* const owner_;
    343 
    344   // What kind of URL we are.
    345   const Type type_;
    346 
    347   // If |type_| is |INDEXED|, this |index_in_owner_| is used instead to refer to
    348   // a url within our owner.
    349   const size_t index_in_owner_;
    350 
    351   // Whether the URL has been parsed.
    352   mutable bool parsed_;
    353 
    354   // Whether the url was successfully parsed.
    355   mutable bool valid_;
    356 
    357   // The parsed URL. All terms have been stripped out of this with
    358   // replacements_ giving the index of the terms to replace.
    359   mutable std::string parsed_url_;
    360 
    361   // Do we support search term replacement?
    362   mutable bool supports_replacements_;
    363 
    364   // The replaceable parts of url (parsed_url_). These are ordered by index
    365   // into the string, and may be empty.
    366   mutable Replacements replacements_;
    367 
    368   // Host, path, key and location of the search term. These are only set if the
    369   // url contains one search term.
    370   mutable std::string host_;
    371   mutable std::string path_;
    372   mutable std::string search_term_key_;
    373   mutable url_parse::Parsed::ComponentType search_term_key_location_;
    374 
    375   mutable PostParams post_params_;
    376 
    377   // Whether the contained URL is a pre-populated URL.
    378   bool prepopulated_;
    379 
    380   DISALLOW_COPY_AND_ASSIGN(TemplateURLRef);
    381 };
    382 
    383 
    384 // TemplateURLData ------------------------------------------------------------
    385 
    386 // The data for the TemplateURL.  Separating this into its own class allows most
    387 // users to do SSA-style usage of TemplateURL: construct a TemplateURLData with
    388 // whatever fields are desired, then create an immutable TemplateURL from it.
    389 struct TemplateURLData {
    390   TemplateURLData();
    391   ~TemplateURLData();
    392 
    393   // A short description of the template. This is the name we show to the user
    394   // in various places that use TemplateURLs. For example, the location bar
    395   // shows this when the user selects a substituting match.
    396   string16 short_name;
    397 
    398   // The shortcut for this TemplateURL.  |keyword| must be non-empty.
    399   void SetKeyword(const string16& keyword);
    400   const string16& keyword() const { return keyword_; }
    401 
    402   // The raw URL for the TemplateURL, which may not be valid as-is (e.g. because
    403   // it requires substitutions first).  This must be non-empty.
    404   void SetURL(const std::string& url);
    405   const std::string& url() const { return url_; }
    406 
    407   // Optional additional raw URLs.
    408   std::string suggestions_url;
    409   std::string instant_url;
    410   std::string image_url;
    411 
    412   // The following post_params are comma-separated lists used to specify the
    413   // post parameters for the corresponding URL.
    414   std::string search_url_post_params;
    415   std::string suggestions_url_post_params;
    416   std::string instant_url_post_params;
    417   std::string image_url_post_params;
    418 
    419   // Optional favicon for the TemplateURL.
    420   GURL favicon_url;
    421 
    422   // URL to the OSD file this came from. May be empty.
    423   GURL originating_url;
    424 
    425   // Whether this TemplateURL is shown in the default list of search providers.
    426   // This is just a property and does not indicate whether the TemplateURL has a
    427   // TemplateURLRef that supports replacement. Use
    428   // TemplateURL::ShowInDefaultList() to test both.
    429   bool show_in_default_list;
    430 
    431   // Whether it's safe for auto-modification code (the autogenerator and the
    432   // code that imports data from other browsers) to replace the TemplateURL.
    433   // This should be set to false for any TemplateURL the user edits, or any
    434   // TemplateURL that the user clearly manually edited in the past, like a
    435   // bookmark keyword from another browser.
    436   bool safe_for_autoreplace;
    437 
    438   // The list of supported encodings for the search terms. This may be empty,
    439   // which indicates the terms should be encoded with UTF-8.
    440   std::vector<std::string> input_encodings;
    441 
    442   // Unique identifier of this TemplateURL. The unique ID is set by the
    443   // TemplateURLService when the TemplateURL is added to it.
    444   TemplateURLID id;
    445 
    446   // Date this TemplateURL was created.
    447   //
    448   // NOTE: this may be 0, which indicates the TemplateURL was created before we
    449   // started tracking creation time.
    450   base::Time date_created;
    451 
    452   // The last time this TemplateURL was modified by a user, since creation.
    453   //
    454   // NOTE: Like date_created above, this may be 0.
    455   base::Time last_modified;
    456 
    457   // True if this TemplateURL was automatically created by the administrator via
    458   // group policy.
    459   bool created_by_policy;
    460 
    461   // Number of times this TemplateURL has been explicitly used to load a URL.
    462   // We don't increment this for uses as the "default search engine" since
    463   // that's not really "explicit" usage and incrementing would result in pinning
    464   // the user's default search engine(s) to the top of the list of searches on
    465   // the New Tab page, de-emphasizing the omnibox as "where you go to search".
    466   int usage_count;
    467 
    468   // If this TemplateURL comes from prepopulated data the prepopulate_id is > 0.
    469   int prepopulate_id;
    470 
    471   // The primary unique identifier for Sync. This set on all TemplateURLs
    472   // regardless of whether they have been associated with Sync.
    473   std::string sync_guid;
    474 
    475   // A list of URL patterns that can be used, in addition to |url_|, to extract
    476   // search terms from a URL.
    477   std::vector<std::string> alternate_urls;
    478 
    479   // A parameter that, if present in the query or ref parameters of a search_url
    480   // or instant_url, causes Chrome to replace the URL with the search term.
    481   std::string search_terms_replacement_key;
    482 
    483  private:
    484   // Private so we can enforce using the setters and thus enforce that these
    485   // fields are never empty.
    486   string16 keyword_;
    487   std::string url_;
    488 };
    489 
    490 
    491 // TemplateURL ----------------------------------------------------------------
    492 
    493 // A TemplateURL represents a single "search engine", defined primarily as a
    494 // subset of the Open Search Description Document
    495 // (http://www.opensearch.org/Specifications/OpenSearch) plus some extensions.
    496 // One TemplateURL contains several TemplateURLRefs, which correspond to various
    497 // different capabilities (e.g. doing searches or getting suggestions), as well
    498 // as a TemplateURLData containing other details like the name, keyword, etc.
    499 //
    500 // TemplateURLs are intended to be read-only for most users; the only public
    501 // non-const method is the Profile getter, which returns a non-const Profile*.
    502 // The TemplateURLService, which handles storing and manipulating TemplateURLs,
    503 // is made a friend so that it can be the exception to this pattern.
    504 class TemplateURL {
    505  public:
    506   // |profile| may be NULL.  This will affect the results of e.g. calling
    507   // ReplaceSearchTerms() on the member TemplateURLRefs.
    508   TemplateURL(Profile* profile, const TemplateURLData& data);
    509   ~TemplateURL();
    510 
    511   // Generates a favicon URL from the specified url.
    512   static GURL GenerateFaviconURL(const GURL& url);
    513 
    514   Profile* profile() { return profile_; }
    515   const TemplateURLData& data() const { return data_; }
    516 
    517   const string16& short_name() const { return data_.short_name; }
    518   // An accessor for the short_name, but adjusted so it can be appropriately
    519   // displayed even if it is LTR and the UI is RTL.
    520   string16 AdjustedShortNameForLocaleDirection() const;
    521 
    522   const string16& keyword() const { return data_.keyword(); }
    523 
    524   const std::string& url() const { return data_.url(); }
    525   const std::string& suggestions_url() const { return data_.suggestions_url; }
    526   const std::string& instant_url() const { return data_.instant_url; }
    527   const std::string& image_url() const { return data_.image_url; }
    528   const std::string& search_url_post_params() const {
    529     return data_.search_url_post_params;
    530   }
    531   const std::string& suggestions_url_post_params() const {
    532     return data_.suggestions_url_post_params;
    533   }
    534   const std::string& instant_url_post_params() const {
    535     return data_.instant_url_post_params;
    536   }
    537   const std::string& image_url_post_params() const {
    538     return data_.image_url_post_params;
    539   }
    540   const std::vector<std::string>& alternate_urls() const {
    541     return data_.alternate_urls;
    542   }
    543   const GURL& favicon_url() const { return data_.favicon_url; }
    544 
    545   const GURL& originating_url() const { return data_.originating_url; }
    546 
    547   bool show_in_default_list() const { return data_.show_in_default_list; }
    548   // Returns true if show_in_default_list() is true and this TemplateURL has a
    549   // TemplateURLRef that supports replacement.
    550   bool ShowInDefaultList() const;
    551 
    552   bool safe_for_autoreplace() const { return data_.safe_for_autoreplace; }
    553 
    554   const std::vector<std::string>& input_encodings() const {
    555     return data_.input_encodings;
    556   }
    557 
    558   TemplateURLID id() const { return data_.id; }
    559 
    560   base::Time date_created() const { return data_.date_created; }
    561   base::Time last_modified() const { return data_.last_modified; }
    562 
    563   bool created_by_policy() const { return data_.created_by_policy; }
    564 
    565   int usage_count() const { return data_.usage_count; }
    566 
    567   int prepopulate_id() const { return data_.prepopulate_id; }
    568 
    569   const std::string& sync_guid() const { return data_.sync_guid; }
    570 
    571   // TODO(beaudoin): Rename this when renaming HasSearchTermsReplacementKey().
    572   const std::string& search_terms_replacement_key() const {
    573     return data_.search_terms_replacement_key;
    574   }
    575 
    576   const TemplateURLRef& url_ref() const { return url_ref_; }
    577   const TemplateURLRef& suggestions_url_ref() const {
    578     return suggestions_url_ref_;
    579   }
    580   const TemplateURLRef& instant_url_ref() const { return instant_url_ref_; }
    581   const TemplateURLRef& image_url_ref() const { return image_url_ref_; }
    582 
    583   // Returns true if |url| supports replacement.
    584   bool SupportsReplacement() const;
    585 
    586   // Like SupportsReplacement but usable on threads other than the UI thread.
    587   bool SupportsReplacementUsingTermsData(
    588       const SearchTermsData& search_terms_data) const;
    589 
    590   // Returns true if this TemplateURL uses Google base URLs and has a keyword
    591   // of "google.TLD".  We use this to decide whether we can automatically
    592   // update the keyword to reflect the current Google base URL TLD.
    593   bool IsGoogleSearchURLWithReplaceableKeyword() const;
    594 
    595   // Returns true if the keywords match or if
    596   // IsGoogleSearchURLWithReplaceableKeyword() is true for both TemplateURLs.
    597   bool HasSameKeywordAs(const TemplateURL& other) const;
    598 
    599   std::string GetExtensionId() const;
    600   bool IsExtensionKeyword() const;
    601 
    602   // Returns the total number of URLs comprised in this template, including
    603   // search and alternate URLs.
    604   size_t URLCount() const;
    605 
    606   // Gets the search URL at the given index. The alternate URLs, if any, are
    607   // numbered starting at 0, and the primary search URL follows. This is used
    608   // to decode the search term given a search URL (see
    609   // ExtractSearchTermsFromURL()).
    610   const std::string& GetURL(size_t index) const;
    611 
    612   // Use the alternate URLs and the search URL to match the provided |url|
    613   // and extract |search_terms| from it. Returns false and an empty
    614   // |search_terms| if no search terms can be matched. The order in which the
    615   // alternate URLs are listed dictates their priority, the URL at index 0 is
    616   // treated as the highest priority and the primary search URL is treated as
    617   // the lowest priority (see GetURL()).  For example, if a TemplateURL has
    618   // alternate URL "http://foo/#q={searchTerms}" and search URL
    619   // "http://foo/?q={searchTerms}", and the URL to be decoded is
    620   // "http://foo/?q=a#q=b", the alternate URL will match first and the decoded
    621   // search term will be "b".
    622   bool ExtractSearchTermsFromURL(const GURL& url, string16* search_terms);
    623 
    624   // Like ExtractSearchTermsFromURL but usable on threads other than the UI
    625   // thread.
    626   bool ExtractSearchTermsFromURLUsingTermsData(
    627       const GURL& url,
    628       string16* search_terms,
    629       const SearchTermsData& search_terms_data);
    630 
    631   // Returns true if non-empty search terms could be extracted from |url| using
    632   // ExtractSearchTermsFromURL(). In other words, this returns whether |url|
    633   // could be the result of performing a search with |this|.
    634   bool IsSearchURL(const GURL& url);
    635 
    636   // Like IsSearchURL but usable on threads other than the UI thread.
    637   bool IsSearchURLUsingTermsData(
    638       const GURL& url,
    639       const SearchTermsData& search_terms_data);
    640 
    641   // Returns true if the specified |url| contains the search terms replacement
    642   // key in either the query or the ref. This method does not verify anything
    643   // else about the URL. In particular, it does not check that the domain
    644   // matches that of this TemplateURL.
    645   // TODO(beaudoin): Rename this to reflect that it really checks for an
    646   // InstantExtended capable URL.
    647   bool HasSearchTermsReplacementKey(const GURL& url) const;
    648 
    649   // Given a |url| corresponding to this TemplateURL, identifies the search
    650   // terms and replaces them with the ones in |search_terms_args|, leaving the
    651   // other parameters untouched. If the replacement fails, returns false and
    652   // leaves |result| untouched. This is used by mobile ports to perform query
    653   // refinement.
    654   bool ReplaceSearchTermsInURL(
    655       const GURL& url,
    656       const TemplateURLRef::SearchTermsArgs& search_terms_args,
    657       GURL* result);
    658 
    659   // Encodes the search terms from |search_terms_args| so that we know the
    660   // |input_encoding|. Returns the |encoded_terms| and the
    661   // |encoded_original_query|. |encoded_terms| may be escaped as path or query
    662   // depending on |is_in_query|; |encoded_original_query| is always escaped as
    663   // query.
    664   void EncodeSearchTerms(
    665       const TemplateURLRef::SearchTermsArgs& search_terms_args,
    666       bool is_in_query,
    667       std::string* input_encoding,
    668       string16* encoded_terms,
    669       string16* encoded_original_query) const;
    670 
    671  private:
    672   friend class TemplateURLService;
    673 
    674   void CopyFrom(const TemplateURL& other);
    675 
    676   void SetURL(const std::string& url);
    677   void SetPrepopulateId(int id);
    678 
    679   // Resets the keyword if IsGoogleSearchURLWithReplaceableKeyword() or |force|.
    680   // The |force| parameter is useful when the existing keyword is known to be
    681   // a placeholder.  The resulting keyword is generated using
    682   // TemplateURLService::GenerateSearchURL() and
    683   // TemplateURLService::GenerateKeyword().
    684   void ResetKeywordIfNecessary(bool force);
    685 
    686   // Uses the alternate URLs and the search URL to match the provided |url|
    687   // and extract |search_terms| from it as well as the |search_terms_component|
    688   // (either REF or QUERY) and |search_terms_component| at which the
    689   // |search_terms| are found in |url|. See also ExtractSearchTermsFromURL().
    690   bool FindSearchTermsInURL(
    691       const GURL& url,
    692       const SearchTermsData& search_terms_data,
    693       string16* search_terms,
    694       url_parse::Parsed::ComponentType* search_terms_component,
    695       url_parse::Component* search_terms_position);
    696 
    697   Profile* profile_;
    698   TemplateURLData data_;
    699   TemplateURLRef url_ref_;
    700   TemplateURLRef suggestions_url_ref_;
    701   TemplateURLRef instant_url_ref_;
    702   TemplateURLRef image_url_ref_;
    703 
    704   // TODO(sky): Add date last parsed OSD file.
    705 
    706   DISALLOW_COPY_AND_ASSIGN(TemplateURL);
    707 };
    708 
    709 #endif  // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
    710