zero_suggest_provider.h revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains the zero-suggest autocomplete provider. This experimental 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provider is invoked when the user focuses in the omnibox prior to editing, 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and generates search query suggestions based on the current URL. To enable 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this provider, point --experimental-zero-suggest-url-prefix at an 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// appropriate suggestion service. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HUGE DISCLAIMER: This is just here for experimenting and will probably be 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// deleted entirely as we revise how suggestions work with the omnibox. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_ 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#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|, limiting suggestions to those 74 // matching |user_text|. |user_text| may be non-empty if the user previously 75 // interacted with zero-suggest suggestions and then unfocused the omnibox. 76 // TODO(jered): Rip out |user_text| once the first match is decoupled from 77 // the current typing in the omnibox. 78 void StartZeroSuggest(const GURL& url, const string16& user_text); 79 80 private: 81 ZeroSuggestProvider(AutocompleteProviderListener* listener, 82 Profile* profile); 83 84 virtual ~ZeroSuggestProvider(); 85 86 bool ShouldRunZeroSuggest(const GURL& url) const; 87 88 // The 4 functions below (that take classes defined in SearchProvider as 89 // arguments) were copied and trimmed from SearchProvider. 90 // TODO(hfung): Refactor them into a new base class common to both 91 // ZeroSuggestProvider and SearchProvider. 92 93 // From the OpenSearch formatted response |root_val|, populate query 94 // suggestions into |suggest_results|, navigation suggestions into 95 // |navigation_results|, and the verbatim relevance score into 96 // |verbatim_relevance|. 97 void FillResults(const base::Value& root_val, 98 int* verbatim_relevance, 99 SearchProvider::SuggestResults* suggest_results, 100 SearchProvider::NavigationResults* navigation_results); 101 102 // Creates AutocompleteMatches for "Search |provider_keyword| for 103 // <suggestion>" for all suggestions in |results|, and adds them to |map|. 104 void AddSuggestResultsToMap(const SearchProvider::SuggestResults& results, 105 const string16& provider_keyword, 106 SearchProvider::MatchMap* map); 107 108 // Creates an AutocompleteMatch for "Search |provider_keyword| for 109 // |query_string|". The supplied |relevance| and |type| and 110 // |accepted_suggestion| will also be used to create the AutocompleteMatch. 111 // Adds this match to |map|; if such a match already exists, whichever one 112 // has lower relevance is eliminated. 113 void AddMatchToMap(const string16& query_string, 114 const string16& provider_keyword, 115 int relevance, 116 AutocompleteMatch::Type type, 117 int accepted_suggestion, 118 SearchProvider::MatchMap* map); 119 120 // Returns an AutocompleteMatch for a navigational suggestion |navigation|. 121 AutocompleteMatch NavigationToMatch( 122 const SearchProvider::NavigationResult& navigation); 123 124 // Sets |user_text_modified_| if the user has modified the omnibox text, based 125 // on the user input |user_text|. 126 void CheckIfTextModfied(const string16& user_text); 127 128 // Fetches zero-suggest suggestions for |current_query_|. 129 void Run(); 130 131 // Parses results from the zero-suggest server and updates results. 132 void ParseSuggestResults(const base::Value& root_val); 133 134 // Converts the parsed results to a set of AutocompleteMatches, based on user 135 // input |user_text|, and adds them to |matches_|. If |update_histograms| is 136 // true, also update the histograms for how many results were received. 137 void ConvertResultsToAutocompleteMatches(string16 user_text, 138 bool update_histograms); 139 140 // Returns an AutocompleteMatch for the current URL. The match should be in 141 // the top position so that pressing enter has the effect of reloading the 142 // page. 143 AutocompleteMatch MatchForCurrentURL(); 144 145 // Used to build default search engine URLs for suggested queries. 146 TemplateURLService* template_url_service_; 147 148 // The URL for which a suggestion fetch is pending. 149 std::string current_query_; 150 151 // What the user has typed. 152 string16 original_user_text_; 153 // Whether the user has modified the omnibox since the zero suggest request. 154 bool user_text_modified_; 155 156 // Fetcher used to retrieve results. 157 scoped_ptr<net::URLFetcher> fetcher_; 158 // Whether there's a pending request in flight. 159 bool have_pending_request_; 160 161 // Suggestion for the current URL. 162 AutocompleteMatch current_url_match_; 163 // Navigation suggestions for the most recent ZeroSuggest input URL. 164 SearchProvider::NavigationResults navigation_results_; 165 // Query suggestions for the most recent ZeroSuggest input URL. 166 SearchProvider::MatchMap query_matches_map_; 167 // The relevance score for the URL of the current page. 168 int verbatim_relevance_; 169 170 // Whether a field trial, if any, has triggered in the most recent 171 // autocomplete query. This field is set to true if the last request 172 // was a zero suggest request, the provider has completed and their 173 // corresponding response contained '"google:fieldtrialtriggered":true'. 174 bool field_trial_triggered_; 175 // Whether a zero suggest request triggered a field trial in the omnibox 176 // session. The user could have clicked on a suggestion when zero suggest 177 // triggered (same condition as field_trial_triggered_), or triggered zero 178 // suggest but kept typing. 179 bool field_trial_triggered_in_session_; 180 181 DISALLOW_COPY_AND_ASSIGN(ZeroSuggestProvider); 182}; 183 184#endif // CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_ 185