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 // 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 CHROME_BROWSER_AUTOCOMPLETE_SEARCH_PROVIDER_H_
12 #define CHROME_BROWSER_AUTOCOMPLETE_SEARCH_PROVIDER_H_
14 #include "base/basictypes.h"
15 #include "base/compiler_specific.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/time/time.h"
18 #include "base/timer/timer.h"
19 #include "chrome/browser/autocomplete/base_search_provider.h"
20 #include "chrome/browser/history/history_types.h"
21 #include "chrome/browser/search_engines/template_url.h"
24 class SearchProviderTest
;
25 class TemplateURLService
;
31 // Autocomplete provider for searches and suggestions from a search engine.
33 // After construction, the autocomplete controller repeatedly calls Start()
34 // with some user input, each time expecting to receive a small set of the best
35 // matches (either synchronously or asynchronously).
37 // Initially the provider creates a match that searches for the current input
38 // text. It also starts a task to query the Suggest servers. When that data
39 // comes back, the provider creates and returns matches for the best
41 class SearchProvider
: public BaseSearchProvider
{
43 SearchProvider(AutocompleteProviderListener
* listener
, Profile
* profile
);
45 // Extracts the suggest response metadata which SearchProvider previously
46 // stored for |match|.
47 static std::string
GetSuggestMetadata(const AutocompleteMatch
& match
);
49 // AutocompleteProvider:
50 virtual void ResetSession() OVERRIDE
;
52 // This URL may be sent with suggest requests; see comments on CanSendURL().
53 void set_current_page_url(const GURL
& current_page_url
) {
54 current_page_url_
= current_page_url
;
58 virtual ~SearchProvider();
61 friend class SearchProviderTest
;
62 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest
, CanSendURL
);
63 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest
, NavigationInline
);
64 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest
, NavigationInlineDomainClassify
);
65 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest
, NavigationInlineSchemeSubstring
);
66 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest
, RemoveStaleResultsTest
);
67 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest
, SuggestRelevanceExperiment
);
68 FRIEND_TEST_ALL_PREFIXES(SearchProviderTest
, TestDeleteMatch
);
69 FRIEND_TEST_ALL_PREFIXES(AutocompleteProviderTest
, GetDestinationURL
);
70 FRIEND_TEST_ALL_PREFIXES(InstantExtendedPrefetchTest
, ClearPrefetchedResults
);
71 FRIEND_TEST_ALL_PREFIXES(InstantExtendedPrefetchTest
, SetPrefetchQuery
);
73 // Manages the providers (TemplateURLs) used by SearchProvider. Two providers
75 // . The default provider. This corresponds to the user's default search
76 // engine. This is always used, except for the rare case of no default
78 // . The keyword provider. This is used if the user has typed in a keyword.
81 explicit Providers(TemplateURLService
* template_url_service
);
83 // Returns true if the specified providers match the two providers cached
85 bool equal(const base::string16
& default_provider
,
86 const base::string16
& keyword_provider
) const {
87 return (default_provider
== default_provider_
) &&
88 (keyword_provider
== keyword_provider_
);
91 // Resets the cached providers.
92 void set(const base::string16
& default_provider
,
93 const base::string16
& keyword_provider
) {
94 default_provider_
= default_provider
;
95 keyword_provider_
= keyword_provider
;
98 TemplateURLService
* template_url_service() { return template_url_service_
; }
99 const base::string16
& default_provider() const { return default_provider_
; }
100 const base::string16
& keyword_provider() const { return keyword_provider_
; }
102 // NOTE: These may return NULL even if the provider members are nonempty!
103 const TemplateURL
* GetDefaultProviderURL() const;
104 const TemplateURL
* GetKeywordProviderURL() const;
106 // Returns true if there is a valid keyword provider.
107 bool has_keyword_provider() const { return !keyword_provider_
.empty(); }
110 TemplateURLService
* template_url_service_
;
112 // Cached across the life of a query so we behave consistently even if the
113 // user changes their default while the query is running.
114 base::string16 default_provider_
;
115 base::string16 keyword_provider_
;
117 DISALLOW_COPY_AND_ASSIGN(Providers
);
120 class CompareScoredResults
;
122 typedef std::vector
<history::KeywordSearchTermVisit
> HistoryResults
;
124 // Removes non-inlineable results until either the top result can inline
125 // autocomplete the current input or verbatim outscores the top result.
126 static void RemoveStaleResults(const base::string16
& input
,
127 int verbatim_relevance
,
128 SuggestResults
* suggest_results
,
129 NavigationResults
* navigation_results
);
131 // Recalculates the match contents class of |results| to better display
132 // against the current input and user's language.
133 void UpdateMatchContentsClass(const base::string16
& input_text
,
136 // Calculates the relevance score for the keyword verbatim result (if the
137 // input matches one of the profile's keyword).
138 static int CalculateRelevanceForKeywordVerbatim(AutocompleteInput::Type type
,
139 bool prefer_keyword
);
141 // AutocompleteProvider:
142 virtual void Start(const AutocompleteInput
& input
,
143 bool minimal_changes
) OVERRIDE
;
145 // BaseSearchProvider:
146 virtual void SortResults(bool is_keyword
,
147 const base::ListValue
* relevances
,
148 Results
* results
) OVERRIDE
;
149 virtual const TemplateURL
* GetTemplateURL(bool is_keyword
) const OVERRIDE
;
150 virtual const AutocompleteInput
GetInput(bool is_keyword
) const OVERRIDE
;
151 virtual Results
* GetResultsToFill(bool is_keyword
) OVERRIDE
;
152 virtual bool ShouldAppendExtraParams(
153 const SuggestResult
& result
) const OVERRIDE
;
154 virtual void StopSuggest() OVERRIDE
;
155 virtual void ClearAllResults() OVERRIDE
;
156 virtual int GetDefaultResultRelevance() const OVERRIDE
;
157 virtual void RecordDeletionResult(bool success
) OVERRIDE
;
158 virtual void LogFetchComplete(bool success
, bool is_keyword
) OVERRIDE
;
159 virtual bool IsKeywordFetcher(const net::URLFetcher
* fetcher
) const OVERRIDE
;
160 virtual void UpdateMatches() OVERRIDE
;
162 // Called when timer_ expires.
165 // Runs the history query, if necessary. The history query is synchronous.
166 // This does not update |done_|.
167 void DoHistoryQuery(bool minimal_changes
);
169 // Determines whether an asynchronous subcomponent query should run for the
170 // current input. If so, starts it if necessary; otherwise stops it.
171 // NOTE: This function does not update |done_|. Callers must do so.
172 void StartOrStopSuggestQuery(bool minimal_changes
);
174 // Returns true when the current query can be sent to the Suggest service.
175 // This will be false e.g. when Suggest is disabled, the query contains
176 // potentially private data, etc.
177 bool IsQuerySuitableForSuggest() const;
179 // Removes stale results for both default and keyword providers. See comments
180 // on RemoveStaleResults().
181 void RemoveAllStaleResults();
183 // Apply calculated relevance scores to the current results.
184 void ApplyCalculatedRelevance();
185 void ApplyCalculatedSuggestRelevance(SuggestResults
* list
);
186 void ApplyCalculatedNavigationRelevance(NavigationResults
* list
);
188 // Starts a new URLFetcher requesting suggest results from |template_url|;
189 // callers own the returned URLFetcher, which is NULL for invalid providers.
190 net::URLFetcher
* CreateSuggestFetcher(int id
,
191 const TemplateURL
* template_url
,
192 const AutocompleteInput
& input
);
194 // Converts the parsed results to a set of AutocompleteMatches, |matches_|.
195 void ConvertResultsToAutocompleteMatches();
197 // Returns an iterator to the first match in |matches_| which might
198 // be chosen as default.
199 ACMatches::const_iterator
FindTopMatch() const;
201 // Checks if suggested relevances violate certain expected constraints.
202 // See UpdateMatches() for the use and explanation of these constraints.
203 bool HasKeywordDefaultMatchInKeywordMode() const;
204 bool IsTopMatchSearchWithURLInput() const;
206 // Converts an appropriate number of navigation results in
207 // |navigation_results| to matches and adds them to |matches|.
208 void AddNavigationResultsToMatches(
209 const NavigationResults
& navigation_results
,
212 // Adds a match for each result in |results| to |map|. |is_keyword| indicates
213 // whether the results correspond to the keyword provider or default provider.
214 void AddHistoryResultsToMap(const HistoryResults
& results
,
216 int did_not_accept_suggestion
,
219 // Calculates relevance scores for all |results|.
220 SuggestResults
ScoreHistoryResults(const HistoryResults
& results
,
221 bool base_prevent_inline_autocomplete
,
222 bool input_multiple_words
,
223 const base::string16
& input_text
,
226 // Adds matches for |results| to |map|.
227 void AddSuggestResultsToMap(const SuggestResults
& results
,
228 const std::string
& metadata
,
231 // Gets the relevance score for the verbatim result. This value may be
232 // provided by the suggest server or calculated locally; if
233 // |relevance_from_server| is non-NULL, it will be set to indicate which of
235 int GetVerbatimRelevance(bool* relevance_from_server
) const;
237 // Calculates the relevance score for the verbatim result from the
238 // default search engine. This version takes into account context:
239 // i.e., whether the user has entered a keyword-based search or not.
240 int CalculateRelevanceForVerbatim() const;
242 // Calculates the relevance score for the verbatim result from the default
243 // search engine *ignoring* whether the input is a keyword-based search
244 // or not. This function should only be used to determine the minimum
245 // relevance score that the best result from this provider should have.
246 // For normal use, prefer the above function.
247 int CalculateRelevanceForVerbatimIgnoringKeywordModeState() const;
249 // Gets the relevance score for the keyword verbatim result.
250 // |relevance_from_server| is handled as in GetVerbatimRelevance().
251 // TODO(mpearson): Refactor so this duplication isn't necessary or
252 // restructure so one static function takes all the parameters it needs
253 // (rather than looking at internal state).
254 int GetKeywordVerbatimRelevance(bool* relevance_from_server
) const;
256 // |time| is the time at which this query was last seen. |is_keyword|
257 // indicates whether the results correspond to the keyword provider or default
258 // provider. |use_aggressive_method| says whether this function can use a
259 // method that gives high scores (1200+) rather than one that gives lower
260 // scores. When using the aggressive method, scores may exceed 1300
261 // unless |prevent_search_history_inlining| is set.
262 int CalculateRelevanceForHistory(const base::Time
& time
,
264 bool use_aggressive_method
,
265 bool prevent_search_history_inlining
) const;
267 // Returns an AutocompleteMatch for a navigational suggestion.
268 AutocompleteMatch
NavigationToMatch(const NavigationResult
& navigation
);
270 // Updates the value of |done_| from the internal state.
273 // The amount of time to wait before sending a new suggest request after the
274 // previous one. Non-const because some unittests modify this value.
275 static int kMinimumTimeBetweenSuggestQueriesMs
;
277 // Maintains the TemplateURLs used.
278 Providers providers_
;
281 AutocompleteInput input_
;
283 // Input when searching against the keyword provider.
284 AutocompleteInput keyword_input_
;
286 // Searches in the user's history that begin with the input text.
287 HistoryResults keyword_history_results_
;
288 HistoryResults default_history_results_
;
290 // A timer to start a query to the suggest server after the user has stopped
291 // typing for long enough.
292 base::OneShotTimer
<SearchProvider
> timer_
;
294 // The time at which we sent a query to the suggest server.
295 base::TimeTicks time_suggest_request_sent_
;
297 // Fetchers used to retrieve results for the keyword and default providers.
298 scoped_ptr
<net::URLFetcher
> keyword_fetcher_
;
299 scoped_ptr
<net::URLFetcher
> default_fetcher_
;
301 // Results from the default and keyword search providers.
302 Results default_results_
;
303 Results keyword_results_
;
305 GURL current_page_url_
;
307 DISALLOW_COPY_AND_ASSIGN(SearchProvider
);
310 #endif // CHROME_BROWSER_AUTOCOMPLETE_SEARCH_PROVIDER_H_