zero_suggest_provider.h revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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( 92 const GURL& url, 93 AutocompleteInput::PageClassification page_classification) const; 94 95 // Whether the URL can get Zero Suggest. For example, don't send the URL of 96 // non-Google HTTPS requests because it may contain sensitive information. 97 bool ShouldSendURL( 98 const GURL& url, 99 AutocompleteInput::PageClassification page_classification) const; 100 101 // The 4 functions below (that take classes defined in SearchProvider as 102 // arguments) were copied and trimmed from SearchProvider. 103 // TODO(hfung): Refactor them into a new base class common to both 104 // ZeroSuggestProvider and SearchProvider. 105 106 // From the OpenSearch formatted response |root_val|, populate query 107 // suggestions into |suggest_results|, navigation suggestions into 108 // |navigation_results|, and the verbatim relevance score into 109 // |verbatim_relevance|. 110 void FillResults(const base::Value& root_val, 111 int* verbatim_relevance, 112 SearchProvider::SuggestResults* suggest_results, 113 SearchProvider::NavigationResults* navigation_results); 114 115 // Creates AutocompleteMatches to search |template_url| for "<suggestion>" for 116 // all suggestions in |results|, and adds them to |map|. 117 void AddSuggestResultsToMap(const SearchProvider::SuggestResults& results, 118 const TemplateURL* template_url, 119 SearchProvider::MatchMap* map); 120 121 // Creates an AutocompleteMatch with the provided |relevance| and |type| to 122 // search |template_url| for |query_string|. |accepted_suggestion| will be 123 // used to generate Assisted Query Stats. 124 // 125 // Adds this match to |map|; if such a match already exists, whichever one 126 // has lower relevance is eliminated. 127 void AddMatchToMap(int relevance, 128 AutocompleteMatch::Type type, 129 const TemplateURL* template_url, 130 const string16& query_string, 131 int accepted_suggestion, 132 SearchProvider::MatchMap* map); 133 134 // Returns an AutocompleteMatch for a navigational suggestion |navigation|. 135 AutocompleteMatch NavigationToMatch( 136 const SearchProvider::NavigationResult& navigation); 137 138 // Fetches zero-suggest suggestions for |current_query_|. 139 void Run(); 140 141 // Parses results from the zero-suggest server and updates results. 142 void ParseSuggestResults(const base::Value& root_val); 143 144 // Converts the parsed results to a set of AutocompleteMatches and adds them 145 // to |matches_|. Also update the histograms for how many results were 146 // received. 147 void ConvertResultsToAutocompleteMatches(); 148 149 // Returns an AutocompleteMatch for the current URL. The match should be in 150 // the top position so that pressing enter has the effect of reloading the 151 // page. 152 AutocompleteMatch MatchForCurrentURL(); 153 154 // When the user is in the Most Visited field trial, we ask the TopSites 155 // service for the most visited URLs during Run(). It calls back to this 156 // function to return those |urls|. 157 void OnMostVisitedUrlsAvailable(const history::MostVisitedURLList& urls); 158 159 // Used to build default search engine URLs for suggested queries. 160 TemplateURLService* template_url_service_; 161 162 // The URL for which a suggestion fetch is pending. 163 std::string current_query_; 164 165 // The type of page the user is viewing (a search results page doing search 166 // term replacement, an arbitrary URL, etc.). 167 AutocompleteInput::PageClassification current_page_classification_; 168 169 // Copy of OmniboxEditModel::permanent_text_. 170 string16 permanent_text_; 171 172 // Fetcher used to retrieve results. 173 scoped_ptr<net::URLFetcher> fetcher_; 174 // Whether there's a pending request in flight. 175 bool have_pending_request_; 176 177 // Suggestion for the current URL. 178 AutocompleteMatch current_url_match_; 179 // Navigation suggestions for the most recent ZeroSuggest input URL. 180 SearchProvider::NavigationResults navigation_results_; 181 // Query suggestions for the most recent ZeroSuggest input URL. 182 SearchProvider::MatchMap query_matches_map_; 183 // The relevance score for the URL of the current page. 184 int verbatim_relevance_; 185 186 // Whether a field trial, if any, has triggered in the most recent 187 // autocomplete query. This field is set to true if the last request 188 // was a zero suggest request, the provider has completed and their 189 // corresponding response contained '"google:fieldtrialtriggered":true'. 190 bool field_trial_triggered_; 191 // Whether a zero suggest request triggered a field trial in the omnibox 192 // session. The user could have clicked on a suggestion when zero suggest 193 // triggered (same condition as field_trial_triggered_), or triggered zero 194 // suggest but kept typing. 195 bool field_trial_triggered_in_session_; 196 197 history::MostVisitedURLList most_visited_urls_; 198 199 // For callbacks that may be run after destruction. 200 base::WeakPtrFactory<ZeroSuggestProvider> weak_ptr_factory_; 201 202 DISALLOW_COPY_AND_ASSIGN(ZeroSuggestProvider); 203}; 204 205#endif // CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_PROVIDER_H_ 206