OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/autocomplete/base_search_provider.h" | 5 #include "chrome/browser/autocomplete/base_search_provider.h" |
6 | 6 |
7 #include "base/i18n/case_conversion.h" | 7 #include "base/i18n/case_conversion.h" |
8 #include "base/prefs/pref_registry_simple.h" | 8 #include "base/prefs/pref_registry_simple.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" | 12 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" |
13 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service.h" | 13 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service.h" |
14 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service_factory.h" | 14 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service_factory.h" |
15 #include "chrome/browser/history/history_service.h" | 15 #include "chrome/browser/history/history_service.h" |
16 #include "chrome/browser/history/history_service_factory.h" | 16 #include "chrome/browser/history/history_service_factory.h" |
17 #include "chrome/browser/omnibox/omnibox_field_trial.h" | 17 #include "chrome/browser/omnibox/omnibox_field_trial.h" |
18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/search/search.h" | |
20 #include "chrome/browser/search_engines/template_url_service_factory.h" | |
21 #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" | |
22 #include "chrome/browser/sync/profile_sync_service.h" | 19 #include "chrome/browser/sync/profile_sync_service.h" |
23 #include "chrome/browser/sync/profile_sync_service_factory.h" | 20 #include "chrome/browser/sync/profile_sync_service_factory.h" |
24 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
25 #include "components/autocomplete/autocomplete_provider_listener.h" | 22 #include "components/autocomplete/autocomplete_provider_listener.h" |
26 #include "components/metrics/proto/omnibox_event.pb.h" | 23 #include "components/metrics/proto/omnibox_event.pb.h" |
27 #include "components/metrics/proto/omnibox_input_type.pb.h" | 24 #include "components/metrics/proto/omnibox_input_type.pb.h" |
28 #include "components/search_engines/template_url.h" | 25 #include "components/search_engines/template_url.h" |
29 #include "components/search_engines/template_url_prepopulate_data.h" | 26 #include "components/search_engines/template_url_prepopulate_data.h" |
30 #include "components/search_engines/template_url_service.h" | 27 #include "components/search_engines/template_url_service.h" |
31 #include "components/sync_driver/sync_prefs.h" | 28 #include "components/sync_driver/sync_prefs.h" |
32 #include "content/public/common/url_constants.h" | |
33 #include "net/base/escape.h" | 29 #include "net/base/escape.h" |
34 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 30 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
35 #include "net/url_request/url_fetcher.h" | 31 #include "net/url_request/url_fetcher.h" |
36 #include "net/url_request/url_fetcher_delegate.h" | 32 #include "net/url_request/url_fetcher_delegate.h" |
37 #include "url/gurl.h" | 33 #include "url/gurl.h" |
38 | 34 |
39 using metrics::OmniboxEventProto; | 35 using metrics::OmniboxEventProto; |
40 | 36 |
41 // SuggestionDeletionHandler ------------------------------------------------- | 37 // SuggestionDeletionHandler ------------------------------------------------- |
42 | 38 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 } | 88 } |
93 | 89 |
94 // BaseSearchProvider --------------------------------------------------------- | 90 // BaseSearchProvider --------------------------------------------------------- |
95 | 91 |
96 // static | 92 // static |
97 const int BaseSearchProvider::kDefaultProviderURLFetcherID = 1; | 93 const int BaseSearchProvider::kDefaultProviderURLFetcherID = 1; |
98 const int BaseSearchProvider::kKeywordProviderURLFetcherID = 2; | 94 const int BaseSearchProvider::kKeywordProviderURLFetcherID = 2; |
99 const int BaseSearchProvider::kDeletionURLFetcherID = 3; | 95 const int BaseSearchProvider::kDeletionURLFetcherID = 3; |
100 | 96 |
101 BaseSearchProvider::BaseSearchProvider(AutocompleteProviderListener* listener, | 97 BaseSearchProvider::BaseSearchProvider(AutocompleteProviderListener* listener, |
| 98 TemplateURLService* template_url_service, |
102 Profile* profile, | 99 Profile* profile, |
103 AutocompleteProvider::Type type) | 100 AutocompleteProvider::Type type) |
104 : AutocompleteProvider(type), | 101 : AutocompleteProvider(type), |
105 listener_(listener), | 102 listener_(listener), |
| 103 template_url_service_(template_url_service), |
106 profile_(profile), | 104 profile_(profile), |
107 field_trial_triggered_(false), | 105 field_trial_triggered_(false), |
108 field_trial_triggered_in_session_(false), | 106 field_trial_triggered_in_session_(false), |
109 suggest_results_pending_(0) { | 107 suggest_results_pending_(0) { |
110 } | 108 } |
111 | 109 |
112 // static | 110 // static |
113 bool BaseSearchProvider::ShouldPrefetch(const AutocompleteMatch& match) { | 111 bool BaseSearchProvider::ShouldPrefetch(const AutocompleteMatch& match) { |
114 return match.GetAdditionalInfo(kShouldPrefetchKey) == kTrue; | 112 return match.GetAdditionalInfo(kShouldPrefetchKey) == kTrue; |
115 } | 113 } |
(...skipping 26 matching lines...) Expand all Loading... |
142 if (!match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey).empty()) { | 140 if (!match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey).empty()) { |
143 deletion_handlers_.push_back(new SuggestionDeletionHandler( | 141 deletion_handlers_.push_back(new SuggestionDeletionHandler( |
144 match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey), | 142 match.GetAdditionalInfo(BaseSearchProvider::kDeletionUrlKey), |
145 profile_, | 143 profile_, |
146 base::Bind(&BaseSearchProvider::OnDeletionComplete, | 144 base::Bind(&BaseSearchProvider::OnDeletionComplete, |
147 base::Unretained(this)))); | 145 base::Unretained(this)))); |
148 } | 146 } |
149 | 147 |
150 HistoryService* const history_service = | 148 HistoryService* const history_service = |
151 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); | 149 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); |
152 TemplateURLService* template_url_service = | 150 TemplateURL* template_url = |
153 TemplateURLServiceFactory::GetForProfile(profile_); | 151 match.GetTemplateURL(template_url_service_, false); |
154 TemplateURL* template_url = match.GetTemplateURL(template_url_service, false); | |
155 // This may be NULL if the template corresponding to the keyword has been | 152 // This may be NULL if the template corresponding to the keyword has been |
156 // deleted or there is no keyword set. | 153 // deleted or there is no keyword set. |
157 if (template_url != NULL) { | 154 if (template_url != NULL) { |
158 history_service->DeleteMatchingURLsForKeyword(template_url->id(), | 155 history_service->DeleteMatchingURLsForKeyword(template_url->id(), |
159 match.contents); | 156 match.contents); |
160 } | 157 } |
161 | 158 |
162 // Immediately update the list of matches to show the match was deleted, | 159 // Immediately update the list of matches to show the match was deleted, |
163 // regardless of whether the server request actually succeeds. | 160 // regardless of whether the server request actually succeeds. |
164 DeleteMatchFromMatches(match); | 161 DeleteMatchFromMatches(match); |
(...skipping 25 matching lines...) Expand all Loading... |
190 const char BaseSearchProvider::kDeletionUrlKey[] = "deletion_url"; | 187 const char BaseSearchProvider::kDeletionUrlKey[] = "deletion_url"; |
191 const char BaseSearchProvider::kTrue[] = "true"; | 188 const char BaseSearchProvider::kTrue[] = "true"; |
192 const char BaseSearchProvider::kFalse[] = "false"; | 189 const char BaseSearchProvider::kFalse[] = "false"; |
193 | 190 |
194 BaseSearchProvider::~BaseSearchProvider() {} | 191 BaseSearchProvider::~BaseSearchProvider() {} |
195 | 192 |
196 void BaseSearchProvider::SetDeletionURL(const std::string& deletion_url, | 193 void BaseSearchProvider::SetDeletionURL(const std::string& deletion_url, |
197 AutocompleteMatch* match) { | 194 AutocompleteMatch* match) { |
198 if (deletion_url.empty()) | 195 if (deletion_url.empty()) |
199 return; | 196 return; |
200 TemplateURLService* template_service = | 197 if (!template_url_service_) |
201 TemplateURLServiceFactory::GetForProfile(profile_); | |
202 if (!template_service) | |
203 return; | 198 return; |
204 GURL url = template_service->GetDefaultSearchProvider()->GenerateSearchURL( | 199 GURL url = |
205 template_service->search_terms_data()); | 200 template_url_service_->GetDefaultSearchProvider()->GenerateSearchURL( |
| 201 template_url_service_->search_terms_data()); |
206 url = url.GetOrigin().Resolve(deletion_url); | 202 url = url.GetOrigin().Resolve(deletion_url); |
207 if (url.is_valid()) { | 203 if (url.is_valid()) { |
208 match->RecordAdditionalInfo(BaseSearchProvider::kDeletionUrlKey, | 204 match->RecordAdditionalInfo(BaseSearchProvider::kDeletionUrlKey, |
209 url.spec()); | 205 url.spec()); |
210 match->deletable = true; | 206 match->deletable = true; |
211 } | 207 } |
212 } | 208 } |
213 | 209 |
214 // static | 210 // static |
215 AutocompleteMatch BaseSearchProvider::CreateSearchSuggestion( | 211 AutocompleteMatch BaseSearchProvider::CreateSearchSuggestion( |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 content::PAGE_TRANSITION_KEYWORD : content::PAGE_TRANSITION_GENERATED; | 284 content::PAGE_TRANSITION_KEYWORD : content::PAGE_TRANSITION_GENERATED; |
289 | 285 |
290 return match; | 286 return match; |
291 } | 287 } |
292 | 288 |
293 // static | 289 // static |
294 bool BaseSearchProvider::ZeroSuggestEnabled( | 290 bool BaseSearchProvider::ZeroSuggestEnabled( |
295 const GURL& suggest_url, | 291 const GURL& suggest_url, |
296 const TemplateURL* template_url, | 292 const TemplateURL* template_url, |
297 OmniboxEventProto::PageClassification page_classification, | 293 OmniboxEventProto::PageClassification page_classification, |
| 294 const SearchTermsData& search_terms_data, |
298 Profile* profile) { | 295 Profile* profile) { |
299 if (!OmniboxFieldTrial::InZeroSuggestFieldTrial()) | 296 if (!OmniboxFieldTrial::InZeroSuggestFieldTrial()) |
300 return false; | 297 return false; |
301 | 298 |
302 // Make sure we are sending the suggest request through HTTPS to prevent | 299 // Make sure we are sending the suggest request through HTTPS to prevent |
303 // exposing the current page URL or personalized results without encryption. | 300 // exposing the current page URL or personalized results without encryption. |
304 if (!suggest_url.SchemeIs(url::kHttpsScheme)) | 301 if (!suggest_url.SchemeIs(url::kHttpsScheme)) |
305 return false; | 302 return false; |
306 | 303 |
307 // Don't show zero suggest on the NTP. | 304 // Don't show zero suggest on the NTP. |
308 // TODO(hfung): Experiment with showing MostVisited zero suggest on NTP | 305 // TODO(hfung): Experiment with showing MostVisited zero suggest on NTP |
309 // under the conditions described in crbug.com/305366. | 306 // under the conditions described in crbug.com/305366. |
310 if ((page_classification == | 307 if ((page_classification == |
311 OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS) || | 308 OmniboxEventProto::INSTANT_NTP_WITH_FAKEBOX_AS_STARTING_FOCUS) || |
312 (page_classification == | 309 (page_classification == |
313 OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS)) | 310 OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS)) |
314 return false; | 311 return false; |
315 | 312 |
316 // Don't run if there's no profile or in incognito mode. | 313 // Don't run if there's no profile or in incognito mode. |
317 if (profile == NULL || profile->IsOffTheRecord()) | 314 if (profile == NULL || profile->IsOffTheRecord()) |
318 return false; | 315 return false; |
319 | 316 |
320 // Don't run if we can't get preferences or search suggest is not enabled. | 317 // Don't run if we can't get preferences or search suggest is not enabled. |
321 PrefService* prefs = profile->GetPrefs(); | 318 PrefService* prefs = profile->GetPrefs(); |
322 if (!prefs->GetBoolean(prefs::kSearchSuggestEnabled)) | 319 if (!prefs->GetBoolean(prefs::kSearchSuggestEnabled)) |
323 return false; | 320 return false; |
324 | 321 |
325 // Only make the request if we know that the provider supports zero suggest | 322 // Only make the request if we know that the provider supports zero suggest |
326 // (currently only the prepopulated Google provider). | 323 // (currently only the prepopulated Google provider). |
327 UIThreadSearchTermsData search_terms_data(profile); | |
328 if (template_url == NULL || | 324 if (template_url == NULL || |
329 !template_url->SupportsReplacement(search_terms_data) || | 325 !template_url->SupportsReplacement(search_terms_data) || |
330 TemplateURLPrepopulateData::GetEngineType( | 326 TemplateURLPrepopulateData::GetEngineType( |
331 *template_url, search_terms_data) != SEARCH_ENGINE_GOOGLE) | 327 *template_url, search_terms_data) != SEARCH_ENGINE_GOOGLE) |
332 return false; | 328 return false; |
333 | 329 |
334 return true; | 330 return true; |
335 } | 331 } |
336 | 332 |
337 // static | 333 // static |
338 bool BaseSearchProvider::CanSendURL( | 334 bool BaseSearchProvider::CanSendURL( |
339 const GURL& current_page_url, | 335 const GURL& current_page_url, |
340 const GURL& suggest_url, | 336 const GURL& suggest_url, |
341 const TemplateURL* template_url, | 337 const TemplateURL* template_url, |
342 OmniboxEventProto::PageClassification page_classification, | 338 OmniboxEventProto::PageClassification page_classification, |
| 339 const SearchTermsData& search_terms_data, |
343 Profile* profile) { | 340 Profile* profile) { |
344 if (!ZeroSuggestEnabled(suggest_url, template_url, page_classification, | 341 if (!ZeroSuggestEnabled(suggest_url, template_url, page_classification, |
345 profile)) | 342 search_terms_data, profile)) |
346 return false; | 343 return false; |
347 | 344 |
348 if (!current_page_url.is_valid()) | 345 if (!current_page_url.is_valid()) |
349 return false; | 346 return false; |
350 | 347 |
351 // Only allow HTTP URLs or HTTPS URLs for the same domain as the search | 348 // Only allow HTTP URLs or HTTPS URLs for the same domain as the search |
352 // provider. | 349 // provider. |
353 if ((current_page_url.scheme() != url::kHttpScheme) && | 350 if ((current_page_url.scheme() != url::kHttpScheme) && |
354 ((current_page_url.scheme() != url::kHttpsScheme) || | 351 ((current_page_url.scheme() != url::kHttpsScheme) || |
355 !net::registry_controlled_domains::SameDomainOrHost( | 352 !net::registry_controlled_domains::SameDomainOrHost( |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 | 402 |
406 void BaseSearchProvider::AddMatchToMap( | 403 void BaseSearchProvider::AddMatchToMap( |
407 const SearchSuggestionParser::SuggestResult& result, | 404 const SearchSuggestionParser::SuggestResult& result, |
408 const std::string& metadata, | 405 const std::string& metadata, |
409 int accepted_suggestion, | 406 int accepted_suggestion, |
410 bool mark_as_deletable, | 407 bool mark_as_deletable, |
411 MatchMap* map) { | 408 MatchMap* map) { |
412 AutocompleteMatch match = CreateSearchSuggestion( | 409 AutocompleteMatch match = CreateSearchSuggestion( |
413 this, GetInput(result.from_keyword_provider()), result, | 410 this, GetInput(result.from_keyword_provider()), result, |
414 GetTemplateURL(result.from_keyword_provider()), | 411 GetTemplateURL(result.from_keyword_provider()), |
415 UIThreadSearchTermsData(profile_), accepted_suggestion, | 412 template_url_service_->search_terms_data(), accepted_suggestion, |
416 ShouldAppendExtraParams(result)); | 413 ShouldAppendExtraParams(result)); |
417 if (!match.destination_url.is_valid()) | 414 if (!match.destination_url.is_valid()) |
418 return; | 415 return; |
419 match.search_terms_args->bookmark_bar_pinned = | 416 match.search_terms_args->bookmark_bar_pinned = |
420 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); | 417 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); |
421 match.RecordAdditionalInfo(kRelevanceFromServerKey, | 418 match.RecordAdditionalInfo(kRelevanceFromServerKey, |
422 result.relevance_from_server() ? kTrue : kFalse); | 419 result.relevance_from_server() ? kTrue : kFalse); |
423 match.RecordAdditionalInfo(kShouldPrefetchKey, | 420 match.RecordAdditionalInfo(kShouldPrefetchKey, |
424 result.should_prefetch() ? kTrue : kFalse); | 421 result.should_prefetch() ? kTrue : kFalse); |
425 SetDeletionURL(result.deletion_url(), &match); | 422 SetDeletionURL(result.deletion_url(), &match); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 } | 533 } |
537 | 534 |
538 void BaseSearchProvider::OnDeletionComplete( | 535 void BaseSearchProvider::OnDeletionComplete( |
539 bool success, SuggestionDeletionHandler* handler) { | 536 bool success, SuggestionDeletionHandler* handler) { |
540 RecordDeletionResult(success); | 537 RecordDeletionResult(success); |
541 SuggestionDeletionHandlers::iterator it = std::find( | 538 SuggestionDeletionHandlers::iterator it = std::find( |
542 deletion_handlers_.begin(), deletion_handlers_.end(), handler); | 539 deletion_handlers_.begin(), deletion_handlers_.end(), handler); |
543 DCHECK(it != deletion_handlers_.end()); | 540 DCHECK(it != deletion_handlers_.end()); |
544 deletion_handlers_.erase(it); | 541 deletion_handlers_.erase(it); |
545 } | 542 } |
OLD | NEW |