| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/callback.h" | 10 #include "base/callback.h" | 
|  | 11 #include "base/i18n/break_iterator.h" | 
| 11 #include "base/i18n/case_conversion.h" | 12 #include "base/i18n/case_conversion.h" | 
| 12 #include "base/i18n/icu_string_conversions.h" | 13 #include "base/i18n/icu_string_conversions.h" | 
| 13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" | 
| 14 #include "base/string16.h" | 15 #include "base/string16.h" | 
| 15 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" | 
| 16 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | 17 #include "chrome/browser/autocomplete/autocomplete_classifier.h" | 
| 17 #include "chrome/browser/autocomplete/autocomplete_match.h" | 18 #include "chrome/browser/autocomplete/autocomplete_match.h" | 
| 18 #include "chrome/browser/autocomplete/keyword_provider.h" | 19 #include "chrome/browser/autocomplete/keyword_provider.h" | 
| 19 #include "chrome/browser/history/history.h" | 20 #include "chrome/browser/history/history.h" | 
| 20 #include "chrome/browser/instant/instant_controller.h" | 21 #include "chrome/browser/instant/instant_controller.h" | 
| 21 #include "chrome/browser/net/url_fixer_upper.h" | 22 #include "chrome/browser/net/url_fixer_upper.h" | 
| 22 #include "chrome/browser/prefs/pref_service.h" | 23 #include "chrome/browser/prefs/pref_service.h" | 
| 23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" | 
| 24 #include "chrome/browser/history/in_memory_database.h" | 25 #include "chrome/browser/history/in_memory_database.h" | 
| 25 #include "chrome/browser/search_engines/template_url_service.h" | 26 #include "chrome/browser/search_engines/template_url_service.h" | 
| 26 #include "chrome/browser/search_engines/template_url_service_factory.h" | 27 #include "chrome/browser/search_engines/template_url_service_factory.h" | 
| 27 #include "chrome/common/pref_names.h" | 28 #include "chrome/common/pref_names.h" | 
| 28 #include "chrome/common/url_constants.h" | 29 #include "chrome/common/url_constants.h" | 
| 29 #include "content/common/json_value_serializer.h" | 30 #include "content/common/json_value_serializer.h" | 
| 30 #include "googleurl/src/url_util.h" | 31 #include "googleurl/src/url_util.h" | 
| 31 #include "grit/generated_resources.h" | 32 #include "grit/generated_resources.h" | 
| 32 #include "net/base/escape.h" | 33 #include "net/base/escape.h" | 
| 33 #include "net/http/http_response_headers.h" | 34 #include "net/http/http_response_headers.h" | 
| 34 #include "net/url_request/url_request_status.h" | 35 #include "net/url_request/url_request_status.h" | 
| 35 #include "ui/base/l10n/l10n_util.h" | 36 #include "ui/base/l10n/l10n_util.h" | 
| 36 | 37 | 
| 37 using base::Time; | 38 using base::Time; | 
| 38 using base::TimeDelta; | 39 using base::TimeDelta; | 
| 39 | 40 | 
|  | 41 namespace { | 
|  | 42 | 
|  | 43 bool HasMultipleWords(const string16& text) { | 
|  | 44   base::i18n::BreakIterator i(text, base::i18n::BreakIterator::BREAK_WORD); | 
|  | 45   bool found_word = false; | 
|  | 46   if (i.Init()) { | 
|  | 47     while (i.Advance()) { | 
|  | 48       if (i.IsWord()) { | 
|  | 49         if (found_word) | 
|  | 50           return true; | 
|  | 51         found_word = true; | 
|  | 52       } | 
|  | 53     } | 
|  | 54   } | 
|  | 55   return false; | 
|  | 56 } | 
|  | 57 | 
|  | 58 }; | 
|  | 59 | 
| 40 // static | 60 // static | 
| 41 const int SearchProvider::kDefaultProviderURLFetcherID = 1; | 61 const int SearchProvider::kDefaultProviderURLFetcherID = 1; | 
| 42 // static | 62 // static | 
| 43 const int SearchProvider::kKeywordProviderURLFetcherID = 2; | 63 const int SearchProvider::kKeywordProviderURLFetcherID = 2; | 
| 44 | 64 | 
| 45 // static | 65 // static | 
| 46 bool SearchProvider::query_suggest_immediately_ = false; | 66 bool SearchProvider::query_suggest_immediately_ = false; | 
| 47 | 67 | 
| 48 void SearchProvider::Providers::Set(const TemplateURL* default_provider, | 68 void SearchProvider::Providers::Set(const TemplateURL* default_provider, | 
| 49                                     const TemplateURL* keyword_provider) { | 69                                     const TemplateURL* keyword_provider) { | 
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 180     return; | 200     return; | 
| 181   } | 201   } | 
| 182 | 202 | 
| 183   input_ = input; | 203   input_ = input; | 
| 184 | 204 | 
| 185   DoHistoryQuery(minimal_changes); | 205   DoHistoryQuery(minimal_changes); | 
| 186   StartOrStopSuggestQuery(minimal_changes); | 206   StartOrStopSuggestQuery(minimal_changes); | 
| 187   ConvertResultsToAutocompleteMatches(); | 207   ConvertResultsToAutocompleteMatches(); | 
| 188 } | 208 } | 
| 189 | 209 | 
|  | 210 class SearchProvider::CompareScoredTerms { | 
|  | 211  public: | 
|  | 212   bool operator()(const ScoredTerm& a, const ScoredTerm& b) { | 
|  | 213     // Sort in descending relevance order. | 
|  | 214     return a.second > b.second; | 
|  | 215   } | 
|  | 216 }; | 
|  | 217 | 
| 190 void SearchProvider::Run() { | 218 void SearchProvider::Run() { | 
| 191   // Start a new request with the current input. | 219   // Start a new request with the current input. | 
| 192   DCHECK(!done_); | 220   DCHECK(!done_); | 
| 193   suggest_results_pending_ = 0; | 221   suggest_results_pending_ = 0; | 
| 194   if (providers_.valid_suggest_for_keyword_provider()) { | 222   if (providers_.valid_suggest_for_keyword_provider()) { | 
| 195     suggest_results_pending_++; | 223     suggest_results_pending_++; | 
| 196     keyword_fetcher_.reset( | 224     keyword_fetcher_.reset( | 
| 197         CreateSuggestFetcher(kKeywordProviderURLFetcherID, | 225         CreateSuggestFetcher(kKeywordProviderURLFetcherID, | 
| 198                              providers_.keyword_provider(), | 226                              providers_.keyword_provider(), | 
| 199                              keyword_input_text_)); | 227                              keyword_input_text_)); | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 274   keyword_history_results_.clear(); | 302   keyword_history_results_.clear(); | 
| 275   default_history_results_.clear(); | 303   default_history_results_.clear(); | 
| 276 | 304 | 
| 277   HistoryService* const history_service = | 305   HistoryService* const history_service = | 
| 278       profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 306       profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 
| 279   history::URLDatabase* url_db = history_service ? | 307   history::URLDatabase* url_db = history_service ? | 
| 280       history_service->InMemoryDatabase() : NULL; | 308       history_service->InMemoryDatabase() : NULL; | 
| 281   if (!url_db) | 309   if (!url_db) | 
| 282     return; | 310     return; | 
| 283 | 311 | 
| 284   // Request history for both the keyword and default provider. | 312   // Request history for both the keyword and default provider.  We grab many | 
|  | 313   // more matches than we'll ultimately clamp to so that if there are several | 
|  | 314   // recent multi-word matches who scores are lowered (see | 
|  | 315   // AddHistoryResultsToMap()), they won't crowd out older, higher-scoring | 
|  | 316   // matches.  Note that this doesn't fix the problem entirely, but merely | 
|  | 317   // limits it to cases with a very large number of such multi-word matches; for | 
|  | 318   // now, this seems OK compared with the complexity of a real fix, which would | 
|  | 319   // require multiple searches and tracking of "single- vs. multi-word" in the | 
|  | 320   // database. | 
|  | 321   int num_matches = kMaxMatches * 5; | 
| 285   if (providers_.valid_keyword_provider()) { | 322   if (providers_.valid_keyword_provider()) { | 
| 286     url_db->GetMostRecentKeywordSearchTerms( | 323     url_db->GetMostRecentKeywordSearchTerms(providers_.keyword_provider().id(), | 
| 287         providers_.keyword_provider().id(), | 324         keyword_input_text_, num_matches, &keyword_history_results_); | 
| 288         keyword_input_text_, |  | 
| 289         static_cast<int>(kMaxMatches), |  | 
| 290         &keyword_history_results_); |  | 
| 291   } | 325   } | 
| 292   if (providers_.valid_default_provider()) { | 326   if (providers_.valid_default_provider()) { | 
| 293     url_db->GetMostRecentKeywordSearchTerms( | 327     url_db->GetMostRecentKeywordSearchTerms(providers_.default_provider().id(), | 
| 294         providers_.default_provider().id(), | 328         input_.text(), num_matches, &default_history_results_); | 
| 295         input_.text(), |  | 
| 296         static_cast<int>(kMaxMatches), |  | 
| 297         &default_history_results_); |  | 
| 298   } | 329   } | 
| 299 } | 330 } | 
| 300 | 331 | 
| 301 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { | 332 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { | 
| 302   // Don't send any queries to the server until some time has elapsed after | 333   // Don't send any queries to the server until some time has elapsed after | 
| 303   // the last keypress, to avoid flooding the server with requests we are | 334   // the last keypress, to avoid flooding the server with requests we are | 
| 304   // likely to end up throwing away anyway. | 335   // likely to end up throwing away anyway. | 
| 305   static const int kQueryDelayMs = 200; | 336   static const int kQueryDelayMs = 200; | 
| 306 | 337 | 
| 307   if (!IsQuerySuitableForSuggest()) { | 338   if (!IsQuerySuitableForSuggest()) { | 
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 580     matches_.push_back(NavigationToMatch(navigation_results.front(), | 611     matches_.push_back(NavigationToMatch(navigation_results.front(), | 
| 581         CalculateRelevanceForNavigation(num_results, 0, is_keyword), | 612         CalculateRelevanceForNavigation(num_results, 0, is_keyword), | 
| 582         is_keyword)); | 613         is_keyword)); | 
| 583   } | 614   } | 
| 584 } | 615 } | 
| 585 | 616 | 
| 586 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, | 617 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, | 
| 587                                             bool is_keyword, | 618                                             bool is_keyword, | 
| 588                                             int did_not_accept_suggestion, | 619                                             int did_not_accept_suggestion, | 
| 589                                             MatchMap* map) { | 620                                             MatchMap* map) { | 
| 590   int last_relevance = 0; | 621   if (results.empty()) | 
|  | 622     return; | 
|  | 623 | 
|  | 624   bool base_prevent_inline_autocomplete = | 
|  | 625       (input_.type() == AutocompleteInput::URL) || | 
|  | 626       input_.prevent_inline_autocomplete(); | 
|  | 627   const string16& input_text( | 
|  | 628       is_keyword ? keyword_input_text_ : input_.text()); | 
|  | 629   bool input_multiple_words = HasMultipleWords(input_text); | 
|  | 630 | 
|  | 631   ScoredTerms scored_terms; | 
|  | 632   if (!base_prevent_inline_autocomplete && input_multiple_words) { | 
|  | 633     // ScoreHistoryTerms() allows autocompletion of multi-word, 1-visit queries | 
|  | 634     // if the input also has multiple words.  But if we were already | 
|  | 635     // autocompleting a multi-word, multi-visit query, and the current input is | 
|  | 636     // still a prefix of it, then changing the autocompletion suddenly feels | 
|  | 637     // wrong.  To detect this case, first score as if only one word has been | 
|  | 638     // typed, then check for a best result that is an autocompleted, multi-word | 
|  | 639     // query.  If we find one, then just keep that score set. | 
|  | 640     scored_terms = ScoreHistoryTerms(results, base_prevent_inline_autocomplete, | 
|  | 641                                      false, input_text, is_keyword); | 
|  | 642     if ((scored_terms[0].second < AutocompleteResult::kLowestDefaultScore) || | 
|  | 643         !HasMultipleWords(scored_terms[0].first)) | 
|  | 644       scored_terms.clear();  // Didn't detect the case above, score normally. | 
|  | 645   } | 
|  | 646   if (scored_terms.empty()) | 
|  | 647     scored_terms = ScoreHistoryTerms(results, base_prevent_inline_autocomplete, | 
|  | 648                                      input_multiple_words, input_text, | 
|  | 649                                      is_keyword); | 
|  | 650   for (ScoredTerms::const_iterator i(scored_terms.begin()); | 
|  | 651        i != scored_terms.end(); ++i) { | 
|  | 652     AddMatchToMap(i->first, input_text, i->second, | 
|  | 653                   AutocompleteMatch::SEARCH_HISTORY, did_not_accept_suggestion, | 
|  | 654                   is_keyword, input_.prevent_inline_autocomplete(), map); | 
|  | 655   } | 
|  | 656 } | 
|  | 657 | 
|  | 658 SearchProvider::ScoredTerms SearchProvider::ScoreHistoryTerms( | 
|  | 659     const HistoryResults& results, | 
|  | 660     bool base_prevent_inline_autocomplete, | 
|  | 661     bool input_multiple_words, | 
|  | 662     const string16& input_text, | 
|  | 663     bool is_keyword) { | 
| 591   AutocompleteClassifier* classifier = profile_->GetAutocompleteClassifier(); | 664   AutocompleteClassifier* classifier = profile_->GetAutocompleteClassifier(); | 
|  | 665   ScoredTerms scored_terms; | 
| 592   for (HistoryResults::const_iterator i(results.begin()); i != results.end(); | 666   for (HistoryResults::const_iterator i(results.begin()); i != results.end(); | 
| 593        ++i) { | 667        ++i) { | 
| 594     // History returns results sorted for us. We force the relevance to decrease | 668     // Don't autocomplete multi-word queries that have only been seen once | 
| 595     // so that the sort from history is honored. We should never end up with a | 669     // unless the user has typed more than one word. | 
| 596     // match having a relevance greater than the previous, but they might be | 670     bool prevent_inline_autocomplete = base_prevent_inline_autocomplete || | 
| 597     // equal. If we didn't force the relevance to decrease and we ended up in a | 671         (!input_multiple_words && (i->visits < 2) && HasMultipleWords(i->term)); | 
| 598     // situation where the relevance was equal, then which was shown first would | 672 | 
| 599     // be random. |  | 
| 600     // This uses >= to handle the case where 3 or more results have the same |  | 
| 601     // relevance. |  | 
| 602     bool term_looks_like_url = false; |  | 
| 603     // Don't autocomplete search terms that would normally be treated as URLs | 673     // Don't autocomplete search terms that would normally be treated as URLs | 
| 604     // when typed. For example, if the user searched for google.com and types | 674     // when typed. For example, if the user searched for "google.com" and types | 
| 605     // goog, don't autocomplete to the search term google.com. Otherwise, the | 675     // "goog", don't autocomplete to the search term "google.com". Otherwise, | 
| 606     // input will look like a URL but act like a search, which is confusing. | 676     // the input will look like a URL but act like a search, which is confusing. | 
| 607     // NOTE: We don't check this in the following cases: | 677     // NOTE: We don't check this in the following cases: | 
| 608     //  * When inline autocomplete is disabled, we won't be inline | 678     //  * When inline autocomplete is disabled, we won't be inline | 
| 609     //    autocompleting this term, so we don't need to worry about confusion as | 679     //    autocompleting this term, so we don't need to worry about confusion as | 
| 610     //    much.  This also prevents calling Classify() again from inside the | 680     //    much.  This also prevents calling Classify() again from inside the | 
| 611     //    classifier (which will corrupt state and likely crash), since the | 681     //    classifier (which will corrupt state and likely crash), since the | 
| 612     //    classifier always disabled inline autocomplete. | 682     //    classifier always disables inline autocomplete. | 
| 613     //  * When the user has typed the whole term, the "what you typed" history | 683     //  * When the user has typed the whole term, the "what you typed" history | 
| 614     //    match will outrank us for URL-like inputs anyway, so we need not do | 684     //    match will outrank us for URL-like inputs anyway, so we need not do | 
| 615     //    anything special. | 685     //    anything special. | 
| 616     if (!input_.prevent_inline_autocomplete() && classifier && | 686     if (!prevent_inline_autocomplete && classifier && (i->term != input_text)) { | 
| 617         i->term != input_.text()) { |  | 
| 618       AutocompleteMatch match; | 687       AutocompleteMatch match; | 
| 619       classifier->Classify(i->term, string16(), false, false, &match, NULL); | 688       classifier->Classify(i->term, string16(), false, false, &match, NULL); | 
| 620       term_looks_like_url = match.transition == PageTransition::TYPED; | 689       prevent_inline_autocomplete = match.transition == PageTransition::TYPED; | 
| 621     } | 690     } | 
| 622     int relevance = CalculateRelevanceForHistory(i->time, term_looks_like_url, | 691 | 
| 623                                                  is_keyword); | 692     int relevance = CalculateRelevanceForHistory(i->time, is_keyword, | 
| 624     if (i != results.begin() && relevance >= last_relevance) | 693                                                  prevent_inline_autocomplete); | 
| 625       relevance = last_relevance - 1; | 694     scored_terms.push_back(std::make_pair(i->term, relevance)); | 
| 626     last_relevance = relevance; |  | 
| 627     AddMatchToMap(i->term, |  | 
| 628                   is_keyword ? keyword_input_text_ : input_.text(), |  | 
| 629                   relevance, |  | 
| 630                   AutocompleteMatch::SEARCH_HISTORY, did_not_accept_suggestion, |  | 
| 631                   is_keyword, input_.prevent_inline_autocomplete(), |  | 
| 632                   map); |  | 
| 633   } | 695   } | 
|  | 696 | 
|  | 697   // History returns results sorted for us.  However, we may have docked some | 
|  | 698   // results' scores, so things are no longer in order.  Do a stable sort to get | 
|  | 699   // things back in order without otherwise disturbing results with equal | 
|  | 700   // scores, then force the scores to be unique, so that the order in which | 
|  | 701   // they're shown is deterministic. | 
|  | 702   std::stable_sort(scored_terms.begin(), scored_terms.end(), | 
|  | 703                    CompareScoredTerms()); | 
|  | 704   int last_relevance = 0; | 
|  | 705   for (ScoredTerms::iterator i(scored_terms.begin()); i != scored_terms.end(); | 
|  | 706        ++i) { | 
|  | 707     if ((i != scored_terms.begin()) && (i->second >= last_relevance)) | 
|  | 708       i->second = last_relevance - 1; | 
|  | 709     last_relevance = i->second; | 
|  | 710   } | 
|  | 711 | 
|  | 712   return scored_terms; | 
| 634 } | 713 } | 
| 635 | 714 | 
| 636 void SearchProvider::AddSuggestResultsToMap( | 715 void SearchProvider::AddSuggestResultsToMap( | 
| 637     const SuggestResults& suggest_results, | 716     const SuggestResults& suggest_results, | 
| 638     bool is_keyword, | 717     bool is_keyword, | 
| 639     int did_not_accept_suggestion, | 718     int did_not_accept_suggestion, | 
| 640     MatchMap* map) { | 719     MatchMap* map) { | 
| 641   for (size_t i = 0; i < suggest_results.size(); ++i) { | 720   for (size_t i = 0; i < suggest_results.size(); ++i) { | 
| 642     AddMatchToMap(suggest_results[i], | 721     AddMatchToMap(suggest_results[i], | 
| 643                   is_keyword ? keyword_input_text_ : input_.text(), | 722                   is_keyword ? keyword_input_text_ : input_.text(), | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 664 | 743 | 
| 665     case AutocompleteInput::URL: | 744     case AutocompleteInput::URL: | 
| 666       return 850; | 745       return 850; | 
| 667 | 746 | 
| 668     default: | 747     default: | 
| 669       NOTREACHED(); | 748       NOTREACHED(); | 
| 670       return 0; | 749       return 0; | 
| 671   } | 750   } | 
| 672 } | 751 } | 
| 673 | 752 | 
| 674 int SearchProvider::CalculateRelevanceForHistory(const Time& time, | 753 int SearchProvider::CalculateRelevanceForHistory( | 
| 675                                                  bool looks_like_url, | 754     const Time& time, | 
| 676                                                  bool is_keyword) const { | 755     bool is_keyword, | 
|  | 756     bool prevent_inline_autocomplete) const { | 
| 677   // The relevance of past searches falls off over time. There are two distinct | 757   // The relevance of past searches falls off over time. There are two distinct | 
| 678   // equations used. If the first equation is used (searches to the primary | 758   // equations used. If the first equation is used (searches to the primary | 
| 679   // provider with a type other than URL that don't autocomplete to a url) the | 759   // provider that we want to inline autocomplete), the score starts at 1399 and | 
| 680   // score starts at 1399 and falls to 1300. If the second equation is used the | 760   // falls to 1300. If the second equation is used the relevance of a search 15 | 
| 681   // relevance of a search 15 minutes ago is discounted about 50 points, while | 761   // minutes ago is discounted 50 points, while the relevance of a search two | 
| 682   // the relevance of a search two weeks ago is discounted about 450 points. | 762   // weeks ago is discounted 450 points. | 
| 683   double elapsed_time = std::max((Time::Now() - time).InSecondsF(), 0.); | 763   double elapsed_time = std::max((Time::Now() - time).InSecondsF(), 0.); | 
| 684 | 764   bool is_primary_provider = providers_.is_primary_provider(is_keyword); | 
| 685   if (providers_.is_primary_provider(is_keyword) && | 765   if (is_primary_provider && !prevent_inline_autocomplete) { | 
| 686       input_.type() != AutocompleteInput::URL && |  | 
| 687       !input_.prevent_inline_autocomplete() && !looks_like_url) { |  | 
| 688     // Searches with the past two days get a different curve. | 766     // Searches with the past two days get a different curve. | 
| 689     const double autocomplete_time= 2 * 24 * 60 * 60; | 767     const double autocomplete_time = 2 * 24 * 60 * 60; | 
| 690     if (elapsed_time < autocomplete_time) { | 768     if (elapsed_time < autocomplete_time) { | 
| 691       return (is_keyword ? 1599 : 1399) - static_cast<int>(99 * | 769       return (is_keyword ? 1599 : 1399) - static_cast<int>(99 * | 
| 692           std::pow(elapsed_time / autocomplete_time, 2.5)); | 770           std::pow(elapsed_time / autocomplete_time, 2.5)); | 
| 693     } | 771     } | 
| 694     elapsed_time -= autocomplete_time; | 772     elapsed_time -= autocomplete_time; | 
| 695   } | 773   } | 
| 696 | 774 | 
| 697   const int score_discount = | 775   const int score_discount = | 
| 698       static_cast<int>(6.5 * std::pow(elapsed_time, 0.3)); | 776       static_cast<int>(6.5 * std::pow(elapsed_time, 0.3)); | 
| 699 | 777 | 
| 700   // Don't let scores go below 0.  Negative relevance scores are meaningful in | 778   // Don't let scores go below 0.  Negative relevance scores are meaningful in | 
| 701   // a different way. | 779   // a different way. | 
| 702   int base_score; | 780   int base_score; | 
| 703   if (!providers_.is_primary_provider(is_keyword)) | 781   if (is_primary_provider) | 
|  | 782     base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050; | 
|  | 783   else | 
| 704     base_score = 200; | 784     base_score = 200; | 
| 705   else |  | 
| 706     base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050; |  | 
| 707   return std::max(0, base_score - score_discount); | 785   return std::max(0, base_score - score_discount); | 
| 708 } | 786 } | 
| 709 | 787 | 
| 710 int SearchProvider::CalculateRelevanceForSuggestion(size_t num_results, | 788 int SearchProvider::CalculateRelevanceForSuggestion(size_t num_results, | 
| 711                                                     size_t result_number, | 789                                                     size_t result_number, | 
| 712                                                     bool is_keyword) const { | 790                                                     bool is_keyword) const { | 
| 713   DCHECK(result_number < num_results); | 791   DCHECK(result_number < num_results); | 
| 714   int base_score; | 792   int base_score; | 
| 715   if (!providers_.is_primary_provider(is_keyword)) | 793   if (!providers_.is_primary_provider(is_keyword)) | 
| 716     base_score = 100; | 794     base_score = 100; | 
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 868 | 946 | 
| 869   return match; | 947   return match; | 
| 870 } | 948 } | 
| 871 | 949 | 
| 872 void SearchProvider::UpdateDone() { | 950 void SearchProvider::UpdateDone() { | 
| 873   // We're done when there are no more suggest queries pending (this is set to 1 | 951   // We're done when there are no more suggest queries pending (this is set to 1 | 
| 874   // when the timer is started) and we're not waiting on instant. | 952   // when the timer is started) and we're not waiting on instant. | 
| 875   done_ = ((suggest_results_pending_ == 0) && | 953   done_ = ((suggest_results_pending_ == 0) && | 
| 876            (instant_finalized_ || !InstantController::IsEnabled(profile_))); | 954            (instant_finalized_ || !InstantController::IsEnabled(profile_))); | 
| 877 } | 955 } | 
| OLD | NEW | 
|---|