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" |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |