| 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 |