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/variations_http_header_provider.h" | 33 #include "components/variations/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 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | 817 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); |
817 if (verbatim_relevance > 0) { | 818 if (verbatim_relevance > 0) { |
818 const base::string16& trimmed_verbatim = | 819 const base::string16& trimmed_verbatim = |
819 base::CollapseWhitespace(input_.text(), false); | 820 base::CollapseWhitespace(input_.text(), false); |
820 | 821 |
821 // Verbatim results don't get suggestions and hence, answers. | 822 // Verbatim results don't get suggestions and hence, answers. |
822 // Scan previous matches if the last answer-bearing suggestion matches | 823 // Scan previous matches if the last answer-bearing suggestion matches |
823 // verbatim, and if so, copy over answer contents. | 824 // verbatim, and if so, copy over answer contents. |
824 base::string16 answer_contents; | 825 base::string16 answer_contents; |
825 base::string16 answer_type; | 826 base::string16 answer_type; |
| 827 SuggestionAnswer answer; |
826 for (ACMatches::iterator it = matches_.begin(); it != matches_.end(); | 828 for (ACMatches::iterator it = matches_.begin(); it != matches_.end(); |
827 ++it) { | 829 ++it) { |
828 if (!it->answer_contents.empty() && | 830 if (it->answer.is_valid() && it->fill_into_edit == trimmed_verbatim) { |
829 it->fill_into_edit == trimmed_verbatim) { | |
830 answer_contents = it->answer_contents; | 831 answer_contents = it->answer_contents; |
831 answer_type = it->answer_type; | 832 answer_type = it->answer_type; |
| 833 answer = it->answer; |
832 break; | 834 break; |
833 } | 835 } |
834 } | 836 } |
835 | 837 |
836 SearchSuggestionParser::SuggestResult verbatim( | 838 SearchSuggestionParser::SuggestResult verbatim( |
837 trimmed_verbatim, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, | 839 trimmed_verbatim, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, |
838 trimmed_verbatim, base::string16(), base::string16(), answer_contents, | 840 trimmed_verbatim, base::string16(), base::string16(), answer_contents, |
839 answer_type, std::string(), std::string(), false, verbatim_relevance, | 841 answer_type, answer, std::string(), std::string(), false, |
840 relevance_from_server, false, trimmed_verbatim); | 842 verbatim_relevance, relevance_from_server, false, trimmed_verbatim); |
841 AddMatchToMap(verbatim, std::string(), did_not_accept_default_suggestion, | 843 AddMatchToMap(verbatim, std::string(), did_not_accept_default_suggestion, |
842 false, keyword_url != NULL, &map); | 844 false, keyword_url != NULL, &map); |
843 } | 845 } |
844 if (!keyword_input_.text().empty()) { | 846 if (!keyword_input_.text().empty()) { |
845 // We only create the verbatim search query match for a keyword | 847 // We only create the verbatim search query match for a keyword |
846 // if it's not an extension keyword. Extension keywords are handled | 848 // if it's not an extension keyword. Extension keywords are handled |
847 // in KeywordProvider::Start(). (Extensions are complicated...) | 849 // in KeywordProvider::Start(). (Extensions are complicated...) |
848 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond | 850 // Note: in this provider, SEARCH_OTHER_ENGINE must correspond |
849 // to the keyword verbatim search query. Do not create other matches | 851 // to the keyword verbatim search query. Do not create other matches |
850 // of type SEARCH_OTHER_ENGINE. | 852 // of type SEARCH_OTHER_ENGINE. |
851 if (keyword_url && | 853 if (keyword_url && |
852 (keyword_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION)) { | 854 (keyword_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION)) { |
853 bool keyword_relevance_from_server; | 855 bool keyword_relevance_from_server; |
854 const int keyword_verbatim_relevance = | 856 const int keyword_verbatim_relevance = |
855 GetKeywordVerbatimRelevance(&keyword_relevance_from_server); | 857 GetKeywordVerbatimRelevance(&keyword_relevance_from_server); |
856 if (keyword_verbatim_relevance > 0) { | 858 if (keyword_verbatim_relevance > 0) { |
857 const base::string16& trimmed_verbatim = | 859 const base::string16& trimmed_verbatim = |
858 base::CollapseWhitespace(keyword_input_.text(), false); | 860 base::CollapseWhitespace(keyword_input_.text(), false); |
859 SearchSuggestionParser::SuggestResult verbatim( | 861 SearchSuggestionParser::SuggestResult verbatim( |
860 trimmed_verbatim, AutocompleteMatchType::SEARCH_OTHER_ENGINE, | 862 trimmed_verbatim, AutocompleteMatchType::SEARCH_OTHER_ENGINE, |
861 trimmed_verbatim, base::string16(), base::string16(), | 863 trimmed_verbatim, base::string16(), base::string16(), |
862 base::string16(), base::string16(), std::string(), std::string(), | 864 base::string16(), base::string16(), SuggestionAnswer(), |
863 true, keyword_verbatim_relevance, keyword_relevance_from_server, | 865 std::string(), std::string(), true, keyword_verbatim_relevance, |
864 false, trimmed_verbatim); | 866 keyword_relevance_from_server, false, trimmed_verbatim); |
865 AddMatchToMap(verbatim, std::string(), | 867 AddMatchToMap(verbatim, std::string(), |
866 did_not_accept_keyword_suggestion, false, true, &map); | 868 did_not_accept_keyword_suggestion, false, true, &map); |
867 } | 869 } |
868 } | 870 } |
869 } | 871 } |
870 AddRawHistoryResultsToMap(true, did_not_accept_keyword_suggestion, &map); | 872 AddRawHistoryResultsToMap(true, did_not_accept_keyword_suggestion, &map); |
871 AddRawHistoryResultsToMap(false, did_not_accept_default_suggestion, &map); | 873 AddRawHistoryResultsToMap(false, did_not_accept_default_suggestion, &map); |
872 | 874 |
873 AddSuggestResultsToMap(keyword_results_.suggest_results, | 875 AddSuggestResultsToMap(keyword_results_.suggest_results, |
874 keyword_results_.metadata, &map); | 876 keyword_results_.metadata, &map); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 | 936 |
935 matches_.push_back(*i); | 937 matches_.push_back(*i); |
936 } | 938 } |
937 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.ConvertResultsTime", | 939 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.ConvertResultsTime", |
938 base::TimeTicks::Now() - start_time); | 940 base::TimeTicks::Now() - start_time); |
939 } | 941 } |
940 | 942 |
941 void SearchProvider::RemoveExtraAnswers(ACMatches* matches) { | 943 void SearchProvider::RemoveExtraAnswers(ACMatches* matches) { |
942 bool answer_seen = false; | 944 bool answer_seen = false; |
943 for (ACMatches::iterator it = matches->begin(); it != matches->end(); ++it) { | 945 for (ACMatches::iterator it = matches->begin(); it != matches->end(); ++it) { |
944 if (!it->answer_contents.empty()) { | 946 if (it->answer.is_valid()) { |
945 if (!answer_seen) { | 947 if (!answer_seen) { |
946 answer_seen = true; | 948 answer_seen = true; |
947 } else { | 949 } else { |
948 it->answer_contents.clear(); | 950 it->answer_contents.clear(); |
949 it->answer_type.clear(); | 951 it->answer_type.clear(); |
| 952 it->answer.Clear(); |
950 } | 953 } |
951 } | 954 } |
952 } | 955 } |
953 } | 956 } |
954 | 957 |
955 ACMatches::const_iterator SearchProvider::FindTopMatch() const { | 958 ACMatches::const_iterator SearchProvider::FindTopMatch() const { |
956 ACMatches::const_iterator it = matches_.begin(); | 959 ACMatches::const_iterator it = matches_.begin(); |
957 while ((it != matches_.end()) && !it->allowed_to_be_default_match) | 960 while ((it != matches_.end()) && !it->allowed_to_be_default_match) |
958 ++it; | 961 ++it; |
959 return it; | 962 return it; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 // typed match to always be first. | 1061 // typed match to always be first. |
1059 SearchSuggestionParser::SuggestResults::iterator insertion_position = | 1062 SearchSuggestionParser::SuggestResults::iterator insertion_position = |
1060 scored_results.end(); | 1063 scored_results.end(); |
1061 if (trimmed_suggestion == trimmed_input) { | 1064 if (trimmed_suggestion == trimmed_input) { |
1062 found_what_you_typed_match = true; | 1065 found_what_you_typed_match = true; |
1063 insertion_position = scored_results.begin(); | 1066 insertion_position = scored_results.begin(); |
1064 } | 1067 } |
1065 SearchSuggestionParser::SuggestResult history_suggestion( | 1068 SearchSuggestionParser::SuggestResult history_suggestion( |
1066 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, | 1069 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, |
1067 trimmed_suggestion, base::string16(), base::string16(), | 1070 trimmed_suggestion, base::string16(), base::string16(), |
1068 base::string16(), base::string16(), std::string(), std::string(), | 1071 base::string16(), base::string16(), SuggestionAnswer(), std::string(), |
1069 is_keyword, relevance, false, false, trimmed_input); | 1072 std::string(), is_keyword, relevance, false, false, trimmed_input); |
1070 // History results are synchronous; they are received on the last keystroke. | 1073 // History results are synchronous; they are received on the last keystroke. |
1071 history_suggestion.set_received_after_last_keystroke(false); | 1074 history_suggestion.set_received_after_last_keystroke(false); |
1072 scored_results.insert(insertion_position, history_suggestion); | 1075 scored_results.insert(insertion_position, history_suggestion); |
1073 } | 1076 } |
1074 | 1077 |
1075 // History returns results sorted for us. However, we may have docked some | 1078 // History returns results sorted for us. However, we may have docked some |
1076 // results' scores, so things are no longer in order. While keeping the | 1079 // results' scores, so things are no longer in order. While keeping the |
1077 // what-you-typed match at the front (if it exists), do a stable sort to get | 1080 // what-you-typed match at the front (if it exists), do a stable sort to get |
1078 // things back in order without otherwise disturbing results with equal | 1081 // things back in order without otherwise disturbing results with equal |
1079 // scores, then force the scores to be unique, so that the order in which | 1082 // 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... |
1431 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) | 1434 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) |
1432 matches.push_back(i->second); | 1435 matches.push_back(i->second); |
1433 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); | 1436 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); |
1434 | 1437 |
1435 // If there is a top scoring entry, find the corresponding answer. | 1438 // If there is a top scoring entry, find the corresponding answer. |
1436 if (!matches.empty()) | 1439 if (!matches.empty()) |
1437 return answers_cache_.GetTopAnswerEntry(matches[0].contents); | 1440 return answers_cache_.GetTopAnswerEntry(matches[0].contents); |
1438 | 1441 |
1439 return AnswersQueryData(); | 1442 return AnswersQueryData(); |
1440 } | 1443 } |
OLD | NEW |