Home | History | Annotate | Download | only in autocomplete
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_
      6 #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_
      7 #pragma once
      8 
      9 #include <map>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/logging.h"
     14 #include "base/memory/ref_counted.h"
     15 #include "base/string16.h"
     16 #include "base/timer.h"
     17 #include "googleurl/src/gurl.h"
     18 #include "googleurl/src/url_parse.h"
     19 
     20 // The AutocompleteController is the center of the autocomplete system.  A
     21 // class creates an instance of the controller, which in turn creates a set of
     22 // AutocompleteProviders to serve it.  The owning class can ask the controller
     23 // to Start() a query; the controller in turn passes this call down to the
     24 // providers, each of which keeps track of its own matches and whether it has
     25 // finished processing the query.  When a provider gets more matches or finishes
     26 // processing, it notifies the controller, which merges the combined matches
     27 // together and makes the result available to interested observers.
     28 //
     29 // The owner may also cancel the current query by calling Stop(), which the
     30 // controller will in turn communicate to all the providers.  No callbacks will
     31 // happen after a request has been stopped.
     32 //
     33 // IMPORTANT: There is NO THREAD SAFETY built into this portion of the
     34 // autocomplete system.  All calls to and from the AutocompleteController should
     35 // happen on the same thread.  AutocompleteProviders are responsible for doing
     36 // their own thread management when they need to return matches asynchronously.
     37 //
     38 // The AutocompleteProviders each return different kinds of matches, such as
     39 // history or search matches.  These matches are given "relevance" scores.
     40 // Higher scores are better matches than lower scores.  The relevance scores and
     41 // classes providing the respective matches are as follows:
     42 //
     43 // UNKNOWN input type:
     44 // --------------------------------------------------------------------|-----
     45 // Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
     46 // Extension App (exact match)                                         | 1425
     47 // HistoryURL (exact or inline autocomplete match)                     | 1400
     48 // Search Primary Provider (past query in history within 2 days)       | 1399**
     49 // Search Primary Provider (what you typed)                            | 1300
     50 // HistoryURL (what you typed)                                         | 1200
     51 // Extension App (inexact match)                                       | 1175*~
     52 // Keyword (substituting, exact match)                                 | 1100
     53 // Search Primary Provider (past query in history older than 2 days)   | 1050--
     54 // HistoryContents (any match in title of starred page)                | 1000++
     55 // HistoryURL (inexact match)                                          |  900++
     56 // Search Primary Provider (navigational suggestion)                   |  800++
     57 // HistoryContents (any match in title of nonstarred page)             |  700++
     58 // Search Primary Provider (suggestion)                                |  600++
     59 // Built-in                                                            |  575++
     60 // HistoryContents (any match in body of starred page)                 |  550++
     61 // HistoryContents (any match in body of nonstarred page)              |  500++
     62 // Keyword (inexact match)                                             |  450
     63 // Search Secondary Provider (what you typed)                          |  250
     64 // Search Secondary Provider (past query in history)                   |  200--
     65 // Search Secondary Provider (navigational suggestion)                 |  150++
     66 // Search Secondary Provider (suggestion)                              |  100++
     67 //
     68 // REQUESTED_URL input type:
     69 // --------------------------------------------------------------------|-----
     70 // Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
     71 // Extension App (exact match)                                         | 1425
     72 // HistoryURL (exact or inline autocomplete match)                     | 1400
     73 // Search Primary Provider (past query in history within 2 days)       | 1399**
     74 // HistoryURL (what you typed)                                         | 1200
     75 // Extension App (inexact match)                                       | 1175*~
     76 // Search Primary Provider (what you typed)                            | 1150
     77 // Keyword (substituting, exact match)                                 | 1100
     78 // Search Primary Provider (past query in history older than 2 days)   | 1050--
     79 // HistoryContents (any match in title of starred page)                | 1000++
     80 // HistoryURL (inexact match)                                          |  900++
     81 // Search Primary Provider (navigational suggestion)                   |  800++
     82 // HistoryContents (any match in title of nonstarred page)             |  700++
     83 // Search Primary Provider (suggestion)                                |  600++
     84 // Built-in                                                            |  575++
     85 // HistoryContents (any match in body of starred page)                 |  550++
     86 // HistoryContents (any match in body of nonstarred page)              |  500++
     87 // Keyword (inexact match)                                             |  450
     88 // Search Secondary Provider (what you typed)                          |  250
     89 // Search Secondary Provider (past query in history)                   |  200--
     90 // Search Secondary Provider (navigational suggestion)                 |  150++
     91 // Search Secondary Provider (suggestion)                              |  100++
     92 //
     93 // URL input type:
     94 // --------------------------------------------------------------------|-----
     95 // Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
     96 // Extension App (exact match)                                         | 1425
     97 // HistoryURL (exact or inline autocomplete match)                     | 1400
     98 // HistoryURL (what you typed)                                         | 1200
     99 // Extension App (inexact match)                                       | 1175*~
    100 // Keyword (substituting, exact match)                                 | 1100
    101 // HistoryURL (inexact match)                                          |  900++
    102 // Search Primary Provider (what you typed)                            |  850
    103 // Search Primary Provider (navigational suggestion)                   |  800++
    104 // Search Primary Provider (past query in history)                     |  750--
    105 // Keyword (inexact match)                                             |  700
    106 // Built-in                                                            |  575++
    107 // Search Primary Provider (suggestion)                                |  300++
    108 // Search Secondary Provider (what you typed)                          |  250
    109 // Search Secondary Provider (past query in history)                   |  200--
    110 // Search Secondary Provider (navigational suggestion)                 |  150++
    111 // Search Secondary Provider (suggestion)                              |  100++
    112 //
    113 // QUERY input type:
    114 // --------------------------------------------------------------------|-----
    115 // Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
    116 // Keyword (substituting, exact match)                                 | 1450
    117 // Extension App (exact match)                                         | 1425
    118 // HistoryURL (exact or inline autocomplete match)                     | 1400
    119 // Search Primary Provider (past query in history within 2 days)       | 1399**
    120 // Search Primary Provider (what you typed)                            | 1300
    121 // Extension App (inexact match)                                       | 1175*~
    122 // Search Primary Provider (past query in history older than 2 days)   | 1050--
    123 // HistoryContents (any match in title of starred page)                | 1000++
    124 // HistoryURL (inexact match)                                          |  900++
    125 // Search Primary Provider (navigational suggestion)                   |  800++
    126 // HistoryContents (any match in title of nonstarred page)             |  700++
    127 // Search Primary Provider (suggestion)                                |  600++
    128 // HistoryContents (any match in body of starred page)                 |  550++
    129 // HistoryContents (any match in body of nonstarred page)              |  500++
    130 // Keyword (inexact match)                                             |  450
    131 // Search Secondary Provider (what you typed)                          |  250
    132 // Search Secondary Provider (past query in history)                   |  200--
    133 // Search Secondary Provider (navigational suggestion)                 |  150++
    134 // Search Secondary Provider (suggestion)                              |  100++
    135 //
    136 // FORCED_QUERY input type:
    137 // --------------------------------------------------------------------|-----
    138 // Extension App (exact match on title only, not url)                  | 1425
    139 // Search Primary Provider (past query in history within 2 days)       | 1399**
    140 // Search Primary Provider (what you typed)                            | 1300
    141 // Extension App (inexact match on title only, not url)                | 1175*~
    142 // Search Primary Provider (past query in history older than 2 days)   | 1050--
    143 // HistoryContents (any match in title of starred page)                | 1000++
    144 // Search Primary Provider (navigational suggestion)                   |  800++
    145 // HistoryContents (any match in title of nonstarred page)             |  700++
    146 // Search Primary Provider (suggestion)                                |  600++
    147 // HistoryContents (any match in body of starred page)                 |  550++
    148 // HistoryContents (any match in body of nonstarred page)              |  500++
    149 //
    150 // (A search keyword is a keyword with a replacement string; a bookmark keyword
    151 // is a keyword with no replacement string, that is, a shortcut for a URL.)
    152 //
    153 // There are two possible providers for search suggestions. If the user has
    154 // typed a keyword, then the primary provider is the keyword provider and the
    155 // secondary provider is the default provider. If the user has not typed a
    156 // keyword, then the primary provider corresponds to the default provider.
    157 //
    158 // The value column gives the ranking returned from the various providers.
    159 // ++: a series of matches with relevance from n up to (n + max_matches).
    160 // --: relevance score falls off over time (discounted 50 points @ 15 minutes,
    161 //     450 points @ two weeks)
    162 // **: relevance score falls off over two days (discounted 99 points after two
    163 //     days).
    164 // *~: Partial matches get a score on a sliding scale from about 575-1125 based
    165 //     on how many times the URL for the Extension App has been typed and how
    166 //     many of the letters match.
    167 
    168 class AutocompleteController;
    169 class AutocompleteControllerDelegate;
    170 class AutocompleteInput;
    171 struct AutocompleteMatch;
    172 class AutocompleteProvider;
    173 class AutocompleteResult;
    174 class HistoryContentsProvider;
    175 class Profile;
    176 class SearchProvider;
    177 class TemplateURL;
    178 
    179 typedef std::vector<AutocompleteMatch> ACMatches;
    180 typedef std::vector<AutocompleteProvider*> ACProviders;
    181 
    182 // AutocompleteInput ----------------------------------------------------------
    183 
    184 // The user input for an autocomplete query.  Allows copying.
    185 class AutocompleteInput {
    186  public:
    187   // Note that the type below may be misleading.  For example, "http:/" alone
    188   // cannot be opened as a URL, so it is marked as a QUERY; yet the user
    189   // probably intends to type more and have it eventually become a URL, so we
    190   // need to make sure we still run it through inline autocomplete.
    191   enum Type {
    192     INVALID,        // Empty input
    193     UNKNOWN,        // Valid input whose type cannot be determined
    194     REQUESTED_URL,  // Input autodetected as UNKNOWN, which the user wants to
    195                     // treat as an URL by specifying a desired_tld
    196     URL,            // Input autodetected as a URL
    197     QUERY,          // Input autodetected as a query
    198     FORCED_QUERY,   // Input forced to be a query by an initial '?'
    199   };
    200 
    201   // Enumeration of the possible match query types. Callers who only need some
    202   // of the matches for a particular input can get answers more quickly by
    203   // specifying that upfront.
    204   enum MatchesRequested {
    205     // Only the best match in the whole result set matters.  Providers should at
    206     // most return synchronously-available matches, and if possible do even less
    207     // work, so that it's safe to ask for these repeatedly in the course of one
    208     // higher-level "synchronous" query.
    209     BEST_MATCH,
    210 
    211     // Only synchronous matches should be returned.
    212     SYNCHRONOUS_MATCHES,
    213 
    214     // All matches should be fetched.
    215     ALL_MATCHES,
    216   };
    217 
    218   AutocompleteInput();
    219   AutocompleteInput(const string16& text,
    220                     const string16& desired_tld,
    221                     bool prevent_inline_autocomplete,
    222                     bool prefer_keyword,
    223                     bool allow_exact_keyword_match,
    224                     MatchesRequested matches_requested);
    225   ~AutocompleteInput();
    226 
    227   // If type is |FORCED_QUERY| and |text| starts with '?', it is removed.
    228   static void RemoveForcedQueryStringIfNecessary(Type type, string16* text);
    229 
    230   // Converts |type| to a string representation.  Used in logging.
    231   static std::string TypeToString(Type type);
    232 
    233   // Parses |text| and returns the type of input this will be interpreted as.
    234   // The components of the input are stored in the output parameter |parts|, if
    235   // it is non-NULL. The scheme is stored in |scheme| if it is non-NULL. The
    236   // canonicalized URL is stored in |canonicalized_url|; however, this URL is
    237   // not guaranteed to be valid, especially if the parsed type is, e.g., QUERY.
    238   static Type Parse(const string16& text,
    239                     const string16& desired_tld,
    240                     url_parse::Parsed* parts,
    241                     string16* scheme,
    242                     GURL* canonicalized_url);
    243 
    244   // Parses |text| and fill |scheme| and |host| by the positions of them.
    245   // The results are almost as same as the result of Parse(), but if the scheme
    246   // is view-source, this function returns the positions of scheme and host
    247   // in the URL qualified by "view-source:" prefix.
    248   static void ParseForEmphasizeComponents(const string16& text,
    249                                           const string16& desired_tld,
    250                                           url_parse::Component* scheme,
    251                                           url_parse::Component* host);
    252 
    253   // Code that wants to format URLs with a format flag including
    254   // net::kFormatUrlOmitTrailingSlashOnBareHostname risk changing the meaning if
    255   // the result is then parsed as AutocompleteInput.  Such code can call this
    256   // function with the URL and its formatted string, and it will return a
    257   // formatted string with the same meaning as the original URL (i.e. it will
    258   // re-append a slash if necessary).
    259   static string16 FormattedStringWithEquivalentMeaning(
    260       const GURL& url,
    261       const string16& formatted_url);
    262 
    263   // User-provided text to be completed.
    264   const string16& text() const { return text_; }
    265 
    266   // Use of this setter is risky, since no other internal state is updated
    267   // besides |text_|.  Only callers who know that they're not changing the
    268   // type/scheme/etc. should use this.
    269   void set_text(const string16& text) { text_ = text; }
    270 
    271   // The text supplied to the constructor. This differs from |text| if the text
    272   // supplied to the constructor had leading or trailing white space.
    273   const string16& original_text() const { return original_text_; }
    274 
    275   // User's desired TLD, if one is not already present in the text to
    276   // autocomplete.  When this is non-empty, it also implies that "www." should
    277   // be prepended to the domain where possible.  This should not have a leading
    278   // '.' (use "com" instead of ".com").
    279   const string16& desired_tld() const { return desired_tld_; }
    280 
    281   // The type of input supplied.
    282   Type type() const { return type_; }
    283 
    284   // Returns parsed URL components.
    285   const url_parse::Parsed& parts() const { return parts_; }
    286 
    287   // The scheme parsed from the provided text; only meaningful when type_ is
    288   // URL.
    289   const string16& scheme() const { return scheme_; }
    290 
    291   // The input as an URL to navigate to, if possible.
    292   const GURL& canonicalized_url() const { return canonicalized_url_; }
    293 
    294   // Returns whether inline autocompletion should be prevented.
    295   bool prevent_inline_autocomplete() const {
    296     return prevent_inline_autocomplete_;
    297   }
    298 
    299   // Returns the value of |prevent_inline_autocomplete| supplied to the
    300   // constructor. This differs from the value returned by
    301   // |prevent_inline_autocomplete()| if the input contained trailing whitespace.
    302   bool initial_prevent_inline_autocomplete() const {
    303     return initial_prevent_inline_autocomplete_;
    304   }
    305 
    306   // Returns whether, given an input string consisting solely of a substituting
    307   // keyword, we should score it like a non-substituting keyword.
    308   bool prefer_keyword() const { return prefer_keyword_; }
    309 
    310   // Returns whether this input is allowed to be treated as an exact
    311   // keyword match.  If not, the default result is guaranteed not to be a
    312   // keyword search, even if the input is "<keyword> <search string>".
    313   bool allow_exact_keyword_match() const { return allow_exact_keyword_match_; }
    314 
    315   // See description of enum for details.
    316   MatchesRequested matches_requested() const { return matches_requested_; }
    317 
    318   // operator==() by another name.
    319   bool Equals(const AutocompleteInput& other) const;
    320 
    321   // Resets all internal variables to the null-constructed state.
    322   void Clear();
    323 
    324  private:
    325   string16 text_;
    326   string16 original_text_;
    327   string16 desired_tld_;
    328   Type type_;
    329   url_parse::Parsed parts_;
    330   string16 scheme_;
    331   GURL canonicalized_url_;
    332   bool initial_prevent_inline_autocomplete_;
    333   bool prevent_inline_autocomplete_;
    334   bool prefer_keyword_;
    335   bool allow_exact_keyword_match_;
    336   MatchesRequested matches_requested_;
    337 };
    338 
    339 // AutocompleteProvider -------------------------------------------------------
    340 
    341 // A single result provider for the autocomplete system.  Given user input, the
    342 // provider decides what (if any) matches to return, their relevance, and their
    343 // classifications.
    344 class AutocompleteProvider
    345     : public base::RefCountedThreadSafe<AutocompleteProvider> {
    346  public:
    347   class ACProviderListener {
    348    public:
    349     // Called by a provider as a notification that something has changed.
    350     // |updated_matches| should be true iff the matches have changed in some
    351     // way (they may not have changed if, for example, the provider did an
    352     // asynchronous query to get more matches, came up with none, and is now
    353     // giving up).
    354     //
    355     // NOTE: Providers MUST only call this method while processing asynchronous
    356     // queries.  Do not call this for a synchronous query.
    357     //
    358     // NOTE: There's no parameter to tell the listener _which_ provider is
    359     // calling it.  Because the AutocompleteController (the typical listener)
    360     // doesn't cache the providers' individual matches locally, it has to get
    361     // them all again when this is called anyway, so such a parameter wouldn't
    362     // actually be useful.
    363     virtual void OnProviderUpdate(bool updated_matches) = 0;
    364 
    365    protected:
    366     virtual ~ACProviderListener();
    367   };
    368 
    369   AutocompleteProvider(ACProviderListener* listener,
    370                        Profile* profile,
    371                        const char* name);
    372 
    373   // Invoked when the profile changes.
    374   // NOTE: Do not access any previous Profile* at this point as it may have
    375   // already been deleted.
    376   void SetProfile(Profile* profile);
    377 
    378   // Called to start an autocomplete query.  The provider is responsible for
    379   // tracking its matches for this query and whether it is done processing the
    380   // query.  When new matches are available or the provider finishes, it
    381   // calls the controller's OnProviderUpdate() method.  The controller can then
    382   // get the new matches using the provider's accessors.
    383   // Exception: Matches available immediately after starting the query (that
    384   // is, synchronously) do not cause any notifications to be sent.  The
    385   // controller is expected to check for these without prompting (since
    386   // otherwise, starting each provider running would result in a flurry of
    387   // notifications).
    388   //
    389   // Once Stop() has been called, no more notifications should be sent.
    390   //
    391   // |minimal_changes| is an optimization that lets the provider do less work
    392   // when the |input|'s text hasn't changed.  See the body of
    393   // AutocompletePopupModel::StartAutocomplete().
    394   virtual void Start(const AutocompleteInput& input,
    395                      bool minimal_changes) = 0;
    396 
    397   // Called when a provider must not make any more callbacks for the current
    398   // query. This will be called regardless of whether the provider is already
    399   // done.
    400   virtual void Stop();
    401 
    402   // Returns the set of matches for the current query.
    403   const ACMatches& matches() const { return matches_; }
    404 
    405   // Returns whether the provider is done processing the query.
    406   bool done() const { return done_; }
    407 
    408   // Returns the name of this provider.
    409   const char* name() const { return name_; }
    410 
    411   // Called to delete a match and the backing data that produced it.  This
    412   // match should not appear again in this or future queries.  This can only be
    413   // called for matches the provider marks as deletable.  This should only be
    414   // called when no query is running.
    415   // NOTE: Remember to call OnProviderUpdate() if matches_ is updated.
    416   virtual void DeleteMatch(const AutocompleteMatch& match);
    417 
    418   // A suggested upper bound for how many matches a provider should return.
    419   // TODO(pkasting): http://b/1111299 , http://b/933133 This should go away once
    420   // we have good relevance heuristics; the controller should handle all
    421   // culling.
    422   static const size_t kMaxMatches;
    423 
    424  protected:
    425   friend class base::RefCountedThreadSafe<AutocompleteProvider>;
    426 
    427   virtual ~AutocompleteProvider();
    428 
    429   // Returns whether |input| begins "http:" or "view-source:http:".
    430   static bool HasHTTPScheme(const string16& input);
    431 
    432   // Updates the starred state of each of the matches in matches_ from the
    433   // profile's bookmark bar model.
    434   void UpdateStarredStateOfMatches();
    435 
    436   // A convenience function to call net::FormatUrl() with the current set of
    437   // "Accept Languages" when check_accept_lang is true.  Otherwise, it's called
    438   // with an empty list.
    439   string16 StringForURLDisplay(const GURL& url,
    440                                bool check_accept_lang,
    441                                bool trim_http) const;
    442 
    443   // The profile associated with the AutocompleteProvider.  Reference is not
    444   // owned by us.
    445   Profile* profile_;
    446 
    447   ACProviderListener* listener_;
    448   ACMatches matches_;
    449   bool done_;
    450 
    451   // The name of this provider.  Used for logging.
    452   const char* name_;
    453 
    454  private:
    455   DISALLOW_COPY_AND_ASSIGN(AutocompleteProvider);
    456 };
    457 
    458 typedef AutocompleteProvider::ACProviderListener ACProviderListener;
    459 
    460 // AutocompleteResult ---------------------------------------------------------
    461 
    462 // All matches from all providers for a particular query.  This also tracks
    463 // what the default match should be if the user doesn't manually select another
    464 // match.
    465 class AutocompleteResult {
    466  public:
    467   typedef ACMatches::const_iterator const_iterator;
    468   typedef ACMatches::iterator iterator;
    469 
    470   // The "Selection" struct is the information we need to select the same match
    471   // in one result set that was selected in another.
    472   struct Selection {
    473     Selection()
    474         : provider_affinity(NULL),
    475           is_history_what_you_typed_match(false) {
    476     }
    477 
    478     // Clear the selection entirely.
    479     void Clear();
    480 
    481     // True when the selection is empty.
    482     bool empty() const {
    483       return destination_url.is_empty() && !provider_affinity &&
    484           !is_history_what_you_typed_match;
    485     }
    486 
    487     // The desired destination URL.
    488     GURL destination_url;
    489 
    490     // The desired provider.  If we can't find a match with the specified
    491     // |destination_url|, we'll use the best match from this provider.
    492     const AutocompleteProvider* provider_affinity;
    493 
    494     // True when this is the HistoryURLProvider's "what you typed" match.  This
    495     // can't be tracked using |destination_url| because its URL changes on every
    496     // keystroke, so if this is set, we'll preserve the selection by simply
    497     // choosing the new "what you typed" entry and ignoring |destination_url|.
    498     bool is_history_what_you_typed_match;
    499   };
    500 
    501   AutocompleteResult();
    502   ~AutocompleteResult();
    503 
    504   // operator=() by another name.
    505   void CopyFrom(const AutocompleteResult& rhs);
    506 
    507   // Copies matches from |old_matches| to provide a consistant result set. See
    508   // comments in code for specifics.
    509   void CopyOldMatches(const AutocompleteInput& input,
    510                       const AutocompleteResult& old_matches);
    511 
    512   // Adds a single match. The match is inserted at the appropriate position
    513   // based on relevancy and display order. This is ONLY for use after
    514   // SortAndCull() has been invoked, and preserves default_match_.
    515   void AddMatch(const AutocompleteMatch& match);
    516 
    517   // Adds a new set of matches to the result set.  Does not re-sort.
    518   void AppendMatches(const ACMatches& matches);
    519 
    520   // Removes duplicates, puts the list in sorted order and culls to leave only
    521   // the best kMaxMatches matches.  Sets the default match to the best match
    522   // and updates the alternate nav URL.
    523   void SortAndCull(const AutocompleteInput& input);
    524 
    525   // Returns true if at least one match was copied from the last result.
    526   bool HasCopiedMatches() const;
    527 
    528   // Vector-style accessors/operators.
    529   size_t size() const;
    530   bool empty() const;
    531   const_iterator begin() const;
    532   iterator begin();
    533   const_iterator end() const;
    534   iterator end();
    535 
    536   // Returns the match at the given index.
    537   const AutocompleteMatch& match_at(size_t index) const;
    538 
    539   // Get the default match for the query (not necessarily the first).  Returns
    540   // end() if there is no default match.
    541   const_iterator default_match() const { return default_match_; }
    542 
    543   GURL alternate_nav_url() const { return alternate_nav_url_; }
    544 
    545   // Clears the matches for this result set.
    546   void Reset();
    547 
    548   void Swap(AutocompleteResult* other);
    549 
    550 #ifndef NDEBUG
    551   // Does a data integrity check on this result.
    552   void Validate() const;
    553 #endif
    554 
    555   // Max number of matches we'll show from the various providers.
    556   static const size_t kMaxMatches;
    557 
    558  private:
    559   typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches;
    560 
    561   // Populates |provider_to_matches| from |matches_|.
    562   void BuildProviderToMatches(ProviderToMatches* provider_to_matches) const;
    563 
    564   // Returns true if |matches| contains a match with the same destination as
    565   // |match|.
    566   static bool HasMatchByDestination(const AutocompleteMatch& match,
    567                                     const ACMatches& matches);
    568 
    569   // Copies matches into this result. |old_matches| gives the matches from the
    570   // last result, and |new_matches| the results from this result.
    571   void MergeMatchesByProvider(const ACMatches& old_matches,
    572                               const ACMatches& new_matches);
    573 
    574   ACMatches matches_;
    575 
    576   const_iterator default_match_;
    577 
    578   // The "alternate navigation URL", if any, for this result set.  This is a URL
    579   // to try offering as a navigational option in case the user navigated to the
    580   // URL of the default match but intended something else.  For example, if the
    581   // user's local intranet contains site "foo", and the user types "foo", we
    582   // default to searching for "foo" when the user may have meant to navigate
    583   // there.  In cases like this, the default match will point to the "search for
    584   // 'foo'" result, and this will contain "http://foo/".
    585   GURL alternate_nav_url_;
    586 
    587   DISALLOW_COPY_AND_ASSIGN(AutocompleteResult);
    588 };
    589 
    590 // AutocompleteController -----------------------------------------------------
    591 
    592 // The coordinator for autocomplete queries, responsible for combining the
    593 // matches from a series of providers into one AutocompleteResult.
    594 class AutocompleteController : public ACProviderListener {
    595  public:
    596   // Used to indicate an index that is not selected in a call to Update().
    597   static const int kNoItemSelected;
    598 
    599   // Normally, you will call the first constructor.  Unit tests can use the
    600   // second to set the providers to some known testing providers.  The default
    601   // providers will be overridden and the controller will take ownership of the
    602   // providers, Release()ing them on destruction.
    603   AutocompleteController(Profile* profile,
    604                          AutocompleteControllerDelegate* delegate);
    605 #ifdef UNIT_TEST
    606   explicit AutocompleteController(const ACProviders& providers)
    607       : delegate_(NULL),
    608         providers_(providers),
    609         search_provider_(NULL),
    610         done_(true),
    611         in_start_(false) {
    612   }
    613 #endif
    614   ~AutocompleteController();
    615 
    616   // Invoked when the profile changes. This forwards the call down to all
    617   // the AutocompleteProviders.
    618   void SetProfile(Profile* profile);
    619 
    620   // Starts an autocomplete query, which continues until all providers are
    621   // done or the query is Stop()ed.  It is safe to Start() a new query without
    622   // Stop()ing the previous one.
    623   //
    624   // See AutocompleteInput::desired_tld() for meaning of |desired_tld|.
    625   //
    626   // |prevent_inline_autocomplete| is true if the generated result set should
    627   // not require inline autocomplete for the default match.  This is difficult
    628   // to explain in the abstract; the practical use case is that after the user
    629   // deletes text in the edit, the HistoryURLProvider should make sure not to
    630   // promote a match requiring inline autocomplete too highly.
    631   //
    632   // |prefer_keyword| should be true when the keyword UI is onscreen; this will
    633   // bias the autocomplete result set toward the keyword provider when the input
    634   // string is a bare keyword.
    635   //
    636   // |allow_exact_keyword_match| should be false when triggering keyword mode on
    637   // the input string would be surprising or wrong, e.g. when highlighting text
    638   // in a page and telling the browser to search for it or navigate to it. This
    639   // parameter only applies to substituting keywords.
    640 
    641   // If |matches_requested| is BEST_MATCH or SYNCHRONOUS_MATCHES the controller
    642   // asks the providers to only return matches which are synchronously
    643   // available, which should mean that all providers will be done immediately.
    644   //
    645   // The controller calls AutocompleteControllerDelegate::OnResultChanged() from
    646   // inside this call at least once. If matches are available later on that
    647   // result in changing the result set the delegate is notified again. When the
    648   // controller is done the notification AUTOCOMPLETE_CONTROLLER_RESULT_READY is
    649   // sent.
    650   void Start(const string16& text,
    651              const string16& desired_tld,
    652              bool prevent_inline_autocomplete,
    653              bool prefer_keyword,
    654              bool allow_exact_keyword_match,
    655              AutocompleteInput::MatchesRequested matches_requested);
    656 
    657   // Cancels the current query, ensuring there will be no future notifications
    658   // fired.  If new matches have come in since the most recent notification was
    659   // fired, they will be discarded.
    660   //
    661   // If |clear_result| is true, the controller will also erase the result set.
    662   void Stop(bool clear_result);
    663 
    664   // Asks the relevant provider to delete |match|, and ensures observers are
    665   // notified of resulting changes immediately.  This should only be called when
    666   // no query is running.
    667   void DeleteMatch(const AutocompleteMatch& match);
    668 
    669   // Removes any entries that were copied from the last result. This is used by
    670   // the popup to ensure it's not showing an out-of-date query.
    671   void ExpireCopiedEntries();
    672 
    673   SearchProvider* search_provider() const { return search_provider_; }
    674 
    675   // Getters
    676   const AutocompleteInput& input() const { return input_; }
    677   const AutocompleteResult& result() const { return result_; }
    678   bool done() const { return done_; }
    679 
    680   // From AutocompleteProvider::Listener
    681   virtual void OnProviderUpdate(bool updated_matches);
    682 
    683  private:
    684   // Updates |result_| to reflect the current provider state.  Resets timers and
    685   // fires notifications as necessary.  |is_synchronous_pass| is true only when
    686   // Start() is calling this to get the synchronous result.
    687   void UpdateResult(bool is_synchronous_pass);
    688 
    689   // Calls AutocompleteControllerDelegate::OnResultChanged() and if done sends
    690   // AUTOCOMPLETE_CONTROLLER_RESULT_READY.
    691   void NotifyChanged(bool notify_default_match);
    692 
    693   // Updates |done_| to be accurate with respect to current providers' statuses.
    694   void CheckIfDone();
    695 
    696   // Starts the expire timer.
    697   void StartExpireTimer();
    698 
    699   AutocompleteControllerDelegate* delegate_;
    700 
    701   // A list of all providers.
    702   ACProviders providers_;
    703 
    704   SearchProvider* search_provider_;
    705 
    706   // Input passed to Start.
    707   AutocompleteInput input_;
    708 
    709   // Data from the autocomplete query.
    710   AutocompleteResult result_;
    711 
    712   // Timer used to remove any matches copied from the last result. When run
    713   // invokes |ExpireCopiedEntries|.
    714   base::OneShotTimer<AutocompleteController> expire_timer_;
    715 
    716   // True if a query is not currently running.
    717   bool done_;
    718 
    719   // Are we in Start()? This is used to avoid updating |result_| and sending
    720   // notifications until Start() has been invoked on all providers.
    721   bool in_start_;
    722 
    723   DISALLOW_COPY_AND_ASSIGN(AutocompleteController);
    724 };
    725 
    726 // AutocompleteLog ------------------------------------------------------------
    727 
    728 // The data to log (via the metrics service) when the user selects an item
    729 // from the omnibox popup.
    730 struct AutocompleteLog {
    731   AutocompleteLog(const string16& text,
    732                   AutocompleteInput::Type input_type,
    733                   size_t selected_index,
    734                   size_t inline_autocompleted_length,
    735                   const AutocompleteResult& result)
    736       : text(text),
    737         input_type(input_type),
    738         selected_index(selected_index),
    739         inline_autocompleted_length(inline_autocompleted_length),
    740         result(result) {
    741   }
    742   // The user's input text in the omnibox.
    743   string16 text;
    744   // The detected type of the user's input.
    745   AutocompleteInput::Type input_type;
    746   // Selected index (if selected) or -1 (AutocompletePopupModel::kNoMatch).
    747   size_t selected_index;
    748   // Inline autocompleted length (if displayed).
    749   size_t inline_autocompleted_length;
    750   // Result set.
    751   const AutocompleteResult& result;
    752 };
    753 
    754 #endif  // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_
    755