Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / components / omnibox / browser / search_provider.h
blob51f5e6c816b3b70fb558b754ac8329f9c2bf8059
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 // This file contains the Search autocomplete provider. This provider is
6 // responsible for all autocomplete entries that start with "Search <engine>
7 // for ...", including searching for the current input string, search
8 // history, and search suggestions. An instance of it gets created and
9 // managed by the autocomplete controller.
11 #ifndef COMPONENTS_OMNIBOX_BROWSER_SEARCH_PROVIDER_H_
12 #define COMPONENTS_OMNIBOX_BROWSER_SEARCH_PROVIDER_H_
14 #include <string>
15 #include <vector>
17 #include "base/basictypes.h"
18 #include "base/compiler_specific.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "base/time/time.h"
21 #include "base/timer/timer.h"
22 #include "components/metrics/proto/omnibox_input_type.pb.h"
23 #include "components/omnibox/browser/answers_cache.h"
24 #include "components/omnibox/browser/base_search_provider.h"
25 #include "components/search_engines/template_url.h"
26 #include "components/search_engines/template_url_service_observer.h"
27 #include "net/url_request/url_fetcher_delegate.h"
29 class AutocompleteProviderClient;
30 class AutocompleteProviderListener;
31 class AutocompleteResult;
32 class SearchProviderTest;
33 class TemplateURLService;
35 namespace history {
36 struct KeywordSearchTermVisit;
39 namespace net {
40 class URLFetcher;
43 // Autocomplete provider for searches and suggestions from a search engine.
45 // After construction, the autocomplete controller repeatedly calls Start()
46 // with some user input, each time expecting to receive a small set of the best
47 // matches (either synchronously or asynchronously).
49 // Initially the provider creates a match that searches for the current input
50 // text. It also starts a task to query the Suggest servers. When that data
51 // comes back, the provider creates and returns matches for the best
52 // suggestions.
53 class SearchProvider : public BaseSearchProvider,
54 public TemplateURLServiceObserver,
55 public net::URLFetcherDelegate {
56 public:
57 SearchProvider(AutocompleteProviderClient* client,
58 AutocompleteProviderListener* listener);
60 // Extracts the suggest response metadata which SearchProvider previously
61 // stored for |match|.
62 static std::string GetSuggestMetadata(const AutocompleteMatch& match);
64 // Answers prefetch handling - register displayed answers. Takes the top
65 // match for Autocomplete and registers the contained answer data, if any.
66 void RegisterDisplayedAnswers(const AutocompleteResult& result);
68 // AutocompleteProvider:
69 void ResetSession() override;
71 protected:
72 ~SearchProvider() override;
74 private:
75 friend class AutocompleteProviderTest;
76 friend class SearchProviderTest;
77 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, CanSendURL);
78 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest,
79 DontInlineAutocompleteAsynchronously);
80 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInline);
81 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInlineDomainClassify);
82 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInlineSchemeSubstring);
83 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SuggestRelevanceExperiment);
84 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, TestDeleteMatch);
85 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SuggestQueryUsesToken);
86 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SessionToken);
87 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, AnswersCache);
88 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, RemoveExtraAnswers);
89 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, DoesNotProvideOnFocus);
90 FRIEND_TEST_ALL_PREFIXES(InstantExtendedPrefetchTest, ClearPrefetchedResults);
91 FRIEND_TEST_ALL_PREFIXES(InstantExtendedPrefetchTest, SetPrefetchQuery);
93 // Manages the providers (TemplateURLs) used by SearchProvider. Two providers
94 // may be used:
95 // . The default provider. This corresponds to the user's default search
96 // engine. This is always used, except for the rare case of no default
97 // engine.
98 // . The keyword provider. This is used if the user has typed in a keyword.
99 class Providers {
100 public:
101 explicit Providers(TemplateURLService* template_url_service);
103 // Returns true if the specified providers match the two providers cached
104 // by this class.
105 bool equal(const base::string16& default_provider,
106 const base::string16& keyword_provider) const {
107 return (default_provider == default_provider_) &&
108 (keyword_provider == keyword_provider_);
111 // Resets the cached providers.
112 void set(const base::string16& default_provider,
113 const base::string16& keyword_provider) {
114 default_provider_ = default_provider;
115 keyword_provider_ = keyword_provider;
118 TemplateURLService* template_url_service() { return template_url_service_; }
119 const base::string16& default_provider() const { return default_provider_; }
120 const base::string16& keyword_provider() const { return keyword_provider_; }
122 // NOTE: These may return NULL even if the provider members are nonempty!
123 const TemplateURL* GetDefaultProviderURL() const;
124 const TemplateURL* GetKeywordProviderURL() const;
126 // Returns true if there is a valid keyword provider.
127 bool has_keyword_provider() const { return !keyword_provider_.empty(); }
129 private:
130 TemplateURLService* template_url_service_;
132 // Cached across the life of a query so we behave consistently even if the
133 // user changes their default while the query is running.
134 base::string16 default_provider_;
135 base::string16 keyword_provider_;
137 DISALLOW_COPY_AND_ASSIGN(Providers);
140 class CompareScoredResults;
142 typedef std::vector<history::KeywordSearchTermVisit> HistoryResults;
144 // Calculates the relevance score for the keyword verbatim result (if the
145 // input matches one of the profile's keyword).
146 static int CalculateRelevanceForKeywordVerbatim(
147 metrics::OmniboxInputType::Type type,
148 bool prefer_keyword);
150 // A helper function for UpdateAllOldResults().
151 static void UpdateOldResults(bool minimal_changes,
152 SearchSuggestionParser::Results* results);
154 // Returns the first match in |matches| which might be chosen as default.
155 static ACMatches::iterator FindTopMatch(ACMatches* matches);
157 // AutocompleteProvider:
158 void Start(const AutocompleteInput& input, bool minimal_changes) override;
159 void Stop(bool clear_cached_results,
160 bool due_to_user_inactivity) override;
162 // BaseSearchProvider:
163 const TemplateURL* GetTemplateURL(bool is_keyword) const override;
164 const AutocompleteInput GetInput(bool is_keyword) const override;
165 bool ShouldAppendExtraParams(
166 const SearchSuggestionParser::SuggestResult& result) const override;
167 void RecordDeletionResult(bool success) override;
169 // TemplateURLServiceObserver:
170 void OnTemplateURLServiceChanged() override;
172 // net::URLFetcherDelegate:
173 void OnURLFetchComplete(const net::URLFetcher* source) override;
175 // Stops the suggest query.
176 // NOTE: This does not update |done_|. Callers must do so.
177 void StopSuggest();
179 // Clears the current results.
180 void ClearAllResults();
182 // Recalculates the match contents class of |results| to better display
183 // against the current input and user's language.
184 void UpdateMatchContentsClass(const base::string16& input_text,
185 SearchSuggestionParser::Results* results);
187 // Called after ParseSuggestResults to rank the |results|.
188 void SortResults(bool is_keyword, SearchSuggestionParser::Results* results);
190 // Records UMA statistics about a suggest server response.
191 void LogFetchComplete(bool success, bool is_keyword);
193 // Updates |matches_| from the latest results; applies calculated relevances
194 // if suggested relevances cause undesirable behavior. Updates |done_|.
195 void UpdateMatches();
197 // Called when |timer_| expires. Sends the suggest requests.
198 // If |query_is_private|, the function doesn't send this query to the default
199 // provider.
200 void Run(bool query_is_private);
202 // Runs the history query, if necessary. The history query is synchronous.
203 // This does not update |done_|.
204 void DoHistoryQuery(bool minimal_changes);
206 // Returns the time to delay before sending the Suggest request.
207 base::TimeDelta GetSuggestQueryDelay() const;
209 // Determines whether an asynchronous subcomponent query should run for the
210 // current input. If so, starts it if necessary; otherwise stops it.
211 // NOTE: This function does not update |done_|. Callers must do so.
212 void StartOrStopSuggestQuery(bool minimal_changes);
214 // Stops |fetcher| if it's running. This includes resetting the scoped_ptr.
215 void CancelFetcher(scoped_ptr<net::URLFetcher>* fetcher);
217 // Returns true when the current query can be sent to at least one suggest
218 // service. This will be false for example when suggest is disabled. In
219 // the process, calculates whether the query may contain potentionally
220 // private data and stores the result in |is_query_private|; such queries
221 // should not be sent to the default search engine.
222 bool IsQuerySuitableForSuggest(bool* query_is_private) const;
224 // Returns true if sending the query to a suggest server may leak sensitive
225 // information (and hence the suggest request shouldn't be sent).
226 bool IsQueryPotentionallyPrivate() const;
228 // Remove existing keyword results if the user is no longer in keyword mode,
229 // and, if |minimal_changes| is false, revise the existing results to
230 // indicate they were received before the last keystroke.
231 void UpdateAllOldResults(bool minimal_changes);
233 // Given new asynchronous results, ensure that we don't clobber the current
234 // top results, which were determined synchronously on the last keystroke.
235 void PersistTopSuggestions(SearchSuggestionParser::Results* results);
237 // Apply calculated relevance scores to the current results.
238 void ApplyCalculatedSuggestRelevance(
239 SearchSuggestionParser::SuggestResults* list);
240 void ApplyCalculatedNavigationRelevance(
241 SearchSuggestionParser::NavigationResults* list);
243 // Starts a new URLFetcher requesting suggest results from |template_url|;
244 // callers own the returned URLFetcher, which is NULL for invalid providers.
245 scoped_ptr<net::URLFetcher> CreateSuggestFetcher(
246 int id,
247 const TemplateURL* template_url,
248 const AutocompleteInput& input);
250 // Converts the parsed results to a set of AutocompleteMatches, |matches_|.
251 void ConvertResultsToAutocompleteMatches();
253 // Remove answer contents from each match in |matches| other than the first
254 // that appears.
255 static void RemoveExtraAnswers(ACMatches* matches);
257 // Returns an iterator to the first match in |matches_| which might
258 // be chosen as default.
259 ACMatches::const_iterator FindTopMatch() const;
261 // Checks if suggested relevances violate an expected constraint.
262 // See UpdateMatches() for the use and explanation of this constraint
263 // and other constraints enforced without the use of helper functions.
264 bool IsTopMatchSearchWithURLInput() const;
266 // Converts an appropriate number of navigation results in
267 // |navigation_results| to matches and adds them to |matches|.
268 void AddNavigationResultsToMatches(
269 const SearchSuggestionParser::NavigationResults& navigation_results,
270 ACMatches* matches);
272 // Adds a match for each result in |raw_default_history_results_| or
273 // |raw_keyword_history_results_| to |map|. |is_keyword| indicates
274 // which one of the two.
275 void AddRawHistoryResultsToMap(bool is_keyword,
276 int did_not_accept_suggestion,
277 MatchMap* map);
279 // Adds a match for each transformed result in |results| to |map|.
280 void AddTransformedHistoryResultsToMap(
281 const SearchSuggestionParser::SuggestResults& results,
282 int did_not_accept_suggestion,
283 MatchMap* map);
285 // Calculates relevance scores for all |results|.
286 SearchSuggestionParser::SuggestResults ScoreHistoryResultsHelper(
287 const HistoryResults& results,
288 bool base_prevent_inline_autocomplete,
289 bool input_multiple_words,
290 const base::string16& input_text,
291 bool is_keyword);
293 // Calculates relevance scores for |results|, adjusting for boundary
294 // conditions around multi-word queries. (See inline comments in function
295 // definition for more details.)
296 void ScoreHistoryResults(
297 const HistoryResults& results,
298 bool is_keyword,
299 SearchSuggestionParser::SuggestResults* scored_results);
301 // Adds matches for |results| to |map|.
302 void AddSuggestResultsToMap(
303 const SearchSuggestionParser::SuggestResults& results,
304 const std::string& metadata,
305 MatchMap* map);
307 // Gets the relevance score for the verbatim result. This value may be
308 // provided by the suggest server or calculated locally; if
309 // |relevance_from_server| is non-null, it will be set to indicate which of
310 // those is true.
311 int GetVerbatimRelevance(bool* relevance_from_server) const;
313 // Calculates the relevance score for the verbatim result from the
314 // default search engine. This version takes into account context:
315 // i.e., whether the user has entered a keyword-based search or not.
316 int CalculateRelevanceForVerbatim() const;
318 // Calculates the relevance score for the verbatim result from the default
319 // search engine *ignoring* whether the input is a keyword-based search
320 // or not. This function should only be used to determine the minimum
321 // relevance score that the best result from this provider should have.
322 // For normal use, prefer the above function.
323 int CalculateRelevanceForVerbatimIgnoringKeywordModeState() const;
325 // Gets the relevance score for the keyword verbatim result.
326 // |relevance_from_server| is handled as in GetVerbatimRelevance().
327 // TODO(mpearson): Refactor so this duplication isn't necessary or
328 // restructure so one static function takes all the parameters it needs
329 // (rather than looking at internal state).
330 int GetKeywordVerbatimRelevance(bool* relevance_from_server) const;
332 // |time| is the time at which this query was last seen. |is_keyword|
333 // indicates whether the results correspond to the keyword provider or default
334 // provider. |use_aggressive_method| says whether this function can use a
335 // method that gives high scores (1200+) rather than one that gives lower
336 // scores. When using the aggressive method, scores may exceed 1300
337 // unless |prevent_search_history_inlining| is set.
338 int CalculateRelevanceForHistory(const base::Time& time,
339 bool is_keyword,
340 bool use_aggressive_method,
341 bool prevent_search_history_inlining) const;
343 // Returns an AutocompleteMatch for a navigational suggestion.
344 AutocompleteMatch NavigationToMatch(
345 const SearchSuggestionParser::NavigationResult& navigation);
347 // Updates the value of |done_| from the internal state.
348 void UpdateDone();
350 // Obtains a session token, regenerating if necessary.
351 std::string GetSessionToken();
353 // Answers prefetch handling - finds the previously displayed answer matching
354 // the current top-scoring history result. If there is a previous answer,
355 // returns the query data associated with it. Otherwise, returns an empty
356 // AnswersQueryData.
357 AnswersQueryData FindAnswersPrefetchData();
359 AutocompleteProviderListener* listener_;
361 // Maintains the TemplateURLs used.
362 Providers providers_;
364 // The user's input.
365 AutocompleteInput input_;
367 // Input when searching against the keyword provider.
368 AutocompleteInput keyword_input_;
370 // Searches in the user's history that begin with the input text.
371 HistoryResults raw_keyword_history_results_;
372 HistoryResults raw_default_history_results_;
374 // Scored searches in the user's history - based on |keyword_history_results_|
375 // or |default_history_results_| as appropriate.
376 SearchSuggestionParser::SuggestResults transformed_keyword_history_results_;
377 SearchSuggestionParser::SuggestResults transformed_default_history_results_;
379 // A timer to start a query to the suggest server after the user has stopped
380 // typing for long enough.
381 base::OneShotTimer<SearchProvider> timer_;
383 // The time at which we sent a query to the suggest server.
384 base::TimeTicks time_suggest_request_sent_;
386 // Fetchers used to retrieve results for the keyword and default providers.
387 // After a fetcher's results are returned, it gets reset, so a non-null
388 // fetcher indicates that fetcher is still in flight.
389 scoped_ptr<net::URLFetcher> keyword_fetcher_;
390 scoped_ptr<net::URLFetcher> default_fetcher_;
392 // Results from the default and keyword search providers.
393 SearchSuggestionParser::Results default_results_;
394 SearchSuggestionParser::Results keyword_results_;
396 // The top query suggestion, left blank if none.
397 base::string16 top_query_suggestion_match_contents_;
398 // The top navigation suggestion, left blank/invalid if none.
399 GURL top_navigation_suggestion_;
401 // Session token management.
402 std::string current_token_;
403 base::TimeTicks token_expiration_time_;
405 // Answers prefetch management.
406 AnswersCache answers_cache_; // Cache for last answers seen.
407 AnswersQueryData prefetch_data_; // Data to use for query prefetching.
409 DISALLOW_COPY_AND_ASSIGN(SearchProvider);
412 #endif // COMPONENTS_OMNIBOX_BROWSER_SEARCH_PROVIDER_H_