Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/autocomplete/zero_suggest_provider.h" | 5 #include "chrome/browser/autocomplete/zero_suggest_provider.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/i18n/case_conversion.h" | 8 #include "base/i18n/case_conversion.h" |
| 9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 void ZeroSuggestProvider::ModifyProviderInfo( | 159 void ZeroSuggestProvider::ModifyProviderInfo( |
| 160 metrics::OmniboxEventProto_ProviderInfo* provider_info) const { | 160 metrics::OmniboxEventProto_ProviderInfo* provider_info) const { |
| 161 if (!results_.suggest_results.empty() || !results_.navigation_results.empty()) | 161 if (!results_.suggest_results.empty() || !results_.navigation_results.empty()) |
| 162 provider_info->set_times_returned_results_in_session(1); | 162 provider_info->set_times_returned_results_in_session(1); |
| 163 } | 163 } |
| 164 | 164 |
| 165 ZeroSuggestProvider::ZeroSuggestProvider( | 165 ZeroSuggestProvider::ZeroSuggestProvider( |
| 166 AutocompleteProviderListener* listener, | 166 AutocompleteProviderListener* listener, |
| 167 TemplateURLService* template_url_service, | 167 TemplateURLService* template_url_service, |
| 168 Profile* profile) | 168 Profile* profile) |
| 169 : BaseSearchProvider(listener, template_url_service, profile, | 169 : BaseSearchProvider(template_url_service, profile, |
| 170 AutocompleteProvider::TYPE_ZERO_SUGGEST), | 170 AutocompleteProvider::TYPE_ZERO_SUGGEST), |
| 171 listener_(listener), | |
| 171 results_from_cache_(false), | 172 results_from_cache_(false), |
| 172 weak_ptr_factory_(this) { | 173 weak_ptr_factory_(this) { |
| 173 } | 174 } |
| 174 | 175 |
| 175 ZeroSuggestProvider::~ZeroSuggestProvider() { | 176 ZeroSuggestProvider::~ZeroSuggestProvider() { |
| 176 } | 177 } |
| 177 | 178 |
| 178 bool ZeroSuggestProvider::StoreSuggestionResponse( | 179 bool ZeroSuggestProvider::StoreSuggestionResponse( |
| 179 const std::string& json_data, | 180 const std::string& json_data, |
| 180 const base::Value& parsed_data) { | 181 const base::Value& parsed_data) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 205 return template_url_service_->GetDefaultSearchProvider(); | 206 return template_url_service_->GetDefaultSearchProvider(); |
| 206 } | 207 } |
| 207 | 208 |
| 208 const AutocompleteInput ZeroSuggestProvider::GetInput(bool is_keyword) const { | 209 const AutocompleteInput ZeroSuggestProvider::GetInput(bool is_keyword) const { |
| 209 return AutocompleteInput( | 210 return AutocompleteInput( |
| 210 base::string16(), base::string16::npos, base::string16(), | 211 base::string16(), base::string16::npos, base::string16(), |
| 211 GURL(current_query_), current_page_classification_, true, false, false, | 212 GURL(current_query_), current_page_classification_, true, false, false, |
| 212 true, ChromeAutocompleteSchemeClassifier(profile_)); | 213 true, ChromeAutocompleteSchemeClassifier(profile_)); |
| 213 } | 214 } |
| 214 | 215 |
| 215 SearchSuggestionParser::Results* ZeroSuggestProvider::GetResultsToFill( | |
| 216 bool is_keyword) { | |
| 217 DCHECK(!is_keyword); | |
| 218 return &results_; | |
| 219 } | |
| 220 | |
| 221 bool ZeroSuggestProvider::ShouldAppendExtraParams( | 216 bool ZeroSuggestProvider::ShouldAppendExtraParams( |
| 222 const SearchSuggestionParser::SuggestResult& result) const { | 217 const SearchSuggestionParser::SuggestResult& result) const { |
| 223 // We always use the default provider for search, so append the params. | 218 // We always use the default provider for search, so append the params. |
| 224 return true; | 219 return true; |
| 225 } | 220 } |
| 226 | 221 |
| 227 void ZeroSuggestProvider::StopSuggest() { | 222 void ZeroSuggestProvider::StopSuggest() { |
| 228 if (suggest_results_pending_ > 0) | 223 if (fetcher_) |
| 229 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_INVALIDATED); | 224 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_INVALIDATED); |
| 230 suggest_results_pending_ = 0; | |
| 231 fetcher_.reset(); | 225 fetcher_.reset(); |
| 232 } | 226 } |
| 233 | 227 |
| 234 void ZeroSuggestProvider::ClearAllResults() { | 228 void ZeroSuggestProvider::ClearAllResults() { |
| 235 // We do not call Clear() on |results_| to retain |verbatim_relevance| | 229 // We do not call Clear() on |results_| to retain |verbatim_relevance| |
| 236 // value in the |results_| object. |verbatim_relevance| is used at the | 230 // value in the |results_| object. |verbatim_relevance| is used at the |
| 237 // beginning of the next StartZeroSuggest() call to determine the current url | 231 // beginning of the next StartZeroSuggest() call to determine the current url |
| 238 // match relevance. | 232 // match relevance. |
| 239 results_.suggest_results.clear(); | 233 results_.suggest_results.clear(); |
| 240 results_.navigation_results.clear(); | 234 results_.navigation_results.clear(); |
| 241 current_query_.clear(); | 235 current_query_.clear(); |
| 242 } | 236 } |
| 243 | 237 |
| 244 int ZeroSuggestProvider::GetDefaultResultRelevance() const { | |
| 245 return kDefaultZeroSuggestRelevance; | |
| 246 } | |
| 247 | |
| 248 void ZeroSuggestProvider::RecordDeletionResult(bool success) { | 238 void ZeroSuggestProvider::RecordDeletionResult(bool success) { |
| 249 if (success) { | 239 if (success) { |
| 250 content::RecordAction( | 240 content::RecordAction( |
| 251 base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Success")); | 241 base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Success")); |
| 252 } else { | 242 } else { |
| 253 content::RecordAction( | 243 content::RecordAction( |
| 254 base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Failure")); | 244 base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Failure")); |
| 255 } | 245 } |
| 256 } | 246 } |
| 257 | 247 |
| 258 void ZeroSuggestProvider::LogFetchComplete(bool success, bool is_keyword) { | |
| 259 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REPLY_RECEIVED); | |
| 260 } | |
| 261 | |
| 262 bool ZeroSuggestProvider::IsKeywordFetcher( | |
| 263 const net::URLFetcher* fetcher) const { | |
| 264 // ZeroSuggestProvider does not have a keyword provider. | |
| 265 DCHECK_EQ(fetcher, fetcher_.get()); | |
| 266 return false; | |
| 267 } | |
| 268 | |
| 269 void ZeroSuggestProvider::UpdateMatches() { | |
| 270 done_ = true; | |
| 271 ConvertResultsToAutocompleteMatches(); | |
| 272 } | |
| 273 | |
| 274 void ZeroSuggestProvider::AddSuggestResultsToMap( | 248 void ZeroSuggestProvider::AddSuggestResultsToMap( |
| 275 const SearchSuggestionParser::SuggestResults& results, | 249 const SearchSuggestionParser::SuggestResults& results, |
| 276 MatchMap* map) { | 250 MatchMap* map) { |
| 277 for (size_t i = 0; i < results.size(); ++i) | 251 for (size_t i = 0; i < results.size(); ++i) |
| 278 AddMatchToMap(results[i], std::string(), i, false, map); | 252 AddMatchToMap(results[i], std::string(), i, false, map); |
| 279 } | 253 } |
| 280 | 254 |
| 281 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( | 255 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( |
| 282 const SearchSuggestionParser::NavigationResult& navigation) { | 256 const SearchSuggestionParser::NavigationResult& navigation) { |
| 283 AutocompleteMatch match(this, navigation.relevance(), false, | 257 AutocompleteMatch match(this, navigation.relevance(), false, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 299 | 273 |
| 300 match.description = | 274 match.description = |
| 301 AutocompleteMatch::SanitizeString(navigation.description()); | 275 AutocompleteMatch::SanitizeString(navigation.description()); |
| 302 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, | 276 AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, |
| 303 match.description.length(), ACMatchClassification::NONE, | 277 match.description.length(), ACMatchClassification::NONE, |
| 304 &match.description_class); | 278 &match.description_class); |
| 305 return match; | 279 return match; |
| 306 } | 280 } |
| 307 | 281 |
| 308 void ZeroSuggestProvider::Run(const GURL& suggest_url) { | 282 void ZeroSuggestProvider::Run(const GURL& suggest_url) { |
| 309 suggest_results_pending_ = 0; | |
| 310 const int kFetcherID = 1; | 283 const int kFetcherID = 1; |
| 311 fetcher_.reset( | 284 fetcher_.reset( |
| 312 net::URLFetcher::Create(kFetcherID, | 285 net::URLFetcher::Create(kFetcherID, |
| 313 suggest_url, | 286 suggest_url, |
| 314 net::URLFetcher::GET, this)); | 287 net::URLFetcher::GET, this)); |
| 315 fetcher_->SetRequestContext(profile_->GetRequestContext()); | 288 fetcher_->SetRequestContext(profile_->GetRequestContext()); |
| 316 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); | 289 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); |
| 317 // Add Chrome experiment state to the request headers. | 290 // Add Chrome experiment state to the request headers. |
| 318 net::HttpRequestHeaders headers; | 291 net::HttpRequestHeaders headers; |
| 319 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( | 292 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( |
| 320 fetcher_->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers); | 293 fetcher_->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers); |
| 321 fetcher_->SetExtraRequestHeaders(headers.ToString()); | 294 fetcher_->SetExtraRequestHeaders(headers.ToString()); |
| 322 fetcher_->Start(); | 295 fetcher_->Start(); |
| 323 | 296 |
| 324 if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) { | 297 if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) { |
| 325 most_visited_urls_.clear(); | 298 most_visited_urls_.clear(); |
| 326 history::TopSites* ts = profile_->GetTopSites(); | 299 history::TopSites* ts = profile_->GetTopSites(); |
| 327 if (ts) { | 300 if (ts) { |
| 328 ts->GetMostVisitedURLs( | 301 ts->GetMostVisitedURLs( |
| 329 base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable, | 302 base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable, |
| 330 weak_ptr_factory_.GetWeakPtr()), false); | 303 weak_ptr_factory_.GetWeakPtr()), false); |
| 331 } | 304 } |
| 332 } | 305 } |
| 333 suggest_results_pending_ = 1; | |
| 334 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT); | 306 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT); |
| 335 } | 307 } |
| 336 | 308 |
| 309 void ZeroSuggestProvider::OnURLFetchComplete(const net::URLFetcher* source) { | |
| 310 DCHECK(!done_); | |
| 311 DCHECK_EQ(fetcher_.get(), source); | |
| 312 | |
| 313 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REPLY_RECEIVED); | |
| 314 | |
| 315 bool results_updated = false; | |
| 316 if (source->GetStatus().is_success() && source->GetResponseCode() == 200) { | |
| 317 std::string json_data = SearchSuggestionParser::ExtractJsonData(source); | |
|
Peter Kasting
2014/08/08 17:33:24
Nit: Would it make sense to have just these condit
hashimoto
2014/08/11 05:15:04
I guess it doesn't benefit us much because ZeroSug
| |
| 318 scoped_ptr<base::Value> data( | |
| 319 SearchSuggestionParser::DeserializeJsonData(json_data)); | |
| 320 if (data) { | |
| 321 if (StoreSuggestionResponse(json_data, *data)) | |
| 322 return; | |
| 323 results_updated = ParseSuggestResults( | |
| 324 *data, kDefaultZeroSuggestRelevance, false, &results_); | |
| 325 } | |
| 326 } | |
| 327 fetcher_.reset(); | |
| 328 done_ = true; | |
| 329 ConvertResultsToAutocompleteMatches(); | |
| 330 listener_->OnProviderUpdate(results_updated); | |
| 331 } | |
| 332 | |
| 337 void ZeroSuggestProvider::OnMostVisitedUrlsAvailable( | 333 void ZeroSuggestProvider::OnMostVisitedUrlsAvailable( |
| 338 const history::MostVisitedURLList& urls) { | 334 const history::MostVisitedURLList& urls) { |
| 339 most_visited_urls_ = urls; | 335 most_visited_urls_ = urls; |
| 340 } | 336 } |
| 341 | 337 |
| 342 void ZeroSuggestProvider::ConvertResultsToAutocompleteMatches() { | 338 void ZeroSuggestProvider::ConvertResultsToAutocompleteMatches() { |
| 343 matches_.clear(); | 339 matches_.clear(); |
| 344 | 340 |
| 345 const TemplateURL* default_provider = | 341 const TemplateURL* default_provider = |
| 346 template_url_service_->GetDefaultSearchProvider(); | 342 template_url_service_->GetDefaultSearchProvider(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 452 | 448 |
| 453 void ZeroSuggestProvider::MaybeUseCachedSuggestions() { | 449 void ZeroSuggestProvider::MaybeUseCachedSuggestions() { |
| 454 if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) | 450 if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) |
| 455 return; | 451 return; |
| 456 | 452 |
| 457 std::string json_data = profile_->GetPrefs()->GetString( | 453 std::string json_data = profile_->GetPrefs()->GetString( |
| 458 prefs::kZeroSuggestCachedResults); | 454 prefs::kZeroSuggestCachedResults); |
| 459 if (!json_data.empty()) { | 455 if (!json_data.empty()) { |
| 460 scoped_ptr<base::Value> data( | 456 scoped_ptr<base::Value> data( |
| 461 SearchSuggestionParser::DeserializeJsonData(json_data)); | 457 SearchSuggestionParser::DeserializeJsonData(json_data)); |
| 462 if (data && ParseSuggestResults(*data.get(), false, &results_)) { | 458 if (data && ParseSuggestResults( |
| 459 *data, kDefaultZeroSuggestRelevance, false, &results_)) { | |
| 463 ConvertResultsToAutocompleteMatches(); | 460 ConvertResultsToAutocompleteMatches(); |
| 464 results_from_cache_ = !matches_.empty(); | 461 results_from_cache_ = !matches_.empty(); |
| 465 } | 462 } |
| 466 } | 463 } |
| 467 } | 464 } |
| OLD | NEW |