zero_suggest_provider.h revision 3551c9c881056c480085172ff9840cab31610854
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 zero-suggest autocomplete provider. This experimental
6// provider is invoked when the user focuses in the omnibox prior to editing,
7// and generates search query suggestions based on the current URL. To enable
8// this provider, point --experimental-zero-suggest-url-prefix at an
9// appropriate suggestion service.
10//
11// HUGE DISCLAIMER: This is just here for experimenting and will probably be
12// deleted entirely as we revise how suggestions work with the omnibox.
13
14#ifndef CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_
15#define CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_
16
17#include <map>
18#include <string>
19#include <vector>
20
21#include "base/basictypes.h"
22#include "base/compiler_specific.h"
23#include "base/memory/scoped_ptr.h"
24#include "base/strings/string16.h"
25#include "chrome/browser/autocomplete/autocomplete_provider.h"
26#include "chrome/browser/autocomplete/search_provider.h"
27#include "net/url_request/url_fetcher_delegate.h"
28
29class AutocompleteInput;
30class GURL;
31class TemplateURLService;
32
33namespace base {
34class ListValue;
35class Value;
36}
37
38namespace net {
39class URLFetcher;
40}
41
42// Autocomplete provider for searches based on the current URL.
43//
44// The controller will call StartZeroSuggest when the user focuses in the
45// omnibox. After construction, the autocomplete controller repeatedly calls
46// Start() with some user input, each time expecting to receive an updated
47// set of matches.
48//
49// TODO(jered): Consider deleting this class and building this functionality
50// into SearchProvider after dogfood and after we break the association between
51// omnibox text and suggestions.
52class ZeroSuggestProvider : public AutocompleteProvider,
53                            public net::URLFetcherDelegate {
54 public:
55  // Creates and returns an instance of this provider.
56  static ZeroSuggestProvider* Create(AutocompleteProviderListener* listener,
57                                     Profile* profile);
58
59  // AutocompleteProvider:
60  virtual void Start(const AutocompleteInput& input,
61                     bool /*minimal_changes*/) OVERRIDE;
62  virtual void Stop(bool clear_cached_results) OVERRIDE;
63
64  // Adds provider-specific information to omnibox event logs.
65  virtual void AddProviderInfo(ProvidersInfo* provider_info) const OVERRIDE;
66
67  // Sets |field_trial_triggered_| to false.
68  virtual void ResetSession() OVERRIDE;
69
70  // net::URLFetcherDelegate
71  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
72
73  // Initiates a new fetch for the given |url| of classification
74  // |page_classification|. |permanent_text| is the omnibox text
75  // for the current page.
76  void StartZeroSuggest(
77      const GURL& url,
78      AutocompleteInput::PageClassification page_classification,
79      const string16& permanent_text);
80
81  bool field_trial_triggered_in_session() const {
82    return field_trial_triggered_in_session_;
83  }
84
85 private:
86  ZeroSuggestProvider(AutocompleteProviderListener* listener,
87                      Profile* profile);
88
89  virtual ~ZeroSuggestProvider();
90
91  bool ShouldRunZeroSuggest(const GURL& url) const;
92
93  // Whether the URL can get Zero Suggest.  For example, don't send the URL of
94  // non-Google HTTPS requests because it may contain sensitive information.
95  bool ShouldSendURL(const GURL& url) const;
96
97  // The 4 functions below (that take classes defined in SearchProvider as
98  // arguments) were copied and trimmed from SearchProvider.
99  // TODO(hfung): Refactor them into a new base class common to both
100  // ZeroSuggestProvider and SearchProvider.
101
102  // From the OpenSearch formatted response |root_val|, populate query
103  // suggestions into |suggest_results|, navigation suggestions into
104  // |navigation_results|, and the verbatim relevance score into
105  // |verbatim_relevance|.
106  void FillResults(const base::Value& root_val,
107                   int* verbatim_relevance,
108                   SearchProvider::SuggestResults* suggest_results,
109                   SearchProvider::NavigationResults* navigation_results);
110
111  // Creates AutocompleteMatches to search |template_url| for "<suggestion>" for
112  // all suggestions in |results|, and adds them to |map|.
113  void AddSuggestResultsToMap(const SearchProvider::SuggestResults& results,
114                              const TemplateURL* template_url,
115                              SearchProvider::MatchMap* map);
116
117  // Creates an AutocompleteMatch with the provided |relevance| and |type| to
118  // search |template_url| for |query_string|.  |accepted_suggestion| will be
119  // used to generate Assisted Query Stats.
120  //
121  // Adds this match to |map|; if such a match already exists, whichever one
122  // has lower relevance is eliminated.
123  void AddMatchToMap(int relevance,
124                     AutocompleteMatch::Type type,
125                     const TemplateURL* template_url,
126                     const string16& query_string,
127                     int accepted_suggestion,
128                     SearchProvider::MatchMap* map);
129
130  // Returns an AutocompleteMatch for a navigational suggestion |navigation|.
131  AutocompleteMatch NavigationToMatch(
132      const SearchProvider::NavigationResult& navigation);
133
134  // Fetches zero-suggest suggestions for |current_query_|.
135  void Run();
136
137  // Parses results from the zero-suggest server and updates results.
138  void ParseSuggestResults(const base::Value& root_val);
139
140  // Converts the parsed results to a set of AutocompleteMatches and adds them
141  // to |matches_|.  Also update the histograms for how many results were
142  // received.
143  void ConvertResultsToAutocompleteMatches();
144
145  // Returns an AutocompleteMatch for the current URL. The match should be in
146  // the top position so that pressing enter has the effect of reloading the
147  // page.
148  AutocompleteMatch MatchForCurrentURL();
149
150  // Used to build default search engine URLs for suggested queries.
151  TemplateURLService* template_url_service_;
152
153  // The URL for which a suggestion fetch is pending.
154  std::string current_query_;
155
156  // The type of page the user is viewing (a search results page doing search
157  // term replacement, an arbitrary URL, etc.).
158  AutocompleteInput::PageClassification current_page_classification_;
159
160  // Copy of OmniboxEditModel::permanent_text_.
161  string16 permanent_text_;
162
163  // Fetcher used to retrieve results.
164  scoped_ptr<net::URLFetcher> fetcher_;
165  // Whether there's a pending request in flight.
166  bool have_pending_request_;
167
168  // Suggestion for the current URL.
169  AutocompleteMatch current_url_match_;
170  // Navigation suggestions for the most recent ZeroSuggest input URL.
171  SearchProvider::NavigationResults navigation_results_;
172  // Query suggestions for the most recent ZeroSuggest input URL.
173  SearchProvider::MatchMap query_matches_map_;
174  // The relevance score for the URL of the current page.
175  int verbatim_relevance_;
176
177  // Whether a field trial, if any, has triggered in the most recent
178  // autocomplete query. This field is set to true if the last request
179  // was a zero suggest request, the provider has completed and their
180  // corresponding response contained '"google:fieldtrialtriggered":true'.
181  bool field_trial_triggered_;
182  // Whether a zero suggest request triggered a field trial in the omnibox
183  // session.  The user could have clicked on a suggestion when zero suggest
184  // triggered (same condition as field_trial_triggered_), or triggered zero
185  // suggest but kept typing.
186  bool field_trial_triggered_in_session_;
187
188  DISALLOW_COPY_AND_ASSIGN(ZeroSuggestProvider);
189};
190
191#endif  // CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_
192