1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CONTROLLER_H_
6 #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CONTROLLER_H_
8 #include "base/basictypes.h"
9 #include "base/compiler_specific.h"
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/strings/string16.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
15 #include "components/omnibox/autocomplete_input.h"
16 #include "components/omnibox/autocomplete_provider.h"
17 #include "components/omnibox/autocomplete_provider_listener.h"
18 #include "components/omnibox/autocomplete_result.h"
20 class AutocompleteControllerDelegate
;
21 class HistoryURLProvider
;
22 class KeywordProvider
;
25 class TemplateURLService
;
26 class ZeroSuggestProvider
;
28 // The AutocompleteController is the center of the autocomplete system. A
29 // class creates an instance of the controller, which in turn creates a set of
30 // AutocompleteProviders to serve it. The owning class can ask the controller
31 // to Start() a query; the controller in turn passes this call down to the
32 // providers, each of which keeps track of its own matches and whether it has
33 // finished processing the query. When a provider gets more matches or finishes
34 // processing, it notifies the controller, which merges the combined matches
35 // together and makes the result available to interested observers.
37 // The owner may also cancel the current query by calling Stop(), which the
38 // controller will in turn communicate to all the providers. No callbacks will
39 // happen after a request has been stopped.
41 // IMPORTANT: There is NO THREAD SAFETY built into this portion of the
42 // autocomplete system. All calls to and from the AutocompleteController should
43 // happen on the same thread. AutocompleteProviders are responsible for doing
44 // their own thread management when they need to return matches asynchronously.
46 // The coordinator for autocomplete queries, responsible for combining the
47 // matches from a series of providers into one AutocompleteResult.
48 class AutocompleteController
: public AutocompleteProviderListener
{
50 typedef std::vector
<scoped_refptr
<AutocompleteProvider
> > Providers
;
52 // |provider_types| is a bitmap containing AutocompleteProvider::Type values
53 // that will (potentially, depending on platform, flags, etc.) be
54 // instantiated. |template_url_service| is used to create URLs from the
55 // autocomplete results.
56 AutocompleteController(Profile
* profile
,
57 TemplateURLService
* template_url_service
,
58 AutocompleteControllerDelegate
* delegate
,
60 ~AutocompleteController();
62 // Starts an autocomplete query, which continues until all providers are
63 // done or the query is Stop()ed. It is safe to Start() a new query without
64 // Stop()ing the previous one.
66 // See AutocompleteInput::AutocompleteInput(...) for more details regarding
69 // The controller calls AutocompleteControllerDelegate::OnResultChanged() from
70 // inside this call at least once. If matches are available later on that
71 // result in changing the result set the delegate is notified again. When the
72 // controller is done the notification AUTOCOMPLETE_CONTROLLER_RESULT_READY is
74 void Start(const AutocompleteInput
& input
);
76 // Cancels the current query, ensuring there will be no future notifications
77 // fired. If new matches have come in since the most recent notification was
78 // fired, they will be discarded.
80 // If |clear_result| is true, the controller will also erase the result set.
81 void Stop(bool clear_result
);
83 // Called when the omnibox is focused while no existing user input is in
84 // progress. This is used to call Start() on all providers with
85 // |called_due_to_focus| parameter set to check if they want to provide
87 void OnOmniboxFocused(const AutocompleteInput
& input
);
89 // Asks the relevant provider to delete |match|, and ensures observers are
90 // notified of resulting changes immediately. This should only be called when
91 // no query is running.
92 void DeleteMatch(const AutocompleteMatch
& match
);
94 // Removes any entries that were copied from the last result. This is used by
95 // the popup to ensure it's not showing an out-of-date query.
96 void ExpireCopiedEntries();
98 // AutocompleteProviderListener:
99 virtual void OnProviderUpdate(bool updated_matches
) override
;
101 // Called when an omnibox event log entry is generated.
102 // Populates provider_info with diagnostic information about the status
103 // of various providers. In turn, calls
104 // AutocompleteProvider::AddProviderInfo() so each provider can add
105 // provider-specific information, information we want to log for a particular
106 // provider but not others.
107 void AddProvidersInfo(ProvidersInfo
* provider_info
) const;
109 // Called when a new omnibox session starts.
110 // We start a new session when the user first begins modifying the omnibox
111 // content; see |OmniboxEditModel::user_input_in_progress_|.
114 // Constructs the final destination URL for a given match using additional
115 // parameters otherwise not available at initial construction time. This
116 // method should be called from OmniboxEditModel::OpenMatch() before the user
117 // navigates to the selected match.
118 void UpdateMatchDestinationURLWithQueryFormulationTime(
119 base::TimeDelta query_formulation_time
,
120 AutocompleteMatch
* match
) const;
122 // Constructs the final destination URL for a given match using additional
123 // parameters otherwise not available at initial construction time.
124 void UpdateMatchDestinationURL(
125 const TemplateURLRef::SearchTermsArgs
& search_terms_args
,
126 AutocompleteMatch
* match
) const;
128 HistoryURLProvider
* history_url_provider() const {
129 return history_url_provider_
;
131 KeywordProvider
* keyword_provider() const { return keyword_provider_
; }
132 SearchProvider
* search_provider() const { return search_provider_
; }
134 // Deprecated. Do not use that method! It's provided temporarily as clank
135 // migrates. If you need to access the aucomplete input you should keep a
137 // TODO(beaudoin): Remove this method once clank no longer rely on it.
139 const AutocompleteInput
& input() const { return input_
; }
141 const AutocompleteResult
& result() const { return result_
; }
142 bool done() const { return done_
; }
143 const Providers
& providers() const { return providers_
; }
145 const base::TimeTicks
& last_time_default_match_changed() const {
146 return last_time_default_match_changed_
;
150 friend class AutocompleteProviderTest
;
151 FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest
,
152 RedundantKeywordsIgnoredInResult
);
153 FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest
, UpdateAssistedQueryStats
);
154 FRIEND_TEST_ALL_PREFIXES(OmniboxViewTest
, DoesNotUpdateAutocompleteOnBlur
);
155 FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest
, CloseOmniboxPopupOnTextDrag
);
157 // Updates |result_| to reflect the current provider state and fires
158 // notifications. If |regenerate_result| then we clear the result
159 // so when we incorporate the current provider state we end up
160 // implicitly removing all expired matches. (Normally we allow
161 // matches from the previous result set carry over. These stale
162 // results may outrank legitimate matches from the current result
163 // set. Sometimes we just want the current matches; the easier way
164 // to do this is to throw everything out and reconstruct the result
165 // set from the providers' current data.)
166 // If |force_notify_default_match_changed|, we tell NotifyChanged
167 // the default match has changed even if it hasn't. This is
168 // necessary in some cases; for instance, if the user typed a new
169 // character, the edit model needs to repaint (highlighting changed)
170 // even if the default match didn't change.
171 void UpdateResult(bool regenerate_result
,
172 bool force_notify_default_match_changed
);
174 // Updates |result| to populate each match's |associated_keyword| if that
175 // match can show a keyword hint. |result| should be sorted by
176 // relevance before this is called.
177 void UpdateAssociatedKeywords(AutocompleteResult
* result
);
179 // For each group of contiguous matches from the same TemplateURL, show the
180 // provider name as a description on the first match in the group.
181 void UpdateKeywordDescriptions(AutocompleteResult
* result
);
183 // For each AutocompleteMatch returned by SearchProvider, updates the
184 // destination_url iff the provider's TemplateURL supports assisted query
186 void UpdateAssistedQueryStats(AutocompleteResult
* result
);
188 // Calls AutocompleteControllerDelegate::OnResultChanged() and if done sends
189 // AUTOCOMPLETE_CONTROLLER_RESULT_READY.
190 void NotifyChanged(bool notify_default_match
);
192 // Updates |done_| to be accurate with respect to current providers' statuses.
195 // Starts |expire_timer_|.
196 void StartExpireTimer();
198 // Starts |stop_timer_|.
199 void StartStopTimer();
201 // Helper function for Stop(). |due_to_user_inactivity| means this call was
202 // triggered by a user's idleness, i.e., not an explicit user action.
203 void StopHelper(bool clear_result
,
204 bool due_to_user_inactivity
);
206 AutocompleteControllerDelegate
* delegate_
;
208 // A list of all providers.
209 Providers providers_
;
211 HistoryURLProvider
* history_url_provider_
;
213 KeywordProvider
* keyword_provider_
;
215 SearchProvider
* search_provider_
;
217 ZeroSuggestProvider
* zero_suggest_provider_
;
219 // Input passed to Start.
220 AutocompleteInput input_
;
222 // Data from the autocomplete query.
223 AutocompleteResult result_
;
225 // The most recent time the default match (inline match) changed. This may
226 // be earlier than the most recent keystroke if the recent keystrokes didn't
227 // change the suggested match in the omnibox. (For instance, if
228 // a user typed "mail.goog" and the match https://mail.google.com/ was
229 // the destination match ever since the user typed "ma" then this is
230 // the time that URL first appeared as the default match.) This may
231 // also be more recent than the last keystroke if there was an
232 // asynchronous provider that returned and changed the default
233 // match. See UpdateResult() for details on when we consider a
234 // match to have changed.
235 base::TimeTicks last_time_default_match_changed_
;
237 // Timer used to remove any matches copied from the last result. When run
238 // invokes |ExpireCopiedEntries|.
239 base::OneShotTimer
<AutocompleteController
> expire_timer_
;
241 // Timer used to tell the providers to Stop() searching for matches.
242 base::OneShotTimer
<AutocompleteController
> stop_timer_
;
244 // Amount of time (in ms) between when the user stops typing and
245 // when we send Stop() to every provider. This is intended to avoid
246 // the disruptive effect of belated omnibox updates, updates that
247 // come after the user has had to time to read the whole dropdown
248 // and doesn't expect it to change.
249 const base::TimeDelta stop_timer_duration_
;
251 // True if a query is not currently running.
254 // Are we in Start()? This is used to avoid updating |result_| and sending
255 // notifications until Start() has been invoked on all providers.
258 TemplateURLService
* template_url_service_
;
260 DISALLOW_COPY_AND_ASSIGN(AutocompleteController
);
263 #endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CONTROLLER_H_