blob: f6fafa50f215ae028da9e3d1d1d3ebdf7a88d7a3 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010017#include <map>
Torne (Richard Coles)58218062012-11-14 11:43:16 +000018#include <string>
19#include <vector>
20
21#include "base/basictypes.h"
22#include "base/compiler_specific.h"
23#include "base/memory/scoped_ptr.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010024#include "base/strings/string16.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000025#include "chrome/browser/autocomplete/autocomplete_provider.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010026#include "chrome/browser/autocomplete/search_provider.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000027#include "net/url_request/url_fetcher_delegate.h"
28
29class AutocompleteInput;
30class GURL;
31class TemplateURLService;
32
33namespace base {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010034class ListValue;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000035class 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:
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010055 // Creates and returns an instance of this provider.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000056 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
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010064 // 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
Torne (Richard Coles)58218062012-11-14 11:43:16 +000070 // net::URLFetcherDelegate
71 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
72
Ben Murdochd3868032013-07-31 10:55:33 +010073 // 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);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000080
81 private:
82 ZeroSuggestProvider(AutocompleteProviderListener* listener,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010083 Profile* profile);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000084
85 virtual ~ZeroSuggestProvider();
86
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010087 bool ShouldRunZeroSuggest(const GURL& url) const;
88
Ben Murdochbb1529c2013-08-08 10:24:53 +010089 // Whether the URL can get Zero Suggest. For example, don't send the URL of
90 // non-Google HTTPS requests because it may contain sensitive information.
91 bool ShouldSendURL(const GURL& url) const;
92
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010093 // The 4 functions below (that take classes defined in SearchProvider as
94 // arguments) were copied and trimmed from SearchProvider.
95 // TODO(hfung): Refactor them into a new base class common to both
96 // ZeroSuggestProvider and SearchProvider.
97
98 // From the OpenSearch formatted response |root_val|, populate query
99 // suggestions into |suggest_results|, navigation suggestions into
100 // |navigation_results|, and the verbatim relevance score into
101 // |verbatim_relevance|.
102 void FillResults(const base::Value& root_val,
103 int* verbatim_relevance,
104 SearchProvider::SuggestResults* suggest_results,
105 SearchProvider::NavigationResults* navigation_results);
106
Ben Murdocheb525c52013-07-10 11:40:50 +0100107 // Creates AutocompleteMatches to search |template_url| for "<suggestion>" for
108 // all suggestions in |results|, and adds them to |map|.
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100109 void AddSuggestResultsToMap(const SearchProvider::SuggestResults& results,
Ben Murdocheb525c52013-07-10 11:40:50 +0100110 const TemplateURL* template_url,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100111 SearchProvider::MatchMap* map);
112
Ben Murdocheb525c52013-07-10 11:40:50 +0100113 // Creates an AutocompleteMatch with the provided |relevance| and |type| to
114 // search |template_url| for |query_string|. |accepted_suggestion| will be
115 // used to generate Assisted Query Stats.
116 //
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100117 // Adds this match to |map|; if such a match already exists, whichever one
118 // has lower relevance is eliminated.
Ben Murdocheb525c52013-07-10 11:40:50 +0100119 void AddMatchToMap(int relevance,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100120 AutocompleteMatch::Type type,
Ben Murdocheb525c52013-07-10 11:40:50 +0100121 const TemplateURL* template_url,
122 const string16& query_string,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100123 int accepted_suggestion,
124 SearchProvider::MatchMap* map);
125
126 // Returns an AutocompleteMatch for a navigational suggestion |navigation|.
127 AutocompleteMatch NavigationToMatch(
128 const SearchProvider::NavigationResult& navigation);
129
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000130 // Fetches zero-suggest suggestions for |current_query_|.
131 void Run();
132
133 // Parses results from the zero-suggest server and updates results.
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100134 void ParseSuggestResults(const base::Value& root_val);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000135
Ben Murdocheb525c52013-07-10 11:40:50 +0100136 // Converts the parsed results to a set of AutocompleteMatches and adds them
137 // to |matches_|. Also update the histograms for how many results were
138 // received.
139 void ConvertResultsToAutocompleteMatches();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000140
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100141 // Returns an AutocompleteMatch for the current URL. The match should be in
142 // the top position so that pressing enter has the effect of reloading the
143 // page.
144 AutocompleteMatch MatchForCurrentURL();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000145
146 // Used to build default search engine URLs for suggested queries.
147 TemplateURLService* template_url_service_;
148
149 // The URL for which a suggestion fetch is pending.
150 std::string current_query_;
151
Ben Murdochd3868032013-07-31 10:55:33 +0100152 // The type of page the user is viewing (a search results page doing search
153 // term replacement, an arbitrary URL, etc.).
154 AutocompleteInput::PageClassification current_page_classification_;
155
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100156 // Copy of OmniboxEditModel::permanent_text_.
157 string16 permanent_text_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000158
159 // Fetcher used to retrieve results.
160 scoped_ptr<net::URLFetcher> fetcher_;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100161 // Whether there's a pending request in flight.
162 bool have_pending_request_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000163
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100164 // Suggestion for the current URL.
165 AutocompleteMatch current_url_match_;
166 // Navigation suggestions for the most recent ZeroSuggest input URL.
167 SearchProvider::NavigationResults navigation_results_;
168 // Query suggestions for the most recent ZeroSuggest input URL.
169 SearchProvider::MatchMap query_matches_map_;
170 // The relevance score for the URL of the current page.
171 int verbatim_relevance_;
172
173 // Whether a field trial, if any, has triggered in the most recent
174 // autocomplete query. This field is set to true if the last request
175 // was a zero suggest request, the provider has completed and their
176 // corresponding response contained '"google:fieldtrialtriggered":true'.
177 bool field_trial_triggered_;
178 // Whether a zero suggest request triggered a field trial in the omnibox
179 // session. The user could have clicked on a suggestion when zero suggest
180 // triggered (same condition as field_trial_triggered_), or triggered zero
181 // suggest but kept typing.
182 bool field_trial_triggered_in_session_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000183
184 DISALLOW_COPY_AND_ASSIGN(ZeroSuggestProvider);
185};
186
187#endif // CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_