| 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 "components/omnibox/search_provider.h" | 5 #include "components/omnibox/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" |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/i18n/break_iterator.h" | 12 #include "base/i18n/break_iterator.h" |
| 13 #include "base/i18n/case_conversion.h" | 13 #include "base/i18n/case_conversion.h" |
| 14 #include "base/json/json_string_value_serializer.h" | 14 #include "base/json/json_string_value_serializer.h" |
| 15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
| 16 #include "base/metrics/user_metrics.h" | 16 #include "base/metrics/user_metrics.h" |
| 17 #include "base/rand_util.h" | 17 #include "base/rand_util.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "components/history/core/browser/in_memory_database.h" | 20 #include "components/history/core/browser/in_memory_database.h" |
| 21 #include "components/history/core/browser/keyword_search_term.h" | 21 #include "components/history/core/browser/keyword_search_term.h" |
| 22 #include "components/metrics/proto/omnibox_input_type.pb.h" | 22 #include "components/metrics/proto/omnibox_input_type.pb.h" |
| 23 #include "components/omnibox/autocomplete_provider_client.h" | 23 #include "components/omnibox/autocomplete_provider_client.h" |
| 24 #include "components/omnibox/autocomplete_provider_listener.h" | 24 #include "components/omnibox/autocomplete_provider_listener.h" |
| 25 #include "components/omnibox/autocomplete_result.h" | 25 #include "components/omnibox/autocomplete_result.h" |
| 26 #include "components/omnibox/keyword_provider.h" | 26 #include "components/omnibox/keyword_provider.h" |
| 27 #include "components/omnibox/omnibox_field_trial.h" | 27 #include "components/omnibox/omnibox_field_trial.h" |
| 28 #include "components/omnibox/suggestion_answer.h" |
| 28 #include "components/omnibox/url_prefix.h" | 29 #include "components/omnibox/url_prefix.h" |
| 29 #include "components/search/search.h" | 30 #include "components/search/search.h" |
| 30 #include "components/search_engines/template_url_prepopulate_data.h" | 31 #include "components/search_engines/template_url_prepopulate_data.h" |
| 31 #include "components/search_engines/template_url_service.h" | 32 #include "components/search_engines/template_url_service.h" |
| 32 #include "components/variations/net/variations_http_header_provider.h" | 33 #include "components/variations/net/variations_http_header_provider.h" |
| 33 #include "grit/components_strings.h" | 34 #include "grit/components_strings.h" |
| 34 #include "net/base/escape.h" | 35 #include "net/base/escape.h" |
| 35 #include "net/base/load_flags.h" | 36 #include "net/base/load_flags.h" |
| 36 #include "net/base/net_util.h" | 37 #include "net/base/net_util.h" |
| 37 #include "net/http/http_request_headers.h" | 38 #include "net/http/http_request_headers.h" |
| (...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | 832 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); |
| 832 if (verbatim_relevance > 0) { | 833 if (verbatim_relevance > 0) { |
| 833 const base::string16& trimmed_verbatim = | 834 const base::string16& trimmed_verbatim = |
| 834 base::CollapseWhitespace(input_.text(), false); | 835 base::CollapseWhitespace(input_.text(), false); |
| 835 | 836 |
| 836 // Verbatim results don't get suggestions and hence, answers. | 837 // Verbatim results don't get suggestions and hence, answers. |
| 837 // Scan previous matches if the last answer-bearing suggestion matches | 838 // Scan previous matches if the last answer-bearing suggestion matches |
| 838 // verbatim, and if so, copy over answer contents. | 839 // verbatim, and if so, copy over answer contents. |
| 839 base::string16 answer_contents; | 840 base::string16 answer_contents; |
| 840 base::string16 answer_type; | 841 base::string16 answer_type; |
| 842 scoped_ptr<SuggestionAnswer> answer; |
| 841 for (ACMatches::iterator it = matches_.begin(); it != matches_.end(); | 843 for (ACMatches::iterator it = matches_.begin(); it != matches_.end(); |
| 842 ++it) { | 844 ++it) { |
| 843 if (!it->answer_contents.empty() && | 845 if (it->answer && it->fill_into_edit == trimmed_verbatim) { |
| 844 it->fill_into_edit == trimmed_verbatim) { | |
| 845 answer_contents = it->answer_contents; | 846 answer_contents = it->answer_contents; |
| 846 answer_type = it->answer_type; | 847 answer_type = it->answer_type; |
| 848 answer = SuggestionAnswer::copy(it->answer.get()); |
| 847 break; | 849 break; |
| 848 } | 850 } |
| 849 } | 851 } |
| 850 | 852 |
| 851 SearchSuggestionParser::SuggestResult verbatim( | 853 SearchSuggestionParser::SuggestResult verbatim( |
| 852 trimmed_verbatim, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, | 854 trimmed_verbatim, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, |
| 853 trimmed_verbatim, base::string16(), base::string16(), answer_contents, | 855 trimmed_verbatim, base::string16(), base::string16(), answer_contents, |
| 854 answer_type, std::string(), std::string(), false, verbatim_relevance, | 856 answer_type, answer.Pass(), std::string(), std::string(), false, |
| 855 relevance_from_server, false, trimmed_verbatim); | 857 verbatim_relevance, relevance_from_server, false, trimmed_verbatim); |
| 856 AddMatchToMap(verbatim, std::string(), did_not_accept_default_suggestion, | 858 AddMatchToMap(verbatim, std::string(), did_not_accept_default_suggestion, |
| 857 false, keyword_url != NULL, &map); | 859 false, keyword_url != NULL, &map); |
| 858 } | 860 } |
| 859 if (!keyword_input_.text().empty()) { | 861 if (!keyword_input_.text().empty()) { |
| 860 // We only create the verbatim search query match for a keyword | 862 // We only create the verbatim search query match for a keyword |
| 861 // if it's not an extension keyword. Extension keywords are handled | 863 // if it's not an extension keyword. Extension keywords are handled |
| 862 // in KeywordProvider::Start(). (Extensions are complicated...) | 864 // in KeywordProvider::Start(). (Extensions are complicated...) |
| 863 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond | 865 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond |
| 864 // to the keyword verbatim search query. Do not create other matches | 866 // to the keyword verbatim search query. Do not create other matches |
| 865 // of type SEARCH_OTHER_ENGINE. | 867 // of type SEARCH_OTHER_ENGINE. |
| 866 if (keyword_url && | 868 if (keyword_url && |
| 867 (keyword_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION)) { | 869 (keyword_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION)) { |
| 868 bool keyword_relevance_from_server; | 870 bool keyword_relevance_from_server; |
| 869 const int keyword_verbatim_relevance = | 871 const int keyword_verbatim_relevance = |
| 870 GetKeywordVerbatimRelevance(&keyword_relevance_from_server); | 872 GetKeywordVerbatimRelevance(&keyword_relevance_from_server); |
| 871 if (keyword_verbatim_relevance > 0) { | 873 if (keyword_verbatim_relevance > 0) { |
| 872 const base::string16& trimmed_verbatim = | 874 const base::string16& trimmed_verbatim = |
| 873 base::CollapseWhitespace(keyword_input_.text(), false); | 875 base::CollapseWhitespace(keyword_input_.text(), false); |
| 874 SearchSuggestionParser::SuggestResult verbatim( | 876 SearchSuggestionParser::SuggestResult verbatim( |
| 875 trimmed_verbatim, AutocompleteMatchType::SEARCH_OTHER_ENGINE, | 877 trimmed_verbatim, AutocompleteMatchType::SEARCH_OTHER_ENGINE, |
| 876 trimmed_verbatim, base::string16(), base::string16(), | 878 trimmed_verbatim, base::string16(), base::string16(), |
| 877 base::string16(), base::string16(), std::string(), std::string(), | 879 base::string16(), base::string16(), nullptr, std::string(), |
| 878 true, keyword_verbatim_relevance, keyword_relevance_from_server, | 880 std::string(), true, keyword_verbatim_relevance, |
| 879 false, trimmed_verbatim); | 881 keyword_relevance_from_server, false, trimmed_verbatim); |
| 880 AddMatchToMap(verbatim, std::string(), | 882 AddMatchToMap(verbatim, std::string(), |
| 881 did_not_accept_keyword_suggestion, false, true, &map); | 883 did_not_accept_keyword_suggestion, false, true, &map); |
| 882 } | 884 } |
| 883 } | 885 } |
| 884 } | 886 } |
| 885 AddRawHistoryResultsToMap(true, did_not_accept_keyword_suggestion, &map); | 887 AddRawHistoryResultsToMap(true, did_not_accept_keyword_suggestion, &map); |
| 886 AddRawHistoryResultsToMap(false, did_not_accept_default_suggestion, &map); | 888 AddRawHistoryResultsToMap(false, did_not_accept_default_suggestion, &map); |
| 887 | 889 |
| 888 AddSuggestResultsToMap(keyword_results_.suggest_results, | 890 AddSuggestResultsToMap(keyword_results_.suggest_results, |
| 889 keyword_results_.metadata, &map); | 891 keyword_results_.metadata, &map); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 | 951 |
| 950 matches_.push_back(*i); | 952 matches_.push_back(*i); |
| 951 } | 953 } |
| 952 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.ConvertResultsTime", | 954 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.ConvertResultsTime", |
| 953 base::TimeTicks::Now() - start_time); | 955 base::TimeTicks::Now() - start_time); |
| 954 } | 956 } |
| 955 | 957 |
| 956 void SearchProvider::RemoveExtraAnswers(ACMatches* matches) { | 958 void SearchProvider::RemoveExtraAnswers(ACMatches* matches) { |
| 957 bool answer_seen = false; | 959 bool answer_seen = false; |
| 958 for (ACMatches::iterator it = matches->begin(); it != matches->end(); ++it) { | 960 for (ACMatches::iterator it = matches->begin(); it != matches->end(); ++it) { |
| 959 if (!it->answer_contents.empty()) { | 961 if (it->answer) { |
| 960 if (!answer_seen) { | 962 if (!answer_seen) { |
| 961 answer_seen = true; | 963 answer_seen = true; |
| 962 } else { | 964 } else { |
| 963 it->answer_contents.clear(); | 965 it->answer_contents.clear(); |
| 964 it->answer_type.clear(); | 966 it->answer_type.clear(); |
| 967 it->answer.reset(); |
| 965 } | 968 } |
| 966 } | 969 } |
| 967 } | 970 } |
| 968 } | 971 } |
| 969 | 972 |
| 970 ACMatches::const_iterator SearchProvider::FindTopMatch() const { | 973 ACMatches::const_iterator SearchProvider::FindTopMatch() const { |
| 971 ACMatches::const_iterator it = matches_.begin(); | 974 ACMatches::const_iterator it = matches_.begin(); |
| 972 while ((it != matches_.end()) && !it->allowed_to_be_default_match) | 975 while ((it != matches_.end()) && !it->allowed_to_be_default_match) |
| 973 ++it; | 976 ++it; |
| 974 return it; | 977 return it; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 // typed match to always be first. | 1076 // typed match to always be first. |
| 1074 SearchSuggestionParser::SuggestResults::iterator insertion_position = | 1077 SearchSuggestionParser::SuggestResults::iterator insertion_position = |
| 1075 scored_results.end(); | 1078 scored_results.end(); |
| 1076 if (trimmed_suggestion == trimmed_input) { | 1079 if (trimmed_suggestion == trimmed_input) { |
| 1077 found_what_you_typed_match = true; | 1080 found_what_you_typed_match = true; |
| 1078 insertion_position = scored_results.begin(); | 1081 insertion_position = scored_results.begin(); |
| 1079 } | 1082 } |
| 1080 SearchSuggestionParser::SuggestResult history_suggestion( | 1083 SearchSuggestionParser::SuggestResult history_suggestion( |
| 1081 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, | 1084 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, |
| 1082 trimmed_suggestion, base::string16(), base::string16(), | 1085 trimmed_suggestion, base::string16(), base::string16(), |
| 1083 base::string16(), base::string16(), std::string(), std::string(), | 1086 base::string16(), base::string16(), nullptr, std::string(), |
| 1084 is_keyword, relevance, false, false, trimmed_input); | 1087 std::string(), is_keyword, relevance, false, false, trimmed_input); |
| 1085 // History results are synchronous; they are received on the last keystroke. | 1088 // History results are synchronous; they are received on the last keystroke. |
| 1086 history_suggestion.set_received_after_last_keystroke(false); | 1089 history_suggestion.set_received_after_last_keystroke(false); |
| 1087 scored_results.insert(insertion_position, history_suggestion); | 1090 scored_results.insert(insertion_position, history_suggestion); |
| 1088 } | 1091 } |
| 1089 | 1092 |
| 1090 // History returns results sorted for us. However, we may have docked some | 1093 // History returns results sorted for us. However, we may have docked some |
| 1091 // results' scores, so things are no longer in order. While keeping the | 1094 // results' scores, so things are no longer in order. While keeping the |
| 1092 // what-you-typed match at the front (if it exists), do a stable sort to get | 1095 // what-you-typed match at the front (if it exists), do a stable sort to get |
| 1093 // things back in order without otherwise disturbing results with equal | 1096 // things back in order without otherwise disturbing results with equal |
| 1094 // scores, then force the scores to be unique, so that the order in which | 1097 // scores, then force the scores to be unique, so that the order in which |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1446 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) | 1449 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) |
| 1447 matches.push_back(i->second); | 1450 matches.push_back(i->second); |
| 1448 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); | 1451 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); |
| 1449 | 1452 |
| 1450 // If there is a top scoring entry, find the corresponding answer. | 1453 // If there is a top scoring entry, find the corresponding answer. |
| 1451 if (!matches.empty()) | 1454 if (!matches.empty()) |
| 1452 return answers_cache_.GetTopAnswerEntry(matches[0].contents); | 1455 return answers_cache_.GetTopAnswerEntry(matches[0].contents); |
| 1453 | 1456 |
| 1454 return AnswersQueryData(); | 1457 return AnswersQueryData(); |
| 1455 } | 1458 } |
| OLD | NEW |