15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/zero_suggest_provider.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/i18n/case_conversion.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_string_value_serializer.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/metrics/histogram.h" 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/metrics/user_metrics.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_classifier.h" 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/autocomplete/history_url_provider.h" 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/history/top_sites.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/history/core/browser/history_types.h" 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/proto/omnibox_input_type.pb.h" 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/autocomplete_input.h" 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/autocomplete_match.h" 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/autocomplete_provider_listener.h" 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/omnibox/omnibox_field_trial.h" 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/search_provider.h" 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_service.h" 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/variations/variations_http_header_provider.h" 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/base/escape.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/base/net_util.h" 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/http/http_request_headers.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h" 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(hfung): The histogram code was copied and modified from 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// search_provider.cc. Refactor and consolidate the code. 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// We keep track in a histogram how many suggest requests we send, how 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// many suggest requests we invalidate (e.g., due to a user typing 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// another character), and how many replies we receive. 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// *** ADD NEW ENUMS AFTER ALL PREVIOUSLY DEFINED ONES! *** 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// (excluding the end-of-list enum value) 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// We do not want values of existing enums to change or else it screws 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// up the statistics. 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)enum ZeroSuggestRequestsHistogramValue { 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ZERO_SUGGEST_REQUEST_SENT = 1, 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ZERO_SUGGEST_REQUEST_INVALIDATED, 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ZERO_SUGGEST_REPLY_RECEIVED, 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ZERO_SUGGEST_MAX_REQUEST_HISTOGRAM_VALUE 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void LogOmniboxZeroSuggestRequest( 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ZeroSuggestRequestsHistogramValue request_value) { 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Omnibox.ZeroSuggestRequests", request_value, 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ZERO_SUGGEST_MAX_REQUEST_HISTOGRAM_VALUE); 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The maximum relevance of the top match from this provider. 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kDefaultVerbatimZeroSuggestRelevance = 1300; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Relevance value to use if it was not set explicitly by the server. 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const int kDefaultZeroSuggestRelevance = 100; 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ZeroSuggestProvider* ZeroSuggestProvider::Create( 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteProviderListener* listener, 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TemplateURLService* template_url_service, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile) { 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new ZeroSuggestProvider(listener, template_url_service, profile); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// static 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ZeroSuggestProvider::RegisterProfilePrefs( 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) user_prefs::PrefRegistrySyncable* registry) { 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) registry->RegisterStringPref( 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs::kZeroSuggestCachedResults, 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string(), 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ZeroSuggestProvider::Start(const AutocompleteInput& input, 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool minimal_changes) { 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch matches_.clear(); 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (input.type() == metrics::OmniboxInputType::INVALID) 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Stop(true); 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) field_trial_triggered_ = false; 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) field_trial_triggered_in_session_ = false; 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) results_from_cache_ = false; 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch permanent_text_ = input.text(); 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch current_query_ = input.current_url().spec(); 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch current_page_classification_ = input.current_page_classification(); 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_url_match_ = MatchForCurrentURL(); 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const TemplateURL* default_provider = 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) template_url_service_->GetDefaultSearchProvider(); 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (default_provider == NULL) 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 prefix; 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TemplateURLRef::SearchTermsArgs search_term_args(prefix); 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GURL suggest_url(default_provider->suggestions_url_ref().ReplaceSearchTerms( 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_term_args, template_url_service_->search_terms_data())); 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!suggest_url.is_valid()) 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // No need to send the current page URL in personalized suggest field trial. 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (CanSendURL(input.current_url(), suggest_url, default_provider, 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current_page_classification_, 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci template_url_service_->search_terms_data(), client_.get()) && 12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) { 12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Update suggest_url to include the current_page_url. 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) search_term_args.current_page_url = current_query_; 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) suggest_url = GURL(default_provider->suggestions_url_ref(). 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ReplaceSearchTerms( 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_term_args, 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template_url_service_->search_terms_data())); 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } else if (!CanShowZeroSuggestWithoutSendingURL(suggest_url, 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch input.current_url())) { 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return; 13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) done_ = false; 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jered): Consider adding locally-sourced zero-suggestions here too. 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // These may be useful on the NTP or more relevant to the user than server 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // suggestions, if based on local browsing history. 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MaybeUseCachedSuggestions(); 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Run(suggest_url); 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ZeroSuggestProvider::Stop(bool clear_cached_results) { 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (fetcher_) 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_INVALIDATED); 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fetcher_.reset(); 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) done_ = true; 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (clear_cached_results) { 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // We do not call Clear() on |results_| to retain |verbatim_relevance| 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // value in the |results_| object. |verbatim_relevance| is used at the 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // beginning of the next StartZeroSuggest() call to determine the current 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // url match relevance. 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) results_.suggest_results.clear(); 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) results_.navigation_results.clear(); 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) current_query_.clear(); 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ZeroSuggestProvider::DeleteMatch(const AutocompleteMatch& match) { 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) { 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Remove the deleted match from the cache, so it is not shown to the user 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // again. Since we cannot remove just one result, blow away the cache. 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) profile_->GetPrefs()->SetString(prefs::kZeroSuggestCachedResults, 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string()); 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BaseSearchProvider::DeleteMatch(match); 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ZeroSuggestProvider::AddProviderInfo(ProvidersInfo* provider_info) const { 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) BaseSearchProvider::AddProviderInfo(provider_info); 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!results_.suggest_results.empty() || !results_.navigation_results.empty()) 17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) provider_info->back().set_times_returned_results_in_session(1); 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ZeroSuggestProvider::ResetSession() { 177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // The user has started editing in the omnibox, so leave 178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // |field_trial_triggered_in_session_| unchanged and set 179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // |field_trial_triggered_| to false since zero suggest is inactive now. 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch field_trial_triggered_ = false; 181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ZeroSuggestProvider::ZeroSuggestProvider( 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AutocompleteProviderListener* listener, 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TemplateURLService* template_url_service, 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile* profile) 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : BaseSearchProvider(template_url_service, 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<AutocompleteProviderClient>( 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ChromeAutocompleteProviderClient(profile)), 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AutocompleteProvider::TYPE_ZERO_SUGGEST), 1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) listener_(listener), 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile_(profile), 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) results_from_cache_(false), 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) weak_ptr_factory_(this) { 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ZeroSuggestProvider::~ZeroSuggestProvider() { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const TemplateURL* ZeroSuggestProvider::GetTemplateURL(bool is_keyword) const { 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Zero suggest provider should not receive keyword results. 20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) DCHECK(!is_keyword); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return template_url_service_->GetDefaultSearchProvider(); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const AutocompleteInput ZeroSuggestProvider::GetInput(bool is_keyword) const { 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return AutocompleteInput( 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::string16(), base::string16::npos, base::string16(), 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL(current_query_), current_page_classification_, true, false, false, 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch true, ChromeAutocompleteSchemeClassifier(profile_)); 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ZeroSuggestProvider::ShouldAppendExtraParams( 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchSuggestionParser::SuggestResult& result) const { 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We always use the default provider for search, so append the params. 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ZeroSuggestProvider::RecordDeletionResult(bool success) { 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (success) { 2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::RecordAction( 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Success")); 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::RecordAction( 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::UserMetricsAction("Omnibox.ZeroSuggestDelete.Failure")); 226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ZeroSuggestProvider::OnURLFetchComplete(const net::URLFetcher* source) { 2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(!done_); 2316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK_EQ(fetcher_.get(), source); 23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REPLY_RECEIVED); 23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool results_updated = false; 2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (source->GetStatus().is_success() && source->GetResponseCode() == 200) { 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::string json_data = SearchSuggestionParser::ExtractJsonData(source); 2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<base::Value> data( 2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SearchSuggestionParser::DeserializeJsonData(json_data)); 2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (data) { 2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (StoreSuggestionResponse(json_data, *data)) 2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) results_updated = ParseSuggestResults( 2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *data, kDefaultZeroSuggestRelevance, false, &results_); 2456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) fetcher_.reset(); 24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) done_ = true; 24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ConvertResultsToAutocompleteMatches(); 2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) listener_->OnProviderUpdate(results_updated); 2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool ZeroSuggestProvider::StoreSuggestionResponse( 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& json_data, 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::Value& parsed_data) { 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial() || 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) json_data.empty()) 2586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) profile_->GetPrefs()->SetString(prefs::kZeroSuggestCachedResults, json_data); 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // If we received an empty result list, we should update the display, as it 2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // may be showing cached results that should not be shown. 2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::ListValue* root_list = NULL; 2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::ListValue* results_list = NULL; 2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (parsed_data.GetAsList(&root_list) && 2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) root_list->GetList(1, &results_list) && 2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) results_list->empty()) 2686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 2696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // We are finished with the request and want to bail early. 2716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (results_from_cache_) 2726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) done_ = true; 2736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return results_from_cache_; 27523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 27623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ZeroSuggestProvider::AddSuggestResultsToMap( 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchSuggestionParser::SuggestResults& results, 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MatchMap* map) { 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; i < results.size(); ++i) 2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AddMatchToMap(results[i], std::string(), i, false, false, map); 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AutocompleteMatch ZeroSuggestProvider::NavigationToMatch( 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchSuggestionParser::NavigationResult& navigation) { 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AutocompleteMatch match(this, navigation.relevance(), false, 287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigation.type()); 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) match.destination_url = navigation.url(); 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Zero suggest results should always omit protocols and never appear bold. 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string languages( 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) match.contents = net::FormatUrl(navigation.url(), languages, 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::kFormatUrlOmitAll, net::UnescapeRule::SPACES, NULL, NULL, NULL); 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) match.fill_into_edit += 296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch match.contents, ChromeAutocompleteSchemeClassifier(profile_)); 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) match.contents.length(), ACMatchClassification::URL, 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &match.contents_class); 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch match.description = 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AutocompleteMatch::SanitizeString(navigation.description()); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AutocompleteMatch::ClassifyLocationInString(base::string16::npos, 0, 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch match.description.length(), ACMatchClassification::NONE, 307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &match.description_class); 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return match; 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ZeroSuggestProvider::Run(const GURL& suggest_url) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kFetcherID = 1; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_.reset( 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLFetcher::Create(kFetcherID, 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) suggest_url, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLFetcher::GET, this)); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_->SetRequestContext(profile_->GetRequestContext()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Add Chrome experiment state to the request headers. 320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::HttpRequestHeaders headers; 321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fetcher_->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers); 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fetcher_->SetExtraRequestHeaders(headers.ToString()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetcher_->Start(); 325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) { 327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) most_visited_urls_.clear(); 328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) history::TopSites* ts = profile_->GetTopSites(); 329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (ts) { 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ts->GetMostVisitedURLs( 331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ZeroSuggestProvider::OnMostVisitedUrlsAvailable, 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), false); 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LogOmniboxZeroSuggestRequest(ZERO_SUGGEST_REQUEST_SENT); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ZeroSuggestProvider::OnMostVisitedUrlsAvailable( 339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const history::MostVisitedURLList& urls) { 340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) most_visited_urls_ = urls; 341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ZeroSuggestProvider::ConvertResultsToAutocompleteMatches() { 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) matches_.clear(); 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const TemplateURL* default_provider = 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template_url_service_->GetDefaultSearchProvider(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fail if we can't set the clickthrough URL for query suggestions. 349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (default_provider == NULL || !default_provider->SupportsReplacement( 350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) template_url_service_->search_terms_data())) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MatchMap map; 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AddSuggestResultsToMap(results_.suggest_results, &map); 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const int num_query_results = map.size(); 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const int num_nav_results = results_.navigation_results.size(); 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const int num_results = num_query_results + num_nav_results; 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UMA_HISTOGRAM_COUNTS("ZeroSuggest.QueryResults", num_query_results); 360010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UMA_HISTOGRAM_COUNTS("ZeroSuggest.URLResults", num_nav_results); 361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UMA_HISTOGRAM_COUNTS("ZeroSuggest.AllResults", num_results); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Show Most Visited results after ZeroSuggest response is received. 364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial()) { 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!current_url_match_.destination_url.is_valid()) 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) matches_.push_back(current_url_match_); 368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int relevance = 600; 369d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (num_results > 0) { 370d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UMA_HISTOGRAM_COUNTS( 371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "Omnibox.ZeroSuggest.MostVisitedResultsCounterfactual", 372d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) most_visited_urls_.size()); 373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::string16 current_query_string16( 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ASCIIToUTF16(current_query_)); 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string languages( 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 378d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (size_t i = 0; i < most_visited_urls_.size(); i++) { 379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const history::MostVisitedURL& url = most_visited_urls_[i]; 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SearchSuggestionParser::NavigationResult nav( 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChromeAutocompleteSchemeClassifier(profile_), url.url, 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AutocompleteMatchType::NAVSUGGEST, url.title, std::string(), false, 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch relevance, true, current_query_string16, languages); 384d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) matches_.push_back(NavigationToMatch(nav)); 385d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) --relevance; 386d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 387d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 388d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (num_results == 0) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(jered): Rip this out once the first match is decoupled from the 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // current typing in the omnibox. 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) matches_.push_back(current_url_match_); 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (MatchMap::const_iterator it(map.begin()); it != map.end(); ++it) 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) matches_.push_back(it->second); 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchSuggestionParser::NavigationResults& nav_results( 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) results_.navigation_results); 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (SearchSuggestionParser::NavigationResults::const_iterator it( 4035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) nav_results.begin()); it != nav_results.end(); ++it) 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) matches_.push_back(NavigationToMatch(*it)); 405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)AutocompleteMatch ZeroSuggestProvider::MatchForCurrentURL() { 408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) AutocompleteMatch match; 409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) AutocompleteClassifierFactory::GetForProfile(profile_)->Classify( 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) permanent_text_, false, true, current_page_classification_, &match, NULL); 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) match.is_history_what_you_typed_match = false; 412c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch match.allowed_to_be_default_match = true; 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The placeholder suggestion for the current URL has high relevance so 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // that it is in the first suggestion slot and inline autocompleted. It 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // gets dropped as soon as the user types something. 417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.relevance = GetVerbatimRelevance(); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return match; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int ZeroSuggestProvider::GetVerbatimRelevance() const { 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return results_.verbatim_relevance >= 0 ? 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) results_.verbatim_relevance : kDefaultVerbatimZeroSuggestRelevance; 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 42623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 42723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool ZeroSuggestProvider::CanShowZeroSuggestWithoutSendingURL( 42823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const GURL& suggest_url, 42923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const GURL& current_page_url) const { 43023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!ZeroSuggestEnabled(suggest_url, 43123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) template_url_service_->GetDefaultSearchProvider(), 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current_page_classification_, 4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci template_url_service_->search_terms_data(), 4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_.get())) 43523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 43623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 43723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // If we cannot send URLs, then only the MostVisited and Personalized 43823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // variations can be shown. 43923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!OmniboxFieldTrial::InZeroSuggestMostVisitedFieldTrial() && 44023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) !OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) 44123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 44223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 44323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Only show zero suggest for HTTP[S] pages. 44423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // TODO(mariakhomenko): We may be able to expand this set to include pages 44523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // with other schemes (e.g. chrome://). That may require improvements to 44623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // the formatting of the verbatim result returned by MatchForCurrentURL(). 44723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!current_page_url.is_valid() || 448010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ((current_page_url.scheme() != url::kHttpScheme) && 449010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (current_page_url.scheme() != url::kHttpsScheme))) 45023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 45123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 45223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return true; 45323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 454010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 455010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ZeroSuggestProvider::MaybeUseCachedSuggestions() { 456010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!OmniboxFieldTrial::InZeroSuggestPersonalizedFieldTrial()) 457010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 458010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 459010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string json_data = profile_->GetPrefs()->GetString( 460010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) prefs::kZeroSuggestCachedResults); 461010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!json_data.empty()) { 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::Value> data( 4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SearchSuggestionParser::DeserializeJsonData(json_data)); 4646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (data && ParseSuggestResults( 4656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *data, kDefaultZeroSuggestRelevance, false, &results_)) { 466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ConvertResultsToAutocompleteMatches(); 467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) results_from_cache_ = !matches_.empty(); 468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 470010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 471