15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/base_search_provider.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/i18n/case_conversion.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/metrics/proto/omnibox_event.pb.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/metrics/proto/omnibox_input_type.pb.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/autocomplete_provider_client.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/omnibox/autocomplete_provider_listener.h" 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/omnibox/omnibox_field_trial.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_prepopulate_data.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_service.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/url_request/url_fetcher.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)using metrics::OmniboxEventProto; 246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// SuggestionDeletionHandler ------------------------------------------------- 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This class handles making requests to the server in order to delete 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// personalized suggestions. 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class SuggestionDeletionHandler : public net::URLFetcherDelegate { 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef base::Callback<void(bool, SuggestionDeletionHandler*)> 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeletionCompletedCallback; 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SuggestionDeletionHandler( 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& deletion_url, 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestContextGetter* request_context, 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const DeletionCompletedCallback& callback); 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~SuggestionDeletionHandler(); 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // net::URLFetcherDelegate: 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<net::URLFetcher> deletion_fetcher_; 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeletionCompletedCallback callback_; 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SuggestionDeletionHandler); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SuggestionDeletionHandler::SuggestionDeletionHandler( 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& deletion_url, 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::URLRequestContextGetter* request_context, 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const DeletionCompletedCallback& callback) : callback_(callback) { 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url(deletion_url); 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(url.is_valid()); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) deletion_fetcher_.reset(net::URLFetcher::Create( 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BaseSearchProvider::kDeletionURLFetcherID, 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url, 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLFetcher::GET, 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this)); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci deletion_fetcher_->SetRequestContext(request_context); 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) deletion_fetcher_->Start(); 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SuggestionDeletionHandler::~SuggestionDeletionHandler() { 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SuggestionDeletionHandler::OnURLFetchComplete( 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const net::URLFetcher* source) { 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(source == deletion_fetcher_.get()); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback_.Run( 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) source->GetStatus().is_success() && (source->GetResponseCode() == 200), 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this); 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// BaseSearchProvider --------------------------------------------------------- 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int BaseSearchProvider::kDefaultProviderURLFetcherID = 1; 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int BaseSearchProvider::kKeywordProviderURLFetcherID = 2; 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int BaseSearchProvider::kDeletionURLFetcherID = 3; 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBaseSearchProvider::BaseSearchProvider( 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TemplateURLService* template_url_service, 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<AutocompleteProviderClient> client, 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AutocompleteProvider::Type type) 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : AutocompleteProvider(type), 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_url_service_(template_url_service), 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_(client.Pass()), 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) field_trial_triggered_(false), 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) field_trial_triggered_in_session_(false) { 9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BaseSearchProvider::ShouldPrefetch(const AutocompleteMatch& match) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return match.GetAdditionalInfo(kShouldPrefetchKey) == kTrue; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 102effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochAutocompleteMatch BaseSearchProvider::CreateSearchSuggestion( 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::string16& suggestion, 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AutocompleteMatchType::Type type, 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool from_keyword_provider, 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const TemplateURL* template_url, 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const SearchTermsData& search_terms_data) { 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // These calls use a number of default values. For instance, they assume 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // that if this match is from a keyword provider, then the user is in keyword 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // mode. They also assume the caller knows what it's doing and we set 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // this match to look as if it was received/created synchronously. 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SearchSuggestionParser::SuggestResult suggest_result( 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci suggestion, type, suggestion, base::string16(), base::string16(), 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::string16(), base::string16(), std::string(), std::string(), 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci from_keyword_provider, 0, false, false, base::string16()); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci suggest_result.set_received_after_last_keystroke(false); 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return CreateSearchSuggestion( 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL, AutocompleteInput(), from_keyword_provider, suggest_result, 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_url, search_terms_data, 0, false); 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BaseSearchProvider::DeleteMatch(const AutocompleteMatch& match) { 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(match.deletable); 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey).empty()) { 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) deletion_handlers_.push_back(new SuggestionDeletionHandler( 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey), 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->RequestContext(), 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&BaseSearchProvider::OnDeletionComplete, 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this)))); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TemplateURL* template_url = 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) match.GetTemplateURL(template_url_service_, false); 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This may be NULL if the template corresponding to the keyword has been 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // deleted or there is no keyword set. 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (template_url != NULL) { 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->DeleteMatchingURLsForKeywordFromHistory(template_url->id(), 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci match.contents); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Immediately update the list of matches to show the match was deleted, 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // regardless of whether the server request actually succeeds. 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeleteMatchFromMatches(match); 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BaseSearchProvider::AddProviderInfo(ProvidersInfo* provider_info) const { 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo()); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back(); 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_entry.set_provider(AsOmniboxEventProviderType()); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_entry.set_provider_done(done_); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<uint32> field_trial_hashes; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OmniboxFieldTrial::GetActiveSuggestFieldTrialHashes(&field_trial_hashes); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < field_trial_hashes.size(); ++i) { 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (field_trial_triggered_) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_entry.mutable_field_trial_triggered()->Add(field_trial_hashes[i]); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (field_trial_triggered_in_session_) { 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_entry.mutable_field_trial_triggered_in_session()->Add( 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) field_trial_hashes[i]); 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char BaseSearchProvider::kRelevanceFromServerKey[] = 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "relevance_from_server"; 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char BaseSearchProvider::kShouldPrefetchKey[] = "should_prefetch"; 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char BaseSearchProvider::kSuggestMetadataKey[] = "suggest_metadata"; 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char BaseSearchProvider::kDeletionUrlKey[] = "deletion_url"; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char BaseSearchProvider::kTrue[] = "true"; 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char BaseSearchProvider::kFalse[] = "false"; 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BaseSearchProvider::~BaseSearchProvider() {} 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void BaseSearchProvider::SetDeletionURL(const std::string& deletion_url, 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AutocompleteMatch* match) { 176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (deletion_url.empty()) 177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!template_url_service_) 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL url = 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_url_service_->GetDefaultSearchProvider()->GenerateSearchURL( 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_url_service_->search_terms_data()); 183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url = url.GetOrigin().Resolve(deletion_url); 184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (url.is_valid()) { 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) match->RecordAdditionalInfo(BaseSearchProvider::kDeletionUrlKey, 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url.spec()); 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) match->deletable = true; 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AutocompleteMatch BaseSearchProvider::CreateSearchSuggestion( 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AutocompleteProvider* autocomplete_provider, 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const AutocompleteInput& input, 1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const bool in_keyword_mode, 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchSuggestionParser::SuggestResult& suggestion, 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const TemplateURL* template_url, 198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const SearchTermsData& search_terms_data, 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int accepted_suggestion, 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool append_extra_query_params) { 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AutocompleteMatch match(autocomplete_provider, suggestion.relevance(), false, 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) suggestion.type()); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!template_url) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return match; 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.keyword = template_url->keyword(); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.contents = suggestion.match_contents(); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.contents_class = suggestion.match_contents_class(); 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) match.answer_contents = suggestion.answer_contents(); 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) match.answer_type = suggestion.answer_type(); 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (suggestion.type() == AutocompleteMatchType::SEARCH_SUGGEST_INFINITE) { 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.RecordAdditionalInfo( 213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kACMatchPropertyInputText, base::UTF16ToUTF8(input.text())); 214effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch match.RecordAdditionalInfo( 215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kACMatchPropertyContentsPrefix, 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::UTF16ToUTF8(suggestion.match_contents_prefix())); 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.RecordAdditionalInfo( 218effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kACMatchPropertyContentsStartIndex, 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static_cast<int>( 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) suggestion.suggestion().length() - match.contents.length())); 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!suggestion.annotation().empty()) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.description = suggestion.annotation(); 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // suggestion.match_contents() should have already been collapsed. 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.allowed_to_be_default_match = 2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) (!in_keyword_mode || suggestion.from_keyword_provider()) && 229effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch (base::CollapseWhitespace(input.text(), false) == 230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch suggestion.match_contents()); 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When the user forced a query, we need to make sure all the fill_into_edit 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // values preserve that property. Otherwise, if the user starts editing a 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // suggestion, non-Search results will suddenly appear. 235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (input.type() == metrics::OmniboxInputType::FORCED_QUERY) 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.fill_into_edit.assign(base::ASCIIToUTF16("?")); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (suggestion.from_keyword_provider()) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.fill_into_edit.append(match.keyword + base::char16(' ')); 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // We only allow inlinable navsuggestions that were received before the 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // last keystroke because we don't want asynchronous inline autocompletions. 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!input.prevent_inline_autocomplete() && 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !suggestion.received_after_last_keystroke() && 2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) (!in_keyword_mode || suggestion.from_keyword_provider()) && 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartsWith(suggestion.suggestion(), input.text(), false)) { 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.inline_autocompletion = 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) suggestion.suggestion().substr(input.text().length()); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.allowed_to_be_default_match = true; 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.fill_into_edit.append(suggestion.suggestion()); 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const TemplateURLRef& search_url = template_url->url_ref(); 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(search_url.SupportsReplacement(search_terms_data)); 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.search_terms_args.reset( 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new TemplateURLRef::SearchTermsArgs(suggestion.suggestion())); 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.search_terms_args->original_query = input.text(); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.search_terms_args->accepted_suggestion = accepted_suggestion; 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) match.search_terms_args->enable_omnibox_start_margin = true; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.search_terms_args->suggest_query_params = 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) suggestion.suggest_query_params(); 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.search_terms_args->append_extra_query_params = 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) append_extra_query_params; 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is the destination URL sans assisted query stats. This must be set 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // so the AutocompleteController can properly de-dupe; the controller will 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // eventually overwrite it before it reaches the user. 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.destination_url = 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GURL(search_url.ReplaceSearchTerms(*match.search_terms_args.get(), 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) search_terms_data)); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Search results don't look like URLs. 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.transition = suggestion.from_keyword_provider() ? 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_KEYWORD : ui::PAGE_TRANSITION_GENERATED; 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return match; 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 27723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool BaseSearchProvider::ZeroSuggestEnabled( 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& suggest_url, 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const TemplateURL* template_url, 2806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) OmniboxEventProto::PageClassification page_classification, 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchTermsData& search_terms_data, 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AutocompleteProviderClient* client) { 28323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!OmniboxFieldTrial::InZeroSuggestFieldTrial()) 28423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 28523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 28623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Make sure we are sending the suggest request through HTTPS to prevent 28723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // exposing the current page URL or personalized results without encryption. 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!suggest_url.SchemeIs(url::kHttpsScheme)) 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 29123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Don't show zero suggest on the NTP. 29223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // TODO(hfung): Experiment with showing MostVisited zero suggest on NTP 29323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // under the conditions described in crbug.com/305366. 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((page_classification == 2956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS) || 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (page_classification == 2976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS)) 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Don't run if in incognito mode. 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (client->IsOffTheRecord()) 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't run if we can't get preferences or search suggest is not enabled. 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!client->SearchSuggestEnabled()) 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Only make the request if we know that the provider supports zero suggest 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // (currently only the prepopulated Google provider). 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (template_url == NULL || 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !template_url->SupportsReplacement(search_terms_data) || 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TemplateURLPrepopulateData::GetEngineType( 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *template_url, search_terms_data) != SEARCH_ENGINE_GOOGLE) 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 31623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return true; 31723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 31823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 31923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// static 32023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool BaseSearchProvider::CanSendURL( 32123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const GURL& current_page_url, 32223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const GURL& suggest_url, 32323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const TemplateURL* template_url, 3246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) OmniboxEventProto::PageClassification page_classification, 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchTermsData& search_terms_data, 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AutocompleteProviderClient* client) { 32723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!ZeroSuggestEnabled(suggest_url, template_url, page_classification, 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci search_terms_data, client)) 32923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 33023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 33123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!current_page_url.is_valid()) 33223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 33323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 33423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Only allow HTTP URLs or HTTPS URLs for the same domain as the search 33523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // provider. 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((current_page_url.scheme() != url::kHttpScheme) && 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ((current_page_url.scheme() != url::kHttpsScheme) || 33823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) !net::registry_controlled_domains::SameDomainOrHost( 33923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) current_page_url, suggest_url, 34023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES))) 34123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 34223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!client->TabSyncEnabledAndUnencrypted()) 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BaseSearchProvider::AddMatchToMap( 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SearchSuggestionParser::SuggestResult& result, 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& metadata, 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int accepted_suggestion, 3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool mark_as_deletable, 3546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool in_keyword_mode, 3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MatchMap* map) { 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AutocompleteMatch match = CreateSearchSuggestion( 3576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) this, GetInput(result.from_keyword_provider()), in_keyword_mode, result, 358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetTemplateURL(result.from_keyword_provider()), 3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_url_service_->search_terms_data(), accepted_suggestion, 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ShouldAppendExtraParams(result)); 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!match.destination_url.is_valid()) 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci match.search_terms_args->bookmark_bar_pinned = client_->ShowBookmarkBar(); 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.RecordAdditionalInfo(kRelevanceFromServerKey, 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result.relevance_from_server() ? kTrue : kFalse); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.RecordAdditionalInfo(kShouldPrefetchKey, 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result.should_prefetch() ? kTrue : kFalse); 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SetDeletionURL(result.deletion_url(), &match); 369010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mark_as_deletable) 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.deletable = true; 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Metadata is needed only for prefetching queries. 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result.should_prefetch()) 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.RecordAdditionalInfo(kSuggestMetadataKey, metadata); 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try to add |match| to |map|. If a match for this suggestion is 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // already in |map|, replace it if |match| is more relevant. 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // NOTE: Keep this ToLower() call in sync with url_database.cc. 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MatchKey match_key( 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::make_pair(base::i18n::ToLower(result.suggestion()), 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.search_terms_args->suggest_query_params)); 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::pair<MatchMap::iterator, bool> i( 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) map->insert(std::make_pair(match_key, match))); 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool should_prefetch = result.should_prefetch(); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!i.second) { 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // NOTE: We purposefully do a direct relevance comparison here instead of 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // added first" rather than "items alphabetically first" when the scores 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // are equal. The only case this matters is when a user has results with 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the same score that differ only by capitalization; because the history 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // system returns results sorted by recency, this means we'll pick the most 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // recent such result even if the precision of our relevance score is too 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // low to distinguish the two. 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (match.relevance > i.first->second.relevance) { 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.duplicate_matches.insert(match.duplicate_matches.end(), 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i.first->second.duplicate_matches.begin(), 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i.first->second.duplicate_matches.end()); 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i.first->second.duplicate_matches.clear(); 399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.duplicate_matches.push_back(i.first->second); 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) i.first->second = match; 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i.first->second.duplicate_matches.push_back(match); 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (match.keyword == i.first->second.keyword) { 404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Old and new matches are from the same search provider. It is okay to 405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // record one match's prefetch data onto a different match (for the same 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // query string) for the following reasons: 407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 1. Because the suggest server only sends down a query string from 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // which we construct a URL, rather than sending a full URL, and because 409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // we construct URLs from query strings in the same way every time, the 410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // URLs for the two matches will be the same. Therefore, we won't end up 411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // prefetching something the server didn't intend. 412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // 2. Presumably the server sets the prefetch bit on a match it things 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // is sufficiently relevant that the user is likely to choose it. 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Surely setting the prefetch bit on a match of even higher relevance 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // won't violate this assumption. 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) should_prefetch |= ShouldPrefetch(i.first->second); 417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i.first->second.RecordAdditionalInfo(kShouldPrefetchKey, 418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) should_prefetch ? kTrue : kFalse); 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (should_prefetch) 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) i.first->second.RecordAdditionalInfo(kSuggestMetadataKey, metadata); 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Copy over answer data from lower-ranking item, if necessary. 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This depends on the lower-ranking item always being added last - see 4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // use of push_back above. 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AutocompleteMatch& more_relevant_match = i.first->second; 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const AutocompleteMatch& less_relevant_match = 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci more_relevant_match.duplicate_matches.back(); 4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!less_relevant_match.answer_type.empty() && 4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci more_relevant_match.answer_type.empty()) { 4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci more_relevant_match.answer_type = less_relevant_match.answer_type; 4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci more_relevant_match.answer_contents = less_relevant_match.answer_contents; 4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool BaseSearchProvider::ParseSuggestResults( 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Value& root_val, 4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int default_result_relevance, 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool is_keyword_result, 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SearchSuggestionParser::Results* results) { 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!SearchSuggestionParser::ParseSuggestResults( 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) root_val, GetInput(is_keyword_result), 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->SchemeClassifier(), default_result_relevance, 4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->AcceptLanguages(), is_keyword_result, results)) 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (std::vector<GURL>::const_iterator it = 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) results->answers_image_urls.begin(); 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) it != results->answers_image_urls.end(); ++it) 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->PrefetchImage(*it); 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) field_trial_triggered_ |= results->field_trial_triggered; 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) field_trial_triggered_in_session_ |= results->field_trial_triggered; 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 4566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 4576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BaseSearchProvider::DeleteMatchFromMatches( 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const AutocompleteMatch& match) { 460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (ACMatches::iterator i(matches_.begin()); i != matches_.end(); ++i) { 461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Find the desired match to delete by checking the type and contents. 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We can't check the destination URL, because the autocomplete controller 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // may have reformulated that. Not that while checking for matching 464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // contents works for personalized suggestions, if more match types gain 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // deletion support, this algorithm may need to be re-examined. 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (i->contents == match.contents && i->type == match.type) { 467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) matches_.erase(i); 468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BaseSearchProvider::OnDeletionComplete( 474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool success, SuggestionDeletionHandler* handler) { 475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RecordDeletionResult(success); 476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SuggestionDeletionHandlers::iterator it = std::find( 477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) deletion_handlers_.begin(), deletion_handlers_.end(), handler); 478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(it != deletion_handlers_.end()); 479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) deletion_handlers_.erase(it); 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 481