• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
text()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.
set_text(const string16 & text)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.
original_text()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").
desired_tld()279   const string16& desired_tld() const { return desired_tld_; }
280 
281   // The type of input supplied.
type()282   Type type() const { return type_; }
283 
284   // Returns parsed URL components.
parts()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.
scheme()289   const string16& scheme() const { return scheme_; }
290 
291   // The input as an URL to navigate to, if possible.
canonicalized_url()292   const GURL& canonicalized_url() const { return canonicalized_url_; }
293 
294   // Returns whether inline autocompletion should be prevented.
prevent_inline_autocomplete()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.
initial_prevent_inline_autocomplete()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.
prefer_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>".
allow_exact_keyword_match()313   bool allow_exact_keyword_match() const { return allow_exact_keyword_match_; }
314 
315   // See description of enum for details.
matches_requested()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.
matches()403   const ACMatches& matches() const { return matches_; }
404 
405   // Returns whether the provider is done processing the query.
done()406   bool done() const { return done_; }
407 
408   // Returns the name of this provider.
name()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 {
SelectionSelection473     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.
emptySelection482     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.
default_match()541   const_iterator default_match() const { return default_match_; }
542 
alternate_nav_url()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
AutocompleteController(const ACProviders & providers)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 
search_provider()673   SearchProvider* search_provider() const { return search_provider_; }
674 
675   // Getters
input()676   const AutocompleteInput& input() const { return input_; }
result()677   const AutocompleteResult& result() const { return result_; }
done()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 {
AutocompleteLogAutocompleteLog731   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