Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 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 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 17 | #include <map> |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 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" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 24 | #include "base/strings/string16.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 25 | #include "chrome/browser/autocomplete/autocomplete_provider.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 26 | #include "chrome/browser/autocomplete/search_provider.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 27 | #include "net/url_request/url_fetcher_delegate.h" |
| 28 | |
| 29 | class AutocompleteInput; |
| 30 | class GURL; |
| 31 | class TemplateURLService; |
| 32 | |
| 33 | namespace base { |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 34 | class ListValue; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 35 | class Value; |
| 36 | } |
| 37 | |
| 38 | namespace net { |
| 39 | class 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. |
| 52 | class ZeroSuggestProvider : public AutocompleteProvider, |
| 53 | public net::URLFetcherDelegate { |
| 54 | public: |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 55 | // Creates and returns an instance of this provider. |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 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 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 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 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 70 | // net::URLFetcherDelegate |
| 71 | virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; |
| 72 | |
Ben Murdoch | d386803 | 2013-07-31 10:55:33 +0100 | [diff] [blame] | 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); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 80 | |
| 81 | private: |
| 82 | ZeroSuggestProvider(AutocompleteProviderListener* listener, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 83 | Profile* profile); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 84 | |
| 85 | virtual ~ZeroSuggestProvider(); |
| 86 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 87 | bool ShouldRunZeroSuggest(const GURL& url) const; |
| 88 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 89 | // 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) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 93 | // 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 Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 107 | // Creates AutocompleteMatches to search |template_url| for "<suggestion>" for |
| 108 | // all suggestions in |results|, and adds them to |map|. |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 109 | void AddSuggestResultsToMap(const SearchProvider::SuggestResults& results, |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 110 | const TemplateURL* template_url, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 111 | SearchProvider::MatchMap* map); |
| 112 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 113 | // 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) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 117 | // Adds this match to |map|; if such a match already exists, whichever one |
| 118 | // has lower relevance is eliminated. |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 119 | void AddMatchToMap(int relevance, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 120 | AutocompleteMatch::Type type, |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 121 | const TemplateURL* template_url, |
| 122 | const string16& query_string, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 123 | 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) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 130 | // 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) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 134 | void ParseSuggestResults(const base::Value& root_val); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 135 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 136 | // 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) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 140 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 141 | // 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) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 145 | |
| 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 Murdoch | d386803 | 2013-07-31 10:55:33 +0100 | [diff] [blame] | 152 | // 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) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 156 | // Copy of OmniboxEditModel::permanent_text_. |
| 157 | string16 permanent_text_; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 158 | |
| 159 | // Fetcher used to retrieve results. |
| 160 | scoped_ptr<net::URLFetcher> fetcher_; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 161 | // Whether there's a pending request in flight. |
| 162 | bool have_pending_request_; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 163 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 164 | // 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) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 183 | |
| 184 | DISALLOW_COPY_AND_ASSIGN(ZeroSuggestProvider); |
| 185 | }; |
| 186 | |
| 187 | #endif // CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_ |