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