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