// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_
#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_
#pragma once
#include <map>
#include <string>
#include <vector>
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/string16.h"
#include "base/timer.h"
#include "googleurl/src/gurl.h"
#include "googleurl/src/url_parse.h"
// The AutocompleteController is the center of the autocomplete system. A
// class creates an instance of the controller, which in turn creates a set of
// AutocompleteProviders to serve it. The owning class can ask the controller
// to Start() a query; the controller in turn passes this call down to the
// providers, each of which keeps track of its own matches and whether it has
// finished processing the query. When a provider gets more matches or finishes
// processing, it notifies the controller, which merges the combined matches
// together and makes the result available to interested observers.
//
// The owner may also cancel the current query by calling Stop(), which the
// controller will in turn communicate to all the providers. No callbacks will
// happen after a request has been stopped.
//
// IMPORTANT: There is NO THREAD SAFETY built into this portion of the
// autocomplete system. All calls to and from the AutocompleteController should
// happen on the same thread. AutocompleteProviders are responsible for doing
// their own thread management when they need to return matches asynchronously.
//
// The AutocompleteProviders each return different kinds of matches, such as
// history or search matches. These matches are given "relevance" scores.
// Higher scores are better matches than lower scores. The relevance scores and
// classes providing the respective matches are as follows:
//
// UNKNOWN input type:
// --------------------------------------------------------------------|-----
// Keyword (non-substituting or in keyword UI mode, exact match) | 1500
// Extension App (exact match) | 1425
// HistoryURL (exact or inline autocomplete match) | 1400
// Search Primary Provider (past query in history within 2 days) | 1399**
// Search Primary Provider (what you typed) | 1300
// HistoryURL (what you typed) | 1200
// Extension App (inexact match) | 1175*~
// Keyword (substituting, exact match) | 1100
// Search Primary Provider (past query in history older than 2 days) | 1050--
// HistoryContents (any match in title of starred page) | 1000++
// HistoryURL (inexact match) | 900++
// Search Primary Provider (navigational suggestion) | 800++
// HistoryContents (any match in title of nonstarred page) | 700++
// Search Primary Provider (suggestion) | 600++
// Built-in | 575++
// HistoryContents (any match in body of starred page) | 550++
// HistoryContents (any match in body of nonstarred page) | 500++
// Keyword (inexact match) | 450
// Search Secondary Provider (what you typed) | 250
// Search Secondary Provider (past query in history) | 200--
// Search Secondary Provider (navigational suggestion) | 150++
// Search Secondary Provider (suggestion) | 100++
//
// REQUESTED_URL input type:
// --------------------------------------------------------------------|-----
// Keyword (non-substituting or in keyword UI mode, exact match) | 1500
// Extension App (exact match) | 1425
// HistoryURL (exact or inline autocomplete match) | 1400
// Search Primary Provider (past query in history within 2 days) | 1399**
// HistoryURL (what you typed) | 1200
// Extension App (inexact match) | 1175*~
// Search Primary Provider (what you typed) | 1150
// Keyword (substituting, exact match) | 1100
// Search Primary Provider (past query in history older than 2 days) | 1050--
// HistoryContents (any match in title of starred page) | 1000++
// HistoryURL (inexact match) | 900++
// Search Primary Provider (navigational suggestion) | 800++
// HistoryContents (any match in title of nonstarred page) | 700++
// Search Primary Provider (suggestion) | 600++
// Built-in | 575++
// HistoryContents (any match in body of starred page) | 550++
// HistoryContents (any match in body of nonstarred page) | 500++
// Keyword (inexact match) | 450
// Search Secondary Provider (what you typed) | 250
// Search Secondary Provider (past query in history) | 200--
// Search Secondary Provider (navigational suggestion) | 150++
// Search Secondary Provider (suggestion) | 100++
//
// URL input type:
// --------------------------------------------------------------------|-----
// Keyword (non-substituting or in keyword UI mode, exact match) | 1500
// Extension App (exact match) | 1425
// HistoryURL (exact or inline autocomplete match) | 1400
// HistoryURL (what you typed) | 1200
// Extension App (inexact match) | 1175*~
// Keyword (substituting, exact match) | 1100
// HistoryURL (inexact match) | 900++
// Search Primary Provider (what you typed) | 850
// Search Primary Provider (navigational suggestion) | 800++
// Search Primary Provider (past query in history) | 750--
// Keyword (inexact match) | 700
// Built-in | 575++
// Search Primary Provider (suggestion) | 300++
// Search Secondary Provider (what you typed) | 250
// Search Secondary Provider (past query in history) | 200--
// Search Secondary Provider (navigational suggestion) | 150++
// Search Secondary Provider (suggestion) | 100++
//
// QUERY input type:
// --------------------------------------------------------------------|-----
// Keyword (non-substituting or in keyword UI mode, exact match) | 1500
// Keyword (substituting, exact match) | 1450
// Extension App (exact match) | 1425
// HistoryURL (exact or inline autocomplete match) | 1400
// Search Primary Provider (past query in history within 2 days) | 1399**
// Search Primary Provider (what you typed) | 1300
// Extension App (inexact match) | 1175*~
// Search Primary Provider (past query in history older than 2 days) | 1050--
// HistoryContents (any match in title of starred page) | 1000++
// HistoryURL (inexact match) | 900++
// Search Primary Provider (navigational suggestion) | 800++
// HistoryContents (any match in title of nonstarred page) | 700++
// Search Primary Provider (suggestion) | 600++
// HistoryContents (any match in body of starred page) | 550++
// HistoryContents (any match in body of nonstarred page) | 500++
// Keyword (inexact match) | 450
// Search Secondary Provider (what you typed) | 250
// Search Secondary Provider (past query in history) | 200--
// Search Secondary Provider (navigational suggestion) | 150++
// Search Secondary Provider (suggestion) | 100++
//
// FORCED_QUERY input type:
// --------------------------------------------------------------------|-----
// Extension App (exact match on title only, not url) | 1425
// Search Primary Provider (past query in history within 2 days) | 1399**
// Search Primary Provider (what you typed) | 1300
// Extension App (inexact match on title only, not url) | 1175*~
// Search Primary Provider (past query in history older than 2 days) | 1050--
// HistoryContents (any match in title of starred page) | 1000++
// Search Primary Provider (navigational suggestion) | 800++
// HistoryContents (any match in title of nonstarred page) | 700++
// Search Primary Provider (suggestion) | 600++
// HistoryContents (any match in body of starred page) | 550++
// HistoryContents (any match in body of nonstarred page) | 500++
//
// (A search keyword is a keyword with a replacement string; a bookmark keyword
// is a keyword with no replacement string, that is, a shortcut for a URL.)
//
// There are two possible providers for search suggestions. If the user has
// typed a keyword, then the primary provider is the keyword provider and the
// secondary provider is the default provider. If the user has not typed a
// keyword, then the primary provider corresponds to the default provider.
//
// The value column gives the ranking returned from the various providers.
// ++: a series of matches with relevance from n up to (n + max_matches).
// --: relevance score falls off over time (discounted 50 points @ 15 minutes,
// 450 points @ two weeks)
// **: relevance score falls off over two days (discounted 99 points after two
// days).
// *~: Partial matches get a score on a sliding scale from about 575-1125 based
// on how many times the URL for the Extension App has been typed and how
// many of the letters match.
class AutocompleteController;
class AutocompleteControllerDelegate;
class AutocompleteInput;
struct AutocompleteMatch;
class AutocompleteProvider;
class AutocompleteResult;
class HistoryContentsProvider;
class Profile;
class SearchProvider;
class TemplateURL;
typedef std::vector<AutocompleteMatch> ACMatches;
typedef std::vector<AutocompleteProvider*> ACProviders;
// AutocompleteInput ----------------------------------------------------------
// The user input for an autocomplete query. Allows copying.
class AutocompleteInput {
public:
// Note that the type below may be misleading. For example, "http:/" alone
// cannot be opened as a URL, so it is marked as a QUERY; yet the user
// probably intends to type more and have it eventually become a URL, so we
// need to make sure we still run it through inline autocomplete.
enum Type {
INVALID, // Empty input
UNKNOWN, // Valid input whose type cannot be determined
REQUESTED_URL, // Input autodetected as UNKNOWN, which the user wants to
// treat as an URL by specifying a desired_tld
URL, // Input autodetected as a URL
QUERY, // Input autodetected as a query
FORCED_QUERY, // Input forced to be a query by an initial '?'
};
// Enumeration of the possible match query types. Callers who only need some
// of the matches for a particular input can get answers more quickly by
// specifying that upfront.
enum MatchesRequested {
// Only the best match in the whole result set matters. Providers should at
// most return synchronously-available matches, and if possible do even less
// work, so that it's safe to ask for these repeatedly in the course of one
// higher-level "synchronous" query.
BEST_MATCH,
// Only synchronous matches should be returned.
SYNCHRONOUS_MATCHES,
// All matches should be fetched.
ALL_MATCHES,
};
AutocompleteInput();
AutocompleteInput(const string16& text,
const string16& desired_tld,
bool prevent_inline_autocomplete,
bool prefer_keyword,
bool allow_exact_keyword_match,
MatchesRequested matches_requested);
~AutocompleteInput();
// If type is |FORCED_QUERY| and |text| starts with '?', it is removed.
static void RemoveForcedQueryStringIfNecessary(Type type, string16* text);
// Converts |type| to a string representation. Used in logging.
static std::string TypeToString(Type type);
// Parses |text| and returns the type of input this will be interpreted as.
// The components of the input are stored in the output parameter |parts|, if
// it is non-NULL. The scheme is stored in |scheme| if it is non-NULL. The
// canonicalized URL is stored in |canonicalized_url|; however, this URL is
// not guaranteed to be valid, especially if the parsed type is, e.g., QUERY.
static Type Parse(const string16& text,
const string16& desired_tld,
url_parse::Parsed* parts,
string16* scheme,
GURL* canonicalized_url);
// Parses |text| and fill |scheme| and |host| by the positions of them.
// The results are almost as same as the result of Parse(), but if the scheme
// is view-source, this function returns the positions of scheme and host
// in the URL qualified by "view-source:" prefix.
static void ParseForEmphasizeComponents(const string16& text,
const string16& desired_tld,
url_parse::Component* scheme,
url_parse::Component* host);
// Code that wants to format URLs with a format flag including
// net::kFormatUrlOmitTrailingSlashOnBareHostname risk changing the meaning if
// the result is then parsed as AutocompleteInput. Such code can call this
// function with the URL and its formatted string, and it will return a
// formatted string with the same meaning as the original URL (i.e. it will
// re-append a slash if necessary).
static string16 FormattedStringWithEquivalentMeaning(
const GURL& url,
const string16& formatted_url);
// User-provided text to be completed.
const string16& text() const { return text_; }
// Use of this setter is risky, since no other internal state is updated
// besides |text_|. Only callers who know that they're not changing the
// type/scheme/etc. should use this.
void set_text(const string16& text) { text_ = text; }
// The text supplied to the constructor. This differs from |text| if the text
// supplied to the constructor had leading or trailing white space.
const string16& original_text() const { return original_text_; }
// User's desired TLD, if one is not already present in the text to
// autocomplete. When this is non-empty, it also implies that "www." should
// be prepended to the domain where possible. This should not have a leading
// '.' (use "com" instead of ".com").
const string16& desired_tld() const { return desired_tld_; }
// The type of input supplied.
Type type() const { return type_; }
// Returns parsed URL components.
const url_parse::Parsed& parts() const { return parts_; }
// The scheme parsed from the provided text; only meaningful when type_ is
// URL.
const string16& scheme() const { return scheme_; }
// The input as an URL to navigate to, if possible.
const GURL& canonicalized_url() const { return canonicalized_url_; }
// Returns whether inline autocompletion should be prevented.
bool prevent_inline_autocomplete() const {
return prevent_inline_autocomplete_;
}
// Returns the value of |prevent_inline_autocomplete| supplied to the
// constructor. This differs from the value returned by
// |prevent_inline_autocomplete()| if the input contained trailing whitespace.
bool initial_prevent_inline_autocomplete() const {
return initial_prevent_inline_autocomplete_;
}
// Returns whether, given an input string consisting solely of a substituting
// keyword, we should score it like a non-substituting keyword.
bool prefer_keyword() const { return prefer_keyword_; }
// Returns whether this input is allowed to be treated as an exact
// keyword match. If not, the default result is guaranteed not to be a
// keyword search, even if the input is "<keyword> <search string>".
bool allow_exact_keyword_match() const { return allow_exact_keyword_match_; }
// See description of enum for details.
MatchesRequested matches_requested() const { return matches_requested_; }
// operator==() by another name.
bool Equals(const AutocompleteInput& other) const;
// Resets all internal variables to the null-constructed state.
void Clear();
private:
string16 text_;
string16 original_text_;
string16 desired_tld_;
Type type_;
url_parse::Parsed parts_;
string16 scheme_;
GURL canonicalized_url_;
bool initial_prevent_inline_autocomplete_;
bool prevent_inline_autocomplete_;
bool prefer_keyword_;
bool allow_exact_keyword_match_;
MatchesRequested matches_requested_;
};
// AutocompleteProvider -------------------------------------------------------
// A single result provider for the autocomplete system. Given user input, the
// provider decides what (if any) matches to return, their relevance, and their
// classifications.
class AutocompleteProvider
: public base::RefCountedThreadSafe<AutocompleteProvider> {
public:
class ACProviderListener {
public:
// Called by a provider as a notification that something has changed.
// |updated_matches| should be true iff the matches have changed in some
// way (they may not have changed if, for example, the provider did an
// asynchronous query to get more matches, came up with none, and is now
// giving up).
//
// NOTE: Providers MUST only call this method while processing asynchronous
// queries. Do not call this for a synchronous query.
//
// NOTE: There's no parameter to tell the listener _which_ provider is
// calling it. Because the AutocompleteController (the typical listener)
// doesn't cache the providers' individual matches locally, it has to get
// them all again when this is called anyway, so such a parameter wouldn't
// actually be useful.
virtual void OnProviderUpdate(bool updated_matches) = 0;
protected:
virtual ~ACProviderListener();
};
AutocompleteProvider(ACProviderListener* listener,
Profile* profile,
const char* name);
// Invoked when the profile changes.
// NOTE: Do not access any previous Profile* at this point as it may have
// already been deleted.
void SetProfile(Profile* profile);
// Called to start an autocomplete query. The provider is responsible for
// tracking its matches for this query and whether it is done processing the
// query. When new matches are available or the provider finishes, it
// calls the controller's OnProviderUpdate() method. The controller can then
// get the new matches using the provider's accessors.
// Exception: Matches available immediately after starting the query (that
// is, synchronously) do not cause any notifications to be sent. The
// controller is expected to check for these without prompting (since
// otherwise, starting each provider running would result in a flurry of
// notifications).
//
// Once Stop() has been called, no more notifications should be sent.
//
// |minimal_changes| is an optimization that lets the provider do less work
// when the |input|'s text hasn't changed. See the body of
// AutocompletePopupModel::StartAutocomplete().
virtual void Start(const AutocompleteInput& input,
bool minimal_changes) = 0;
// Called when a provider must not make any more callbacks for the current
// query. This will be called regardless of whether the provider is already
// done.
virtual void Stop();
// Returns the set of matches for the current query.
const ACMatches& matches() const { return matches_; }
// Returns whether the provider is done processing the query.
bool done() const { return done_; }
// Returns the name of this provider.
const char* name() const { return name_; }
// Called to delete a match and the backing data that produced it. This
// match should not appear again in this or future queries. This can only be
// called for matches the provider marks as deletable. This should only be
// called when no query is running.
// NOTE: Remember to call OnProviderUpdate() if matches_ is updated.
virtual void DeleteMatch(const AutocompleteMatch& match);
// A suggested upper bound for how many matches a provider should return.
// TODO(pkasting): http://b/1111299 , http://b/933133 This should go away once
// we have good relevance heuristics; the controller should handle all
// culling.
static const size_t kMaxMatches;
protected:
friend class base::RefCountedThreadSafe<AutocompleteProvider>;
virtual ~AutocompleteProvider();
// Returns whether |input| begins "http:" or "view-source:http:".
static bool HasHTTPScheme(const string16& input);
// Updates the starred state of each of the matches in matches_ from the
// profile's bookmark bar model.
void UpdateStarredStateOfMatches();
// A convenience function to call net::FormatUrl() with the current set of
// "Accept Languages" when check_accept_lang is true. Otherwise, it's called
// with an empty list.
string16 StringForURLDisplay(const GURL& url,
bool check_accept_lang,
bool trim_http) const;
// The profile associated with the AutocompleteProvider. Reference is not
// owned by us.
Profile* profile_;
ACProviderListener* listener_;
ACMatches matches_;
bool done_;
// The name of this provider. Used for logging.
const char* name_;
private:
DISALLOW_COPY_AND_ASSIGN(AutocompleteProvider);
};
typedef AutocompleteProvider::ACProviderListener ACProviderListener;
// AutocompleteResult ---------------------------------------------------------
// All matches from all providers for a particular query. This also tracks
// what the default match should be if the user doesn't manually select another
// match.
class AutocompleteResult {
public:
typedef ACMatches::const_iterator const_iterator;
typedef ACMatches::iterator iterator;
// The "Selection" struct is the information we need to select the same match
// in one result set that was selected in another.
struct Selection {
Selection()
: provider_affinity(NULL),
is_history_what_you_typed_match(false) {
}
// Clear the selection entirely.
void Clear();
// True when the selection is empty.
bool empty() const {
return destination_url.is_empty() && !provider_affinity &&
!is_history_what_you_typed_match;
}
// The desired destination URL.
GURL destination_url;
// The desired provider. If we can't find a match with the specified
// |destination_url|, we'll use the best match from this provider.
const AutocompleteProvider* provider_affinity;
// True when this is the HistoryURLProvider's "what you typed" match. This
// can't be tracked using |destination_url| because its URL changes on every
// keystroke, so if this is set, we'll preserve the selection by simply
// choosing the new "what you typed" entry and ignoring |destination_url|.
bool is_history_what_you_typed_match;
};
AutocompleteResult();
~AutocompleteResult();
// operator=() by another name.
void CopyFrom(const AutocompleteResult& rhs);
// Copies matches from |old_matches| to provide a consistant result set. See
// comments in code for specifics.
void CopyOldMatches(const AutocompleteInput& input,
const AutocompleteResult& old_matches);
// Adds a single match. The match is inserted at the appropriate position
// based on relevancy and display order. This is ONLY for use after
// SortAndCull() has been invoked, and preserves default_match_.
void AddMatch(const AutocompleteMatch& match);
// Adds a new set of matches to the result set. Does not re-sort.
void AppendMatches(const ACMatches& matches);
// Removes duplicates, puts the list in sorted order and culls to leave only
// the best kMaxMatches matches. Sets the default match to the best match
// and updates the alternate nav URL.
void SortAndCull(const AutocompleteInput& input);
// Returns true if at least one match was copied from the last result.
bool HasCopiedMatches() const;
// Vector-style accessors/operators.
size_t size() const;
bool empty() const;
const_iterator begin() const;
iterator begin();
const_iterator end() const;
iterator end();
// Returns the match at the given index.
const AutocompleteMatch& match_at(size_t index) const;
// Get the default match for the query (not necessarily the first). Returns
// end() if there is no default match.
const_iterator default_match() const { return default_match_; }
GURL alternate_nav_url() const { return alternate_nav_url_; }
// Clears the matches for this result set.
void Reset();
void Swap(AutocompleteResult* other);
#ifndef NDEBUG
// Does a data integrity check on this result.
void Validate() const;
#endif
// Max number of matches we'll show from the various providers.
static const size_t kMaxMatches;
private:
typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches;
// Populates |provider_to_matches| from |matches_|.
void BuildProviderToMatches(ProviderToMatches* provider_to_matches) const;
// Returns true if |matches| contains a match with the same destination as
// |match|.
static bool HasMatchByDestination(const AutocompleteMatch& match,
const ACMatches& matches);
// Copies matches into this result. |old_matches| gives the matches from the
// last result, and |new_matches| the results from this result.
void MergeMatchesByProvider(const ACMatches& old_matches,
const ACMatches& new_matches);
ACMatches matches_;
const_iterator default_match_;
// The "alternate navigation URL", if any, for this result set. This is a URL
// to try offering as a navigational option in case the user navigated to the
// URL of the default match but intended something else. For example, if the
// user's local intranet contains site "foo", and the user types "foo", we
// default to searching for "foo" when the user may have meant to navigate
// there. In cases like this, the default match will point to the "search for
// 'foo'" result, and this will contain "http://foo/".
GURL alternate_nav_url_;
DISALLOW_COPY_AND_ASSIGN(AutocompleteResult);
};
// AutocompleteController -----------------------------------------------------
// The coordinator for autocomplete queries, responsible for combining the
// matches from a series of providers into one AutocompleteResult.
class AutocompleteController : public ACProviderListener {
public:
// Used to indicate an index that is not selected in a call to Update().
static const int kNoItemSelected;
// Normally, you will call the first constructor. Unit tests can use the
// second to set the providers to some known testing providers. The default
// providers will be overridden and the controller will take ownership of the
// providers, Release()ing them on destruction.
AutocompleteController(Profile* profile,
AutocompleteControllerDelegate* delegate);
#ifdef UNIT_TEST
explicit AutocompleteController(const ACProviders& providers)
: delegate_(NULL),
providers_(providers),
search_provider_(NULL),
done_(true),
in_start_(false) {
}
#endif
~AutocompleteController();
// Invoked when the profile changes. This forwards the call down to all
// the AutocompleteProviders.
void SetProfile(Profile* profile);
// Starts an autocomplete query, which continues until all providers are
// done or the query is Stop()ed. It is safe to Start() a new query without
// Stop()ing the previous one.
//
// See AutocompleteInput::desired_tld() for meaning of |desired_tld|.
//
// |prevent_inline_autocomplete| is true if the generated result set should
// not require inline autocomplete for the default match. This is difficult
// to explain in the abstract; the practical use case is that after the user
// deletes text in the edit, the HistoryURLProvider should make sure not to
// promote a match requiring inline autocomplete too highly.
//
// |prefer_keyword| should be true when the keyword UI is onscreen; this will
// bias the autocomplete result set toward the keyword provider when the input
// string is a bare keyword.
//
// |allow_exact_keyword_match| should be false when triggering keyword mode on
// the input string would be surprising or wrong, e.g. when highlighting text
// in a page and telling the browser to search for it or navigate to it. This
// parameter only applies to substituting keywords.
// If |matches_requested| is BEST_MATCH or SYNCHRONOUS_MATCHES the controller
// asks the providers to only return matches which are synchronously
// available, which should mean that all providers will be done immediately.
//
// The controller calls AutocompleteControllerDelegate::OnResultChanged() from
// inside this call at least once. If matches are available later on that
// result in changing the result set the delegate is notified again. When the
// controller is done the notification AUTOCOMPLETE_CONTROLLER_RESULT_READY is
// sent.
void Start(const string16& text,
const string16& desired_tld,
bool prevent_inline_autocomplete,
bool prefer_keyword,
bool allow_exact_keyword_match,
AutocompleteInput::MatchesRequested matches_requested);
// Cancels the current query, ensuring there will be no future notifications
// fired. If new matches have come in since the most recent notification was
// fired, they will be discarded.
//
// If |clear_result| is true, the controller will also erase the result set.
void Stop(bool clear_result);
// Asks the relevant provider to delete |match|, and ensures observers are
// notified of resulting changes immediately. This should only be called when
// no query is running.
void DeleteMatch(const AutocompleteMatch& match);
// Removes any entries that were copied from the last result. This is used by
// the popup to ensure it's not showing an out-of-date query.
void ExpireCopiedEntries();
SearchProvider* search_provider() const { return search_provider_; }
// Getters
const AutocompleteInput& input() const { return input_; }
const AutocompleteResult& result() const { return result_; }
bool done() const { return done_; }
// From AutocompleteProvider::Listener
virtual void OnProviderUpdate(bool updated_matches);
private:
// Updates |result_| to reflect the current provider state. Resets timers and
// fires notifications as necessary. |is_synchronous_pass| is true only when
// Start() is calling this to get the synchronous result.
void UpdateResult(bool is_synchronous_pass);
// Calls AutocompleteControllerDelegate::OnResultChanged() and if done sends
// AUTOCOMPLETE_CONTROLLER_RESULT_READY.
void NotifyChanged(bool notify_default_match);
// Updates |done_| to be accurate with respect to current providers' statuses.
void CheckIfDone();
// Starts the expire timer.
void StartExpireTimer();
AutocompleteControllerDelegate* delegate_;
// A list of all providers.
ACProviders providers_;
SearchProvider* search_provider_;
// Input passed to Start.
AutocompleteInput input_;
// Data from the autocomplete query.
AutocompleteResult result_;
// Timer used to remove any matches copied from the last result. When run
// invokes |ExpireCopiedEntries|.
base::OneShotTimer<AutocompleteController> expire_timer_;
// True if a query is not currently running.
bool done_;
// Are we in Start()? This is used to avoid updating |result_| and sending
// notifications until Start() has been invoked on all providers.
bool in_start_;
DISALLOW_COPY_AND_ASSIGN(AutocompleteController);
};
// AutocompleteLog ------------------------------------------------------------
// The data to log (via the metrics service) when the user selects an item
// from the omnibox popup.
struct AutocompleteLog {
AutocompleteLog(const string16& text,
AutocompleteInput::Type input_type,
size_t selected_index,
size_t inline_autocompleted_length,
const AutocompleteResult& result)
: text(text),
input_type(input_type),
selected_index(selected_index),
inline_autocompleted_length(inline_autocompleted_length),
result(result) {
}
// The user's input text in the omnibox.
string16 text;
// The detected type of the user's input.
AutocompleteInput::Type input_type;
// Selected index (if selected) or -1 (AutocompletePopupModel::kNoMatch).
size_t selected_index;
// Inline autocompleted length (if displayed).
size_t inline_autocompleted_length;
// Result set.
const AutocompleteResult& result;
};
#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_