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

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

Issue 500023002: Introduce AutocompleteProviderDelegate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 6 years, 4 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
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"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/i18n/break_iterator.h" 12 #include "base/i18n/break_iterator.h"
14 #include "base/i18n/case_conversion.h" 13 #include "base/i18n/case_conversion.h"
15 #include "base/json/json_string_value_serializer.h" 14 #include "base/json/json_string_value_serializer.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
18 #include "base/metrics/user_metrics.h" 16 #include "base/metrics/user_metrics.h"
19 #include "base/prefs/pref_service.h"
20 #include "base/rand_util.h" 17 #include "base/rand_util.h"
21 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
22 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
23 #include "chrome/browser/autocomplete/autocomplete_classifier.h"
24 #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h"
25 #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h"
26 #include "chrome/browser/history/history_service.h"
27 #include "chrome/browser/history/history_service_factory.h"
28 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/common/pref_names.h"
30 #include "components/google/core/browser/google_util.h"
31 #include "components/history/core/browser/in_memory_database.h" 20 #include "components/history/core/browser/in_memory_database.h"
32 #include "components/history/core/browser/keyword_search_term.h" 21 #include "components/history/core/browser/keyword_search_term.h"
33 #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_delegate.h"
34 #include "components/omnibox/autocomplete_provider_listener.h" 24 #include "components/omnibox/autocomplete_provider_listener.h"
35 #include "components/omnibox/autocomplete_result.h" 25 #include "components/omnibox/autocomplete_result.h"
36 #include "components/omnibox/keyword_provider.h" 26 #include "components/omnibox/keyword_provider.h"
37 #include "components/omnibox/omnibox_field_trial.h" 27 #include "components/omnibox/omnibox_field_trial.h"
38 #include "components/omnibox/url_prefix.h" 28 #include "components/omnibox/url_prefix.h"
39 #include "components/search/search.h" 29 #include "components/search/search.h"
40 #include "components/search_engines/template_url_prepopulate_data.h" 30 #include "components/search_engines/template_url_prepopulate_data.h"
41 #include "components/search_engines/template_url_service.h" 31 #include "components/search_engines/template_url_service.h"
42 #include "components/variations/variations_http_header_provider.h" 32 #include "components/variations/variations_http_header_provider.h"
43 #include "grit/components_strings.h" 33 #include "grit/components_strings.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 return a.relevance() > b.relevance(); 112 return a.relevance() > b.relevance();
123 } 113 }
124 }; 114 };
125 115
126 116
127 // SearchProvider ------------------------------------------------------------- 117 // SearchProvider -------------------------------------------------------------
128 118
129 // static 119 // static
130 int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100; 120 int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100;
131 121
132 SearchProvider::SearchProvider(AutocompleteProviderListener* listener, 122 SearchProvider::SearchProvider(
133 TemplateURLService* template_url_service, 123 AutocompleteProviderListener* listener,
134 Profile* profile) 124 TemplateURLService* template_url_service,
135 : BaseSearchProvider(template_url_service, profile, 125 scoped_ptr<AutocompleteProviderDelegate> delegate)
126 : BaseSearchProvider(template_url_service, delegate.Pass(),
136 AutocompleteProvider::TYPE_SEARCH), 127 AutocompleteProvider::TYPE_SEARCH),
137 listener_(listener), 128 listener_(listener),
138 suggest_results_pending_(0), 129 suggest_results_pending_(0),
139 providers_(template_url_service), 130 providers_(template_url_service),
140 answers_cache_(1) { 131 answers_cache_(1) {
141 } 132 }
142 133
143 // static 134 // static
144 std::string SearchProvider::GetSuggestMetadata(const AutocompleteMatch& match) { 135 std::string SearchProvider::GetSuggestMetadata(const AutocompleteMatch& match) {
145 return match.GetAdditionalInfo(kSuggestMetadataKey); 136 return match.GetAdditionalInfo(kSuggestMetadataKey);
(...skipping 29 matching lines...) Expand all
175 bool minimal_changes) { 166 bool minimal_changes) {
176 // Do our best to load the model as early as possible. This will reduce 167 // Do our best to load the model as early as possible. This will reduce
177 // odds of having the model not ready when really needed (a non-empty input). 168 // odds of having the model not ready when really needed (a non-empty input).
178 TemplateURLService* model = providers_.template_url_service(); 169 TemplateURLService* model = providers_.template_url_service();
179 DCHECK(model); 170 DCHECK(model);
180 model->Load(); 171 model->Load();
181 172
182 matches_.clear(); 173 matches_.clear();
183 field_trial_triggered_ = false; 174 field_trial_triggered_ = false;
184 175
185 // Can't return search/suggest results for bogus input or without a profile. 176 // Can't return search/suggest results for bogus input.
186 if (!profile_ || (input.type() == metrics::OmniboxInputType::INVALID)) { 177 if (input.type() == metrics::OmniboxInputType::INVALID) {
187 Stop(true); 178 Stop(true);
188 return; 179 return;
189 } 180 }
190 181
191 keyword_input_ = input; 182 keyword_input_ = input;
192 const TemplateURL* keyword_provider = 183 const TemplateURL* keyword_provider =
193 KeywordProvider::GetSubstitutingTemplateURLForInput(model, 184 KeywordProvider::GetSubstitutingTemplateURLForInput(model,
194 &keyword_input_); 185 &keyword_input_);
195 if (keyword_provider == NULL) 186 if (keyword_provider == NULL)
196 keyword_input_.Clear(); 187 keyword_input_.Clear();
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 } 325 }
335 326
336 void SearchProvider::UpdateMatchContentsClass( 327 void SearchProvider::UpdateMatchContentsClass(
337 const base::string16& input_text, 328 const base::string16& input_text,
338 SearchSuggestionParser::Results* results) { 329 SearchSuggestionParser::Results* results) {
339 for (SearchSuggestionParser::SuggestResults::iterator sug_it = 330 for (SearchSuggestionParser::SuggestResults::iterator sug_it =
340 results->suggest_results.begin(); 331 results->suggest_results.begin();
341 sug_it != results->suggest_results.end(); ++sug_it) { 332 sug_it != results->suggest_results.end(); ++sug_it) {
342 sug_it->ClassifyMatchContents(false, input_text); 333 sug_it->ClassifyMatchContents(false, input_text);
343 } 334 }
344 const std::string languages( 335 const std::string languages(delegate_->AcceptLanguages());
345 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
346 for (SearchSuggestionParser::NavigationResults::iterator nav_it = 336 for (SearchSuggestionParser::NavigationResults::iterator nav_it =
347 results->navigation_results.begin(); 337 results->navigation_results.begin();
348 nav_it != results->navigation_results.end(); ++nav_it) { 338 nav_it != results->navigation_results.end(); ++nav_it) {
349 nav_it->CalculateAndClassifyMatchContents(false, input_text, languages); 339 nav_it->CalculateAndClassifyMatchContents(false, input_text, languages);
350 } 340 }
351 } 341 }
352 342
353 void SearchProvider::SortResults(bool is_keyword, 343 void SearchProvider::SortResults(bool is_keyword,
354 SearchSuggestionParser::Results* results) { 344 SearchSuggestionParser::Results* results) {
355 // Ignore suggested scores for non-keyword matches in keyword mode; if the 345 // Ignore suggested scores for non-keyword matches in keyword mode; if the
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 if (minimal_changes) 466 if (minimal_changes)
477 return; 467 return;
478 468
479 keyword_history_results_.clear(); 469 keyword_history_results_.clear();
480 default_history_results_.clear(); 470 default_history_results_.clear();
481 471
482 if (OmniboxFieldTrial::SearchHistoryDisable( 472 if (OmniboxFieldTrial::SearchHistoryDisable(
483 input_.current_page_classification())) 473 input_.current_page_classification()))
484 return; 474 return;
485 475
486 HistoryService* const history_service = 476 history::URLDatabase* url_db = delegate_->InMemoryDatabase();
487 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
488 history::URLDatabase* url_db = history_service ?
489 history_service->InMemoryDatabase() : NULL;
490 if (!url_db) 477 if (!url_db)
491 return; 478 return;
492 479
493 // Request history for both the keyword and default provider. We grab many 480 // Request history for both the keyword and default provider. We grab many
494 // more matches than we'll ultimately clamp to so that if there are several 481 // more matches than we'll ultimately clamp to so that if there are several
495 // recent multi-word matches who scores are lowered (see 482 // recent multi-word matches who scores are lowered (see
496 // AddHistoryResultsToMap()), they won't crowd out older, higher-scoring 483 // AddHistoryResultsToMap()), they won't crowd out older, higher-scoring
497 // matches. Note that this doesn't fix the problem entirely, but merely 484 // matches. Note that this doesn't fix the problem entirely, but merely
498 // limits it to cases with a very large number of such multi-word matches; for 485 // limits it to cases with a very large number of such multi-word matches; for
499 // now, this seems OK compared with the complexity of a real fix, which would 486 // now, this seems OK compared with the complexity of a real fix, which would
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 return; 547 return;
561 } 548 }
562 timer_.Start(FROM_HERE, next_suggest_time - now, this, &SearchProvider::Run); 549 timer_.Start(FROM_HERE, next_suggest_time - now, this, &SearchProvider::Run);
563 } 550 }
564 551
565 bool SearchProvider::IsQuerySuitableForSuggest() const { 552 bool SearchProvider::IsQuerySuitableForSuggest() const {
566 // Don't run Suggest in incognito mode, if the engine doesn't support it, or 553 // Don't run Suggest in incognito mode, if the engine doesn't support it, or
567 // if the user has disabled it. 554 // if the user has disabled it.
568 const TemplateURL* default_url = providers_.GetDefaultProviderURL(); 555 const TemplateURL* default_url = providers_.GetDefaultProviderURL();
569 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); 556 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL();
570 if (profile_->IsOffTheRecord() || 557 if (delegate_->IsOffTheRecord() ||
571 ((!default_url || default_url->suggestions_url().empty()) && 558 ((!default_url || default_url->suggestions_url().empty()) &&
572 (!keyword_url || keyword_url->suggestions_url().empty())) || 559 (!keyword_url || keyword_url->suggestions_url().empty())) ||
573 !profile_->GetPrefs()->GetBoolean(prefs::kSearchSuggestEnabled)) 560 !delegate_->SearchSuggestEnabled())
574 return false; 561 return false;
575 562
576 // If the input type might be a URL, we take extra care so that private data 563 // If the input type might be a URL, we take extra care so that private data
577 // isn't sent to the server. 564 // isn't sent to the server.
578 565
579 // FORCED_QUERY means the user is explicitly asking us to search for this, so 566 // FORCED_QUERY means the user is explicitly asking us to search for this, so
580 // we assume it isn't a URL and/or there isn't private data. 567 // we assume it isn't a URL and/or there isn't private data.
581 if (input_.type() == metrics::OmniboxInputType::FORCED_QUERY) 568 if (input_.type() == metrics::OmniboxInputType::FORCED_QUERY)
582 return true; 569 return true;
583 570
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 } 671 }
685 GURL suggest_url(template_url->suggestions_url_ref().ReplaceSearchTerms( 672 GURL suggest_url(template_url->suggestions_url_ref().ReplaceSearchTerms(
686 search_term_args, 673 search_term_args,
687 providers_.template_url_service()->search_terms_data())); 674 providers_.template_url_service()->search_terms_data()));
688 if (!suggest_url.is_valid()) 675 if (!suggest_url.is_valid())
689 return NULL; 676 return NULL;
690 // Send the current page URL if user setting and URL requirements are met and 677 // Send the current page URL if user setting and URL requirements are met and
691 // the user is in the field trial. 678 // the user is in the field trial.
692 if (CanSendURL(current_page_url_, suggest_url, template_url, 679 if (CanSendURL(current_page_url_, suggest_url, template_url,
693 input.current_page_classification(), 680 input.current_page_classification(),
694 template_url_service_->search_terms_data(), profile_) && 681 template_url_service_->search_terms_data(), delegate_.get()) &&
695 OmniboxFieldTrial::InZeroSuggestAfterTypingFieldTrial()) { 682 OmniboxFieldTrial::InZeroSuggestAfterTypingFieldTrial()) {
696 search_term_args.current_page_url = current_page_url_.spec(); 683 search_term_args.current_page_url = current_page_url_.spec();
697 // Create the suggest URL again with the current page URL. 684 // Create the suggest URL again with the current page URL.
698 suggest_url = GURL(template_url->suggestions_url_ref().ReplaceSearchTerms( 685 suggest_url = GURL(template_url->suggestions_url_ref().ReplaceSearchTerms(
699 search_term_args, 686 search_term_args,
700 providers_.template_url_service()->search_terms_data())); 687 providers_.template_url_service()->search_terms_data()));
701 } 688 }
702 689
703 suggest_results_pending_++; 690 suggest_results_pending_++;
704 LogOmniboxSuggestRequest(REQUEST_SENT); 691 LogOmniboxSuggestRequest(REQUEST_SENT);
705 692
706 net::URLFetcher* fetcher = 693 net::URLFetcher* fetcher =
707 net::URLFetcher::Create(id, suggest_url, net::URLFetcher::GET, this); 694 net::URLFetcher::Create(id, suggest_url, net::URLFetcher::GET, this);
708 fetcher->SetRequestContext(profile_->GetRequestContext()); 695 fetcher->SetRequestContext(delegate_->RequestContext());
709 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); 696 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES);
710 // Add Chrome experiment state to the request headers. 697 // Add Chrome experiment state to the request headers.
711 net::HttpRequestHeaders headers; 698 net::HttpRequestHeaders headers;
712 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders( 699 variations::VariationsHttpHeaderProvider::GetInstance()->AppendHeaders(
713 fetcher->GetOriginalURL(), profile_->IsOffTheRecord(), false, &headers); 700 fetcher->GetOriginalURL(), delegate_->IsOffTheRecord(), false, &headers);
714 fetcher->SetExtraRequestHeaders(headers.ToString()); 701 fetcher->SetExtraRequestHeaders(headers.ToString());
715 fetcher->Start(); 702 fetcher->Start();
716 return fetcher; 703 return fetcher;
717 } 704 }
718 705
719 void SearchProvider::ConvertResultsToAutocompleteMatches() { 706 void SearchProvider::ConvertResultsToAutocompleteMatches() {
720 // Convert all the results to matches and add them to a map, so we can keep 707 // Convert all the results to matches and add them to a map, so we can keep
721 // the most relevant match for each result. 708 // the most relevant match for each result.
722 base::TimeTicks start_time(base::TimeTicks::Now()); 709 base::TimeTicks start_time(base::TimeTicks::Now());
723 MatchMap map; 710 MatchMap map;
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 // NOTE: We don't check for autocompleting to URLs in the following cases: 973 // NOTE: We don't check for autocompleting to URLs in the following cases:
987 // * When inline autocomplete is disabled, we won't be inline autocompleting 974 // * When inline autocomplete is disabled, we won't be inline autocompleting
988 // this term, so we don't need to worry about confusion as much. This 975 // this term, so we don't need to worry about confusion as much. This
989 // also prevents calling Classify() again from inside the classifier 976 // also prevents calling Classify() again from inside the classifier
990 // (which will corrupt state and likely crash), since the classifier 977 // (which will corrupt state and likely crash), since the classifier
991 // always disables inline autocomplete. 978 // always disables inline autocomplete.
992 // * When the user has typed the whole string before as a query, then it's 979 // * When the user has typed the whole string before as a query, then it's
993 // likely the user has no expectation that term should be interpreted as 980 // likely the user has no expectation that term should be interpreted as
994 // as a URL, so we need not do anything special to preserve user 981 // as a URL, so we need not do anything special to preserve user
995 // expectation. 982 // expectation.
996 AutocompleteClassifier* classifier =
997 AutocompleteClassifierFactory::GetForProfile(profile_);
998 int last_relevance = 0; 983 int last_relevance = 0;
999 if (!base_prevent_inline_autocomplete && !found_what_you_typed_match && 984 if (!base_prevent_inline_autocomplete && !found_what_you_typed_match &&
1000 classifier && (scored_results.front().relevance() >= 1200)) { 985 scored_results.front().relevance() >= 1200) {
1001 AutocompleteMatch match; 986 AutocompleteMatch match;
1002 classifier->Classify(scored_results.front().suggestion(), false, false, 987 delegate_->Classify(scored_results.front().suggestion(), false, false,
1003 input_.current_page_classification(), &match, NULL); 988 input_.current_page_classification(), &match, NULL);
1004 // Demote this match that would normally be interpreted as a URL to have 989 // Demote this match that would normally be interpreted as a URL to have
1005 // the highest score a previously-issued search query could have when 990 // the highest score a previously-issued search query could have when
1006 // scoring with the non-aggressive method. A consequence of demoting 991 // scoring with the non-aggressive method. A consequence of demoting
1007 // by revising |last_relevance| is that this match and all following 992 // by revising |last_relevance| is that this match and all following
1008 // matches get demoted; the relative order of matches is preserved. 993 // matches get demoted; the relative order of matches is preserved.
1009 // One could imagine demoting only those matches that might cause 994 // One could imagine demoting only those matches that might cause
1010 // confusion (which, by the way, might change the relative order of 995 // confusion (which, by the way, might change the relative order of
1011 // matches. We have decided to go with the simple demote-all approach 996 // matches. We have decided to go with the simple demote-all approach
1012 // because selective demotion requires multiple Classify() calls and 997 // because selective demotion requires multiple Classify() calls and
1013 // such calls can be expensive (as expensive as running the whole 998 // such calls can be expensive (as expensive as running the whole
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 // scheme. 1148 // scheme.
1164 const URLPrefix* prefix = 1149 const URLPrefix* prefix =
1165 URLPrefix::BestURLPrefix(navigation.formatted_url(), input); 1150 URLPrefix::BestURLPrefix(navigation.formatted_url(), input);
1166 size_t match_start = (prefix == NULL) ? 1151 size_t match_start = (prefix == NULL) ?
1167 navigation.formatted_url().find(input) : prefix->prefix.length(); 1152 navigation.formatted_url().find(input) : prefix->prefix.length();
1168 bool trim_http = !AutocompleteInput::HasHTTPScheme(input) && 1153 bool trim_http = !AutocompleteInput::HasHTTPScheme(input) &&
1169 (!prefix || (match_start != 0)); 1154 (!prefix || (match_start != 0));
1170 const net::FormatUrlTypes format_types = 1155 const net::FormatUrlTypes format_types =
1171 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP); 1156 net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP);
1172 1157
1173 const std::string languages( 1158 const std::string languages(delegate_->AcceptLanguages());
1174 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
1175 size_t inline_autocomplete_offset = (prefix == NULL) ? 1159 size_t inline_autocomplete_offset = (prefix == NULL) ?
1176 base::string16::npos : (match_start + input.length()); 1160 base::string16::npos : (match_start + input.length());
1177 match.fill_into_edit += 1161 match.fill_into_edit +=
1178 AutocompleteInput::FormattedStringWithEquivalentMeaning( 1162 AutocompleteInput::FormattedStringWithEquivalentMeaning(
1179 navigation.url(), 1163 navigation.url(),
1180 net::FormatUrl(navigation.url(), languages, format_types, 1164 net::FormatUrl(navigation.url(), languages, format_types,
1181 net::UnescapeRule::SPACES, NULL, NULL, 1165 net::UnescapeRule::SPACES, NULL, NULL,
1182 &inline_autocomplete_offset), 1166 &inline_autocomplete_offset),
1183 ChromeAutocompleteSchemeClassifier(profile_)); 1167 delegate_->SchemeClassifier());
1184 // Preserve the forced query '?' prefix in |match.fill_into_edit|. 1168 // Preserve the forced query '?' prefix in |match.fill_into_edit|.
1185 // Otherwise, user edits to a suggestion would show non-Search results. 1169 // Otherwise, user edits to a suggestion would show non-Search results.
1186 if (input_.type() == metrics::OmniboxInputType::FORCED_QUERY) { 1170 if (input_.type() == metrics::OmniboxInputType::FORCED_QUERY) {
1187 match.fill_into_edit.insert(0, base::ASCIIToUTF16("?")); 1171 match.fill_into_edit.insert(0, base::ASCIIToUTF16("?"));
1188 if (inline_autocomplete_offset != base::string16::npos) 1172 if (inline_autocomplete_offset != base::string16::npos)
1189 ++inline_autocomplete_offset; 1173 ++inline_autocomplete_offset;
1190 } 1174 }
1191 if (inline_autocomplete_offset != base::string16::npos) { 1175 if (inline_autocomplete_offset != base::string16::npos) {
1192 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length()); 1176 DCHECK(inline_autocomplete_offset <= match.fill_into_edit.length());
1193 match.inline_autocompletion = 1177 match.inline_autocompletion =
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 match->fill_into_edit.empty()) 1247 match->fill_into_edit.empty())
1264 return; 1248 return;
1265 1249
1266 // Valid answer encountered, cache it for further queries. 1250 // Valid answer encountered, cache it for further queries.
1267 answers_cache_.UpdateRecentAnswers(match->fill_into_edit, match->answer_type); 1251 answers_cache_.UpdateRecentAnswers(match->fill_into_edit, match->answer_type);
1268 } 1252 }
1269 1253
1270 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) { 1254 void SearchProvider::DoAnswersQuery(const AutocompleteInput& input) {
1271 prefetch_data_ = answers_cache_.GetTopAnswerEntry(input.text()); 1255 prefetch_data_ = answers_cache_.GetTopAnswerEntry(input.text());
1272 } 1256 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698