OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/search_provider.h" | 5 #include "chrome/browser/autocomplete/search_provider.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 void SearchProvider::UpdateMatches() { | 394 void SearchProvider::UpdateMatches() { |
395 ConvertResultsToAutocompleteMatches(); | 395 ConvertResultsToAutocompleteMatches(); |
396 | 396 |
397 // Check constraints that may be violated by suggested relevances. | 397 // Check constraints that may be violated by suggested relevances. |
398 if (!matches_.empty() && | 398 if (!matches_.empty() && |
399 (default_results_.HasServerProvidedScores() || | 399 (default_results_.HasServerProvidedScores() || |
400 keyword_results_.HasServerProvidedScores())) { | 400 keyword_results_.HasServerProvidedScores())) { |
401 // These blocks attempt to repair undesirable behavior by suggested | 401 // These blocks attempt to repair undesirable behavior by suggested |
402 // relevances with minimal impact, preserving other suggested relevances. | 402 // relevances with minimal impact, preserving other suggested relevances. |
403 | 403 |
404 if (!HasKeywordDefaultMatchInKeywordMode()) { | 404 if ((providers_.GetKeywordProviderURL() != NULL) && |
| 405 (FindTopMatch() == matches_.end())) { |
405 // In keyword mode, disregard the keyword verbatim suggested relevance | 406 // In keyword mode, disregard the keyword verbatim suggested relevance |
406 // if necessary so there at least one keyword match that's allowed to | 407 // if necessary, so at least one match is allowed to be default. |
407 // be the default match. | |
408 keyword_results_.verbatim_relevance = -1; | 408 keyword_results_.verbatim_relevance = -1; |
409 ConvertResultsToAutocompleteMatches(); | 409 ConvertResultsToAutocompleteMatches(); |
410 } | 410 } |
411 if (IsTopMatchSearchWithURLInput()) { | 411 if (IsTopMatchSearchWithURLInput()) { |
412 // Disregard the suggested search and verbatim relevances if the input | 412 // Disregard the suggested search and verbatim relevances if the input |
413 // type is URL and the top match is a highly-ranked search suggestion. | 413 // type is URL and the top match is a highly-ranked search suggestion. |
414 // For example, prevent a search for "foo.com" from outranking another | 414 // For example, prevent a search for "foo.com" from outranking another |
415 // provider's navigation for "foo.com" or "foo.com/url_from_history". | 415 // provider's navigation for "foo.com" or "foo.com/url_from_history". |
416 ApplyCalculatedSuggestRelevance(&keyword_results_.suggest_results); | 416 ApplyCalculatedSuggestRelevance(&keyword_results_.suggest_results); |
417 ApplyCalculatedSuggestRelevance(&default_results_.suggest_results); | 417 ApplyCalculatedSuggestRelevance(&default_results_.suggest_results); |
418 default_results_.verbatim_relevance = -1; | 418 default_results_.verbatim_relevance = -1; |
419 keyword_results_.verbatim_relevance = -1; | 419 keyword_results_.verbatim_relevance = -1; |
420 ConvertResultsToAutocompleteMatches(); | 420 ConvertResultsToAutocompleteMatches(); |
421 } | 421 } |
422 if (FindTopMatch() == matches_.end()) { | 422 if (FindTopMatch() == matches_.end()) { |
423 // Guarantee that SearchProvider returns a legal default match. (The | 423 // Guarantee that SearchProvider returns a legal default match. (The |
424 // omnibox always needs at least one legal default match, and it relies | 424 // omnibox always needs at least one legal default match, and it relies |
425 // on SearchProvider to always return one.) | 425 // on SearchProvider to always return one.) |
426 ApplyCalculatedRelevance(); | 426 ApplyCalculatedRelevance(); |
427 ConvertResultsToAutocompleteMatches(); | 427 ConvertResultsToAutocompleteMatches(); |
428 } | 428 } |
429 DCHECK(HasKeywordDefaultMatchInKeywordMode()); | |
430 DCHECK(!IsTopMatchSearchWithURLInput()); | 429 DCHECK(!IsTopMatchSearchWithURLInput()); |
431 DCHECK(FindTopMatch() != matches_.end()); | 430 DCHECK(FindTopMatch() != matches_.end()); |
432 } | 431 } |
433 UMA_HISTOGRAM_CUSTOM_COUNTS( | 432 UMA_HISTOGRAM_CUSTOM_COUNTS( |
434 "Omnibox.SearchProviderMatches", matches_.size(), 1, 6, 7); | 433 "Omnibox.SearchProviderMatches", matches_.size(), 1, 6, 7); |
435 | |
436 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | |
437 if ((keyword_url != NULL) && HasKeywordDefaultMatchInKeywordMode()) { | |
438 // If there is a keyword match that is allowed to be the default match, | |
439 // then prohibit default provider matches from being the default match lest | |
440 // such matches cause the user to break out of keyword mode. | |
441 for (ACMatches::iterator it = matches_.begin(); it != matches_.end(); | |
442 ++it) { | |
443 if (it->keyword != keyword_url->keyword()) | |
444 it->allowed_to_be_default_match = false; | |
445 } | |
446 } | |
447 UpdateDone(); | 434 UpdateDone(); |
448 } | 435 } |
449 | 436 |
450 void SearchProvider::Run() { | 437 void SearchProvider::Run() { |
451 // Start a new request with the current input. | 438 // Start a new request with the current input. |
452 suggest_results_pending_ = 0; | 439 suggest_results_pending_ = 0; |
453 time_suggest_request_sent_ = base::TimeTicks::Now(); | 440 time_suggest_request_sent_ = base::TimeTicks::Now(); |
454 | 441 |
455 default_fetcher_.reset(CreateSuggestFetcher(kDefaultProviderURLFetcherID, | 442 default_fetcher_.reset(CreateSuggestFetcher(kDefaultProviderURLFetcherID, |
456 providers_.GetDefaultProviderURL(), input_)); | 443 providers_.GetDefaultProviderURL(), input_)); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 keyword_results_.suggest_results.empty() ? | 710 keyword_results_.suggest_results.empty() ? |
724 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : | 711 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : |
725 TemplateURLRef::NO_SUGGESTION_CHOSEN; | 712 TemplateURLRef::NO_SUGGESTION_CHOSEN; |
726 | 713 |
727 bool relevance_from_server; | 714 bool relevance_from_server; |
728 int verbatim_relevance = GetVerbatimRelevance(&relevance_from_server); | 715 int verbatim_relevance = GetVerbatimRelevance(&relevance_from_server); |
729 int did_not_accept_default_suggestion = | 716 int did_not_accept_default_suggestion = |
730 default_results_.suggest_results.empty() ? | 717 default_results_.suggest_results.empty() ? |
731 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : | 718 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE : |
732 TemplateURLRef::NO_SUGGESTION_CHOSEN; | 719 TemplateURLRef::NO_SUGGESTION_CHOSEN; |
| 720 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); |
733 if (verbatim_relevance > 0) { | 721 if (verbatim_relevance > 0) { |
734 const base::string16& trimmed_verbatim = | 722 const base::string16& trimmed_verbatim = |
735 base::CollapseWhitespace(input_.text(), false); | 723 base::CollapseWhitespace(input_.text(), false); |
736 SearchSuggestionParser::SuggestResult verbatim( | 724 SearchSuggestionParser::SuggestResult verbatim( |
737 trimmed_verbatim, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, | 725 trimmed_verbatim, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, |
738 trimmed_verbatim, base::string16(), base::string16(), base::string16(), | 726 trimmed_verbatim, base::string16(), base::string16(), base::string16(), |
739 base::string16(), std::string(), std::string(), false, | 727 base::string16(), std::string(), std::string(), false, |
740 verbatim_relevance, relevance_from_server, false, | 728 verbatim_relevance, relevance_from_server, false, |
741 trimmed_verbatim); | 729 trimmed_verbatim); |
742 AddMatchToMap(verbatim, std::string(), did_not_accept_default_suggestion, | 730 AddMatchToMap(verbatim, std::string(), did_not_accept_default_suggestion, |
743 false, &map); | 731 false, keyword_url != NULL, &map); |
744 } | 732 } |
745 if (!keyword_input_.text().empty()) { | 733 if (!keyword_input_.text().empty()) { |
746 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | |
747 // We only create the verbatim search query match for a keyword | 734 // We only create the verbatim search query match for a keyword |
748 // if it's not an extension keyword. Extension keywords are handled | 735 // if it's not an extension keyword. Extension keywords are handled |
749 // in KeywordProvider::Start(). (Extensions are complicated...) | 736 // in KeywordProvider::Start(). (Extensions are complicated...) |
750 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond | 737 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond |
751 // to the keyword verbatim search query. Do not create other matches | 738 // to the keyword verbatim search query. Do not create other matches |
752 // of type SEARCH_OTHER_ENGINE. | 739 // of type SEARCH_OTHER_ENGINE. |
753 if (keyword_url && | 740 if (keyword_url && |
754 (keyword_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION)) { | 741 (keyword_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION)) { |
755 bool keyword_relevance_from_server; | 742 bool keyword_relevance_from_server; |
756 const int keyword_verbatim_relevance = | 743 const int keyword_verbatim_relevance = |
757 GetKeywordVerbatimRelevance(&keyword_relevance_from_server); | 744 GetKeywordVerbatimRelevance(&keyword_relevance_from_server); |
758 if (keyword_verbatim_relevance > 0) { | 745 if (keyword_verbatim_relevance > 0) { |
759 const base::string16& trimmed_verbatim = | 746 const base::string16& trimmed_verbatim = |
760 base::CollapseWhitespace(keyword_input_.text(), false); | 747 base::CollapseWhitespace(keyword_input_.text(), false); |
761 SearchSuggestionParser::SuggestResult verbatim( | 748 SearchSuggestionParser::SuggestResult verbatim( |
762 trimmed_verbatim, AutocompleteMatchType::SEARCH_OTHER_ENGINE, | 749 trimmed_verbatim, AutocompleteMatchType::SEARCH_OTHER_ENGINE, |
763 trimmed_verbatim, base::string16(), base::string16(), | 750 trimmed_verbatim, base::string16(), base::string16(), |
764 base::string16(), base::string16(), std::string(), std::string(), | 751 base::string16(), base::string16(), std::string(), std::string(), |
765 true, keyword_verbatim_relevance, keyword_relevance_from_server, | 752 true, keyword_verbatim_relevance, keyword_relevance_from_server, |
766 false, trimmed_verbatim); | 753 false, trimmed_verbatim); |
767 AddMatchToMap(verbatim, std::string(), | 754 AddMatchToMap(verbatim, std::string(), |
768 did_not_accept_keyword_suggestion, false, &map); | 755 did_not_accept_keyword_suggestion, false, true, &map); |
769 } | 756 } |
770 } | 757 } |
771 } | 758 } |
772 AddHistoryResultsToMap(keyword_history_results_, true, | 759 AddHistoryResultsToMap(keyword_history_results_, true, |
773 did_not_accept_keyword_suggestion, &map); | 760 did_not_accept_keyword_suggestion, &map); |
774 AddHistoryResultsToMap(default_history_results_, false, | 761 AddHistoryResultsToMap(default_history_results_, false, |
775 did_not_accept_default_suggestion, &map); | 762 did_not_accept_default_suggestion, &map); |
776 | 763 |
777 AddSuggestResultsToMap(keyword_results_.suggest_results, | 764 AddSuggestResultsToMap(keyword_results_.suggest_results, |
778 keyword_results_.metadata, &map); | 765 keyword_results_.metadata, &map); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 base::TimeTicks::Now() - start_time); | 813 base::TimeTicks::Now() - start_time); |
827 } | 814 } |
828 | 815 |
829 ACMatches::const_iterator SearchProvider::FindTopMatch() const { | 816 ACMatches::const_iterator SearchProvider::FindTopMatch() const { |
830 ACMatches::const_iterator it = matches_.begin(); | 817 ACMatches::const_iterator it = matches_.begin(); |
831 while ((it != matches_.end()) && !it->allowed_to_be_default_match) | 818 while ((it != matches_.end()) && !it->allowed_to_be_default_match) |
832 ++it; | 819 ++it; |
833 return it; | 820 return it; |
834 } | 821 } |
835 | 822 |
836 bool SearchProvider::HasKeywordDefaultMatchInKeywordMode() const { | |
837 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | |
838 // If the user is not in keyword mode, return true to say that this | |
839 // constraint is not violated. | |
840 if (keyword_url == NULL) | |
841 return true; | |
842 for (ACMatches::const_iterator it = matches_.begin(); it != matches_.end(); | |
843 ++it) { | |
844 if ((it->keyword == keyword_url->keyword()) && | |
845 it->allowed_to_be_default_match) | |
846 return true; | |
847 } | |
848 return false; | |
849 } | |
850 | |
851 bool SearchProvider::IsTopMatchSearchWithURLInput() const { | 823 bool SearchProvider::IsTopMatchSearchWithURLInput() const { |
852 ACMatches::const_iterator first_match = FindTopMatch(); | 824 ACMatches::const_iterator first_match = FindTopMatch(); |
853 return (input_.type() == metrics::OmniboxInputType::URL) && | 825 return (input_.type() == metrics::OmniboxInputType::URL) && |
854 (first_match != matches_.end()) && | 826 (first_match != matches_.end()) && |
855 (first_match->relevance > CalculateRelevanceForVerbatim()) && | 827 (first_match->relevance > CalculateRelevanceForVerbatim()) && |
856 (first_match->type != AutocompleteMatchType::NAVSUGGEST) && | 828 (first_match->type != AutocompleteMatchType::NAVSUGGEST) && |
857 (first_match->type != AutocompleteMatchType::NAVSUGGEST_PERSONALIZED); | 829 (first_match->type != AutocompleteMatchType::NAVSUGGEST_PERSONALIZED); |
858 } | 830 } |
859 | 831 |
860 void SearchProvider::AddNavigationResultsToMatches( | 832 void SearchProvider::AddNavigationResultsToMatches( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 if ((scored_results.front().relevance() < 1200) || | 872 if ((scored_results.front().relevance() < 1200) || |
901 !HasMultipleWords(scored_results.front().suggestion())) | 873 !HasMultipleWords(scored_results.front().suggestion())) |
902 scored_results.clear(); // Didn't detect the case above, score normally. | 874 scored_results.clear(); // Didn't detect the case above, score normally. |
903 } | 875 } |
904 if (scored_results.empty()) | 876 if (scored_results.empty()) |
905 scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, | 877 scored_results = ScoreHistoryResults(results, prevent_inline_autocomplete, |
906 input_multiple_words, input_text, | 878 input_multiple_words, input_text, |
907 is_keyword); | 879 is_keyword); |
908 for (SearchSuggestionParser::SuggestResults::const_iterator i( | 880 for (SearchSuggestionParser::SuggestResults::const_iterator i( |
909 scored_results.begin()); i != scored_results.end(); ++i) { | 881 scored_results.begin()); i != scored_results.end(); ++i) { |
910 AddMatchToMap(*i, std::string(), did_not_accept_suggestion, true, map); | 882 AddMatchToMap(*i, std::string(), did_not_accept_suggestion, true, |
| 883 providers_.GetKeywordProviderURL() != NULL, map); |
911 } | 884 } |
912 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", | 885 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", |
913 base::TimeTicks::Now() - start_time); | 886 base::TimeTicks::Now() - start_time); |
914 } | 887 } |
915 | 888 |
916 SearchSuggestionParser::SuggestResults SearchProvider::ScoreHistoryResults( | 889 SearchSuggestionParser::SuggestResults SearchProvider::ScoreHistoryResults( |
917 const HistoryResults& results, | 890 const HistoryResults& results, |
918 bool base_prevent_inline_autocomplete, | 891 bool base_prevent_inline_autocomplete, |
919 bool input_multiple_words, | 892 bool input_multiple_words, |
920 const base::string16& input_text, | 893 const base::string16& input_text, |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 last_relevance = i->relevance(); | 995 last_relevance = i->relevance(); |
1023 } | 996 } |
1024 | 997 |
1025 return scored_results; | 998 return scored_results; |
1026 } | 999 } |
1027 | 1000 |
1028 void SearchProvider::AddSuggestResultsToMap( | 1001 void SearchProvider::AddSuggestResultsToMap( |
1029 const SearchSuggestionParser::SuggestResults& results, | 1002 const SearchSuggestionParser::SuggestResults& results, |
1030 const std::string& metadata, | 1003 const std::string& metadata, |
1031 MatchMap* map) { | 1004 MatchMap* map) { |
1032 for (size_t i = 0; i < results.size(); ++i) | 1005 for (size_t i = 0; i < results.size(); ++i) { |
1033 AddMatchToMap(results[i], metadata, i, false, map); | 1006 AddMatchToMap(results[i], metadata, i, false, |
| 1007 providers_.GetKeywordProviderURL() != NULL, map); |
| 1008 } |
1034 } | 1009 } |
1035 | 1010 |
1036 int SearchProvider::GetVerbatimRelevance(bool* relevance_from_server) const { | 1011 int SearchProvider::GetVerbatimRelevance(bool* relevance_from_server) const { |
1037 // Use the suggested verbatim relevance score if it is non-negative (valid), | 1012 // Use the suggested verbatim relevance score if it is non-negative (valid), |
1038 // if inline autocomplete isn't prevented (always show verbatim on backspace), | 1013 // if inline autocomplete isn't prevented (always show verbatim on backspace), |
1039 // and if it won't suppress verbatim, leaving no default provider matches. | 1014 // and if it won't suppress verbatim, leaving no default provider matches. |
1040 // Otherwise, if the default provider returned no matches and was still able | 1015 // Otherwise, if the default provider returned no matches and was still able |
1041 // to suppress verbatim, the user would have no search/nav matches and may be | 1016 // to suppress verbatim, the user would have no search/nav matches and may be |
1042 // left unable to search using their default provider from the omnibox. | 1017 // left unable to search using their default provider from the omnibox. |
1043 // Check for results on each verbatim calculation, as results from older | 1018 // Check for results on each verbatim calculation, as results from older |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 last_answer_seen_.query_type = match->answer_type; | 1237 last_answer_seen_.query_type = match->answer_type; |
1263 } | 1238 } |
1264 | 1239 |
1265 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { | 1240 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { |
1266 // If the query text starts with trimmed input, this is valid prefetch data. | 1241 // If the query text starts with trimmed input, this is valid prefetch data. |
1267 prefetch_data_ = StartsWith(last_answer_seen_.full_query_text, | 1242 prefetch_data_ = StartsWith(last_answer_seen_.full_query_text, |
1268 base::CollapseWhitespace(input.text(), false), | 1243 base::CollapseWhitespace(input.text(), false), |
1269 false) ? | 1244 false) ? |
1270 last_answer_seen_ : AnswersQueryData(); | 1245 last_answer_seen_ : AnswersQueryData(); |
1271 } | 1246 } |
OLD | NEW |