| OLD | NEW | 
 | (Empty) | 
|    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 #include "chrome/browser/autocomplete/zero_suggest_provider.h" |  | 
|    6  |  | 
|    7 #include "base/callback.h" |  | 
|    8 #include "base/i18n/case_conversion.h" |  | 
|    9 #include "base/json/json_string_value_serializer.h" |  | 
|   10 #include "base/metrics/histogram.h" |  | 
|   11 #include "base/metrics/user_metrics.h" |  | 
|   12 #include "base/prefs/pref_service.h" |  | 
|   13 #include "base/strings/string16.h" |  | 
|   14 #include "base/strings/string_util.h" |  | 
|   15 #include "base/strings/utf_string_conversions.h" |  | 
|   16 #include "base/time/time.h" |  | 
|   17 #include "chrome/browser/autocomplete/autocomplete_classifier.h" |  | 
|   18 #include "components/history/core/browser/history_types.h" |  | 
|   19 #include "components/history/core/browser/top_sites.h" |  | 
|   20 #include "components/metrics/proto/omnibox_input_type.pb.h" |  | 
|   21 #include "components/omnibox/autocomplete_input.h" |  | 
|   22 #include "components/omnibox/autocomplete_match.h" |  | 
|   23 #include "components/omnibox/autocomplete_provider_listener.h" |  | 
|   24 #include "components/omnibox/history_url_provider.h" |  | 
|   25 #include "components/omnibox/omnibox_field_trial.h" |  | 
|   26 #include "components/omnibox/omnibox_pref_names.h" |  | 
|   27 #include "components/omnibox/search_provider.h" |  | 
|   28 #include "components/pref_registry/pref_registry_syncable.h" |  | 
|   29 #include "components/search_engines/template_url_service.h" |  | 
|   30 #include "components/variations/net/variations_http_header_provider.h" |  | 
|   31 #include "net/base/escape.h" |  | 
|   32 #include "net/base/load_flags.h" |  | 
|   33 #include "net/base/net_util.h" |  | 
|   34 #include "net/http/http_request_headers.h" |  | 
|   35 #include "net/url_request/url_fetcher.h" |  | 
|   36 #include "net/url_request/url_request_status.h" |  | 
|   37 #include "url/gurl.h" |  | 
|   38  |  | 
|   39 namespace { |  | 
|   40  |  | 
|   41 // TODO(hfung): The histogram code was copied and modified from |  | 
|   42 // search_provider.cc.  Refactor and consolidate the code. |  | 
|   43 // We keep track in a histogram how many suggest requests we send, how |  | 
|   44 // many suggest requests we invalidate (e.g., due to a user typing |  | 
|   45 // another character), and how many replies we receive. |  | 
|   46 // *** ADD NEW ENUMS AFTER ALL PREVIOUSLY DEFINED ONES! *** |  | 
|   47 //     (excluding the end-of-list enum value) |  | 
|   48 // We do not want values of existing enums to change or else it screws |  | 
|   49 // up the statistics. |  | 
|   50 enum ZeroSuggestRequestsHistogramValue { |  | 
|   51   ZERO_SUGGEST_REQUEST_SENT = 1, |  | 
|   52   ZERO_SUGGEST_REQUEST_INVALIDATED, |  | 
|   53   ZERO_SUGGEST_REPLY_RECEIVED, |  | 
|   54   ZERO_SUGGEST_MAX_REQUEST_HISTOGRAM_VALUE |  | 
|   55 }; |  | 
|   56  |  | 
|   57 void LogOmniboxZeroSuggestRequest( |  | 
|   58     ZeroSuggestRequestsHistogramValue request_value) { |  | 
|   59   UMA_HISTOGRAM_ENUMERATION("Omnibox.ZeroSuggestRequests", request_value, |  | 
|   60                             ZERO_SUGGEST_MAX_REQUEST_HISTOGRAM_VALUE); |  | 
|   61 } |  | 
|   62  |  | 
|   63 // The maximum relevance of the top match from this provider. |  | 
|   64 const int kDefaultVerbatimZeroSuggestRelevance = 1300; |  | 
|   65  |  | 
|   66 // Relevance value to use if it was not set explicitly by the server. |  | 
|   67 const int kDefaultZeroSuggestRelevance = 100; |  | 
|   68  |  | 
|   69 }  // namespace |  | 
|   70  |  | 
|   71 // static |  | 
|   72 ZeroSuggestProvider* ZeroSuggestProvider::Create( |  | 
|   73     AutocompleteProviderClient* client, |  | 
|   74     AutocompleteProviderListener* listener) { |  | 
|   75   return new ZeroSuggestProvider(client, listener); |  | 
|   76 } |  | 
|   77  |  | 
|   78 // static |  | 
|   79 void ZeroSuggestProvider::RegisterProfilePrefs( |  | 
|   80     user_prefs::PrefRegistrySyncable* registry) { |  | 
|   81   registry->RegisterStringPref(omnibox::kZeroSuggestCachedResults, |  | 
|   82                                std::string()); |  | 
|   83 } |  | 
|   84  |  | 
|   85 void ZeroSuggestProvider::Start(const AutocompleteInput& input, |  | 
|   86                                 bool minimal_changes) { |  | 
|   87   matches_.clear(); |  | 
|   88   if (!input.from_omnibox_focus() || |  | 
|   89       input.type() == metrics::OmniboxInputType::INVALID) |  | 
|   90     return; |  | 
|   91  |  | 
|   92   Stop(true, false); |  | 
|   93   set_field_trial_triggered(false); |  | 
|   94   set_field_trial_triggered_in_session(false); |  | 
|   95   results_from_cache_ = false; |  | 
|   96   permanent_text_ = input.text(); |  | 
|   97   current_query_ = input.current_url().spec(); |  | 
|   98   current_page_classification_ = input.current_page_classification(); |  | 
|   99   current_url_match_ = MatchForCurrentURL(); |  | 
|  100   TemplateURLService* template_url_service = client()->GetTemplateURLService(); |  | 
|  101  |  | 
|  102   const TemplateURL* default_provider = |  | 
|  103       template_url_service->GetDefaultSearchProvider(); |  | 
|  104   if (default_provider == NULL) |  | 
|  105     return; |  | 
|  106  |  | 
|  107   base::string16 prefix; |  | 
|  108   TemplateURLRef::SearchTermsArgs search_term_args(prefix); |  | 
|  109   GURL suggest_url(default_provider->suggestions_url_ref().ReplaceSearchTerms( |  | 
|  110       search_term_args, template_url_service->search_terms_data())); |  | 
|  111   if (!suggest_url.is_valid()) |  | 
|  112     return; |  | 
|  113  |  | 
|  114   // No need to send the current page URL in personalized suggest or |  | 
|  115   // most visited field trials. |  | 
|  116   if (CanSendURL(input.current_url(), suggest_url, default_provider, |  | 
|  117                  current_page_classification_, |  | 
|  118                  template_url_service->search_terms_data(), client()) && |  | 
|  119       !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial() && |  | 
|  120       !OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) { |  | 
|  121     // Update suggest_url to include the current_page_url. |  | 
|  122     search_term_args.current_page_url = current_query_; |  | 
|  123     suggest_url = |  | 
|  124         GURL(default_provider->suggestions_url_ref().ReplaceSearchTerms( |  | 
|  125             search_term_args, template_url_service->search_terms_data())); |  | 
|  126   } else if (!ShouldShowNonContextualZeroSuggest(suggest_url, |  | 
|  127                                                  input.current_url())) { |  | 
|  128     return; |  | 
|  129   } |  | 
|  130  |  | 
|  131   done_ = false; |  | 
|  132   // TODO(jered): Consider adding locally-sourced zero-suggestions here too. |  | 
|  133   // These may be useful on the NTP or more relevant to the user than server |  | 
|  134   // suggestions, if based on local browsing history. |  | 
|  135   MaybeUseCachedSuggestions(); |  | 
|  136   Run(suggest_url); |  | 
|  137 } |  | 
|  138  |  | 
|  139 void ZeroSuggestProvider::Stop(bool clear_cached_results, |  | 
|  140                                bool due_to_user_inactivity) { |  | 
|  141   if (fetcher_) |  | 
|  142     LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_INVALIDATED); |  | 
|  143   fetcher_.reset(); |  | 
|  144   waiting_for_most_visited_urls_request_ = false; |  | 
|  145   done_ = true; |  | 
|  146  |  | 
|  147   if (clear_cached_results) { |  | 
|  148     // We do not call Clear() on |results_| to retain |verbatim_relevance| |  | 
|  149     // value in the |results_| object. |verbatim_relevance| is used at the |  | 
|  150     // beginning of the next call to Start() to determine the current url |  | 
|  151     // match relevance. |  | 
|  152     results_.suggest_results.clear(); |  | 
|  153     results_.navigation_results.clear(); |  | 
|  154     current_query_.clear(); |  | 
|  155     most_visited_urls_.clear(); |  | 
|  156   } |  | 
|  157 } |  | 
|  158  |  | 
|  159 void ZeroSuggestProvider::DeleteMatch(const AutocompleteMatch& match) { |  | 
|  160   if (OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) { |  | 
|  161     // Remove the deleted match from the cache, so it is not shown to the user |  | 
|  162     // again. Since we cannot remove just one result, blow away the cache. |  | 
|  163     client()->GetPrefs()->SetString(omnibox::kZeroSuggestCachedResults, |  | 
|  164                                     std::string()); |  | 
|  165   } |  | 
|  166   BaseSearchProvider::DeleteMatch(match); |  | 
|  167 } |  | 
|  168  |  | 
|  169 void ZeroSuggestProvider::AddProviderInfo(ProvidersInfo* provider_info) const { |  | 
|  170   BaseSearchProvider::AddProviderInfo(provider_info); |  | 
|  171   if (!results_.suggest_results.empty() || |  | 
|  172       !results_.navigation_results.empty() || |  | 
|  173       !most_visited_urls_.empty()) |  | 
|  174     provider_info->back().set_times_returned_results_in_session(1); |  | 
|  175 } |  | 
|  176  |  | 
|  177 void ZeroSuggestProvider::ResetSession() { |  | 
|  178   // The user has started editing in the omnibox, so leave |  | 
|  179   // |field_trial_triggered_in_session| unchanged and set |  | 
|  180   // |field_trial_triggered| to false since zero suggest is inactive now. |  | 
|  181   set_field_trial_triggered(false); |  | 
|  182 } |  | 
|  183  |  | 
|  184 ZeroSuggestProvider::ZeroSuggestProvider(AutocompleteProviderClient* client, |  | 
|  185                                          AutocompleteProviderListener* listener) |  | 
|  186     : BaseSearchProvider(AutocompleteProvider::TYPE_ZERO_SUGGEST, client), |  | 
|  187       listener_(listener), |  | 
|  188       results_from_cache_(false), |  | 
|  189       waiting_for_most_visited_urls_request_(false), |  | 
|  190       weak_ptr_factory_(this) { |  | 
|  191 } |  | 
|  192  |  | 
|  193 ZeroSuggestProvider::~ZeroSuggestProvider() { |  | 
|  194 } |  | 
|  195  |  | 
|  196 const TemplateURL* ZeroSuggestProvider::GetTemplateURL(bool is_keyword) const { |  | 
|  197   // Zero suggest provider should not receive keyword results. |  | 
|  198   DCHECK(!is_keyword); |  | 
|  199   return client()->GetTemplateURLService()->GetDefaultSearchProvider(); |  | 
|  200 } |  | 
|  201  |  | 
|  202 const AutocompleteInput ZeroSuggestProvider::GetInput(bool is_keyword) const { |  | 
|  203   // The callers of this method won't look at the AutocompleteInput's |  | 
|  204   // |from_omnibox_focus| member, so we can set its value to false. |  | 
|  205   return AutocompleteInput(base::string16(), base::string16::npos, |  | 
|  206                            std::string(), GURL(current_query_), |  | 
|  207                            current_page_classification_, true, false, false, |  | 
|  208                            true, false, client()->GetSchemeClassifier()); |  | 
|  209 } |  | 
|  210  |  | 
|  211 bool ZeroSuggestProvider::ShouldAppendExtraParams( |  | 
|  212       const SearchSuggestionParser::SuggestResult& result) const { |  | 
|  213   // We always use the default provider for search, so append the params. |  | 
|  214   return true; |  | 
|  215 } |  | 
|  216  |  | 
|  217 void ZeroSuggestProvider::RecordDeletionResult(bool success) { |  | 
|  218   if (success) { |  | 
|  219     base::RecordAction( |  | 
|  220         base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Success")); |  | 
|  221   } else { |  | 
|  222     base::RecordAction( |  | 
|  223         base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Failure")); |  | 
|  224   } |  | 
|  225 } |  | 
|  226  |  | 
|  227 void ZeroSuggestProvider::OnURLFetchComplete(const net::URLFetcher* source) { |  | 
|  228   DCHECK(!done_); |  | 
|  229   DCHECK_EQ(fetcher_.get(), source); |  | 
|  230  |  | 
|  231   LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REPLY_RECEIVED); |  | 
|  232  |  | 
|  233   bool results_updated = false; |  | 
|  234   if (source->GetStatus().is_success() && source->GetResponseCode() == 200) { |  | 
|  235     std::string json_data = SearchSuggestionParser::ExtractJsonData(source); |  | 
|  236     scoped_ptr<base::Value> data( |  | 
|  237         SearchSuggestionParser::DeserializeJsonData(json_data)); |  | 
|  238     if (data) { |  | 
|  239       if (StoreSuggestionResponse(json_data, *data)) |  | 
|  240         return; |  | 
|  241       results_updated = ParseSuggestResults( |  | 
|  242           *data, kDefaultZeroSuggestRelevance, false, &results_); |  | 
|  243     } |  | 
|  244   } |  | 
|  245   fetcher_.reset(); |  | 
|  246   done_ = true; |  | 
|  247   ConvertResultsToAutocompleteMatches(); |  | 
|  248   listener_->OnProviderUpdate(results_updated); |  | 
|  249 } |  | 
|  250  |  | 
|  251 bool ZeroSuggestProvider::StoreSuggestionResponse( |  | 
|  252     const std::string& json_data, |  | 
|  253     const base::Value& parsed_data) { |  | 
|  254   if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial() || |  | 
|  255       json_data.empty()) |  | 
|  256     return false; |  | 
|  257   client()->GetPrefs()->SetString(omnibox::kZeroSuggestCachedResults, |  | 
|  258                                   json_data); |  | 
|  259  |  | 
|  260   // If we received an empty result list, we should update the display, as it |  | 
|  261   // may be showing cached results that should not be shown. |  | 
|  262   const base::ListValue* root_list = NULL; |  | 
|  263   const base::ListValue* results_list = NULL; |  | 
|  264   if (parsed_data.GetAsList(&root_list) && |  | 
|  265       root_list->GetList(1, &results_list) && |  | 
|  266       results_list->empty()) |  | 
|  267     return false; |  | 
|  268  |  | 
|  269   // We are finished with the request and want to bail early. |  | 
|  270   if (results_from_cache_) |  | 
|  271     done_ = true; |  | 
|  272  |  | 
|  273   return results_from_cache_; |  | 
|  274 } |  | 
|  275  |  | 
|  276 void ZeroSuggestProvider::AddSuggestResultsToMap( |  | 
|  277     const SearchSuggestionParser::SuggestResults& results, |  | 
|  278     MatchMap* map) { |  | 
|  279   for (size_t i = 0; i < results.size(); ++i) |  | 
|  280     AddMatchToMap(results[i], std::string(), i, false, false, map); |  | 
|  281 } |  | 
|  282  |  | 
|  283 AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( |  | 
|  284     const SearchSuggestionParser::NavigationResult& navigation) { |  | 
|  285   AutocompleteMatch match(this, navigation.relevance(), false, |  | 
|  286                           navigation.type()); |  | 
|  287   match.destination_url = navigation.url(); |  | 
|  288  |  | 
|  289   // Zero suggest results should always omit protocols and never appear bold. |  | 
|  290   const std::string languages(client()->GetAcceptLanguages()); |  | 
|  291   match.contents = net::FormatUrl(navigation.url(), languages, |  | 
|  292       net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); |  | 
|  293   match.fill_into_edit += |  | 
|  294       AutocompleteInput::FormattedStringWithEquivalentMeaning( |  | 
|  295           navigation.url(), match.contents, client()->GetSchemeClassifier()); |  | 
|  296  |  | 
|  297   AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, |  | 
|  298       match.contents.length(), ACMatchClassification::URL, |  | 
|  299       &match.contents_class); |  | 
|  300  |  | 
|  301   match.description = |  | 
|  302       AutocompleteMatch::SanitizeString(navigation.description()); |  | 
|  303   AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, |  | 
|  304       match.description.length(), ACMatchClassification::NONE, |  | 
|  305       &match.description_class); |  | 
|  306   return match; |  | 
|  307 } |  | 
|  308  |  | 
|  309 void ZeroSuggestProvider::Run(const GURL& suggest_url) { |  | 
|  310   if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) { |  | 
|  311     most_visited_urls_.clear(); |  | 
|  312     scoped_refptr<history::TopSites> ts = client()->GetTopSites(); |  | 
|  313     if (ts) { |  | 
|  314       waiting_for_most_visited_urls_request_ = true; |  | 
|  315       ts->GetMostVisitedURLs( |  | 
|  316           base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable, |  | 
|  317                      weak_ptr_factory_.GetWeakPtr()), false); |  | 
|  318     } |  | 
|  319   } else { |  | 
|  320     const int kFetcherID = 1; |  | 
|  321     fetcher_ = net::URLFetcher::Create(kFetcherID, suggest_url, |  | 
|  322                                        net::URLFetcher::GET, this); |  | 
|  323     fetcher_->SetRequestContext(client()->GetRequestContext()); |  | 
|  324     fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); |  | 
|  325     // Add Chrome experiment state to the request headers. |  | 
|  326     net::HttpRequestHeaders headers; |  | 
|  327     variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( |  | 
|  328         fetcher_->GetOriginalURL(), client()->IsOffTheRecord(), false, |  | 
|  329         &headers); |  | 
|  330     fetcher_->SetExtraRequestHeaders(headers.ToString()); |  | 
|  331     fetcher_->Start(); |  | 
|  332     LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT); |  | 
|  333   } |  | 
|  334 } |  | 
|  335  |  | 
|  336 void ZeroSuggestProvider::OnMostVisitedUrlsAvailable( |  | 
|  337     const history::MostVisitedURLList& urls) { |  | 
|  338   if (!waiting_for_most_visited_urls_request_) return; |  | 
|  339   most_visited_urls_ = urls; |  | 
|  340   waiting_for_most_visited_urls_request_ = false; |  | 
|  341   done_ = true; |  | 
|  342   ConvertResultsToAutocompleteMatches(); |  | 
|  343   listener_->OnProviderUpdate(true); |  | 
|  344 } |  | 
|  345  |  | 
|  346 void ZeroSuggestProvider::ConvertResultsToAutocompleteMatches() { |  | 
|  347   matches_.clear(); |  | 
|  348  |  | 
|  349   TemplateURLService* template_url_service = client()->GetTemplateURLService(); |  | 
|  350   const TemplateURL* default_provider = |  | 
|  351       template_url_service->GetDefaultSearchProvider(); |  | 
|  352   // Fail if we can't set the clickthrough URL for query suggestions. |  | 
|  353   if (default_provider == NULL || |  | 
|  354       !default_provider->SupportsReplacement( |  | 
|  355           template_url_service->search_terms_data())) |  | 
|  356     return; |  | 
|  357  |  | 
|  358   MatchMap map; |  | 
|  359   AddSuggestResultsToMap(results_.suggest_results, &map); |  | 
|  360  |  | 
|  361   const int num_query_results = map.size(); |  | 
|  362   const int num_nav_results = results_.navigation_results.size(); |  | 
|  363   const int num_results = num_query_results + num_nav_results; |  | 
|  364   UMA_HISTOGRAM_COUNTS("ZeroSuggest.QueryResults", num_query_results); |  | 
|  365   UMA_HISTOGRAM_COUNTS("ZeroSuggest.URLResults", num_nav_results); |  | 
|  366   UMA_HISTOGRAM_COUNTS("ZeroSuggest.AllResults", num_results); |  | 
|  367  |  | 
|  368   // Show Most Visited results after ZeroSuggest response is received. |  | 
|  369   if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) { |  | 
|  370     if (!current_url_match_.destination_url.is_valid()) |  | 
|  371       return; |  | 
|  372     matches_.push_back(current_url_match_); |  | 
|  373     int relevance = 600; |  | 
|  374     if (num_results > 0) { |  | 
|  375       UMA_HISTOGRAM_COUNTS( |  | 
|  376           "Omnibox.ZeroSuggest.MostVisitedResultsCounterfactual", |  | 
|  377           most_visited_urls_.size()); |  | 
|  378     } |  | 
|  379     const base::string16 current_query_string16( |  | 
|  380         base::ASCIIToUTF16(current_query_)); |  | 
|  381     const std::string languages(client()->GetAcceptLanguages()); |  | 
|  382     for (size_t i = 0; i < most_visited_urls_.size(); i++) { |  | 
|  383       const history::MostVisitedURL& url = most_visited_urls_[i]; |  | 
|  384       SearchSuggestionParser::NavigationResult nav( |  | 
|  385           client()->GetSchemeClassifier(), url.url, |  | 
|  386           AutocompleteMatchType::NAVSUGGEST, url.title, std::string(), false, |  | 
|  387           relevance, true, current_query_string16, languages); |  | 
|  388       matches_.push_back(NavigationToMatch(nav)); |  | 
|  389       --relevance; |  | 
|  390     } |  | 
|  391     return; |  | 
|  392   } |  | 
|  393  |  | 
|  394   if (num_results == 0) |  | 
|  395     return; |  | 
|  396  |  | 
|  397   // TODO(jered): Rip this out once the first match is decoupled from the |  | 
|  398   // current typing in the omnibox. |  | 
|  399   matches_.push_back(current_url_match_); |  | 
|  400  |  | 
|  401   for (MatchMap::const_iterator it(map.begin()); it != map.end(); ++it) |  | 
|  402     matches_.push_back(it->second); |  | 
|  403  |  | 
|  404   const SearchSuggestionParser::NavigationResults& nav_results( |  | 
|  405       results_.navigation_results); |  | 
|  406   for (SearchSuggestionParser::NavigationResults::const_iterator it( |  | 
|  407            nav_results.begin()); it != nav_results.end(); ++it) |  | 
|  408     matches_.push_back(NavigationToMatch(*it)); |  | 
|  409 } |  | 
|  410  |  | 
|  411 AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() { |  | 
|  412   AutocompleteMatch match; |  | 
|  413   client()->GetAutocompleteClassifier()->Classify( |  | 
|  414       permanent_text_, false, true, current_page_classification_, &match, NULL); |  | 
|  415   match.allowed_to_be_default_match = true; |  | 
|  416  |  | 
|  417   // The placeholder suggestion for the current URL has high relevance so |  | 
|  418   // that it is in the first suggestion slot and inline autocompleted. It |  | 
|  419   // gets dropped as soon as the user types something. |  | 
|  420   match.relevance = GetVerbatimRelevance(); |  | 
|  421  |  | 
|  422   return match; |  | 
|  423 } |  | 
|  424  |  | 
|  425 int ZeroSuggestProvider::GetVerbatimRelevance() const { |  | 
|  426   return results_.verbatim_relevance >= 0 ? |  | 
|  427       results_.verbatim_relevance : kDefaultVerbatimZeroSuggestRelevance; |  | 
|  428 } |  | 
|  429  |  | 
|  430 bool ZeroSuggestProvider::ShouldShowNonContextualZeroSuggest( |  | 
|  431     const GURL& suggest_url, |  | 
|  432     const GURL& current_page_url) const { |  | 
|  433   const TemplateURLService* template_url_service = |  | 
|  434       client()->GetTemplateURLService(); |  | 
|  435   if (!ZeroSuggestEnabled(suggest_url, |  | 
|  436                           template_url_service->GetDefaultSearchProvider(), |  | 
|  437                           current_page_classification_, |  | 
|  438                           template_url_service->search_terms_data(), client())) |  | 
|  439     return false; |  | 
|  440  |  | 
|  441   // If we cannot send URLs, then only the MostVisited and Personalized |  | 
|  442   // variations can be shown. |  | 
|  443   if (!OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial() && |  | 
|  444       !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) |  | 
|  445     return false; |  | 
|  446  |  | 
|  447   // Only show zero suggest for HTTP[S] pages. |  | 
|  448   // TODO(mariakhomenko): We may be able to expand this set to include pages |  | 
|  449   // with other schemes (e.g. chrome://). That may require improvements to |  | 
|  450   // the formatting of the verbatim result returned by MatchForCurrentURL(). |  | 
|  451   if (!current_page_url.is_valid() || |  | 
|  452       ((current_page_url.scheme() != url::kHttpScheme) && |  | 
|  453       (current_page_url.scheme() != url::kHttpsScheme))) |  | 
|  454     return false; |  | 
|  455  |  | 
|  456   if (OmniboxFieldTrial::InZeroSuggestMostVisitedWithoutSerpFieldTrial() && |  | 
|  457       client() |  | 
|  458           ->GetTemplateURLService() |  | 
|  459           ->IsSearchResultsPageFromDefaultSearchProvider(current_page_url)) |  | 
|  460     return false; |  | 
|  461  |  | 
|  462   return true; |  | 
|  463 } |  | 
|  464  |  | 
|  465 void ZeroSuggestProvider::MaybeUseCachedSuggestions() { |  | 
|  466   if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) |  | 
|  467     return; |  | 
|  468  |  | 
|  469   std::string json_data = |  | 
|  470       client()->GetPrefs()->GetString(omnibox::kZeroSuggestCachedResults); |  | 
|  471   if (!json_data.empty()) { |  | 
|  472     scoped_ptr<base::Value> data( |  | 
|  473         SearchSuggestionParser::DeserializeJsonData(json_data)); |  | 
|  474     if (data && ParseSuggestResults( |  | 
|  475             *data, kDefaultZeroSuggestRelevance, false, &results_)) { |  | 
|  476       ConvertResultsToAutocompleteMatches(); |  | 
|  477       results_from_cache_ = !matches_.empty(); |  | 
|  478     } |  | 
|  479   } |  | 
|  480 } |  | 
| OLD | NEW |