Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: chrome/browser/autocomplete/zero_suggest_provider.cc

Issue 131003011: Part 1 of search provider refactoring. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: change wrapping back Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string16.h" 12 #include "base/strings/string16.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "chrome/browser/autocomplete/autocomplete_classifier.h" 16 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
17 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" 17 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
18 #include "chrome/browser/autocomplete/autocomplete_input.h" 18 #include "chrome/browser/autocomplete/autocomplete_input.h"
19 #include "chrome/browser/autocomplete/autocomplete_match.h" 19 #include "chrome/browser/autocomplete/autocomplete_match.h"
20 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h" 20 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
21 #include "chrome/browser/autocomplete/base_search_provider.h"
msw 2014/02/03 22:53:14 nit: remove redundant includes like this.
Maria 2014/02/04 03:16:39 Done.
21 #include "chrome/browser/autocomplete/history_url_provider.h" 22 #include "chrome/browser/autocomplete/history_url_provider.h"
22 #include "chrome/browser/autocomplete/search_provider.h" 23 #include "chrome/browser/autocomplete/search_provider.h"
23 #include "chrome/browser/autocomplete/url_prefix.h" 24 #include "chrome/browser/autocomplete/url_prefix.h"
24 #include "chrome/browser/history/history_types.h" 25 #include "chrome/browser/history/history_types.h"
25 #include "chrome/browser/history/top_sites.h" 26 #include "chrome/browser/history/top_sites.h"
26 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" 27 #include "chrome/browser/metrics/variations/variations_http_header_provider.h"
27 #include "chrome/browser/omnibox/omnibox_field_trial.h" 28 #include "chrome/browser/omnibox/omnibox_field_trial.h"
28 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/browser/search/search.h" 30 #include "chrome/browser/search/search.h"
30 #include "chrome/browser/search_engines/template_url_service.h" 31 #include "chrome/browser/search_engines/template_url_service.h"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 done_ = false; 177 done_ = false;
177 // TODO(jered): Consider adding locally-sourced zero-suggestions here too. 178 // TODO(jered): Consider adding locally-sourced zero-suggestions here too.
178 // These may be useful on the NTP or more relevant to the user than server 179 // These may be useful on the NTP or more relevant to the user than server
179 // suggestions, if based on local browsing history. 180 // suggestions, if based on local browsing history.
180 Run(suggest_url); 181 Run(suggest_url);
181 } 182 }
182 183
183 ZeroSuggestProvider::ZeroSuggestProvider( 184 ZeroSuggestProvider::ZeroSuggestProvider(
184 AutocompleteProviderListener* listener, 185 AutocompleteProviderListener* listener,
185 Profile* profile) 186 Profile* profile)
186 : AutocompleteProvider(listener, profile, 187 : BaseSearchProvider(listener,
187 AutocompleteProvider::TYPE_ZERO_SUGGEST), 188 profile,
msw 2014/02/03 22:53:14 nit: this can be wrapped on the line above.
Maria 2014/02/04 03:16:39 Done.
189 AutocompleteProvider::TYPE_ZERO_SUGGEST),
188 template_url_service_(TemplateURLServiceFactory::GetForProfile(profile)), 190 template_url_service_(TemplateURLServiceFactory::GetForProfile(profile)),
189 have_pending_request_(false), 191 have_pending_request_(false),
190 verbatim_relevance_(kDefaultVerbatimZeroSuggestRelevance), 192 verbatim_relevance_(kDefaultVerbatimZeroSuggestRelevance),
191 field_trial_triggered_(false), 193 field_trial_triggered_(false),
192 field_trial_triggered_in_session_(false), 194 field_trial_triggered_in_session_(false),
193 weak_ptr_factory_(this) { 195 weak_ptr_factory_(this) {
194 } 196 }
195 197
196 ZeroSuggestProvider::~ZeroSuggestProvider() { 198 ZeroSuggestProvider::~ZeroSuggestProvider() {
197 } 199 }
198 200
199 void ZeroSuggestProvider::FillResults( 201 void ZeroSuggestProvider::FillResults(
200 const base::Value& root_val, 202 const base::Value& root_val,
msw 2014/02/03 22:53:14 nit: wrap this on the line above; indent others to
Maria 2014/02/04 03:16:39 Done.
201 int* verbatim_relevance, 203 int* verbatim_relevance,
202 SearchProvider::SuggestResults* suggest_results, 204 SuggestResults* suggest_results,
203 SearchProvider::NavigationResults* navigation_results) { 205 NavigationResults* navigation_results) {
204 base::string16 query; 206 base::string16 query;
205 const base::ListValue* root_list = NULL; 207 const base::ListValue* root_list = NULL;
206 const base::ListValue* results = NULL; 208 const base::ListValue* results = NULL;
207 const base::ListValue* relevances = NULL; 209 const base::ListValue* relevances = NULL;
208 // The response includes the query, which should be empty for ZeroSuggest 210 // The response includes the query, which should be empty for ZeroSuggest
209 // responses. 211 // responses.
210 if (!root_val.GetAsList(&root_list) || !root_list->GetString(0, &query) || 212 if (!root_val.GetAsList(&root_list) || !root_list->GetString(0, &query) ||
211 (!query.empty()) || !root_list->GetList(1, &results)) 213 (!query.empty()) || !root_list->GetList(1, &results))
212 return; 214 return;
213 215
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // Apply valid suggested relevance scores; discard invalid lists. 262 // Apply valid suggested relevance scores; discard invalid lists.
261 if (relevances != NULL && !relevances->GetInteger(index, &relevance)) 263 if (relevances != NULL && !relevances->GetInteger(index, &relevance))
262 relevances = NULL; 264 relevances = NULL;
263 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) { 265 if (types && types->GetString(index, &type) && (type == "NAVIGATION")) {
264 // Do not blindly trust the URL coming from the server to be valid. 266 // Do not blindly trust the URL coming from the server to be valid.
265 GURL url(URLFixerUpper::FixupURL( 267 GURL url(URLFixerUpper::FixupURL(
266 base::UTF16ToUTF8(result), std::string())); 268 base::UTF16ToUTF8(result), std::string()));
267 if (url.is_valid()) { 269 if (url.is_valid()) {
268 if (descriptions != NULL) 270 if (descriptions != NULL)
269 descriptions->GetString(index, &title); 271 descriptions->GetString(index, &title);
270 navigation_results->push_back(SearchProvider::NavigationResult( 272 navigation_results->push_back(NavigationResult(
271 *this, url, title, false, relevance, relevances != NULL, 273 *this, url, title, false, relevance, relevances != NULL,
272 current_query_string16, languages)); 274 current_query_string16, languages));
273 } 275 }
274 } else { 276 } else {
275 suggest_results->push_back(SearchProvider::SuggestResult( 277 suggest_results->push_back(SuggestResult(
276 result, AutocompleteMatchType::SEARCH_SUGGEST, result, 278 result, AutocompleteMatchType::SEARCH_SUGGEST, result,
277 base::string16(), std::string(), std::string(), false, relevance, 279 base::string16(), std::string(), std::string(), false, relevance,
278 relevances != NULL, false, current_query_string16)); 280 relevances != NULL, false, current_query_string16));
279 } 281 }
280 } 282 }
281 } 283 }
282 284
283 void ZeroSuggestProvider::AddSuggestResultsToMap( 285 void ZeroSuggestProvider::AddSuggestResultsToMap(
284 const SearchProvider::SuggestResults& results, 286 const SuggestResults& results,
285 const TemplateURL* template_url, 287 const TemplateURL* template_url,
286 SearchProvider::MatchMap* map) { 288 MatchMap* map) {
287 for (size_t i = 0; i < results.size(); ++i) { 289 for (size_t i = 0; i < results.size(); ++i) {
288 AddMatchToMap(results[i].relevance(), AutocompleteMatchType::SEARCH_SUGGEST, 290 AddMatchToMap(results[i].relevance(), AutocompleteMatchType::SEARCH_SUGGEST,
289 template_url, results[i].suggestion(), i, map); 291 template_url, results[i].suggestion(), i, map);
290 } 292 }
291 } 293 }
292 294
293 void ZeroSuggestProvider::AddMatchToMap(int relevance, 295 void ZeroSuggestProvider::AddMatchToMap(int relevance,
294 AutocompleteMatch::Type type, 296 AutocompleteMatch::Type type,
295 const TemplateURL* template_url, 297 const TemplateURL* template_url,
296 const base::string16& query_string, 298 const base::string16& query_string,
297 int accepted_suggestion, 299 int accepted_suggestion,
298 SearchProvider::MatchMap* map) { 300 MatchMap* map) {
299 // Pass in query_string as the input_text to avoid bolding. 301 // Pass in query_string as the input_text to avoid bolding.
300 SearchProvider::SuggestResult suggestion( 302 SuggestResult suggestion(
301 query_string, type, query_string, base::string16(), std::string(), 303 query_string, type, query_string, base::string16(), std::string(),
302 std::string(), false, relevance, true, false, query_string); 304 std::string(), false, relevance, true, false, query_string);
303 // TODO(samarth|melevin): use the actual omnibox margin here as well instead 305 // TODO(samarth|melevin): use the actual omnibox margin here as well instead
304 // of passing in -1. 306 // of passing in -1.
305 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion( 307 AutocompleteMatch match = SearchProvider::CreateSearchSuggestion(
306 this, AutocompleteInput(), query_string, suggestion, template_url, 308 this, AutocompleteInput(), query_string, suggestion, template_url,
307 accepted_suggestion, -1, true); 309 accepted_suggestion, -1, true);
308 if (!match.destination_url.is_valid()) 310 if (!match.destination_url.is_valid())
309 return; 311 return;
310 312
311 // Try to add |match| to |map|. If a match for |query_string| is already in 313 // Try to add |match| to |map|. If a match for |query_string| is already in
312 // |map|, replace it if |match| is more relevant. 314 // |map|, replace it if |match| is more relevant.
313 // NOTE: Keep this ToLower() call in sync with url_database.cc. 315 // NOTE: Keep this ToLower() call in sync with url_database.cc.
314 SearchProvider::MatchKey match_key( 316 MatchKey match_key(
315 std::make_pair(base::i18n::ToLower(query_string), std::string())); 317 std::make_pair(base::i18n::ToLower(query_string), std::string()));
316 const std::pair<SearchProvider::MatchMap::iterator, bool> i(map->insert( 318 const std::pair<MatchMap::iterator, bool> i(map->insert(
317 std::make_pair(match_key, match))); 319 std::make_pair(match_key, match)));
318 // NOTE: We purposefully do a direct relevance comparison here instead of 320 // NOTE: We purposefully do a direct relevance comparison here instead of
319 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added 321 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items added
320 // first" rather than "items alphabetically first" when the scores are equal. 322 // first" rather than "items alphabetically first" when the scores are equal.
321 // The only case this matters is when a user has results with the same score 323 // The only case this matters is when a user has results with the same score
322 // that differ only by capitalization; because the history system returns 324 // that differ only by capitalization; because the history system returns
323 // results sorted by recency, this means we'll pick the most recent such 325 // results sorted by recency, this means we'll pick the most recent such
324 // result even if the precision of our relevance score is too low to 326 // result even if the precision of our relevance score is too low to
325 // distinguish the two. 327 // distinguish the two.
326 if (!i.second && (match.relevance > i.first->second.relevance)) 328 if (!i.second && (match.relevance > i.first->second.relevance))
327 i.first->second = match; 329 i.first->second = match;
328 } 330 }
329 331
330 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( 332 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch(
331 const SearchProvider::NavigationResult& navigation) { 333 const NavigationResult& navigation) {
332 AutocompleteMatch match(this, navigation.relevance(), false, 334 AutocompleteMatch match(this, navigation.relevance(), false,
333 AutocompleteMatchType::NAVSUGGEST); 335 AutocompleteMatchType::NAVSUGGEST);
334 match.destination_url = navigation.url(); 336 match.destination_url = navigation.url();
335 337
336 // Zero suggest results should always omit protocols and never appear bold. 338 // Zero suggest results should always omit protocols and never appear bold.
337 const std::string languages( 339 const std::string languages(
338 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 340 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
339 match.contents = net::FormatUrl(navigation.url(), languages, 341 match.contents = net::FormatUrl(navigation.url(), languages,
340 net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); 342 net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL);
341 match.fill_into_edit += 343 match.fill_into_edit +=
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 ts->GetMostVisitedURLs( 380 ts->GetMostVisitedURLs(
379 base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable, 381 base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable,
380 weak_ptr_factory_.GetWeakPtr()), false); 382 weak_ptr_factory_.GetWeakPtr()), false);
381 } 383 }
382 } 384 }
383 have_pending_request_ = true; 385 have_pending_request_ = true;
384 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT); 386 LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT);
385 } 387 }
386 388
387 void ZeroSuggestProvider::ParseSuggestResults(const base::Value& root_val) { 389 void ZeroSuggestProvider::ParseSuggestResults(const base::Value& root_val) {
388 SearchProvider::SuggestResults suggest_results; 390 SuggestResults suggest_results;
389 FillResults(root_val, &verbatim_relevance_, 391 FillResults(root_val, &verbatim_relevance_,
390 &suggest_results, &navigation_results_); 392 &suggest_results, &navigation_results_);
391 393
392 query_matches_map_.clear(); 394 query_matches_map_.clear();
393 AddSuggestResultsToMap(suggest_results, 395 AddSuggestResultsToMap(suggest_results,
394 template_url_service_->GetDefaultSearchProvider(), 396 template_url_service_->GetDefaultSearchProvider(),
395 &query_matches_map_); 397 &query_matches_map_);
396 } 398 }
397 399
398 void ZeroSuggestProvider::OnMostVisitedUrlsAvailable( 400 void ZeroSuggestProvider::OnMostVisitedUrlsAvailable(
(...skipping 27 matching lines...) Expand all
426 UMA_HISTOGRAM_COUNTS( 428 UMA_HISTOGRAM_COUNTS(
427 "Omnibox.ZeroSuggest.MostVisitedResultsCounterfactual", 429 "Omnibox.ZeroSuggest.MostVisitedResultsCounterfactual",
428 most_visited_urls_.size()); 430 most_visited_urls_.size());
429 } 431 }
430 const base::string16 current_query_string16( 432 const base::string16 current_query_string16(
431 base::ASCIIToUTF16(current_query_)); 433 base::ASCIIToUTF16(current_query_));
432 const std::string languages( 434 const std::string languages(
433 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 435 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
434 for (size_t i = 0; i < most_visited_urls_.size(); i++) { 436 for (size_t i = 0; i < most_visited_urls_.size(); i++) {
435 const history::MostVisitedURL& url = most_visited_urls_[i]; 437 const history::MostVisitedURL& url = most_visited_urls_[i];
436 SearchProvider::NavigationResult nav( 438 NavigationResult nav(*this, url.url, url.title, false, relevance, true,
437 *this, url.url, url.title, false, relevance, true,
438 current_query_string16, languages); 439 current_query_string16, languages);
439 matches_.push_back(NavigationToMatch(nav)); 440 matches_.push_back(NavigationToMatch(nav));
440 --relevance; 441 --relevance;
441 } 442 }
442 return; 443 return;
443 } 444 }
444 445
445 if (num_results == 0) 446 if (num_results == 0)
446 return; 447 return;
447 448
448 // TODO(jered): Rip this out once the first match is decoupled from the 449 // TODO(jered): Rip this out once the first match is decoupled from the
449 // current typing in the omnibox. 450 // current typing in the omnibox.
450 matches_.push_back(current_url_match_); 451 matches_.push_back(current_url_match_);
451 452
452 for (SearchProvider::MatchMap::const_iterator it(query_matches_map_.begin()); 453 for (MatchMap::const_iterator it(query_matches_map_.begin());
453 it != query_matches_map_.end(); ++it) 454 it != query_matches_map_.end(); ++it)
454 matches_.push_back(it->second); 455 matches_.push_back(it->second);
455 456
456 for (SearchProvider::NavigationResults::const_iterator it( 457 for (NavigationResults::const_iterator it(navigation_results_.begin());
457 navigation_results_.begin()); it != navigation_results_.end(); ++it) 458 it != navigation_results_.end(); ++it)
msw 2014/02/03 22:53:14 nit: indent one more space.
Maria 2014/02/04 03:16:39 Done.
458 matches_.push_back(NavigationToMatch(*it)); 459 matches_.push_back(NavigationToMatch(*it));
459 } 460 }
460 461
461 AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() { 462 AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() {
462 AutocompleteInput input(permanent_text_, base::string16::npos, base::string16( ), 463 AutocompleteInput input(permanent_text_, base::string16::npos, base::string16( ),
463 GURL(current_query_), current_page_classification_, 464 GURL(current_query_), current_page_classification_,
464 false, false, true, AutocompleteInput::ALL_MATCHES); 465 false, false, true, AutocompleteInput::ALL_MATCHES);
465 466
466 AutocompleteMatch match; 467 AutocompleteMatch match;
467 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify( 468 AutocompleteClassifierFactory::GetForProfile(profile_)->Classify(
468 permanent_text_, false, true, &match, NULL); 469 permanent_text_, false, true, &match, NULL);
469 match.is_history_what_you_typed_match = false; 470 match.is_history_what_you_typed_match = false;
470 match.allowed_to_be_default_match = true; 471 match.allowed_to_be_default_match = true;
471 472
472 // The placeholder suggestion for the current URL has high relevance so 473 // The placeholder suggestion for the current URL has high relevance so
473 // that it is in the first suggestion slot and inline autocompleted. It 474 // that it is in the first suggestion slot and inline autocompleted. It
474 // gets dropped as soon as the user types something. 475 // gets dropped as soon as the user types something.
475 match.relevance = verbatim_relevance_; 476 match.relevance = verbatim_relevance_;
476 477
477 return match; 478 return match;
478 } 479 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698