autocomplete.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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 <string>
10#include <vector>
11
12#include "base/logging.h"
13#include "base/ref_counted.h"
14#include "base/timer.h"
15#include "chrome/common/page_transition_types.h"
16#include "googleurl/src/gurl.h"
17#include "googleurl/src/url_parse.h"
18
19// The AutocompleteController is the center of the autocomplete system.  A
20// class creates an instance of the controller, which in turn creates a set of
21// AutocompleteProviders to serve it.  The owning class can ask the controller
22// to Start() a query; the controller in turn passes this call down to the
23// providers, each of which keeps track of its own matches and whether it has
24// finished processing the query.  When a provider gets more matches or finishes
25// processing, it notifies the controller, which merges the combined matches
26// together and makes the result available to interested observers.
27//
28// The owner may also cancel the current query by calling Stop(), which the
29// controller will in turn communicate to all the providers.  No callbacks will
30// happen after a request has been stopped.
31//
32// IMPORTANT: There is NO THREAD SAFETY built into this portion of the
33// autocomplete system.  All calls to and from the AutocompleteController should
34// happen on the same thread.  AutocompleteProviders are responsible for doing
35// their own thread management when they need to return matches asynchronously.
36//
37// The AutocompleteProviders each return different kinds of matches, such as
38// history or search matches.  These matches are given "relevance" scores.
39// Higher scores are better matches than lower scores.  The relevance scores and
40// classes providing the respective matches are as follows:
41//
42// UNKNOWN input type:
43// --------------------------------------------------------------------|-----
44// Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
45// HistoryURL (exact or inline autocomplete match)                     | 1400
46// Search Primary Provider (what you typed)                            | 1300
47// HistoryURL (what you typed)                                         | 1200
48// Keyword (substituting, exact match)                                 | 1100
49// Search Primary Provider (past query in history)                     | 1050--
50// HistoryContents (any match in title of starred page)                | 1000++
51// HistoryURL (inexact match)                                          |  900++
52// Search Primary Provider (navigational suggestion)                   |  800++
53// HistoryContents (any match in title of nonstarred page)             |  700++
54// Search Primary Provider (suggestion)                                |  600++
55// HistoryContents (any match in body of starred page)                 |  550++
56// HistoryContents (any match in body of nonstarred page)              |  500++
57// Keyword (inexact match)                                             |  450
58// Search Secondary Provider (what you typed)                          |  250
59// Search Secondary Provider (past query in history)                   |  200--
60// Search Secondary Provider (navigational suggestion)                 |  150++
61// Search Secondary Provider (suggestion)                              |  100++
62//
63// REQUESTED_URL input type:
64// --------------------------------------------------------------------|-----
65// Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
66// HistoryURL (exact or inline autocomplete match)                     | 1400
67// HistoryURL (what you typed)                                         | 1200
68// Search Primary Provider (what you typed)                            | 1150
69// Keyword (substituting, exact match)                                 | 1100
70// Search Primary Provider (past query in history)                     | 1050--
71// HistoryContents (any match in title of starred page)                | 1000++
72// HistoryURL (inexact match)                                          |  900++
73// Search Primary Provider (navigational suggestion)                   |  800++
74// HistoryContents (any match in title of nonstarred page)             |  700++
75// Search Primary Provider (suggestion)                                |  600++
76// HistoryContents (any match in body of starred page)                 |  550++
77// HistoryContents (any match in body of nonstarred page)              |  500++
78// Keyword (inexact match)                                             |  450
79// Search Secondary Provider (what you typed)                          |  250
80// Search Secondary Provider (past query in history)                   |  200--
81// Search Secondary Provider (navigational suggestion)                 |  150++
82// Search Secondary Provider (suggestion)                              |  100++
83//
84// URL input type:
85// --------------------------------------------------------------------|-----
86// Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
87// HistoryURL (exact or inline autocomplete match)                     | 1400
88// HistoryURL (what you typed)                                         | 1200
89// Keyword (substituting, exact match)                                 | 1100
90// HistoryURL (inexact match)                                          |  900++
91// Search Primary Provider (what you typed)                            |  850
92// Search Primary Provider (navigational suggestion)                   |  800++
93// Search Primary Provider (past query in history)                     |  750--
94// Keyword (inexact match)                                             |  700
95// Search Primary Provider (suggestion)                                |  300++
96// Search Secondary Provider (what you typed)                          |  250
97// Search Secondary Provider (past query in history)                   |  200--
98// Search Secondary Provider (navigational suggestion)                 |  150++
99// Search Secondary Provider (suggestion)                              |  100++
100//
101// QUERY input type:
102// --------------------------------------------------------------------|-----
103// Keyword (non-substituting or in keyword UI mode, exact match)       | 1500
104// Keyword (substituting, exact match)                                 | 1450
105// HistoryURL (exact or inline autocomplete match)                     | 1400
106// Search Primary Provider (what you typed)                            | 1300
107// Search Primary Provider (past query in history)                     | 1050--
108// HistoryContents (any match in title of starred page)                | 1000++
109// HistoryURL (inexact match)                                          |  900++
110// Search Primary Provider (navigational suggestion)                   |  800++
111// HistoryContents (any match in title of nonstarred page)             |  700++
112// Search Primary Provider (suggestion)                                |  600++
113// HistoryContents (any match in body of starred page)                 |  550++
114// HistoryContents (any match in body of nonstarred page)              |  500++
115// Keyword (inexact match)                                             |  450
116// Search Secondary Provider (what you typed)                          |  250
117// Search Secondary Provider (past query in history)                   |  200--
118// Search Secondary Provider (navigational suggestion)                 |  150++
119// Search Secondary Provider (suggestion)                              |  100++
120//
121// FORCED_QUERY input type:
122// --------------------------------------------------------------------|-----
123// Search Primary Provider (what you typed)                            | 1300
124// Search Primary Provider (past query in history)                     | 1050--
125// HistoryContents (any match in title of starred page)                | 1000++
126// Search Primary Provider (navigational suggestion)                   |  800++
127// HistoryContents (any match in title of nonstarred page)             |  700++
128// Search Primary Provider (suggestion)                                |  600++
129// HistoryContents (any match in body of starred page)                 |  550++
130// HistoryContents (any match in body of nonstarred page)              |  500++
131//
132// (A search keyword is a keyword with a replacement string; a bookmark keyword
133// is a keyword with no replacement string, that is, a shortcut for a URL.)
134//
135// There are two possible providers for search suggestions. If the user has
136// typed a keyword, then the primary provider is the keyword provider and the
137// secondary provider is the default provider. If the user has not typed a
138// keyword, then the primary provider corresponds to the default provider.
139//
140// The value column gives the ranking returned from the various providers.
141// ++: a series of matches with relevance from n up to (n + max_matches).
142// --: relevance score falls off over time (discounted 50 points @ 15 minutes,
143//     450 points @ two weeks)
144
145class AutocompleteInput;
146struct AutocompleteMatch;
147class AutocompleteProvider;
148class AutocompleteResult;
149class AutocompleteController;
150class HistoryContentsProvider;
151class Profile;
152class TemplateURL;
153
154typedef std::vector<AutocompleteMatch> ACMatches;
155typedef std::vector<AutocompleteProvider*> ACProviders;
156
157// AutocompleteInput ----------------------------------------------------------
158
159// The user input for an autocomplete query.  Allows copying.
160class AutocompleteInput {
161 public:
162  // Note that the type below may be misleading.  For example, "http:/" alone
163  // cannot be opened as a URL, so it is marked as a QUERY; yet the user
164  // probably intends to type more and have it eventually become a URL, so we
165  // need to make sure we still run it through inline autocomplete.
166  enum Type {
167    INVALID,        // Empty input
168    UNKNOWN,        // Valid input whose type cannot be determined
169    REQUESTED_URL,  // Input autodetected as UNKNOWN, which the user wants to
170                    // treat as an URL by specifying a desired_tld
171    URL,            // Input autodetected as a URL
172    QUERY,          // Input autodetected as a query
173    FORCED_QUERY,   // Input forced to be a query by an initial '?'
174  };
175
176  AutocompleteInput();
177  AutocompleteInput(const std::wstring& text,
178                    const std::wstring& desired_tld,
179                    bool prevent_inline_autocomplete,
180                    bool prefer_keyword,
181                    bool synchronous_only);
182  ~AutocompleteInput();
183
184  // Converts |type| to a string representation.  Used in logging.
185  static std::string TypeToString(Type type);
186
187  // Parses |text| and returns the type of input this will be interpreted as.
188  // The components of the input are stored in the output parameter |parts|, if
189  // it is non-NULL.
190  static Type Parse(const std::wstring& text,
191                    const std::wstring& desired_tld,
192                    url_parse::Parsed* parts,
193                    std::wstring* scheme);
194
195  // Parses |text| and fill |scheme| and |host| by the positions of them.
196  // The results are almost as same as the result of Parse(), but if the scheme
197  // is view-source, this function returns the positions of scheme and host
198  // in the URL qualified by "view-source:" prefix.
199  static void ParseForEmphasizeComponents(const std::wstring& text,
200                                          const std::wstring& desired_tld,
201                                          url_parse::Component* scheme,
202                                          url_parse::Component* host);
203
204  // Code that wants to format URLs with a format flag including
205  // net::kFormatUrlOmitTrailingSlashOnBareHostname risk changing the meaning if
206  // the result is then parsed as AutocompleteInput.  Such code can call this
207  // function with the URL and its formatted string, and it will return a
208  // formatted string with the same meaning as the original URL (i.e. it will
209  // re-append a slash if necessary).
210  static std::wstring FormattedStringWithEquivalentMeaning(
211      const GURL& url,
212      const std::wstring& formatted_url);
213
214  // User-provided text to be completed.
215  const std::wstring& text() const { return text_; }
216
217  // Use of this setter is risky, since no other internal state is updated
218  // besides |text_|.  Only callers who know that they're not changing the
219  // type/scheme/etc. should use this.
220  void set_text(const std::wstring& text) { text_ = text; }
221
222  // User's desired TLD, if one is not already present in the text to
223  // autocomplete.  When this is non-empty, it also implies that "www." should
224  // be prepended to the domain where possible.  This should not have a leading
225  // '.' (use "com" instead of ".com").
226  const std::wstring& desired_tld() const { return desired_tld_; }
227
228  // The type of input supplied.
229  Type type() const { return type_; }
230
231  // Returns parsed URL components.
232  const url_parse::Parsed& parts() const { return parts_; }
233
234  // The scheme parsed from the provided text; only meaningful when type_ is
235  // URL.
236  const std::wstring& scheme() const { return scheme_; }
237
238  // The input as an URL to navigate to, if possible.
239  const GURL& canonicalized_url() const { return canonicalized_url_; }
240
241  // Returns whether inline autocompletion should be prevented.
242  bool prevent_inline_autocomplete() const {
243    return prevent_inline_autocomplete_;
244  }
245
246  // Returns whether, given an input string consisting solely of a substituting
247  // keyword, we should score it like a non-substituting keyword.
248  bool prefer_keyword() const { return prefer_keyword_; }
249
250  // Returns whether providers should avoid scheduling asynchronous work.  If
251  // this is true, providers should stop after returning all the
252  // synchronously-available matches.  This also means any in-progress
253  // asynchronous work should be canceled, so no later callbacks are fired.
254  bool synchronous_only() const { return synchronous_only_; }
255
256  // operator==() by another name.
257  bool Equals(const AutocompleteInput& other) const;
258
259  // Resets all internal variables to the null-constructed state.
260  void Clear();
261
262 private:
263  std::wstring text_;
264  std::wstring desired_tld_;
265  Type type_;
266  url_parse::Parsed parts_;
267  std::wstring scheme_;
268  GURL canonicalized_url_;
269  bool prevent_inline_autocomplete_;
270  bool prefer_keyword_;
271  bool synchronous_only_;
272};
273
274// AutocompleteMatch ----------------------------------------------------------
275
276// A single result line with classified spans.  The autocomplete popup displays
277// the 'contents' and the 'description' (the description is optional) in the
278// autocomplete dropdown, and fills in 'fill_into_edit' into the textbox when
279// that line is selected.  fill_into_edit may be the same as 'description' for
280// things like URLs, but may be different for searches or other providers.  For
281// example, a search result may say "Search for asdf" as the description, but
282// "asdf" should appear in the box.
283struct AutocompleteMatch {
284  // Autocomplete matches contain strings that are classified according to a
285  // separate vector of styles.  This vector associates flags with particular
286  // string segments, and must be in sorted order.  All text must be associated
287  // with some kind of classification.  Even if a match has no distinct
288  // segments, its vector should contain an entry at offset 0 with no flags.
289  //
290  // Example: The user typed "goog"
291  //   http://www.google.com/        Google
292  //   ^          ^   ^              ^   ^
293  //   0,         |   15,            |   4,
294  //              11,match           0,match
295  //
296  // This structure holds the classification information for each span.
297  struct ACMatchClassification {
298    // The values in here are not mutually exclusive -- use them like a
299    // bitfield.  This also means we use "int" instead of this enum type when
300    // passing the values around, so the compiler doesn't complain.
301    enum Style {
302      NONE  = 0,
303      URL   = 1 << 0,  // A URL
304      MATCH = 1 << 1,  // A match for the user's search term
305      DIM   = 1 << 2,  // "Helper text"
306    };
307
308    ACMatchClassification(size_t offset, int style)
309        : offset(offset),
310          style(style) {
311    }
312
313    // Offset within the string that this classification starts
314    size_t offset;
315
316    int style;
317  };
318
319  typedef std::vector<ACMatchClassification> ACMatchClassifications;
320
321  // The type of this match.
322  enum Type {
323    URL_WHAT_YOU_TYPED = 0,  // The input as a URL.
324    HISTORY_URL,             // A past page whose URL contains the input.
325    HISTORY_TITLE,           // A past page whose title contains the input.
326    HISTORY_BODY,            // A past page whose body contains the input.
327    HISTORY_KEYWORD,         // A past page whose keyword contains the input.
328    NAVSUGGEST,              // A suggested URL.
329    SEARCH_WHAT_YOU_TYPED,   // The input as a search query (with the default
330                             // engine).
331    SEARCH_HISTORY,          // A past search (with the default engine)
332                             // containing the input.
333    SEARCH_SUGGEST,          // A suggested search (with the default engine).
334    SEARCH_OTHER_ENGINE,     // A search with a non-default engine.
335    OPEN_HISTORY_PAGE,       // A synthetic result that opens the history page
336                             // to search for the input.
337    NUM_TYPES,
338  };
339
340  AutocompleteMatch();
341  AutocompleteMatch(AutocompleteProvider* provider,
342                    int relevance,
343                    bool deletable,
344                    Type type);
345  ~AutocompleteMatch();
346
347  // Converts |type| to a string representation.  Used in logging.
348  static std::string TypeToString(Type type);
349
350  // Converts |type| to a resource identifier for the appropriate icon for this
351  // type.
352  static int TypeToIcon(Type type);
353
354  // Comparison function for determining when one match is better than another.
355  static bool MoreRelevant(const AutocompleteMatch& elem1,
356                           const AutocompleteMatch& elem2);
357
358  // Comparison functions for removing matches with duplicate destinations.
359  static bool DestinationSortFunc(const AutocompleteMatch& elem1,
360                                  const AutocompleteMatch& elem2);
361  static bool DestinationsEqual(const AutocompleteMatch& elem1,
362                                const AutocompleteMatch& elem2);
363
364  // Helper functions for classes creating matches:
365  // Fills in the classifications for |text|, using |style| as the base style
366  // and marking the first instance of |find_text| as a match.  (This match
367  // will also not be dimmed, if |style| has DIM set.)
368  static void ClassifyMatchInString(const std::wstring& find_text,
369                                    const std::wstring& text,
370                                    int style,
371                                    ACMatchClassifications* classifications);
372
373  // Similar to ClassifyMatchInString(), but for cases where the range to mark
374  // as matching is already known (avoids calling find()).  This can be helpful
375  // when find() would be misleading (e.g. you want to mark the second match in
376  // a string instead of the first).
377  static void ClassifyLocationInString(size_t match_location,
378                                       size_t match_length,
379                                       size_t overall_length,
380                                       int style,
381                                       ACMatchClassifications* classifications);
382
383  // The provider of this match, used to  remember which provider the user had
384  // selected when the input changes. This may be NULL, in which case there is
385  // no provider (or memory of the user's selection).
386  AutocompleteProvider* provider;
387
388  // The relevance of this match. See table above for scores returned by
389  // various providers. This is used to rank matches among all responding
390  // providers, so different providers must be carefully tuned to supply
391  // matches with appropriate relevance.
392  //
393  // If the relevance is negative, it will only be displayed if there are not
394  // enough non-negative items in all the providers to max out the popup. In
395  // this case, the relevance of the additional items will be inverted so they
396  // can be mixed in with the rest of the relevances. This allows a provider
397  // to group its matches, having the added items appear intermixed with its
398  // other matches.
399  //
400  // TODO(pkasting): http://b/1111299 This should be calculated algorithmically,
401  // rather than being a fairly fixed value defined by the table above.
402  int relevance;
403
404  // True if the user should be able to delete this match.
405  bool deletable;
406
407  // This string is loaded into the location bar when the item is selected
408  // by pressing the arrow keys. This may be different than a URL, for example,
409  // for search suggestions, this would just be the search terms.
410  std::wstring fill_into_edit;
411
412  // The position within fill_into_edit from which we'll display the inline
413  // autocomplete string.  This will be std::wstring::npos if this match should
414  // not be inline autocompleted.
415  size_t inline_autocomplete_offset;
416
417  // The URL to actually load when the autocomplete item is selected. This URL
418  // should be canonical so we can compare URLs with strcmp to avoid dupes.
419  // It may be empty if there is no possible navigation.
420  GURL destination_url;
421
422  // The main text displayed in the address bar dropdown.
423  std::wstring contents;
424  ACMatchClassifications contents_class;
425
426  // Additional helper text for each entry, such as a title or description.
427  std::wstring description;
428  ACMatchClassifications description_class;
429
430  // The transition type to use when the user opens this match.  By default
431  // this is TYPED.  Providers whose matches do not look like URLs should set
432  // it to GENERATED.
433  PageTransition::Type transition;
434
435  // True when this match is the "what you typed" match from the history
436  // system.
437  bool is_history_what_you_typed_match;
438
439  // Type of this match.
440  Type type;
441
442  // If this match corresponds to a keyword, this is the TemplateURL the
443  // keyword was obtained from.
444  const TemplateURL* template_url;
445
446  // True if the user has starred the destination URL.
447  bool starred;
448
449#ifndef NDEBUG
450  // Does a data integrity check on this match.
451  void Validate() const;
452
453  // Checks one text/classifications pair for valid values.
454  void ValidateClassifications(
455      const std::wstring& text,
456      const ACMatchClassifications& classifications) const;
457#endif
458};
459
460typedef AutocompleteMatch::ACMatchClassification ACMatchClassification;
461typedef std::vector<ACMatchClassification> ACMatchClassifications;
462
463// AutocompleteProvider -------------------------------------------------------
464
465// A single result provider for the autocomplete system.  Given user input, the
466// provider decides what (if any) matches to return, their relevance, and their
467// classifications.
468class AutocompleteProvider
469    : public base::RefCountedThreadSafe<AutocompleteProvider> {
470 public:
471  class ACProviderListener {
472   public:
473    // Called by a provider as a notification that something has changed.
474    // |updated_matches| should be true iff the matches have changed in some
475    // way (they may not have changed if, for example, the provider did an
476    // asynchronous query to get more matches, came up with none, and is now
477    // giving up).
478    //
479    // NOTE: Providers MUST only call this method while processing asynchronous
480    // queries.  Do not call this for a synchronous query.
481    //
482    // NOTE: There's no parameter to tell the listener _which_ provider is
483    // calling it.  Because the AutocompleteController (the typical listener)
484    // doesn't cache the providers' individual matches locally, it has to get
485    // them all again when this is called anyway, so such a parameter wouldn't
486    // actually be useful.
487    virtual void OnProviderUpdate(bool updated_matches) = 0;
488
489   protected:
490    virtual ~ACProviderListener();
491  };
492
493  AutocompleteProvider(ACProviderListener* listener,
494                       Profile* profile,
495                       const char* name);
496
497  // Invoked when the profile changes.
498  // NOTE: Do not access any previous Profile* at this point as it may have
499  // already been deleted.
500  void SetProfile(Profile* profile);
501
502  // Called to start an autocomplete query.  The provider is responsible for
503  // tracking its matches for this query and whether it is done processing the
504  // query.  When new matches are available or the provider finishes, it
505  // calls the controller's OnProviderUpdate() method.  The controller can then
506  // get the new matches using the provider's accessors.
507  // Exception: Matches available immediately after starting the query (that
508  // is, synchronously) do not cause any notifications to be sent.  The
509  // controller is expected to check for these without prompting (since
510  // otherwise, starting each provider running would result in a flurry of
511  // notifications).
512  //
513  // Once Stop() has been called, no more notifications should be sent.
514  //
515  // |minimal_changes| is an optimization that lets the provider do less work
516  // when the |input|'s text hasn't changed.  See the body of
517  // AutocompletePopupModel::StartAutocomplete().
518  virtual void Start(const AutocompleteInput& input,
519                     bool minimal_changes) = 0;
520
521  // Called when a provider must not make any more callbacks for the current
522  // query. This will be called regardless of whether the provider is already
523  // done.
524  virtual void Stop();
525
526  // Returns the set of matches for the current query.
527  const ACMatches& matches() const { return matches_; }
528
529  // Returns whether the provider is done processing the query.
530  bool done() const { return done_; }
531
532  // Returns the name of this provider.
533  const char* name() const { return name_; }
534
535  // Called to delete a match and the backing data that produced it.  This
536  // match should not appear again in this or future queries.  This can only be
537  // called for matches the provider marks as deletable.  This should only be
538  // called when no query is running.
539  // NOTE: Remember to call OnProviderUpdate() if matches_ is updated.
540  virtual void DeleteMatch(const AutocompleteMatch& match);
541
542  // A suggested upper bound for how many matches a provider should return.
543  // TODO(pkasting): http://b/1111299 , http://b/933133 This should go away once
544  // we have good relevance heuristics; the controller should handle all
545  // culling.
546  static const size_t kMaxMatches;
547
548 protected:
549  friend class base::RefCountedThreadSafe<AutocompleteProvider>;
550
551  virtual ~AutocompleteProvider();
552
553  // Returns whether |input| begins "http:" or "view-source:http:".
554  static bool HasHTTPScheme(const std::wstring& input);
555
556  // Updates the starred state of each of the matches in matches_ from the
557  // profile's bookmark bar model.
558  void UpdateStarredStateOfMatches();
559
560  // A convenience function to call net::FormatUrl() with the current set of
561  // "Accept Languages" when check_accept_lang is true.  Otherwise, it's called
562  // with an empty list.
563  std::wstring StringForURLDisplay(const GURL& url,
564                                   bool check_accept_lang,
565                                   bool trim_http) const;
566
567  // The profile associated with the AutocompleteProvider.  Reference is not
568  // owned by us.
569  Profile* profile_;
570
571  ACProviderListener* listener_;
572  ACMatches matches_;
573  bool done_;
574
575  // The name of this provider.  Used for logging.
576  const char* name_;
577
578 private:
579  DISALLOW_COPY_AND_ASSIGN(AutocompleteProvider);
580};
581
582typedef AutocompleteProvider::ACProviderListener ACProviderListener;
583
584// AutocompleteResult ---------------------------------------------------------
585
586// All matches from all providers for a particular query.  This also tracks
587// what the default match should be if the user doesn't manually select another
588// match.
589class AutocompleteResult {
590 public:
591  typedef ACMatches::const_iterator const_iterator;
592  typedef ACMatches::iterator iterator;
593
594  // The "Selection" struct is the information we need to select the same match
595  // in one result set that was selected in another.
596  struct Selection {
597    Selection()
598        : provider_affinity(NULL),
599          is_history_what_you_typed_match(false) {
600    }
601
602    // Clear the selection entirely.
603    void Clear();
604
605    // True when the selection is empty.
606    bool empty() const {
607      return destination_url.is_empty() && !provider_affinity &&
608          !is_history_what_you_typed_match;
609    }
610
611    // The desired destination URL.
612    GURL destination_url;
613
614    // The desired provider.  If we can't find a match with the specified
615    // |destination_url|, we'll use the best match from this provider.
616    const AutocompleteProvider* provider_affinity;
617
618    // True when this is the HistoryURLProvider's "what you typed" match.  This
619    // can't be tracked using |destination_url| because its URL changes on every
620    // keystroke, so if this is set, we'll preserve the selection by simply
621    // choosing the new "what you typed" entry and ignoring |destination_url|.
622    bool is_history_what_you_typed_match;
623  };
624
625  AutocompleteResult();
626
627  // operator=() by another name.
628  void CopyFrom(const AutocompleteResult& rhs);
629
630  // Adds a single match. The match is inserted at the appropriate position
631  // based on relevancy and display order. This is ONLY for use after
632  // SortAndCull() has been invoked, and preserves default_match_.
633  void AddMatch(const AutocompleteMatch& match);
634
635  // Adds a new set of matches to the result set.  Does not re-sort.
636  void AppendMatches(const ACMatches& matches);
637
638  // Removes duplicates, puts the list in sorted order and culls to leave only
639  // the best kMaxMatches matches.  Sets the default match to the best match
640  // and updates the alternate nav URL.
641  void SortAndCull(const AutocompleteInput& input);
642
643  // Vector-style accessors/operators.
644  size_t size() const { return matches_.size(); }
645  bool empty() const { return matches_.empty(); }
646  const_iterator begin() const { return matches_.begin(); }
647  iterator begin() { return matches_.begin(); }
648  const_iterator end() const { return matches_.end(); }
649  iterator end() { return matches_.end(); }
650
651  // Returns the match at the given index.
652  const AutocompleteMatch& match_at(size_t index) const {
653    DCHECK(index < matches_.size());
654    return matches_[index];
655  }
656
657  // Get the default match for the query (not necessarily the first).  Returns
658  // end() if there is no default match.
659  const_iterator default_match() const { return default_match_; }
660
661  GURL alternate_nav_url() const { return alternate_nav_url_; }
662
663  // Clears the matches for this result set.
664  void Reset() {
665    matches_.clear();
666    default_match_ = end();
667  }
668
669#ifndef NDEBUG
670  // Does a data integrity check on this result.
671  void Validate() const;
672#endif
673
674  // Max number of matches we'll show from the various providers. We may end
675  // up showing an additional shortcut for Destinations->History, see
676  // AddHistoryContentsShortcut.
677  static const size_t kMaxMatches;
678
679 private:
680  ACMatches matches_;
681
682  const_iterator default_match_;
683
684  // The "alternate navigation URL", if any, for this result set.  This is a URL
685  // to try offering as a navigational option in case the user navigated to the
686  // URL of the default match but intended something else.  For example, if the
687  // user's local intranet contains site "foo", and the user types "foo", we
688  // default to searching for "foo" when the user may have meant to navigate
689  // there.  In cases like this, the default match will point to the "search for
690  // 'foo'" result, and this will contain "http://foo/".
691  GURL alternate_nav_url_;
692
693  DISALLOW_COPY_AND_ASSIGN(AutocompleteResult);
694};
695
696// AutocompleteController -----------------------------------------------------
697
698// The coordinator for autocomplete queries, responsible for combining the
699// matches from a series of providers into one AutocompleteResult.
700class AutocompleteController : public ACProviderListener {
701 public:
702  // Used to indicate an index that is not selected in a call to Update().
703  static const int kNoItemSelected;
704
705  // Normally, you will call the first constructor.  Unit tests can use the
706  // second to set the providers to some known testing providers.  The default
707  // providers will be overridden and the controller will take ownership of the
708  // providers, Release()ing them on destruction.
709  explicit AutocompleteController(Profile* profile);
710#ifdef UNIT_TEST
711  explicit AutocompleteController(const ACProviders& providers)
712      : providers_(providers),
713        history_contents_provider_(NULL),
714        updated_latest_result_(false),
715        delay_interval_has_passed_(false),
716        have_committed_during_this_query_(false),
717        done_(true) {
718  }
719#endif
720  ~AutocompleteController();
721
722  // Invoked when the profile changes. This forwards the call down to all
723  // the AutocompleteProviders.
724  void SetProfile(Profile* profile);
725
726  // Starts an autocomplete query, which continues until all providers are
727  // done or the query is Stop()ed.  It is safe to Start() a new query without
728  // Stop()ing the previous one.
729  //
730  // See AutocompleteInput::desired_tld() for meaning of |desired_tld|.
731  //
732  // |prevent_inline_autocomplete| is true if the generated result set should
733  // not require inline autocomplete for the default match.  This is difficult
734  // to explain in the abstract; the practical use case is that after the user
735  // deletes text in the edit, the HistoryURLProvider should make sure not to
736  // promote a match requiring inline autocomplete too highly.
737  //
738  // |prefer_keyword| should be true when the keyword UI is onscreen; this will
739  // bias the autocomplete result set toward the keyword provider when the input
740  // string is a bare keyword.
741  //
742  // If |synchronous_only| is true, the controller asks the providers to only
743  // return matches which are synchronously available, which should mean that
744  // all providers will be done immediately.
745  //
746  // The controller will fire
747  // AUTOCOMPLETE_CONTROLLER_SYNCHRONOUS_MATCHES_AVAILABLE from inside this
748  // call, and unless the query is stopped, will fire at least one (and perhaps
749  // more) AUTOCOMPLETE_CONTROLLER_RESULT_UPDATED later as more matches come in
750  // (even if the query completes synchronously).  Listeners should use the
751  // result set provided in the accompanying Details object to update
752  // themselves.
753  void Start(const std::wstring& text,
754             const std::wstring& desired_tld,
755             bool prevent_inline_autocomplete,
756             bool prefer_keyword,
757             bool synchronous_only);
758
759  // Cancels the current query, ensuring there will be no future notifications
760  // fired.  If new matches have come in since the most recent notification was
761  // fired, they will be discarded.
762  //
763  // If |clear_result| is true, the controller will also erase the result set.
764  void Stop(bool clear_result);
765
766  // Asks the relevant provider to delete |match|, and ensures observers are
767  // notified of resulting changes immediately.  This should only be called when
768  // no query is running.
769  void DeleteMatch(const AutocompleteMatch& match);
770
771  // Commits the results for the current query if they've never been committed.
772  // This is used by the popup to ensure it's not showing an out-of-date query.
773  void CommitIfQueryHasNeverBeenCommitted();
774
775  // Getters
776  const AutocompleteInput& input() const { return input_; }
777  const AutocompleteResult& result() const { return result_; }
778  // This next is temporary and should go away when
779  // AutocompletePopup::InfoForCurrentSelection() moves to the controller.
780  const AutocompleteResult& latest_result() const { return latest_result_; }
781  bool done() const { return done_ && !update_delay_timer_.IsRunning(); }
782
783  // From AutocompleteProvider::Listener
784  virtual void OnProviderUpdate(bool updated_matches);
785
786 private:
787  // Updates |latest_result_| and |done_| to reflect the current provider state.
788  // Resets timers and fires notifications as necessary.  |is_synchronous_pass|
789  // is true only when Start() is calling this to get the synchronous result.
790  void UpdateLatestResult(bool is_synchronous_pass);
791
792  // Callback for when |max_delay_timer_| fires; this notes that the delay
793  // interval has passed and commits the result, if it's changed.
794  void DelayTimerFired();
795
796  // Copies |latest_result_| to |result_| and notifies observers of updates.
797  // |notify_default_match| should normally be true; if it's false, we don't
798  // send an AUTOCOMPLETE_CONTROLLER_DEFAULT_MATCH_UPDATED notification.  This
799  // is a hack to avoid updating the edit with out-of-date data.
800  // TODO(pkasting): Don't hardcode assumptions about who listens to these
801  // notificiations.
802  void CommitResult(bool notify_default_match);
803
804  // Returns the matches from |provider| whose destination urls are not in
805  // |latest_result_|.
806  ACMatches GetMatchesNotInLatestResult(
807      const AutocompleteProvider* provider) const;
808
809  // If the HistoryContentsAutocomplete provider is done and there are more
810  // matches in the database than currently shown, an entry is added to
811  // |latest_result_| to show all history matches.
812  void AddHistoryContentsShortcut();
813
814  // Updates |done_| to be accurate with respect to current providers' statuses.
815  void CheckIfDone();
816
817  // A list of all providers.
818  ACProviders providers_;
819
820  HistoryContentsProvider* history_contents_provider_;
821
822  // Input passed to Start.
823  AutocompleteInput input_;
824
825  // Data from the autocomplete query.
826  AutocompleteResult result_;
827
828  // The latest result available from the autocomplete providers.  This may be
829  // different than |result_| if we've gotten matches from our providers that we
830  // haven't yet shown the user.  If there aren't yet as many matches as in
831  // |result|, we'll wait to display these in hopes of minimizing flicker in GUI
832  // observers.
833  AutocompleteResult latest_result_;
834
835  // True if |latest_result_| has been updated since it was last committed to
836  // |result_|.  Used to determine whether we need to commit any changes.
837  bool updated_latest_result_;
838
839  // True when it's been at least one interval of the delay timer since we
840  // committed any updates.  This is used to allow a new update to be committed
841  // immediately.
842  //
843  // NOTE: This can never be true when |have_committed_during_this_query_| is
844  // false (except transiently while processing the timer firing).
845  bool delay_interval_has_passed_;
846
847  // True when we've committed a result set at least once during this query.
848  // When this is false, we commit immediately when |done_| is set, since there
849  // are no more updates to come and thus no possible flicker due to committing
850  // immediately.
851  //
852  // NOTE: This can never be false when |delay_interval_has_passed_| is true
853  // (except transiently while processing the timer firing).
854  bool have_committed_during_this_query_;
855
856  // True if a query is not currently running.
857  bool done_;
858
859  // Timer that tracks how long it's been since the last time we sent our
860  // observers a new result set.  This is used both to enforce a lower bound on
861  // the delay between most commits (to reduce flicker), and ensure that updates
862  // eventually get committed no matter what delays occur between them or how
863  // fast or continuously the user is typing.
864  base::RepeatingTimer<AutocompleteController> update_delay_timer_;
865
866  DISALLOW_COPY_AND_ASSIGN(AutocompleteController);
867};
868
869// AutocompleteLog ------------------------------------------------------------
870
871// The data to log (via the metrics service) when the user selects an item
872// from the omnibox popup.
873struct AutocompleteLog {
874  AutocompleteLog(std::wstring text,
875                  AutocompleteInput::Type input_type,
876                  size_t selected_index,
877                  size_t inline_autocompleted_length,
878                  const AutocompleteResult& result)
879      : text(text),
880        input_type(input_type),
881        selected_index(selected_index),
882        inline_autocompleted_length(inline_autocompleted_length),
883        result(result) {
884  }
885  // The user's input text in the omnibox.
886  std::wstring text;
887  // The detected type of the user's input.
888  AutocompleteInput::Type input_type;
889  // Selected index (if selected) or -1 (AutocompletePopupModel::kNoMatch).
890  size_t selected_index;
891  // Inline autocompleted length (if displayed).
892  size_t inline_autocompleted_length;
893  // Result set.
894  const AutocompleteResult& result;
895};
896
897#endif  // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_
898