autocomplete_controller.h revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CONTROLLER_H_
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CONTROLLER_H_
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/basictypes.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/compiler_specific.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/gtest_prod_util.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/strings/string16.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/timer/timer.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_input.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_provider.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_result.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass AutocompleteControllerDelegate;
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass HistoryURLProvider;
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass KeywordProvider;
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass Profile;
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass SearchProvider;
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ZeroSuggestProvider;
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// The AutocompleteController is the center of the autocomplete system.  A
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// class creates an instance of the controller, which in turn creates a set of
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// AutocompleteProviders to serve it.  The owning class can ask the controller
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// to Start() a query; the controller in turn passes this call down to the
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// providers, each of which keeps track of its own matches and whether it has
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// finished processing the query.  When a provider gets more matches or finishes
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// processing, it notifies the controller, which merges the combined matches
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// together and makes the result available to interested observers.
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The owner may also cancel the current query by calling Stop(), which the
366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// controller will in turn communicate to all the providers.  No callbacks will
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// happen after a request has been stopped.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// IMPORTANT: There is NO THREAD SAFETY built into this portion of the
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// autocomplete system.  All calls to and from the AutocompleteController should
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// happen on the same thread.  AutocompleteProviders are responsible for doing
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// their own thread management when they need to return matches asynchronously.
436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)//
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The coordinator for autocomplete queries, responsible for combining the
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// matches from a series of providers into one AutocompleteResult.
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class AutocompleteController : public AutocompleteProviderListener {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |provider_types| is a bitmap containing AutocompleteProvider::Type values
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // that will (potentially, depending on platform, flags, etc.) be
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // instantiated.
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AutocompleteController(Profile* profile,
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         AutocompleteControllerDelegate* delegate,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         int provider_types);
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~AutocompleteController();
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Starts an autocomplete query, which continues until all providers are
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // done or the query is Stop()ed.  It is safe to Start() a new query without
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Stop()ing the previous one.
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  //
60  // See AutocompleteInput::AutocompleteInput(...) for more details regarding
61  // |input| params.
62  //
63  // The controller calls AutocompleteControllerDelegate::OnResultChanged() from
64  // inside this call at least once. If matches are available later on that
65  // result in changing the result set the delegate is notified again. When the
66  // controller is done the notification AUTOCOMPLETE_CONTROLLER_RESULT_READY is
67  // sent.
68  void Start(const AutocompleteInput& input);
69
70  // Cancels the current query, ensuring there will be no future notifications
71  // fired.  If new matches have come in since the most recent notification was
72  // fired, they will be discarded.
73  //
74  // If |clear_result| is true, the controller will also erase the result set.
75  void Stop(bool clear_result);
76
77  // Begin asynchronous fetch of zero-suggest suggestions. The |input| should
78  // contain current omnibox input, the URL of the page we are on, and
79  // that page's classification.
80  void StartZeroSuggest(const AutocompleteInput& input);
81
82  // Asks the relevant provider to delete |match|, and ensures observers are
83  // notified of resulting changes immediately.  This should only be called when
84  // no query is running.
85  void DeleteMatch(const AutocompleteMatch& match);
86
87  // Removes any entries that were copied from the last result. This is used by
88  // the popup to ensure it's not showing an out-of-date query.
89  void ExpireCopiedEntries();
90
91  // AutocompleteProviderListener:
92  virtual void OnProviderUpdate(bool updated_matches) OVERRIDE;
93
94  // Called when an omnibox event log entry is generated.
95  // Populates provider_info with diagnostic information about the status
96  // of various providers.  In turn, calls
97  // AutocompleteProvider::AddProviderInfo() so each provider can add
98  // provider-specific information, information we want to log for a particular
99  // provider but not others.
100  void AddProvidersInfo(ProvidersInfo* provider_info) const;
101
102  // Called when a new omnibox session starts.
103  // We start a new session when the user first begins modifying the omnibox
104  // content; see |OmniboxEditModel::user_input_in_progress_|.
105  void ResetSession();
106
107  // Constructs the final destination URL for a given match using additional
108  // parameters otherwise not available at initial construction time.  This
109  // method should be called from OmniboxEditModel::OpenMatch() before the user
110  // navigates to the selected match.
111  void UpdateMatchDestinationURL(base::TimeDelta query_formulation_time,
112                                 AutocompleteMatch* match) const;
113
114  HistoryURLProvider* history_url_provider() const {
115    return history_url_provider_;
116  }
117  KeywordProvider* keyword_provider() const { return keyword_provider_; }
118  SearchProvider* search_provider() const { return search_provider_; }
119
120  // Deprecated. Do not use that method! It's provided temporarily as clank
121  // migrates. If you need to access the aucomplete input you should keep a
122  // local copy of it.
123  // TODO(beaudoin): Remove this method once clank no longer rely on it.
124  // crbug.com/367832
125  const AutocompleteInput& input() const { return input_; }
126
127  const AutocompleteResult& result() const { return result_; }
128  bool done() const { return done_; }
129  const ACProviders* providers() const { return &providers_; }
130
131  const base::TimeTicks& last_time_default_match_changed() const {
132    return last_time_default_match_changed_;
133  }
134
135 private:
136  friend class AutocompleteProviderTest;
137  FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest,
138                           RedundantKeywordsIgnoredInResult);
139  FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest, UpdateAssistedQueryStats);
140  FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest, GetDestinationURL);
141  FRIEND_TEST_ALL_PREFIXES(OmniboxViewTest, DoesNotUpdateAutocompleteOnBlur);
142
143  // Updates |result_| to reflect the current provider state and fires
144  // notifications.  If |regenerate_result| then we clear the result
145  // so when we incorporate the current provider state we end up
146  // implicitly removing all expired matches.  (Normally we allow
147  // matches from the previous result set carry over.  These stale
148  // results may outrank legitimate matches from the current result
149  // set.  Sometimes we just want the current matches; the easier way
150  // to do this is to throw everything out and reconstruct the result
151  // set from the providers' current data.)
152  // If |force_notify_default_match_changed|, we tell NotifyChanged
153  // the default match has changed even if it hasn't.  This is
154  // necessary in some cases; for instance, if the user typed a new
155  // character, the edit model needs to repaint (highlighting changed)
156  // even if the default match didn't change.
157  void UpdateResult(bool regenerate_result,
158                    bool force_notify_default_match_changed);
159
160  // Updates |result| to populate each match's |associated_keyword| if that
161  // match can show a keyword hint.  |result| should be sorted by
162  // relevance before this is called.
163  void UpdateAssociatedKeywords(AutocompleteResult* result);
164
165  // For each group of contiguous matches from the same TemplateURL, show the
166  // provider name as a description on the first match in the group.
167  void UpdateKeywordDescriptions(AutocompleteResult* result);
168
169  // For each AutocompleteMatch returned by SearchProvider, updates the
170  // destination_url iff the provider's TemplateURL supports assisted query
171  // stats.
172  void UpdateAssistedQueryStats(AutocompleteResult* result);
173
174  // Calls AutocompleteControllerDelegate::OnResultChanged() and if done sends
175  // AUTOCOMPLETE_CONTROLLER_RESULT_READY.
176  void NotifyChanged(bool notify_default_match);
177
178  // Updates |done_| to be accurate with respect to current providers' statuses.
179  void CheckIfDone();
180
181  // Starts |expire_timer_|.
182  void StartExpireTimer();
183
184  // Starts |stop_timer_|.
185  void StartStopTimer();
186
187  AutocompleteControllerDelegate* delegate_;
188
189  // A list of all providers.
190  ACProviders providers_;
191
192  HistoryURLProvider* history_url_provider_;
193
194  KeywordProvider* keyword_provider_;
195
196  SearchProvider* search_provider_;
197
198  ZeroSuggestProvider* zero_suggest_provider_;
199
200  // Input passed to Start.
201  AutocompleteInput input_;
202
203  // Data from the autocomplete query.
204  AutocompleteResult result_;
205
206  // The most recent time the default match (inline match) changed.  This may
207  // be earlier than the most recent keystroke if the recent keystrokes didn't
208  // change the suggested match in the omnibox.  (For instance, if
209  // a user typed "mail.goog" and the match https://mail.google.com/ was
210  // the destination match ever since the user typed "ma" then this is
211  // the time that URL first appeared as the default match.)  This may
212  // also be more recent than the last keystroke if there was an
213  // asynchronous provider that returned and changed the default
214  // match.  See UpdateResult() for details on when we consider a
215  // match to have changed.
216  base::TimeTicks last_time_default_match_changed_;
217
218  // Timer used to remove any matches copied from the last result. When run
219  // invokes |ExpireCopiedEntries|.
220  base::OneShotTimer<AutocompleteController> expire_timer_;
221
222  // Timer used to tell the providers to Stop() searching for matches.
223  base::OneShotTimer<AutocompleteController> stop_timer_;
224
225  // Amount of time (in ms) between when the user stops typing and
226  // when we send Stop() to every provider.  This is intended to avoid
227  // the disruptive effect of belated omnibox updates, updates that
228  // come after the user has had to time to read the whole dropdown
229  // and doesn't expect it to change.
230  const base::TimeDelta stop_timer_duration_;
231
232  // True if a query is not currently running.
233  bool done_;
234
235  // Are we in Start()? This is used to avoid updating |result_| and sending
236  // notifications until Start() has been invoked on all providers.
237  bool in_start_;
238
239  Profile* profile_;
240
241  DISALLOW_COPY_AND_ASSIGN(AutocompleteController);
242};
243
244#endif  // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CONTROLLER_H_
245