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