Chromium Code Reviews| 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/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
| 8 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 9 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 11 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h" | 12 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h" |
| 12 #include "chrome/browser/autocomplete/url_prefix.h" | 13 #include "chrome/browser/autocomplete/url_prefix.h" |
| 13 #include "chrome/browser/omnibox/omnibox_field_trial.h" | 14 #include "chrome/browser/omnibox/omnibox_field_trial.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 16 #include "chrome/browser/search/instant_service.h" | |
| 17 #include "chrome/browser/search/instant_service_factory.h" | |
| 18 #include "chrome/browser/search/search.h" | |
| 15 #include "chrome/browser/search_engines/template_url.h" | 19 #include "chrome/browser/search_engines/template_url.h" |
| 16 #include "chrome/browser/search_engines/template_url_prepopulate_data.h" | 20 #include "chrome/browser/search_engines/template_url_prepopulate_data.h" |
| 17 #include "chrome/browser/sync/profile_sync_service.h" | 21 #include "chrome/browser/sync/profile_sync_service.h" |
| 18 #include "chrome/browser/sync/profile_sync_service_factory.h" | 22 #include "chrome/browser/sync/profile_sync_service_factory.h" |
| 19 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
| 20 #include "content/public/common/url_constants.h" | 24 #include "content/public/common/url_constants.h" |
| 21 #include "net/base/escape.h" | 25 #include "net/base/escape.h" |
| 22 #include "net/base/net_util.h" | 26 #include "net/base/net_util.h" |
| 23 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 27 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 24 #include "net/url_request/url_fetcher_delegate.h" | 28 #include "net/url_request/url_fetcher_delegate.h" |
| 25 #include "url/gurl.h" | 29 #include "url/gurl.h" |
| 26 | 30 |
| 27 // BaseSearchProvider --------------------------------------------------------- | 31 // BaseSearchProvider --------------------------------------------------------- |
| 28 | 32 |
| 29 BaseSearchProvider::BaseSearchProvider(AutocompleteProviderListener* listener, | 33 BaseSearchProvider::BaseSearchProvider(AutocompleteProviderListener* listener, |
| 30 Profile* profile, | 34 Profile* profile, |
| 31 AutocompleteProvider::Type type) | 35 AutocompleteProvider::Type type) |
| 32 : AutocompleteProvider(listener, profile, type), | 36 : AutocompleteProvider(listener, profile, type), |
| 33 field_trial_triggered_(false), | 37 field_trial_triggered_(false), |
| 34 field_trial_triggered_in_session_(false) {} | 38 field_trial_triggered_in_session_(false) {} |
| 35 | 39 |
| 40 // static | |
| 41 bool BaseSearchProvider::ShouldPrefetch(const AutocompleteMatch& match) { | |
| 42 return match.GetAdditionalInfo(kShouldPrefetchKey) == kTrue; | |
| 43 } | |
| 44 | |
| 36 void BaseSearchProvider::AddProviderInfo(ProvidersInfo* provider_info) const { | 45 void BaseSearchProvider::AddProviderInfo(ProvidersInfo* provider_info) const { |
| 37 provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo()); | 46 provider_info->push_back(metrics::OmniboxEventProto_ProviderInfo()); |
| 38 metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back(); | 47 metrics::OmniboxEventProto_ProviderInfo& new_entry = provider_info->back(); |
| 39 new_entry.set_provider(AsOmniboxEventProviderType()); | 48 new_entry.set_provider(AsOmniboxEventProviderType()); |
| 40 new_entry.set_provider_done(done_); | 49 new_entry.set_provider_done(done_); |
| 41 std::vector<uint32> field_trial_hashes; | 50 std::vector<uint32> field_trial_hashes; |
| 42 OmniboxFieldTrial::GetActiveSuggestFieldTrialHashes(&field_trial_hashes); | 51 OmniboxFieldTrial::GetActiveSuggestFieldTrialHashes(&field_trial_hashes); |
| 43 for (size_t i = 0; i < field_trial_hashes.size(); ++i) { | 52 for (size_t i = 0; i < field_trial_hashes.size(); ++i) { |
| 44 if (field_trial_triggered_) | 53 if (field_trial_triggered_) |
| 45 new_entry.mutable_field_trial_triggered()->Add(field_trial_hashes[i]); | 54 new_entry.mutable_field_trial_triggered()->Add(field_trial_hashes[i]); |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 i != navigation_results.end(); ++i) { | 256 i != navigation_results.end(); ++i) { |
| 248 if (i->relevance_from_server()) | 257 if (i->relevance_from_server()) |
| 249 return true; | 258 return true; |
| 250 } | 259 } |
| 251 | 260 |
| 252 return false; | 261 return false; |
| 253 } | 262 } |
| 254 | 263 |
| 255 // BaseSearchProvider --------------------------------------------------------- | 264 // BaseSearchProvider --------------------------------------------------------- |
| 256 | 265 |
| 266 const char BaseSearchProvider::kRelevanceFromServerKey[] = | |
|
Mark P
2014/02/10 23:25:55
nit: comment // static
Maria
2014/02/11 21:42:32
Done.
| |
| 267 "relevance_from_server"; | |
| 268 const char BaseSearchProvider::kShouldPrefetchKey[] = "should_prefetch"; | |
| 269 const char BaseSearchProvider::kSuggestMetadataKey[] = "suggest_metadata"; | |
| 270 const char BaseSearchProvider::kDeletionUrlKey[] = "deletion_url"; | |
| 271 const char BaseSearchProvider::kTrue[] = "true"; | |
| 272 const char BaseSearchProvider::kFalse[] = "false"; | |
| 273 | |
| 257 // static | 274 // static |
| 258 AutocompleteMatch BaseSearchProvider::CreateSearchSuggestion( | 275 AutocompleteMatch BaseSearchProvider::CreateSearchSuggestion( |
| 259 AutocompleteProvider* autocomplete_provider, | 276 AutocompleteProvider* autocomplete_provider, |
| 260 const AutocompleteInput& input, | 277 const AutocompleteInput& input, |
| 261 const base::string16& input_text, | 278 const base::string16& input_text, |
| 262 const SuggestResult& suggestion, | 279 const SuggestResult& suggestion, |
| 263 const TemplateURL* template_url, | 280 const TemplateURL* template_url, |
| 264 int accepted_suggestion, | 281 int accepted_suggestion, |
| 265 int omnibox_start_margin, | 282 int omnibox_start_margin, |
| 266 bool append_extra_query_params) { | 283 bool append_extra_query_params) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 service == NULL || | 413 service == NULL || |
| 397 !service->IsSyncEnabledAndLoggedIn() || | 414 !service->IsSyncEnabledAndLoggedIn() || |
| 398 !sync_prefs.GetPreferredDataTypes(syncer::UserTypes()).Has( | 415 !sync_prefs.GetPreferredDataTypes(syncer::UserTypes()).Has( |
| 399 syncer::PROXY_TABS) || | 416 syncer::PROXY_TABS) || |
| 400 service->GetEncryptedDataTypes().Has(syncer::SESSIONS)) | 417 service->GetEncryptedDataTypes().Has(syncer::SESSIONS)) |
| 401 return false; | 418 return false; |
| 402 | 419 |
| 403 return true; | 420 return true; |
| 404 } | 421 } |
| 405 | 422 |
| 423 void BaseSearchProvider::AddMatchToMap(const SuggestResult& result, | |
| 424 const AutocompleteInput input, | |
| 425 const base::string16& query_string, | |
| 426 const TemplateURL* template_url, | |
| 427 const std::string& metadata, | |
| 428 int accepted_suggestion, | |
| 429 bool append_extra_query_params, | |
| 430 MatchMap* map) { | |
| 431 InstantService* instant_service = | |
| 432 InstantServiceFactory::GetForProfile(profile_); | |
| 433 // Android and iOS have on InstantService | |
| 434 const int omnibox_start_margin = instant_service ? | |
| 435 instant_service->omnibox_start_margin() : chrome::kDisableStartMargin; | |
| 436 | |
| 437 AutocompleteMatch match = CreateSearchSuggestion(this, input, query_string, | |
|
Mark P
2014/02/10 23:25:55
nit: formatting. (I think it's either always-alig
Mark P
2014/02/10 23:25:55
You've switched this from |input_| to |input_| or
Maria
2014/02/11 01:22:09
Thanks for catching this. The switch to matching i
Maria
2014/02/11 21:42:32
Done.
| |
| 438 result, template_url, accepted_suggestion, omnibox_start_margin, | |
| 439 append_extra_query_params); | |
| 440 if (!match.destination_url.is_valid()) | |
| 441 return; | |
| 442 match.search_terms_args->bookmark_bar_pinned = | |
| 443 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); | |
| 444 match.RecordAdditionalInfo(kRelevanceFromServerKey, | |
| 445 result.relevance_from_server() ? kTrue : kFalse); | |
| 446 match.RecordAdditionalInfo(kShouldPrefetchKey, | |
| 447 result.should_prefetch() ? kTrue : kFalse); | |
| 448 | |
| 449 if (!result.deletion_url().empty()) { | |
| 450 GURL url(match.destination_url.GetOrigin().Resolve(result.deletion_url())); | |
| 451 if (url.is_valid()) { | |
| 452 match.RecordAdditionalInfo(kDeletionUrlKey, url.spec()); | |
| 453 match.deletable = true; | |
| 454 } | |
| 455 } | |
| 456 | |
| 457 // Metadata is needed only for prefetching queries. | |
| 458 if (result.should_prefetch()) | |
| 459 match.RecordAdditionalInfo(kSuggestMetadataKey, metadata); | |
| 460 | |
| 461 // Try to add |match| to |map|. If a match for |query_string| is already in | |
| 462 // |map|, replace it if |match| is more relevant. | |
| 463 // NOTE: Keep this ToLower() call in sync with url_database.cc. | |
| 464 MatchKey match_key( | |
| 465 std::make_pair(base::i18n::ToLower(result.suggestion()), | |
| 466 match.search_terms_args->suggest_query_params)); | |
| 467 const std::pair<MatchMap::iterator, bool> i( | |
| 468 map->insert(std::make_pair(match_key, match))); | |
| 469 | |
| 470 bool should_prefetch = result.should_prefetch(); | |
| 471 if (!i.second) { | |
| 472 // NOTE: We purposefully do a direct relevance comparison here instead of | |
| 473 // using AutocompleteMatch::MoreRelevant(), so that we'll prefer "items | |
| 474 // added first" rather than "items alphabetically first" when the scores | |
| 475 // are equal. The only case this matters is when a user has results with | |
| 476 // the same score that differ only by capitalization; because the history | |
| 477 // system returns results sorted by recency, this means we'll pick the most | |
| 478 // recent such result even if the precision of our relevance score is too | |
| 479 // low to distinguish the two. | |
| 480 if (match.relevance > i.first->second.relevance) { | |
| 481 i.first->second = match; | |
| 482 } else if (match.keyword == i.first->second.keyword) { | |
| 483 // Old and new matches are from the same search provider. It is okay to | |
| 484 // record one match's prefetch data onto a different match (for the same | |
| 485 // query string) for the following reasons: | |
| 486 // 1. Because the suggest server only sends down a query string from | |
| 487 // which we construct a URL, rather than sending a full URL, and because | |
| 488 // we construct URLs from query strings in the same way every time, the | |
| 489 // URLs for the two matches will be the same. Therefore, we won't end up | |
| 490 // prefetching something the server didn't intend. | |
| 491 // 2. Presumably the server sets the prefetch bit on a match it things is | |
| 492 // sufficiently relevant that the user is likely to choose it. Surely | |
| 493 // setting the prefetch bit on a match of even higher relevance won't | |
| 494 // violate this assumption. | |
| 495 should_prefetch |= ShouldPrefetch(i.first->second); | |
| 496 i.first->second.RecordAdditionalInfo(kShouldPrefetchKey, | |
| 497 should_prefetch ? kTrue : kFalse); | |
| 498 if (should_prefetch) | |
| 499 i.first->second.RecordAdditionalInfo(kSuggestMetadataKey, metadata); | |
| 500 } | |
| 501 } | |
| 502 } | |
| OLD | NEW |