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

Side by Side Diff: components/omnibox/browser/search_provider.cc

Issue 1411543011: Omnibox: Make Keyword Provide More Generous with Matching (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: all peter's comments (except one), including previously-promised refactoring, and additional unit t… Created 5 years, 1 month 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
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 "components/omnibox/browser/search_provider.h" 5 #include "components/omnibox/browser/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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // |template_url_service| can be null in tests. 130 // |template_url_service| can be null in tests.
131 if (template_url_service) 131 if (template_url_service)
132 template_url_service->AddObserver(this); 132 template_url_service->AddObserver(this);
133 } 133 }
134 134
135 // static 135 // static
136 std::string SearchProvider::GetSuggestMetadata(const AutocompleteMatch& match) { 136 std::string SearchProvider::GetSuggestMetadata(const AutocompleteMatch& match) {
137 return match.GetAdditionalInfo(kSuggestMetadataKey); 137 return match.GetAdditionalInfo(kSuggestMetadataKey);
138 } 138 }
139 139
140 void SearchProvider::RegisterDisplayedAnswers(
141 const AutocompleteResult& result) {
142 if (result.empty())
143 return;
144
145 // The answer must be in the first or second slot to be considered. It should
146 // only be in the second slot if AutocompleteController ranked a local search
147 // history or a verbatim item higher than the answer.
148 AutocompleteResult::const_iterator match = result.begin();
149 if (match->answer_contents.empty() && result.size() > 1)
150 ++match;
151 if (match->answer_contents.empty() || match->answer_type.empty() ||
152 match->fill_into_edit.empty())
153 return;
154
155 // Valid answer encountered, cache it for further queries.
156 answers_cache_.UpdateRecentAnswers(match->fill_into_edit, match->answer_type);
157 }
158
159 // static
160 int SearchProvider::CalculateRelevanceForKeywordVerbatim(
161 metrics::OmniboxInputType::Type type,
162 bool allow_exact_keyword_match,
163 bool prefer_keyword) {
164 // This function is responsible for scoring verbatim query matches
165 // for non-extension substituting keywords.
166 // KeywordProvider::CalculateRelevance() scores all other types of
167 // keyword verbatim matches.
168 if (allow_exact_keyword_match && prefer_keyword)
169 return 1500;
170 return (allow_exact_keyword_match &&
171 (type == metrics::OmniboxInputType::QUERY)) ?
172 1450 : 1100;
173 }
174
140 void SearchProvider::ResetSession() { 175 void SearchProvider::ResetSession() {
141 set_field_trial_triggered_in_session(false); 176 set_field_trial_triggered_in_session(false);
142 } 177 }
143 178
144 void SearchProvider::OnTemplateURLServiceChanged() {
145 // Only update matches at this time if we haven't already claimed we're done
146 // processing the query.
147 if (done_)
148 return;
149
150 // Check that the engines we're using weren't renamed or deleted. (In short,
151 // require that an engine still exists with the keywords in use.) For each
152 // deleted engine, cancel the in-flight request if any, drop its suggestions,
153 // and, in the case when the default provider was affected, point the cached
154 // default provider keyword name at the new name for the default provider.
155
156 // Get...ProviderURL() looks up the provider using the cached keyword name
157 // stored in |providers_|.
158 const TemplateURL* template_url = providers_.GetDefaultProviderURL();
159 if (!template_url) {
160 CancelFetcher(&default_fetcher_);
161 default_results_.Clear();
162 providers_.set(client()
163 ->GetTemplateURLService()
164 ->GetDefaultSearchProvider()
165 ->keyword(),
166 providers_.keyword_provider());
167 }
168 template_url = providers_.GetKeywordProviderURL();
169 if (!providers_.keyword_provider().empty() && !template_url) {
170 CancelFetcher(&keyword_fetcher_);
171 keyword_results_.Clear();
172 providers_.set(providers_.default_provider(), base::string16());
173 }
174 // It's possible the template URL changed without changing associated keyword.
175 // Hence, it's always necessary to update matches to use the new template
176 // URL. (One could cache the template URL and only call UpdateMatches() and
177 // OnProviderUpdate() if a keyword was deleted/renamed or the template URL
178 // was changed. That would save extra calls to these functions. However,
179 // this is uncommon and not likely to be worth the extra work.)
180 UpdateMatches();
181 listener_->OnProviderUpdate(true); // always pretend something changed
182 }
183
184 SearchProvider::~SearchProvider() { 179 SearchProvider::~SearchProvider() {
185 TemplateURLService* template_url_service = client()->GetTemplateURLService(); 180 TemplateURLService* template_url_service = client()->GetTemplateURLService();
186 if (template_url_service) 181 if (template_url_service)
187 template_url_service->RemoveObserver(this); 182 template_url_service->RemoveObserver(this);
188 } 183 }
189 184
190 // static 185 // static
191 int SearchProvider::CalculateRelevanceForKeywordVerbatim(
192 metrics::OmniboxInputType::Type type,
193 bool prefer_keyword) {
194 // This function is responsible for scoring verbatim query matches
195 // for non-extension keywords. KeywordProvider::CalculateRelevance()
196 // scores verbatim query matches for extension keywords, as well as
197 // for keyword matches (i.e., suggestions of a keyword itself, not a
198 // suggestion of a query on a keyword search engine). These two
199 // functions are currently in sync, but there's no reason we
200 // couldn't decide in the future to score verbatim matches
201 // differently for extension and non-extension keywords. If you
202 // make such a change, however, you should update this comment to
203 // describe it, so it's clear why the functions diverge.
204 if (prefer_keyword)
205 return 1500;
206 return (type == metrics::OmniboxInputType::QUERY) ? 1450 : 1100;
207 }
208
209 // static
210 void SearchProvider::UpdateOldResults( 186 void SearchProvider::UpdateOldResults(
211 bool minimal_changes, 187 bool minimal_changes,
212 SearchSuggestionParser::Results* results) { 188 SearchSuggestionParser::Results* results) {
213 // When called without |minimal_changes|, it likely means the user has 189 // When called without |minimal_changes|, it likely means the user has
214 // pressed a key. Revise the cached results appropriately. 190 // pressed a key. Revise the cached results appropriately.
215 if (!minimal_changes) { 191 if (!minimal_changes) {
216 for (SearchSuggestionParser::SuggestResults::iterator sug_it = 192 for (SearchSuggestionParser::SuggestResults::iterator sug_it =
217 results->suggest_results.begin(); 193 results->suggest_results.begin();
218 sug_it != results->suggest_results.end(); ++sug_it) { 194 sug_it != results->suggest_results.end(); ++sug_it) {
219 sug_it->set_received_after_last_keystroke(false); 195 sug_it->set_received_after_last_keystroke(false);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 void SearchProvider::RecordDeletionResult(bool success) { 332 void SearchProvider::RecordDeletionResult(bool success) {
357 if (success) { 333 if (success) {
358 base::RecordAction( 334 base::RecordAction(
359 base::UserMetricsAction("Omnibox.ServerSuggestDelete.Success")); 335 base::UserMetricsAction("Omnibox.ServerSuggestDelete.Success"));
360 } else { 336 } else {
361 base::RecordAction( 337 base::RecordAction(
362 base::UserMetricsAction("Omnibox.ServerSuggestDelete.Failure")); 338 base::UserMetricsAction("Omnibox.ServerSuggestDelete.Failure"));
363 } 339 }
364 } 340 }
365 341
342 void SearchProvider::OnTemplateURLServiceChanged() {
343 // Only update matches at this time if we haven't already claimed we're done
344 // processing the query.
345 if (done_)
346 return;
347
348 // Check that the engines we're using weren't renamed or deleted. (In short,
349 // require that an engine still exists with the keywords in use.) For each
350 // deleted engine, cancel the in-flight request if any, drop its suggestions,
351 // and, in the case when the default provider was affected, point the cached
352 // default provider keyword name at the new name for the default provider.
353
354 // Get...ProviderURL() looks up the provider using the cached keyword name
355 // stored in |providers_|.
356 const TemplateURL* template_url = providers_.GetDefaultProviderURL();
357 if (!template_url) {
358 CancelFetcher(&default_fetcher_);
359 default_results_.Clear();
360 providers_.set(client()
361 ->GetTemplateURLService()
362 ->GetDefaultSearchProvider()
363 ->keyword(),
364 providers_.keyword_provider());
365 }
366 template_url = providers_.GetKeywordProviderURL();
367 if (!providers_.keyword_provider().empty() && !template_url) {
368 CancelFetcher(&keyword_fetcher_);
369 keyword_results_.Clear();
370 providers_.set(providers_.default_provider(), base::string16());
371 }
372 // It's possible the template URL changed without changing associated keyword.
373 // Hence, it's always necessary to update matches to use the new template
374 // URL. (One could cache the template URL and only call UpdateMatches() and
375 // OnProviderUpdate() if a keyword was deleted/renamed or the template URL
376 // was changed. That would save extra calls to these functions. However,
377 // this is uncommon and not likely to be worth the extra work.)
378 UpdateMatches();
379 listener_->OnProviderUpdate(true); // always pretend something changed
380 }
381
366 void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) { 382 void SearchProvider::OnURLFetchComplete(const net::URLFetcher* source) {
367 DCHECK(!done_); 383 DCHECK(!done_);
368 const bool is_keyword = source == keyword_fetcher_.get(); 384 const bool is_keyword = source == keyword_fetcher_.get();
369 385
370 // Ensure the request succeeded and that the provider used is still available. 386 // Ensure the request succeeded and that the provider used is still available.
371 // A verbatim match cannot be generated without this provider, causing errors. 387 // A verbatim match cannot be generated without this provider, causing errors.
372 const bool request_succeeded = 388 const bool request_succeeded =
373 source->GetStatus().is_success() && (source->GetResponseCode() == 200) && 389 source->GetStatus().is_success() && (source->GetResponseCode() == 200) &&
374 GetTemplateURL(is_keyword); 390 GetTemplateURL(is_keyword);
375 391
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 (keyword_results_.verbatim_relevance >= 0) && 1328 (keyword_results_.verbatim_relevance >= 0) &&
1313 !input_.prevent_inline_autocomplete() && 1329 !input_.prevent_inline_autocomplete() &&
1314 ((keyword_results_.verbatim_relevance > 0) || 1330 ((keyword_results_.verbatim_relevance > 0) ||
1315 !keyword_results_.suggest_results.empty() || 1331 !keyword_results_.suggest_results.empty() ||
1316 !keyword_results_.navigation_results.empty()); 1332 !keyword_results_.navigation_results.empty());
1317 if (relevance_from_server) 1333 if (relevance_from_server)
1318 *relevance_from_server = use_server_relevance; 1334 *relevance_from_server = use_server_relevance;
1319 return use_server_relevance ? 1335 return use_server_relevance ?
1320 keyword_results_.verbatim_relevance : 1336 keyword_results_.verbatim_relevance :
1321 CalculateRelevanceForKeywordVerbatim(keyword_input_.type(), 1337 CalculateRelevanceForKeywordVerbatim(keyword_input_.type(),
1338 true,
1322 keyword_input_.prefer_keyword()); 1339 keyword_input_.prefer_keyword());
1323 } 1340 }
1324 1341
1325 int SearchProvider::CalculateRelevanceForHistory( 1342 int SearchProvider::CalculateRelevanceForHistory(
1326 const base::Time& time, 1343 const base::Time& time,
1327 bool is_keyword, 1344 bool is_keyword,
1328 bool use_aggressive_method, 1345 bool use_aggressive_method,
1329 bool prevent_search_history_inlining) const { 1346 bool prevent_search_history_inlining) const {
1330 // The relevance of past searches falls off over time. There are two distinct 1347 // The relevance of past searches falls off over time. There are two distinct
1331 // equations used. If the first equation is used (searches to the primary 1348 // equations used. If the first equation is used (searches to the primary
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 std::replace(current_token_.begin(), current_token_.end(), '+', '-'); 1477 std::replace(current_token_.begin(), current_token_.end(), '+', '-');
1461 std::replace(current_token_.begin(), current_token_.end(), '/', '_'); 1478 std::replace(current_token_.begin(), current_token_.end(), '/', '_');
1462 } 1479 }
1463 1480
1464 // Extend expiration time another 60 seconds. 1481 // Extend expiration time another 60 seconds.
1465 token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60); 1482 token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60);
1466 1483
1467 return current_token_; 1484 return current_token_;
1468 } 1485 }
1469 1486
1470 void SearchProvider::RegisterDisplayedAnswers(
1471 const AutocompleteResult& result) {
1472 if (result.empty())
1473 return;
1474
1475 // The answer must be in the first or second slot to be considered. It should
1476 // only be in the second slot if AutocompleteController ranked a local search
1477 // history or a verbatim item higher than the answer.
1478 AutocompleteResult::const_iterator match = result.begin();
1479 if (match->answer_contents.empty() && result.size() > 1)
1480 ++match;
1481 if (match->answer_contents.empty() || match->answer_type.empty() ||
1482 match->fill_into_edit.empty())
1483 return;
1484
1485 // Valid answer encountered, cache it for further queries.
1486 answers_cache_.UpdateRecentAnswers(match->fill_into_edit, match->answer_type);
1487 }
1488
1489 AnswersQueryData SearchProvider::FindAnswersPrefetchData() { 1487 AnswersQueryData SearchProvider::FindAnswersPrefetchData() {
1490 // Retrieve the top entry from scored history results. 1488 // Retrieve the top entry from scored history results.
1491 MatchMap map; 1489 MatchMap map;
1492 AddTransformedHistoryResultsToMap(transformed_keyword_history_results_, 1490 AddTransformedHistoryResultsToMap(transformed_keyword_history_results_,
1493 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, 1491 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE,
1494 &map); 1492 &map);
1495 AddTransformedHistoryResultsToMap(transformed_default_history_results_, 1493 AddTransformedHistoryResultsToMap(transformed_default_history_results_,
1496 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, 1494 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE,
1497 &map); 1495 &map);
1498 1496
1499 ACMatches matches; 1497 ACMatches matches;
1500 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) 1498 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i)
1501 matches.push_back(i->second); 1499 matches.push_back(i->second);
1502 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); 1500 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant);
1503 1501
1504 // If there is a top scoring entry, find the corresponding answer. 1502 // If there is a top scoring entry, find the corresponding answer.
1505 if (!matches.empty()) 1503 if (!matches.empty())
1506 return answers_cache_.GetTopAnswerEntry(matches[0].contents); 1504 return answers_cache_.GetTopAnswerEntry(matches[0].contents);
1507 1505
1508 return AnswersQueryData(); 1506 return AnswersQueryData();
1509 } 1507 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698