Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(969)

Side by Side Diff: chrome/browser/autocomplete/search_provider.cc

Issue 319523005: Omnibox: Combine Two Input Type Enums into One (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: followed suggestions Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 21 matching lines...) Expand all
32 #include "chrome/browser/metrics/variations/variations_http_header_provider.h" 32 #include "chrome/browser/metrics/variations/variations_http_header_provider.h"
33 #include "chrome/browser/omnibox/omnibox_field_trial.h" 33 #include "chrome/browser/omnibox/omnibox_field_trial.h"
34 #include "chrome/browser/profiles/profile.h" 34 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/search/search.h" 35 #include "chrome/browser/search/search.h"
36 #include "chrome/browser/search_engines/template_url_prepopulate_data.h" 36 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
37 #include "chrome/browser/search_engines/template_url_service.h" 37 #include "chrome/browser/search_engines/template_url_service.h"
38 #include "chrome/browser/search_engines/template_url_service_factory.h" 38 #include "chrome/browser/search_engines/template_url_service_factory.h"
39 #include "chrome/browser/ui/search/instant_controller.h" 39 #include "chrome/browser/ui/search/instant_controller.h"
40 #include "chrome/common/chrome_switches.h" 40 #include "chrome/common/chrome_switches.h"
41 #include "chrome/common/pref_names.h" 41 #include "chrome/common/pref_names.h"
42 #include "components/metrics/proto/omnibox_input_type.pb.h"
42 #include "content/public/browser/user_metrics.h" 43 #include "content/public/browser/user_metrics.h"
43 #include "grit/generated_resources.h" 44 #include "grit/generated_resources.h"
44 #include "net/base/escape.h" 45 #include "net/base/escape.h"
45 #include "net/base/load_flags.h" 46 #include "net/base/load_flags.h"
46 #include "net/base/net_util.h" 47 #include "net/base/net_util.h"
47 #include "net/http/http_request_headers.h" 48 #include "net/http/http_request_headers.h"
48 #include "net/url_request/url_fetcher.h" 49 #include "net/url_request/url_fetcher.h"
49 #include "net/url_request/url_request_status.h" 50 #include "net/url_request/url_request_status.h"
50 #include "ui/base/l10n/l10n_util.h" 51 #include "ui/base/l10n/l10n_util.h"
51 #include "url/url_constants.h" 52 #include "url/url_constants.h"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 // scores verbatim query matches for extension keywords, as well as 170 // scores verbatim query matches for extension keywords, as well as
170 // for keyword matches (i.e., suggestions of a keyword itself, not a 171 // for keyword matches (i.e., suggestions of a keyword itself, not a
171 // suggestion of a query on a keyword search engine). These two 172 // suggestion of a query on a keyword search engine). These two
172 // functions are currently in sync, but there's no reason we 173 // functions are currently in sync, but there's no reason we
173 // couldn't decide in the future to score verbatim matches 174 // couldn't decide in the future to score verbatim matches
174 // differently for extension and non-extension keywords. If you 175 // differently for extension and non-extension keywords. If you
175 // make such a change, however, you should update this comment to 176 // make such a change, however, you should update this comment to
176 // describe it, so it's clear why the functions diverge. 177 // describe it, so it's clear why the functions diverge.
177 if (prefer_keyword) 178 if (prefer_keyword)
178 return 1500; 179 return 1500;
179 return (type == AutocompleteInput::QUERY) ? 1450 : 1100; 180 return (type == metrics::OmniboxInputType::QUERY) ? 1450 : 1100;
180 } 181 }
181 182
182 void SearchProvider::Start(const AutocompleteInput& input, 183 void SearchProvider::Start(const AutocompleteInput& input,
183 bool minimal_changes) { 184 bool minimal_changes) {
184 // Do our best to load the model as early as possible. This will reduce 185 // Do our best to load the model as early as possible. This will reduce
185 // odds of having the model not ready when really needed (a non-empty input). 186 // odds of having the model not ready when really needed (a non-empty input).
186 TemplateURLService* model = providers_.template_url_service(); 187 TemplateURLService* model = providers_.template_url_service();
187 DCHECK(model); 188 DCHECK(model);
188 model->Load(); 189 model->Load();
189 190
190 matches_.clear(); 191 matches_.clear();
191 field_trial_triggered_ = false; 192 field_trial_triggered_ = false;
192 193
193 // Can't return search/suggest results for bogus input or without a profile. 194 // Can't return search/suggest results for bogus input or without a profile.
194 if (!profile_ || (input.type() == AutocompleteInput::INVALID)) { 195 if (!profile_ || (input.type() == metrics::OmniboxInputType::INVALID)) {
195 Stop(true); 196 Stop(true);
196 return; 197 return;
197 } 198 }
198 199
199 keyword_input_ = input; 200 keyword_input_ = input;
200 const TemplateURL* keyword_provider = 201 const TemplateURL* keyword_provider =
201 KeywordProvider::GetSubstitutingTemplateURLForInput(model, 202 KeywordProvider::GetSubstitutingTemplateURLForInput(model,
202 &keyword_input_); 203 &keyword_input_);
203 if (keyword_provider == NULL) 204 if (keyword_provider == NULL)
204 keyword_input_.Clear(); 205 keyword_input_.Clear();
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 ((!default_url || default_url->suggestions_url().empty()) && 543 ((!default_url || default_url->suggestions_url().empty()) &&
543 (!keyword_url || keyword_url->suggestions_url().empty())) || 544 (!keyword_url || keyword_url->suggestions_url().empty())) ||
544 !profile_->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled)) 545 !profile_->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled))
545 return false; 546 return false;
546 547
547 // If the input type might be a URL, we take extra care so that private data 548 // If the input type might be a URL, we take extra care so that private data
548 // isn't sent to the server. 549 // isn't sent to the server.
549 550
550 // FORCED_QUERY means the user is explicitly asking us to search for this, so 551 // FORCED_QUERY means the user is explicitly asking us to search for this, so
551 // we assume it isn't a URL and/or there isn't private data. 552 // we assume it isn't a URL and/or there isn't private data.
552 if (input_.type() == AutocompleteInput::FORCED_QUERY) 553 if (input_.type() == metrics::OmniboxInputType::FORCED_QUERY)
553 return true; 554 return true;
554 555
555 // Next we check the scheme. If this is UNKNOWN/URL with a scheme that isn't 556 // Next we check the scheme. If this is UNKNOWN/URL with a scheme that isn't
556 // http/https/ftp, we shouldn't send it. Sending things like file: and data: 557 // http/https/ftp, we shouldn't send it. Sending things like file: and data:
557 // is both a waste of time and a disclosure of potentially private, local 558 // is both a waste of time and a disclosure of potentially private, local
558 // data. Other "schemes" may actually be usernames, and we don't want to send 559 // data. Other "schemes" may actually be usernames, and we don't want to send
559 // passwords. If the scheme is OK, we still need to check other cases below. 560 // passwords. If the scheme is OK, we still need to check other cases below.
560 // If this is QUERY, then the presence of these schemes means the user 561 // If this is QUERY, then the presence of these schemes means the user
561 // explicitly typed one, and thus this is probably a URL that's being entered 562 // explicitly typed one, and thus this is probably a URL that's being entered
562 // and happens to currently be invalid -- in which case we again want to run 563 // and happens to currently be invalid -- in which case we again want to run
563 // our checks below. Other QUERY cases are less likely to be URLs and thus we 564 // our checks below. Other QUERY cases are less likely to be URLs and thus we
564 // assume we're OK. 565 // assume we're OK.
565 if (!LowerCaseEqualsASCII(input_.scheme(), url::kHttpScheme) && 566 if (!LowerCaseEqualsASCII(input_.scheme(), url::kHttpScheme) &&
566 !LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) && 567 !LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) &&
567 !LowerCaseEqualsASCII(input_.scheme(), url::kFtpScheme)) 568 !LowerCaseEqualsASCII(input_.scheme(), url::kFtpScheme))
568 return (input_.type() == AutocompleteInput::QUERY); 569 return (input_.type() == metrics::OmniboxInputType::QUERY);
569 570
570 // Don't send URLs with usernames, queries or refs. Some of these are 571 // Don't send URLs with usernames, queries or refs. Some of these are
571 // private, and the Suggest server is unlikely to have any useful results 572 // private, and the Suggest server is unlikely to have any useful results
572 // for any of them. Also don't send URLs with ports, as we may initially 573 // for any of them. Also don't send URLs with ports, as we may initially
573 // think that a username + password is a host + port (and we don't want to 574 // think that a username + password is a host + port (and we don't want to
574 // send usernames/passwords), and even if the port really is a port, the 575 // send usernames/passwords), and even if the port really is a port, the
575 // server is once again unlikely to have and useful results. 576 // server is once again unlikely to have and useful results.
576 // Note that we only block based on refs if the input is URL-typed, as search 577 // Note that we only block based on refs if the input is URL-typed, as search
577 // queries can legitimately have #s in them which the URL parser 578 // queries can legitimately have #s in them which the URL parser
578 // overaggressively categorizes as a url with a ref. 579 // overaggressively categorizes as a url with a ref.
579 const url::Parsed& parts = input_.parts(); 580 const url::Parsed& parts = input_.parts();
580 if (parts.username.is_nonempty() || parts.port.is_nonempty() || 581 if (parts.username.is_nonempty() || parts.port.is_nonempty() ||
581 parts.query.is_nonempty() || 582 parts.query.is_nonempty() ||
582 (parts.ref.is_nonempty() && (input_.type() == AutocompleteInput::URL))) 583 (parts.ref.is_nonempty() &&
584 (input_.type() == metrics::OmniboxInputType::URL)))
583 return false; 585 return false;
584 586
585 // Don't send anything for https except the hostname. Hostnames are OK 587 // Don't send anything for https except the hostname. Hostnames are OK
586 // because they are visible when the TCP connection is established, but the 588 // because they are visible when the TCP connection is established, but the
587 // specific path may reveal private information. 589 // specific path may reveal private information.
588 if (LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) && 590 if (LowerCaseEqualsASCII(input_.scheme(), url::kHttpsScheme) &&
589 parts.path.is_nonempty()) 591 parts.path.is_nonempty())
590 return false; 592 return false;
591 593
592 return true; 594 return true;
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 ++it) { 807 ++it) {
806 if ((it->keyword == keyword_url->keyword()) && 808 if ((it->keyword == keyword_url->keyword()) &&
807 it->allowed_to_be_default_match) 809 it->allowed_to_be_default_match)
808 return true; 810 return true;
809 } 811 }
810 return false; 812 return false;
811 } 813 }
812 814
813 bool SearchProvider::IsTopMatchSearchWithURLInput() const { 815 bool SearchProvider::IsTopMatchSearchWithURLInput() const {
814 ACMatches::const_iterator first_match = FindTopMatch(); 816 ACMatches::const_iterator first_match = FindTopMatch();
815 return (input_.type() == AutocompleteInput::URL) && 817 return (input_.type() == metrics::OmniboxInputType::URL) &&
816 (first_match != matches_.end()) && 818 (first_match != matches_.end()) &&
817 (first_match->relevance > CalculateRelevanceForVerbatim()) && 819 (first_match->relevance > CalculateRelevanceForVerbatim()) &&
818 (first_match->type != AutocompleteMatchType::NAVSUGGEST) && 820 (first_match->type != AutocompleteMatchType::NAVSUGGEST) &&
819 (first_match->type != AutocompleteMatchType::NAVSUGGEST_PERSONALIZED); 821 (first_match->type != AutocompleteMatchType::NAVSUGGEST_PERSONALIZED);
820 } 822 }
821 823
822 void SearchProvider::AddNavigationResultsToMatches( 824 void SearchProvider::AddNavigationResultsToMatches(
823 const NavigationResults& navigation_results, 825 const NavigationResults& navigation_results,
824 ACMatches* matches) { 826 ACMatches* matches) {
825 for (NavigationResults::const_iterator it = navigation_results.begin(); 827 for (NavigationResults::const_iterator it = navigation_results.begin();
826 it != navigation_results.end(); ++it) { 828 it != navigation_results.end(); ++it) {
827 matches->push_back(NavigationToMatch(*it)); 829 matches->push_back(NavigationToMatch(*it));
828 // In the absence of suggested relevance scores, use only the single 830 // In the absence of suggested relevance scores, use only the single
829 // highest-scoring result. (The results are already sorted by relevance.) 831 // highest-scoring result. (The results are already sorted by relevance.)
830 if (!it->relevance_from_server()) 832 if (!it->relevance_from_server())
831 return; 833 return;
832 } 834 }
833 } 835 }
834 836
835 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, 837 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results,
836 bool is_keyword, 838 bool is_keyword,
837 int did_not_accept_suggestion, 839 int did_not_accept_suggestion,
838 MatchMap* map) { 840 MatchMap* map) {
839 if (results.empty()) 841 if (results.empty())
840 return; 842 return;
841 843
842 base::TimeTicks start_time(base::TimeTicks::Now()); 844 base::TimeTicks start_time(base::TimeTicks::Now());
843 bool prevent_inline_autocomplete = input_.prevent_inline_autocomplete() || 845 bool prevent_inline_autocomplete = input_.prevent_inline_autocomplete() ||
844 (input_.type() == AutocompleteInput::URL); 846 (input_.type() == metrics::OmniboxInputType::URL);
845 const base::string16& input_text = 847 const base::string16& input_text =
846 is_keyword ? keyword_input_.text() : input_.text(); 848 is_keyword ? keyword_input_.text() : input_.text();
847 bool input_multiple_words = HasMultipleWords(input_text); 849 bool input_multiple_words = HasMultipleWords(input_text);
848 850
849 SuggestResults scored_results; 851 SuggestResults scored_results;
850 if (!prevent_inline_autocomplete && input_multiple_words) { 852 if (!prevent_inline_autocomplete && input_multiple_words) {
851 // ScoreHistoryResults() allows autocompletion of multi-word, 1-visit 853 // ScoreHistoryResults() allows autocompletion of multi-word, 1-visit
852 // queries if the input also has multiple words. But if we were already 854 // queries if the input also has multiple words. But if we were already
853 // scoring a multi-word, multi-visit query aggressively, and the current 855 // scoring a multi-word, multi-visit query aggressively, and the current
854 // input is still a prefix of it, then changing the suggestion suddenly 856 // input is still a prefix of it, then changing the suggestion suddenly
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 982
981 int SearchProvider::CalculateRelevanceForVerbatim() const { 983 int SearchProvider::CalculateRelevanceForVerbatim() const {
982 if (!providers_.keyword_provider().empty()) 984 if (!providers_.keyword_provider().empty())
983 return 250; 985 return 250;
984 return CalculateRelevanceForVerbatimIgnoringKeywordModeState(); 986 return CalculateRelevanceForVerbatimIgnoringKeywordModeState();
985 } 987 }
986 988
987 int SearchProvider:: 989 int SearchProvider::
988 CalculateRelevanceForVerbatimIgnoringKeywordModeState() const { 990 CalculateRelevanceForVerbatimIgnoringKeywordModeState() const {
989 switch (input_.type()) { 991 switch (input_.type()) {
990 case AutocompleteInput::UNKNOWN: 992 case metrics::OmniboxInputType::UNKNOWN:
991 case AutocompleteInput::QUERY: 993 case metrics::OmniboxInputType::QUERY:
992 case AutocompleteInput::FORCED_QUERY: 994 case metrics::OmniboxInputType::FORCED_QUERY:
993 return kNonURLVerbatimRelevance; 995 return kNonURLVerbatimRelevance;
994 996
995 case AutocompleteInput::URL: 997 case metrics::OmniboxInputType::URL:
996 return 850; 998 return 850;
997 999
998 default: 1000 case metrics::OmniboxInputType::INVALID:
999 NOTREACHED(); 1001 case metrics::OmniboxInputType::DEPRECATED_REQUESTED_URL:
Peter Kasting 2014/06/06 20:42:33 I'm actually going to push back and say that I dis
Mark P 2014/06/06 21:24:52 I went back to the old way. The reason the old wa
1000 return 0; 1002 ;
Ilya Sherman 2014/06/06 20:29:24 nit: I'd have a break or a return. Just a semicol
Mark P 2014/06/06 21:24:52 Took Peter's advice; see comment there.
1001 } 1003 }
1004 NOTREACHED();
1005 return 0;
1002 } 1006 }
1003 1007
1004 int SearchProvider::GetKeywordVerbatimRelevance( 1008 int SearchProvider::GetKeywordVerbatimRelevance(
1005 bool* relevance_from_server) const { 1009 bool* relevance_from_server) const {
1006 // Use the suggested verbatim relevance score if it is non-negative (valid), 1010 // Use the suggested verbatim relevance score if it is non-negative (valid),
1007 // if inline autocomplete isn't prevented (always show verbatim on backspace), 1011 // if inline autocomplete isn't prevented (always show verbatim on backspace),
1008 // and if it won't suppress verbatim, leaving no keyword provider matches. 1012 // and if it won't suppress verbatim, leaving no keyword provider matches.
1009 // Otherwise, if the keyword provider returned no matches and was still able 1013 // Otherwise, if the keyword provider returned no matches and was still able
1010 // to suppress verbatim, the user would have no search/nav matches and may be 1014 // to suppress verbatim, the user would have no search/nav matches and may be
1011 // left unable to search using their keyword provider from the omnibox. 1015 // left unable to search using their keyword provider from the omnibox.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 elapsed_time -= autocomplete_time; 1056 elapsed_time -= autocomplete_time;
1053 } 1057 }
1054 1058
1055 const int score_discount = 1059 const int score_discount =
1056 static_cast<int>(6.5 * std::pow(elapsed_time, 0.3)); 1060 static_cast<int>(6.5 * std::pow(elapsed_time, 0.3));
1057 1061
1058 // Don't let scores go below 0. Negative relevance scores are meaningful in 1062 // Don't let scores go below 0. Negative relevance scores are meaningful in
1059 // a different way. 1063 // a different way.
1060 int base_score; 1064 int base_score;
1061 if (is_primary_provider) 1065 if (is_primary_provider)
1062 base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050; 1066 base_score = (input_.type() == metrics::OmniboxInputType::URL) ? 750 : 1050;
1063 else 1067 else
1064 base_score = 200; 1068 base_score = 200;
1065 return std::max(0, base_score - score_discount); 1069 return std::max(0, base_score - score_discount);
1066 } 1070 }
1067 1071
1068 AutocompleteMatch SearchProvider::NavigationToMatch( 1072 AutocompleteMatch SearchProvider::NavigationToMatch(
1069 const NavigationResult& navigation) { 1073 const NavigationResult& navigation) {
1070 base::string16 input; 1074 base::string16 input;
1071 const bool trimmed_whitespace = base::TrimWhitespace( 1075 const bool trimmed_whitespace = base::TrimWhitespace(
1072 navigation.from_keyword_provider() ? 1076 navigation.from_keyword_provider() ?
(...skipping 19 matching lines...) Expand all
1092 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 1096 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
1093 size_t inline_autocomplete_offset = (prefix == NULL) ? 1097 size_t inline_autocomplete_offset = (prefix == NULL) ?
1094 base::string16::npos : (match_start + input.length()); 1098 base::string16::npos : (match_start + input.length());
1095 match.fill_into_edit += 1099 match.fill_into_edit +=
1096 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(), 1100 AutocompleteInput::FormattedStringWithEquivalentMeaning(navigation.url(),
1097 net::FormatUrl(navigation.url(), languages, format_types, 1101 net::FormatUrl(navigation.url(), languages, format_types,
1098 net::UnescapeRule::SPACES, NULL, NULL, 1102 net::UnescapeRule::SPACES, NULL, NULL,
1099 &inline_autocomplete_offset)); 1103 &inline_autocomplete_offset));
1100 // Preserve the forced query '?' prefix in |match.fill_into_edit|. 1104 // Preserve the forced query '?' prefix in |match.fill_into_edit|.
1101 // Otherwise, user edits to a suggestion would show non-Search results. 1105 // Otherwise, user edits to a suggestion would show non-Search results.
1102 if (input_.type() == AutocompleteInput::FORCED_QUERY) { 1106 if (input_.type() == metrics::OmniboxInputType::FORCED_QUERY) {
1103 match.fill_into_edit.insert(0, base::ASCIIToUTF16("?")); 1107 match.fill_into_edit.insert(0, base::ASCIIToUTF16("?"));
1104 if (inline_autocomplete_offset != base::string16::npos) 1108 if (inline_autocomplete_offset != base::string16::npos)
1105 ++inline_autocomplete_offset; 1109 ++inline_autocomplete_offset;
1106 } 1110 }
1107 if (inline_autocomplete_offset != base::string16::npos) { 1111 if (inline_autocomplete_offset != base::string16::npos) {
1108 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length()); 1112 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length());
1109 match.inline_autocompletion = 1113 match.inline_autocompletion =
1110 match.fill_into_edit.substr(inline_autocomplete_offset); 1114 match.fill_into_edit.substr(inline_autocomplete_offset);
1111 } 1115 }
1112 // An inlineable navsuggestion can only be the default match when there 1116 // An inlineable navsuggestion can only be the default match when there
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 // Make the base64 encoded value URL and filename safe(see RFC 3548). 1158 // Make the base64 encoded value URL and filename safe(see RFC 3548).
1155 std::replace(current_token_.begin(), current_token_.end(), '+', '-'); 1159 std::replace(current_token_.begin(), current_token_.end(), '+', '-');
1156 std::replace(current_token_.begin(), current_token_.end(), '/', '_'); 1160 std::replace(current_token_.begin(), current_token_.end(), '/', '_');
1157 } 1161 }
1158 1162
1159 // Extend expiration time another 60 seconds. 1163 // Extend expiration time another 60 seconds.
1160 token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60); 1164 token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60);
1161 1165
1162 return current_token_; 1166 return current_token_;
1163 } 1167 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698