Chromium Code Reviews| 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 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 884 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", | 884 UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime", |
| 885 base::TimeTicks::Now() - start_time); | 885 base::TimeTicks::Now() - start_time); |
| 886 } | 886 } |
| 887 | 887 |
| 888 SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults( | 888 SearchProvider::SuggestResults SearchProvider::ScoreHistoryResults( |
| 889 const HistoryResults& results, | 889 const HistoryResults& results, |
| 890 bool base_prevent_inline_autocomplete, | 890 bool base_prevent_inline_autocomplete, |
| 891 bool input_multiple_words, | 891 bool input_multiple_words, |
| 892 const base::string16& input_text, | 892 const base::string16& input_text, |
| 893 bool is_keyword) { | 893 bool is_keyword) { |
| 894 AutocompleteClassifier* classifier = | |
| 895 AutocompleteClassifierFactory::GetForProfile(profile_); | |
| 896 SuggestResults scored_results; | 894 SuggestResults scored_results; |
| 897 // True if the user has asked this exact query previously. | 895 // True if the user has asked this exact query previously. |
| 898 bool found_what_you_typed_match = false; | 896 bool found_what_you_typed_match = false; |
| 899 const bool prevent_search_history_inlining = | 897 const bool prevent_search_history_inlining = |
| 900 OmniboxFieldTrial::SearchHistoryPreventInlining( | 898 OmniboxFieldTrial::SearchHistoryPreventInlining( |
| 901 input_.current_page_classification()); | 899 input_.current_page_classification()); |
| 902 const base::string16& trimmed_input = | 900 const base::string16& trimmed_input = |
| 903 base::CollapseWhitespace(input_text, false); | 901 base::CollapseWhitespace(input_text, false); |
| 904 for (HistoryResults::const_iterator i(results.begin()); i != results.end(); | 902 for (HistoryResults::const_iterator i(results.begin()); i != results.end(); |
| 905 ++i) { | 903 ++i) { |
| 906 const base::string16& trimmed_suggestion = | 904 const base::string16& trimmed_suggestion = |
| 907 base::CollapseWhitespace(i->term, false); | 905 base::CollapseWhitespace(i->term, false); |
| 908 | 906 |
| 909 // Don't autocomplete multi-word queries that have only been seen once | 907 // Don't autocomplete multi-word queries that have only been seen once |
| 910 // unless the user has typed more than one word. | 908 // unless the user has typed more than one word. |
| 911 bool prevent_inline_autocomplete = base_prevent_inline_autocomplete || | 909 bool prevent_inline_autocomplete = base_prevent_inline_autocomplete || |
| 912 (!input_multiple_words && (i->visits < 2) && | 910 (!input_multiple_words && (i->visits < 2) && |
| 913 HasMultipleWords(trimmed_suggestion)); | 911 HasMultipleWords(trimmed_suggestion)); |
| 914 | 912 |
| 915 // Don't autocomplete search terms that would normally be treated as URLs | |
| 916 // when typed. For example, if the user searched for "google.com" and types | |
| 917 // "goog", don't autocomplete to the search term "google.com". Otherwise, | |
| 918 // the input will look like a URL but act like a search, which is confusing. | |
| 919 // NOTE: We don't check this in the following cases: | |
| 920 // * When inline autocomplete is disabled, we won't be inline | |
| 921 // autocompleting this term, so we don't need to worry about confusion as | |
| 922 // much. This also prevents calling Classify() again from inside the | |
| 923 // classifier (which will corrupt state and likely crash), since the | |
| 924 // classifier always disables inline autocomplete. | |
| 925 // * When the user has typed the whole term, the "what you typed" history | |
| 926 // match will outrank us for URL-like inputs anyway, so we need not do | |
| 927 // anything special. | |
| 928 if (!prevent_inline_autocomplete && classifier && | |
| 929 (trimmed_suggestion != trimmed_input)) { | |
| 930 AutocompleteMatch match; | |
| 931 classifier->Classify(trimmed_suggestion, false, false, | |
| 932 input_.current_page_classification(), &match, NULL); | |
| 933 prevent_inline_autocomplete = | |
| 934 !AutocompleteMatch::IsSearchType(match.type); | |
| 935 } | |
| 936 | |
| 937 int relevance = CalculateRelevanceForHistory( | 913 int relevance = CalculateRelevanceForHistory( |
| 938 i->time, is_keyword, !prevent_inline_autocomplete, | 914 i->time, is_keyword, !prevent_inline_autocomplete, |
| 939 prevent_search_history_inlining); | 915 prevent_search_history_inlining); |
| 940 // Add the match to |scored_results| by putting the what-you-typed match | 916 // Add the match to |scored_results| by putting the what-you-typed match |
| 941 // on the front and appending all other matches. We want the what-you- | 917 // on the front and appending all other matches. We want the what-you- |
| 942 // typed match to always be first. | 918 // typed match to always be first. |
| 943 SuggestResults::iterator insertion_position = scored_results.end(); | 919 SuggestResults::iterator insertion_position = scored_results.end(); |
| 944 if (trimmed_suggestion == trimmed_input) { | 920 if (trimmed_suggestion == trimmed_input) { |
| 945 found_what_you_typed_match = true; | 921 found_what_you_typed_match = true; |
| 946 insertion_position = scored_results.begin(); | 922 insertion_position = scored_results.begin(); |
| 947 } | 923 } |
| 948 scored_results.insert(insertion_position, SuggestResult( | 924 scored_results.insert(insertion_position, SuggestResult( |
| 949 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, | 925 trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY, |
| 950 trimmed_suggestion, base::string16(), base::string16(), | 926 trimmed_suggestion, base::string16(), base::string16(), |
| 951 base::string16(), base::string16(), std::string(), std::string(), | 927 base::string16(), base::string16(), std::string(), std::string(), |
| 952 is_keyword, relevance, false, false, trimmed_input)); | 928 is_keyword, relevance, false, false, trimmed_input)); |
| 953 } | 929 } |
| 954 | 930 |
| 955 // History returns results sorted for us. However, we may have docked some | 931 // History returns results sorted for us. However, we may have docked some |
| 956 // results' scores, so things are no longer in order. While keeping the | 932 // results' scores, so things are no longer in order. While keeping the |
| 957 // what-you-typed match at the front (if it exists), do a stable sort to get | 933 // what-you-typed match at the front (if it exists), do a stable sort to get |
| 958 // things back in order without otherwise disturbing results with equal | 934 // things back in order without otherwise disturbing results with equal |
| 959 // scores, then force the scores to be unique, so that the order in which | 935 // scores, then force the scores to be unique, so that the order in which |
| 960 // they're shown is deterministic. | 936 // they're shown is deterministic. |
| 961 std::stable_sort(scored_results.begin() + | 937 std::stable_sort(scored_results.begin() + |
| 962 (found_what_you_typed_match ? 1 : 0), | 938 (found_what_you_typed_match ? 1 : 0), |
| 963 scored_results.end(), | 939 scored_results.end(), |
| 964 CompareScoredResults()); | 940 CompareScoredResults()); |
| 941 | |
| 942 // Don't autocomplete to search terms that would normally be treated as URLs | |
| 943 // when typed. For example, if the user searched for "google.com" and types | |
| 944 // "goog", don't autocomplete to the search term "google.com". Otherwise, | |
| 945 // the input will look like a URL but act like a search, which is confusing. | |
| 946 // The 1200 relevance score threshold in the test below is the lowest | |
|
Mark P
2014/07/23 23:52:39
I added stuff here to the comment.
| |
| 947 // possible score in CalculateRelevanceForHistory()'s aggressive-scoring | |
| 948 // curve. This is an appropriate threshold to use to decide if we're overly | |
| 949 // aggressively inlining because, if we decide the answer is yes, the | |
| 950 // way we resolve it it to not use the aggressive-scoring curve. | |
| 951 // NOTE: We don't check for autocompleting to URLs in the following cases: | |
| 952 // * When inline autocomplete is disabled, we won't be inline autocompleting | |
| 953 // this term, so we don't need to worry about confusion as much. This | |
| 954 // also prevents calling Classify() again from inside the classifier | |
| 955 // (which will corrupt state and likely crash), since the classifier | |
| 956 // always disables inline autocomplete. | |
| 957 // * When the user has typed the whole string before as a query, then it's | |
|
Mark P
2014/07/23 23:52:39
I rewrote (re-justified) this second bullet point
| |
| 958 // likely the user has no expectation that term should be interpreted as | |
| 959 // as a URL, so we need not do anything special to preserve user | |
| 960 // expectation. | |
| 961 AutocompleteClassifier* classifier = | |
| 962 AutocompleteClassifierFactory::GetForProfile(profile_); | |
| 965 int last_relevance = 0; | 963 int last_relevance = 0; |
| 964 if (!base_prevent_inline_autocomplete && !found_what_you_typed_match && | |
| 965 classifier && (scored_results.front().relevance() >= 1200)) { | |
| 966 AutocompleteMatch match; | |
| 967 classifier->Classify(scored_results.front().suggestion(), false, false, | |
| 968 input_.current_page_classification(), &match, NULL); | |
| 969 // Demote this match that would normally be interpreted as a URL to have | |
| 970 // the highest score a previously-issued search query could have when | |
| 971 // scoring with the non-aggressive method. A consequence of demoting | |
| 972 // by revising |last_relevance| is that this match and all following | |
| 973 // matches get demoted; the relative order of matches is preserved. | |
| 974 // One could imagine demoting only those matches that might cause | |
| 975 // confusion (which, by the way, might change the relative order of | |
| 976 // matches. We have decided to go with the simple demote-all approach | |
| 977 // because selective demotion requires multiple Classify() calls and | |
| 978 // such calls can be expensive (as expensive as running the whole | |
| 979 // autocomplete system). | |
| 980 if (!AutocompleteMatch::IsSearchType(match.type)) { | |
| 981 last_relevance = CalculateRelevanceForHistory( | |
| 982 base::Time::Now(), is_keyword, false, | |
| 983 prevent_search_history_inlining); | |
| 984 } | |
| 985 } | |
| 986 | |
| 966 for (SuggestResults::iterator i(scored_results.begin()); | 987 for (SuggestResults::iterator i(scored_results.begin()); |
| 967 i != scored_results.end(); ++i) { | 988 i != scored_results.end(); ++i) { |
| 968 if ((i != scored_results.begin()) && (i->relevance() >= last_relevance)) | 989 if ((last_relevance != 0) && (i->relevance() >= last_relevance)) |
| 969 i->set_relevance(last_relevance - 1); | 990 i->set_relevance(last_relevance - 1); |
| 970 last_relevance = i->relevance(); | 991 last_relevance = i->relevance(); |
| 971 } | 992 } |
| 972 | 993 |
| 973 return scored_results; | 994 return scored_results; |
| 974 } | 995 } |
| 975 | 996 |
| 976 void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results, | 997 void SearchProvider::AddSuggestResultsToMap(const SuggestResults& results, |
| 977 const std::string& metadata, | 998 const std::string& metadata, |
| 978 MatchMap* map) { | 999 MatchMap* map) { |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1181 // Make the base64 encoded value URL and filename safe(see RFC 3548). | 1202 // Make the base64 encoded value URL and filename safe(see RFC 3548). |
| 1182 std::replace(current_token_.begin(), current_token_.end(), '+', '-'); | 1203 std::replace(current_token_.begin(), current_token_.end(), '+', '-'); |
| 1183 std::replace(current_token_.begin(), current_token_.end(), '/', '_'); | 1204 std::replace(current_token_.begin(), current_token_.end(), '/', '_'); |
| 1184 } | 1205 } |
| 1185 | 1206 |
| 1186 // Extend expiration time another 60 seconds. | 1207 // Extend expiration time another 60 seconds. |
| 1187 token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60); | 1208 token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60); |
| 1188 | 1209 |
| 1189 return current_token_; | 1210 return current_token_; |
| 1190 } | 1211 } |
| OLD | NEW |