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

Unified Diff: chrome/browser/autocomplete/zero_suggest_provider.cc

Issue 1191373002: Componentize AutocompleteController and its supporting cast (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@prep_builtin_provider_for_c14n
Patch Set: Rebase Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/autocomplete/zero_suggest_provider.cc
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.cc b/chrome/browser/autocomplete/zero_suggest_provider.cc
deleted file mode 100644
index 68c8019673621e5215f9ebdcc292df3e4f5f6544..0000000000000000000000000000000000000000
--- a/chrome/browser/autocomplete/zero_suggest_provider.cc
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/autocomplete/zero_suggest_provider.h"
-
-#include "base/callback.h"
-#include "base/i18n/case_conversion.h"
-#include "base/json/json_string_value_serializer.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/user_metrics.h"
-#include "base/prefs/pref_service.h"
-#include "base/strings/string16.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "chrome/browser/autocomplete/autocomplete_classifier.h"
-#include "components/history/core/browser/history_types.h"
-#include "components/history/core/browser/top_sites.h"
-#include "components/metrics/proto/omnibox_input_type.pb.h"
-#include "components/omnibox/autocomplete_input.h"
-#include "components/omnibox/autocomplete_match.h"
-#include "components/omnibox/autocomplete_provider_listener.h"
-#include "components/omnibox/history_url_provider.h"
-#include "components/omnibox/omnibox_field_trial.h"
-#include "components/omnibox/omnibox_pref_names.h"
-#include "components/omnibox/search_provider.h"
-#include "components/pref_registry/pref_registry_syncable.h"
-#include "components/search_engines/template_url_service.h"
-#include "components/variations/net/variations_http_header_provider.h"
-#include "net/base/escape.h"
-#include "net/base/load_flags.h"
-#include "net/base/net_util.h"
-#include "net/http/http_request_headers.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request_status.h"
-#include "url/gurl.h"
-
-namespace {
-
-// TODO(hfung): The histogram code was copied and modified from
-// search_provider.cc. Refactor and consolidate the code.
-// We keep track in a histogram how many suggest requests we send, how
-// many suggest requests we invalidate (e.g., due to a user typing
-// another character), and how many replies we receive.
-// *** ADD NEW ENUMS AFTER ALL PREVIOUSLY DEFINED ONES! ***
-// (excluding the end-of-list enum value)
-// We do not want values of existing enums to change or else it screws
-// up the statistics.
-enum ZeroSuggestRequestsHistogramValue {
- ZERO_SUGGEST_REQUEST_SENT = 1,
- ZERO_SUGGEST_REQUEST_INVALIDATED,
- ZERO_SUGGEST_REPLY_RECEIVED,
- ZERO_SUGGEST_MAX_REQUEST_HISTOGRAM_VALUE
-};
-
-void LogOmniboxZeroSuggestRequest(
- ZeroSuggestRequestsHistogramValue request_value) {
- UMA_HISTOGRAM_ENUMERATION("Omnibox.ZeroSuggestRequests", request_value,
- ZERO_SUGGEST_MAX_REQUEST_HISTOGRAM_VALUE);
-}
-
-// The maximum relevance of the top match from this provider.
-const int kDefaultVerbatimZeroSuggestRelevance = 1300;
-
-// Relevance value to use if it was not set explicitly by the server.
-const int kDefaultZeroSuggestRelevance = 100;
-
-} // namespace
-
-// static
-ZeroSuggestProvider* ZeroSuggestProvider::Create(
- AutocompleteProviderClient* client,
- AutocompleteProviderListener* listener) {
- return new ZeroSuggestProvider(client, listener);
-}
-
-// static
-void ZeroSuggestProvider::RegisterProfilePrefs(
- user_prefs::PrefRegistrySyncable* registry) {
- registry->RegisterStringPref(omnibox::kZeroSuggestCachedResults,
- std::string());
-}
-
-void ZeroSuggestProvider::Start(const AutocompleteInput& input,
- bool minimal_changes) {
- matches_.clear();
- if (!input.from_omnibox_focus() ||
- input.type() == metrics::OmniboxInputType::INVALID)
- return;
-
- Stop(true, false);
- set_field_trial_triggered(false);
- set_field_trial_triggered_in_session(false);
- results_from_cache_ = false;
- permanent_text_ = input.text();
- current_query_ = input.current_url().spec();
- current_page_classification_ = input.current_page_classification();
- current_url_match_ = MatchForCurrentURL();
- TemplateURLService* template_url_service = client()->GetTemplateURLService();
-
- const TemplateURL* default_provider =
- template_url_service->GetDefaultSearchProvider();
- if (default_provider == NULL)
- return;
-
- base::string16 prefix;
- TemplateURLRef::SearchTermsArgs search_term_args(prefix);
- GURL suggest_url(default_provider->suggestions_url_ref().ReplaceSearchTerms(
- search_term_args, template_url_service->search_terms_data()));
- if (!suggest_url.is_valid())
- return;
-
- // No need to send the current page URL in personalized suggest or
- // most visited field trials.
- if (CanSendURL(input.current_url(), suggest_url, default_provider,
- current_page_classification_,
- template_url_service->search_terms_data(), client()) &&
- !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial() &&
- !OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) {
- // Update suggest_url to include the current_page_url.
- search_term_args.current_page_url = current_query_;
- suggest_url =
- GURL(default_provider->suggestions_url_ref().ReplaceSearchTerms(
- search_term_args, template_url_service->search_terms_data()));
- } else if (!ShouldShowNonContextualZeroSuggest(suggest_url,
- input.current_url())) {
- return;
- }
-
- done_ = false;
- // TODO(jered): Consider adding locally-sourced zero-suggestions here too.
- // These may be useful on the NTP or more relevant to the user than server
- // suggestions, if based on local browsing history.
- MaybeUseCachedSuggestions();
- Run(suggest_url);
-}
-
-void ZeroSuggestProvider::Stop(bool clear_cached_results,
- bool due_to_user_inactivity) {
- if (fetcher_)
- LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_INVALIDATED);
- fetcher_.reset();
- waiting_for_most_visited_urls_request_ = false;
- done_ = true;
-
- if (clear_cached_results) {
- // We do not call Clear() on |results_| to retain |verbatim_relevance|
- // value in the |results_| object. |verbatim_relevance| is used at the
- // beginning of the next call to Start() to determine the current url
- // match relevance.
- results_.suggest_results.clear();
- results_.navigation_results.clear();
- current_query_.clear();
- most_visited_urls_.clear();
- }
-}
-
-void ZeroSuggestProvider::DeleteMatch(const AutocompleteMatch& match) {
- if (OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) {
- // Remove the deleted match from the cache, so it is not shown to the user
- // again. Since we cannot remove just one result, blow away the cache.
- client()->GetPrefs()->SetString(omnibox::kZeroSuggestCachedResults,
- std::string());
- }
- BaseSearchProvider::DeleteMatch(match);
-}
-
-void ZeroSuggestProvider::AddProviderInfo(ProvidersInfo* provider_info) const {
- BaseSearchProvider::AddProviderInfo(provider_info);
- if (!results_.suggest_results.empty() ||
- !results_.navigation_results.empty() ||
- !most_visited_urls_.empty())
- provider_info->back().set_times_returned_results_in_session(1);
-}
-
-void ZeroSuggestProvider::ResetSession() {
- // The user has started editing in the omnibox, so leave
- // |field_trial_triggered_in_session| unchanged and set
- // |field_trial_triggered| to false since zero suggest is inactive now.
- set_field_trial_triggered(false);
-}
-
-ZeroSuggestProvider::ZeroSuggestProvider(AutocompleteProviderClient* client,
- AutocompleteProviderListener* listener)
- : BaseSearchProvider(AutocompleteProvider::TYPE_ZERO_SUGGEST, client),
- listener_(listener),
- results_from_cache_(false),
- waiting_for_most_visited_urls_request_(false),
- weak_ptr_factory_(this) {
-}
-
-ZeroSuggestProvider::~ZeroSuggestProvider() {
-}
-
-const TemplateURL* ZeroSuggestProvider::GetTemplateURL(bool is_keyword) const {
- // Zero suggest provider should not receive keyword results.
- DCHECK(!is_keyword);
- return client()->GetTemplateURLService()->GetDefaultSearchProvider();
-}
-
-const AutocompleteInput ZeroSuggestProvider::GetInput(bool is_keyword) const {
- // The callers of this method won't look at the AutocompleteInput's
- // |from_omnibox_focus| member, so we can set its value to false.
- return AutocompleteInput(base::string16(), base::string16::npos,
- std::string(), GURL(current_query_),
- current_page_classification_, true, false, false,
- true, false, client()->GetSchemeClassifier());
-}
-
-bool ZeroSuggestProvider::ShouldAppendExtraParams(
- const SearchSuggestionParser::SuggestResult& result) const {
- // We always use the default provider for search, so append the params.
- return true;
-}
-
-void ZeroSuggestProvider::RecordDeletionResult(bool success) {
- if (success) {
- base::RecordAction(
- base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Success"));
- } else {
- base::RecordAction(
- base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Failure"));
- }
-}
-
-void ZeroSuggestProvider::OnURLFetchComplete(const net::URLFetcher* source) {
- DCHECK(!done_);
- DCHECK_EQ(fetcher_.get(), source);
-
- LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REPLY_RECEIVED);
-
- bool results_updated = false;
- if (source->GetStatus().is_success() && source->GetResponseCode() == 200) {
- std::string json_data = SearchSuggestionParser::ExtractJsonData(source);
- scoped_ptr<base::Value> data(
- SearchSuggestionParser::DeserializeJsonData(json_data));
- if (data) {
- if (StoreSuggestionResponse(json_data, *data))
- return;
- results_updated = ParseSuggestResults(
- *data, kDefaultZeroSuggestRelevance, false, &results_);
- }
- }
- fetcher_.reset();
- done_ = true;
- ConvertResultsToAutocompleteMatches();
- listener_->OnProviderUpdate(results_updated);
-}
-
-bool ZeroSuggestProvider::StoreSuggestionResponse(
- const std::string& json_data,
- const base::Value& parsed_data) {
- if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial() ||
- json_data.empty())
- return false;
- client()->GetPrefs()->SetString(omnibox::kZeroSuggestCachedResults,
- json_data);
-
- // If we received an empty result list, we should update the display, as it
- // may be showing cached results that should not be shown.
- const base::ListValue* root_list = NULL;
- const base::ListValue* results_list = NULL;
- if (parsed_data.GetAsList(&root_list) &&
- root_list->GetList(1, &results_list) &&
- results_list->empty())
- return false;
-
- // We are finished with the request and want to bail early.
- if (results_from_cache_)
- done_ = true;
-
- return results_from_cache_;
-}
-
-void ZeroSuggestProvider::AddSuggestResultsToMap(
- const SearchSuggestionParser::SuggestResults& results,
- MatchMap* map) {
- for (size_t i = 0; i < results.size(); ++i)
- AddMatchToMap(results[i], std::string(), i, false, false, map);
-}
-
-AutocompleteMatch ZeroSuggestProvider::NavigationToMatch(
- const SearchSuggestionParser::NavigationResult& navigation) {
- AutocompleteMatch match(this, navigation.relevance(), false,
- navigation.type());
- match.destination_url = navigation.url();
-
- // Zero suggest results should always omit protocols and never appear bold.
- const std::string languages(client()->GetAcceptLanguages());
- match.contents = net::FormatUrl(navigation.url(), languages,
- net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL);
- match.fill_into_edit +=
- AutocompleteInput::FormattedStringWithEquivalentMeaning(
- navigation.url(), match.contents, client()->GetSchemeClassifier());
-
- AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0,
- match.contents.length(), ACMatchClassification::URL,
- &match.contents_class);
-
- match.description =
- AutocompleteMatch::SanitizeString(navigation.description());
- AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0,
- match.description.length(), ACMatchClassification::NONE,
- &match.description_class);
- return match;
-}
-
-void ZeroSuggestProvider::Run(const GURL& suggest_url) {
- if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) {
- most_visited_urls_.clear();
- scoped_refptr<history::TopSites> ts = client()->GetTopSites();
- if (ts) {
- waiting_for_most_visited_urls_request_ = true;
- ts->GetMostVisitedURLs(
- base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable,
- weak_ptr_factory_.GetWeakPtr()), false);
- }
- } else {
- const int kFetcherID = 1;
- fetcher_ = net::URLFetcher::Create(kFetcherID, suggest_url,
- net::URLFetcher::GET, this);
- fetcher_->SetRequestContext(client()->GetRequestContext());
- fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
- // Add Chrome experiment state to the request headers.
- net::HttpRequestHeaders headers;
- variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
- fetcher_->GetOriginalURL(), client()->IsOffTheRecord(), false,
- &headers);
- fetcher_->SetExtraRequestHeaders(headers.ToString());
- fetcher_->Start();
- LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT);
- }
-}
-
-void ZeroSuggestProvider::OnMostVisitedUrlsAvailable(
- const history::MostVisitedURLList& urls) {
- if (!waiting_for_most_visited_urls_request_) return;
- most_visited_urls_ = urls;
- waiting_for_most_visited_urls_request_ = false;
- done_ = true;
- ConvertResultsToAutocompleteMatches();
- listener_->OnProviderUpdate(true);
-}
-
-void ZeroSuggestProvider::ConvertResultsToAutocompleteMatches() {
- matches_.clear();
-
- TemplateURLService* template_url_service = client()->GetTemplateURLService();
- const TemplateURL* default_provider =
- template_url_service->GetDefaultSearchProvider();
- // Fail if we can't set the clickthrough URL for query suggestions.
- if (default_provider == NULL ||
- !default_provider->SupportsReplacement(
- template_url_service->search_terms_data()))
- return;
-
- MatchMap map;
- AddSuggestResultsToMap(results_.suggest_results, &map);
-
- const int num_query_results = map.size();
- const int num_nav_results = results_.navigation_results.size();
- const int num_results = num_query_results + num_nav_results;
- UMA_HISTOGRAM_COUNTS("ZeroSuggest.QueryResults", num_query_results);
- UMA_HISTOGRAM_COUNTS("ZeroSuggest.URLResults", num_nav_results);
- UMA_HISTOGRAM_COUNTS("ZeroSuggest.AllResults", num_results);
-
- // Show Most Visited results after ZeroSuggest response is received.
- if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) {
- if (!current_url_match_.destination_url.is_valid())
- return;
- matches_.push_back(current_url_match_);
- int relevance = 600;
- if (num_results > 0) {
- UMA_HISTOGRAM_COUNTS(
- "Omnibox.ZeroSuggest.MostVisitedResultsCounterfactual",
- most_visited_urls_.size());
- }
- const base::string16 current_query_string16(
- base::ASCIIToUTF16(current_query_));
- const std::string languages(client()->GetAcceptLanguages());
- for (size_t i = 0; i < most_visited_urls_.size(); i++) {
- const history::MostVisitedURL& url = most_visited_urls_[i];
- SearchSuggestionParser::NavigationResult nav(
- client()->GetSchemeClassifier(), url.url,
- AutocompleteMatchType::NAVSUGGEST, url.title, std::string(), false,
- relevance, true, current_query_string16, languages);
- matches_.push_back(NavigationToMatch(nav));
- --relevance;
- }
- return;
- }
-
- if (num_results == 0)
- return;
-
- // TODO(jered): Rip this out once the first match is decoupled from the
- // current typing in the omnibox.
- matches_.push_back(current_url_match_);
-
- for (MatchMap::const_iterator it(map.begin()); it != map.end(); ++it)
- matches_.push_back(it->second);
-
- const SearchSuggestionParser::NavigationResults& nav_results(
- results_.navigation_results);
- for (SearchSuggestionParser::NavigationResults::const_iterator it(
- nav_results.begin()); it != nav_results.end(); ++it)
- matches_.push_back(NavigationToMatch(*it));
-}
-
-AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() {
- AutocompleteMatch match;
- client()->GetAutocompleteClassifier()->Classify(
- permanent_text_, false, true, current_page_classification_, &match, NULL);
- match.allowed_to_be_default_match = true;
-
- // The placeholder suggestion for the current URL has high relevance so
- // that it is in the first suggestion slot and inline autocompleted. It
- // gets dropped as soon as the user types something.
- match.relevance = GetVerbatimRelevance();
-
- return match;
-}
-
-int ZeroSuggestProvider::GetVerbatimRelevance() const {
- return results_.verbatim_relevance >= 0 ?
- results_.verbatim_relevance : kDefaultVerbatimZeroSuggestRelevance;
-}
-
-bool ZeroSuggestProvider::ShouldShowNonContextualZeroSuggest(
- const GURL& suggest_url,
- const GURL& current_page_url) const {
- const TemplateURLService* template_url_service =
- client()->GetTemplateURLService();
- if (!ZeroSuggestEnabled(suggest_url,
- template_url_service->GetDefaultSearchProvider(),
- current_page_classification_,
- template_url_service->search_terms_data(), client()))
- return false;
-
- // If we cannot send URLs, then only the MostVisited and Personalized
- // variations can be shown.
- if (!OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial() &&
- !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial())
- return false;
-
- // Only show zero suggest for HTTP[S] pages.
- // TODO(mariakhomenko): We may be able to expand this set to include pages
- // with other schemes (e.g. chrome://). That may require improvements to
- // the formatting of the verbatim result returned by MatchForCurrentURL().
- if (!current_page_url.is_valid() ||
- ((current_page_url.scheme() != url::kHttpScheme) &&
- (current_page_url.scheme() != url::kHttpsScheme)))
- return false;
-
- if (OmniboxFieldTrial::InZeroSuggestMostVisitedWithoutSerpFieldTrial() &&
- client()
- ->GetTemplateURLService()
- ->IsSearchResultsPageFromDefaultSearchProvider(current_page_url))
- return false;
-
- return true;
-}
-
-void ZeroSuggestProvider::MaybeUseCachedSuggestions() {
- if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial())
- return;
-
- std::string json_data =
- client()->GetPrefs()->GetString(omnibox::kZeroSuggestCachedResults);
- if (!json_data.empty()) {
- scoped_ptr<base::Value> data(
- SearchSuggestionParser::DeserializeJsonData(json_data));
- if (data && ParseSuggestResults(
- *data, kDefaultZeroSuggestRelevance, false, &results_)) {
- ConvertResultsToAutocompleteMatches();
- results_from_cache_ = !matches_.empty();
- }
- }
-}
« no previous file with comments | « chrome/browser/autocomplete/zero_suggest_provider.h ('k') | chrome/browser/autocomplete/zero_suggest_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698