1 // Copyright 2014 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 class contains common functionality for search-based autocomplete
6 // providers. Search provider and zero suggest provider both use it for common
9 #ifndef CHROME_BROWSER_AUTOCOMPLETE_BASE_SEARCH_PROVIDER_H_
10 #define CHROME_BROWSER_AUTOCOMPLETE_BASE_SEARCH_PROVIDER_H_
17 #include "base/strings/string16.h"
18 #include "chrome/browser/autocomplete/autocomplete_input.h"
19 #include "chrome/browser/autocomplete/autocomplete_match.h"
20 #include "chrome/browser/autocomplete/autocomplete_provider.h"
21 #include "net/url_request/url_fetcher_delegate.h"
23 class AutocompleteProviderListener;
32 // Base functionality for receiving suggestions from a search engine.
33 // This class is abstract and should only be used as a base for other
34 // autocomplete providers utilizing its functionality.
35 class BaseSearchProvider : public AutocompleteProvider,
36 public net::URLFetcherDelegate {
38 BaseSearchProvider(AutocompleteProviderListener* listener,
40 AutocompleteProvider::Type type);
42 // Returns whether |match| is flagged as a query that should be prefetched.
43 static bool ShouldPrefetch(const AutocompleteMatch& match);
45 // AutocompleteProvider:
46 virtual void Stop(bool clear_cached_results) OVERRIDE;
47 virtual void AddProviderInfo(ProvidersInfo* provider_info) const OVERRIDE;
49 bool field_trial_triggered_in_session() const {
50 return field_trial_triggered_in_session_;
54 // The following keys are used to record additional information on matches.
56 // We annotate our AutocompleteMatches with whether their relevance scores
57 // were server-provided using this key in the |additional_info| field.
58 static const char kRelevanceFromServerKey[];
60 // Indicates whether the server said a match should be prefetched.
61 static const char kShouldPrefetchKey[];
63 // Used to store metadata from the server response, which is needed for
65 static const char kSuggestMetadataKey[];
67 // Used to store a deletion request url for server-provided suggestions.
68 static const char kDeletionUrlKey[];
70 // These are the values for the above keys.
71 static const char kTrue[];
72 static const char kFalse[];
74 virtual ~BaseSearchProvider();
76 // The Result classes are intermediate representations of AutocompleteMatches,
77 // simply containing relevance-ranked search and navigation suggestions.
78 // They may be cached to provide some synchronous matches while requests for
79 // new suggestions from updated input are in flight.
80 // TODO(msw) Extend these classes to generate their corresponding matches and
81 // other requisite data, in order to consolidate and simplify the
82 // highly fragmented SearchProvider logic for each Result type.
85 Result(bool from_keyword_provider,
87 bool relevance_from_server);
90 bool from_keyword_provider() const { return from_keyword_provider_; }
92 const base::string16& match_contents() const { return match_contents_; }
93 const ACMatchClassifications& match_contents_class() const {
94 return match_contents_class_;
97 int relevance() const { return relevance_; }
98 void set_relevance(int relevance) { relevance_ = relevance; }
100 bool relevance_from_server() const { return relevance_from_server_; }
101 void set_relevance_from_server(bool relevance_from_server) {
102 relevance_from_server_ = relevance_from_server;
105 // Returns if this result is inlineable against the current input |input|.
106 // Non-inlineable results are stale.
107 virtual bool IsInlineable(const base::string16& input) const = 0;
109 // Returns the default relevance value for this result (which may
110 // be left over from a previous omnibox input) given the current
111 // input and whether the current input caused a keyword provider
113 virtual int CalculateRelevance(const AutocompleteInput& input,
114 bool keyword_provider_requested) const = 0;
117 // The contents to be displayed and its style info.
118 base::string16 match_contents_;
119 ACMatchClassifications match_contents_class_;
121 // True if the result came from the keyword provider.
122 bool from_keyword_provider_;
124 // The relevance score.
128 // Whether this result's relevance score was fully or partly calculated
129 // based on server information, and thus is assumed to be more accurate.
130 // This is ultimately used in
131 // SearchProvider::ConvertResultsToAutocompleteMatches(), see comments
133 bool relevance_from_server_;
136 class SuggestResult : public Result {
138 SuggestResult(const base::string16& suggestion,
139 AutocompleteMatchType::Type type,
140 const base::string16& match_contents,
141 const base::string16& annotation,
142 const std::string& suggest_query_params,
143 const std::string& deletion_url,
144 bool from_keyword_provider,
146 bool relevance_from_server,
147 bool should_prefetch,
148 const base::string16& input_text);
149 virtual ~SuggestResult();
151 const base::string16& suggestion() const { return suggestion_; }
152 AutocompleteMatchType::Type type() const { return type_; }
153 const base::string16& annotation() const { return annotation_; }
154 const std::string& suggest_query_params() const {
155 return suggest_query_params_;
157 const std::string& deletion_url() const { return deletion_url_; }
158 bool should_prefetch() const { return should_prefetch_; }
160 // Fills in |match_contents_class_| to reflect how |match_contents_| should
161 // be displayed and bolded against the current |input_text|. If
162 // |allow_bolding_all| is false and |match_contents_class_| would have all
163 // of |match_contents_| bolded, do nothing.
164 void ClassifyMatchContents(const bool allow_bolding_all,
165 const base::string16& input_text);
168 virtual bool IsInlineable(const base::string16& input) const OVERRIDE;
169 virtual int CalculateRelevance(
170 const AutocompleteInput& input,
171 bool keyword_provider_requested) const OVERRIDE;
174 // The search terms to be used for this suggestion.
175 base::string16 suggestion_;
177 AutocompleteMatchType::Type type_;
179 // Optional annotation for the |match_contents_| for disambiguation.
180 // This may be displayed in the autocomplete match contents, but is defined
181 // separately to facilitate different formatting.
182 base::string16 annotation_;
184 // Optional additional parameters to be added to the search URL.
185 std::string suggest_query_params_;
187 // Optional deletion URL provided with suggestions. Fetching this URL
188 // should result in some reasonable deletion behaviour on the server,
189 // e.g. deleting this term out of a user's server-side search history.
190 std::string deletion_url_;
192 // Should this result be prefetched?
193 bool should_prefetch_;
196 class NavigationResult : public Result {
198 // |provider| is necessary to use StringForURLDisplay() in order to
199 // compute |formatted_url_|.
200 NavigationResult(const AutocompleteProvider& provider,
202 const base::string16& description,
203 bool from_keyword_provider,
205 bool relevance_from_server,
206 const base::string16& input_text,
207 const std::string& languages);
208 virtual ~NavigationResult();
210 const GURL& url() const { return url_; }
211 const base::string16& description() const { return description_; }
212 const base::string16& formatted_url() const { return formatted_url_; }
214 // Fills in |match_contents_| and |match_contents_class_| to reflect how
215 // the URL should be displayed and bolded against the current |input_text|
216 // and user |languages|. If |allow_bolding_nothing| is false and
217 // |match_contents_class_| would result in an entirely unbolded
218 // |match_contents_|, do nothing.
219 void CalculateAndClassifyMatchContents(const bool allow_bolding_nothing,
220 const base::string16& input_text,
221 const std::string& languages);
224 virtual bool IsInlineable(const base::string16& input) const OVERRIDE;
225 virtual int CalculateRelevance(
226 const AutocompleteInput& input,
227 bool keyword_provider_requested) const OVERRIDE;
230 // The suggested url for navigation.
233 // The properly formatted ("fixed up") URL string with equivalent meaning
234 // to the one in |url_|.
235 base::string16 formatted_url_;
237 // The suggested navigational result description; generally the site name.
238 base::string16 description_;
241 typedef std::vector<SuggestResult> SuggestResults;
242 typedef std::vector<NavigationResult> NavigationResults;
243 typedef std::pair<base::string16, std::string> MatchKey;
244 typedef std::map<MatchKey, AutocompleteMatch> MatchMap;
246 // A simple structure bundling most of the information (including
247 // both SuggestResults and NavigationResults) returned by a call to
248 // the suggest server.
250 // This has to be declared after the typedefs since it relies on some of them.
255 // Clears |suggest_results| and |navigation_results| and resets
256 // |verbatim_relevance| to -1 (implies unset).
259 // Returns whether any of the results (including verbatim) have
260 // server-provided scores.
261 bool HasServerProvidedScores() const;
263 // Query suggestions sorted by relevance score.
264 SuggestResults suggest_results;
266 // Navigational suggestions sorted by relevance score.
267 NavigationResults navigation_results;
269 // The server supplied verbatim relevance scores. Negative values
270 // indicate that there is no suggested score; a value of 0
271 // suppresses the verbatim result.
272 int verbatim_relevance;
274 // The JSON metadata associated with this server response.
275 std::string metadata;
278 DISALLOW_COPY_AND_ASSIGN(Results);
281 // Returns an AutocompleteMatch with the given |autocomplete_provider|
282 // for the search |suggestion|, which represents a search via |template_url|.
283 // If |template_url| is NULL, returns a match with an invalid destination URL.
285 // |input| is the original user input. Text in the input is used to highlight
286 // portions of the match contents to distinguish locally-typed text from
289 // |input| is also necessary for various other details, like whether we should
290 // allow inline autocompletion and what the transition type should be.
291 // |accepted_suggestion| and |omnibox_start_margin| are used to generate
292 // Assisted Query Stats.
293 // |append_extra_query_params| should be set if |template_url| is the default
294 // search engine, so the destination URL will contain any
295 // command-line-specified query params.
296 static AutocompleteMatch CreateSearchSuggestion(
297 AutocompleteProvider* autocomplete_provider,
298 const AutocompleteInput& input,
299 const SuggestResult& suggestion,
300 const TemplateURL* template_url,
301 int accepted_suggestion,
302 int omnibox_start_margin,
303 bool append_extra_query_params);
305 // Parses JSON response received from the provider, stripping XSSI
306 // protection if needed. Returns the parsed data if successful, NULL
308 static scoped_ptr<base::Value> DeserializeJsonData(std::string json_data);
310 // Returns whether we can send the URL of the current page in any suggest
311 // requests. Doing this requires that all the following hold:
312 // * The user has suggest enabled in their settings and is not in incognito
313 // mode. (Incognito disables suggest entirely.)
314 // * The current URL is HTTP, or HTTPS with the same domain as the suggest
315 // server. Non-HTTP[S] URLs (e.g. FTP/file URLs) may contain sensitive
316 // information. HTTPS URLs may also contain sensitive information, but if
317 // they're on the same domain as the suggest server, then the relevant
318 // entity could have already seen/logged this data.
319 // * The suggest request is sent over HTTPS. This avoids leaking the current
320 // page URL in world-readable network traffic.
321 // * The user's suggest provider is Google. We might want to allow other
322 // providers to see this data someday, but for now this has only been
323 // implemented for Google. Also see next bullet.
324 // * The user is OK in principle with sending URLs of current pages to their
325 // provider. Today, there is no explicit setting that controls this, but if
326 // the user has tab sync enabled and tab sync is unencrypted, then they're
327 // already sending this data to Google for sync purposes. Thus we use this
328 // setting as a proxy for "it's OK to send such data". In the future,
329 // especially if we want to support suggest providers other than Google, we
330 // may change this to be a standalone setting or part of some explicit
332 static bool CanSendURL(
333 const GURL& current_page_url,
334 const GURL& suggest_url,
335 const TemplateURL* template_url,
336 AutocompleteInput::PageClassification page_classification,
339 // Creates an AutocompleteMatch from |result| to search for the query in
340 // |result|. Adds the created match to |map|; if such a match
341 // already exists, whichever one has lower relevance is eliminated.
342 // |metadata| and |accepted_suggestion| are used for generating an
343 // AutocompleteMatch.
344 void AddMatchToMap(const SuggestResult& result,
345 const std::string& metadata,
346 int accepted_suggestion,
349 // Returns the TemplateURL for the given |result|.
350 virtual const TemplateURL* GetTemplateURL(
351 const SuggestResult& result) const = 0;
353 // Returns the AutocompleteInput based on whether the |result| is from the
354 // default provider or from the keyword provider.
355 virtual const AutocompleteInput GetInput(
356 const SuggestResult& result) const = 0;
358 // Returns whether the destination URL corresponding to the given |result|
359 // should contain command-line-specified query params.
360 virtual bool ShouldAppendExtraParams(const SuggestResult& result) const = 0;
362 // Stops the suggest query.
363 // NOTE: This does not update |done_|. Callers must do so.
364 virtual void StopSuggest() = 0;
366 // Clears the current results.
367 virtual void ClearAllResults() = 0;
369 // Whether a field trial, if any, has triggered in the most recent
370 // autocomplete query. This field is set to true only if the suggestion
371 // provider has completed and the response contained
372 // '"google:fieldtrialtriggered":true'.
373 bool field_trial_triggered_;
375 // Same as above except that it is maintained across the current Omnibox
377 bool field_trial_triggered_in_session_;
380 DISALLOW_COPY_AND_ASSIGN(BaseSearchProvider);
383 #endif // CHROME_BROWSER_AUTOCOMPLETE_BASE_SEARCH_PROVIDER_H_