| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "base/i18n/icu_string_conversions.h" | 8 #include "base/i18n/icu_string_conversions.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 done_ = !history_request_pending_ && !suggest_results_pending_; | 514 done_ = !history_request_pending_ && !suggest_results_pending_; |
| 515 } | 515 } |
| 516 | 516 |
| 517 void SearchProvider::AddNavigationResultsToMatches( | 517 void SearchProvider::AddNavigationResultsToMatches( |
| 518 const NavigationResults& navigation_results, | 518 const NavigationResults& navigation_results, |
| 519 bool is_keyword) { | 519 bool is_keyword) { |
| 520 if (!navigation_results.empty()) { | 520 if (!navigation_results.empty()) { |
| 521 // TODO(kochi): http://b/1170574 We add only one results for navigational | 521 // TODO(kochi): http://b/1170574 We add only one results for navigational |
| 522 // suggestions. If we can get more useful information about the score, | 522 // suggestions. If we can get more useful information about the score, |
| 523 // consider adding more results. | 523 // consider adding more results. |
| 524 matches_.push_back( | 524 const size_t num_results = is_keyword ? |
| 525 NavigationToMatch(navigation_results.front(), | 525 keyword_navigation_results_.size() : default_navigation_results_.size(); |
| 526 CalculateRelevanceForNavigation(0, is_keyword), | 526 matches_.push_back(NavigationToMatch(navigation_results.front(), |
| 527 is_keyword)); | 527 CalculateRelevanceForNavigation(num_results, 0, is_keyword), |
| 528 is_keyword)); |
| 528 } | 529 } |
| 529 } | 530 } |
| 530 | 531 |
| 531 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, | 532 void SearchProvider::AddHistoryResultsToMap(const HistoryResults& results, |
| 532 bool is_keyword, | 533 bool is_keyword, |
| 533 int did_not_accept_suggestion, | 534 int did_not_accept_suggestion, |
| 534 MatchMap* map) { | 535 MatchMap* map) { |
| 535 for (HistoryResults::const_iterator i(results.begin()); i != results.end(); | 536 for (HistoryResults::const_iterator i(results.begin()); i != results.end(); |
| 536 ++i) { | 537 ++i) { |
| 537 AddMatchToMap(i->term, CalculateRelevanceForHistory(i->time, is_keyword), | 538 AddMatchToMap(i->term, CalculateRelevanceForHistory(i->time, is_keyword), |
| 538 AutocompleteMatch::SEARCH_HISTORY, did_not_accept_suggestion, | 539 AutocompleteMatch::SEARCH_HISTORY, did_not_accept_suggestion, |
| 539 is_keyword, map); | 540 is_keyword, map); |
| 540 } | 541 } |
| 541 } | 542 } |
| 542 | 543 |
| 543 void SearchProvider::AddSuggestResultsToMap( | 544 void SearchProvider::AddSuggestResultsToMap( |
| 544 const SuggestResults& suggest_results, | 545 const SuggestResults& suggest_results, |
| 545 bool is_keyword, | 546 bool is_keyword, |
| 546 int did_not_accept_suggestion, | 547 int did_not_accept_suggestion, |
| 547 MatchMap* map) { | 548 MatchMap* map) { |
| 548 for (size_t i = 0; i < suggest_results.size(); ++i) { | 549 for (size_t i = 0; i < suggest_results.size(); ++i) { |
| 549 AddMatchToMap(suggest_results[i], | 550 AddMatchToMap(suggest_results[i], |
| 550 CalculateRelevanceForSuggestion(suggest_results, i, | 551 CalculateRelevanceForSuggestion(suggest_results.size(), i, |
| 551 is_keyword), | 552 is_keyword), |
| 552 AutocompleteMatch::SEARCH_SUGGEST, | 553 AutocompleteMatch::SEARCH_SUGGEST, |
| 553 static_cast<int>(i), is_keyword, map); | 554 static_cast<int>(i), is_keyword, map); |
| 554 } | 555 } |
| 555 } | 556 } |
| 556 | 557 |
| 557 int SearchProvider::CalculateRelevanceForWhatYouTyped() const { | 558 int SearchProvider::CalculateRelevanceForWhatYouTyped() const { |
| 559 if (providers_.valid_keyword_provider()) |
| 560 return 250; |
| 561 |
| 558 switch (input_.type()) { | 562 switch (input_.type()) { |
| 559 case AutocompleteInput::UNKNOWN: | 563 case AutocompleteInput::UNKNOWN: |
| 560 return providers_.valid_keyword_provider() ? 250 : 1300; | 564 case AutocompleteInput::QUERY: |
| 565 case AutocompleteInput::FORCED_QUERY: |
| 566 return 1300; |
| 561 | 567 |
| 562 case AutocompleteInput::REQUESTED_URL: | 568 case AutocompleteInput::REQUESTED_URL: |
| 563 return providers_.valid_keyword_provider() ? 250 : 1200; | 569 return 1150; |
| 564 | 570 |
| 565 case AutocompleteInput::URL: | 571 case AutocompleteInput::URL: |
| 566 return providers_.valid_keyword_provider() ? 250 : 850; | 572 return 850; |
| 567 | |
| 568 case AutocompleteInput::QUERY: | |
| 569 return providers_.valid_keyword_provider() ? 250 : 1300; | |
| 570 | |
| 571 case AutocompleteInput::FORCED_QUERY: | |
| 572 return providers_.valid_keyword_provider() ? 250 : 1500; | |
| 573 | 573 |
| 574 default: | 574 default: |
| 575 NOTREACHED(); | 575 NOTREACHED(); |
| 576 return 0; | 576 return 0; |
| 577 } | 577 } |
| 578 } | 578 } |
| 579 | 579 |
| 580 int SearchProvider::CalculateRelevanceForHistory(const Time& time, | 580 int SearchProvider::CalculateRelevanceForHistory(const Time& time, |
| 581 bool is_keyword) const { | 581 bool is_keyword) const { |
| 582 // The relevance of past searches falls off over time. This curve is chosen | 582 // The relevance of past searches falls off over time. This curve is chosen |
| 583 // so that the relevance of a search 15 minutes ago is discounted about 50 | 583 // so that the relevance of a search 15 minutes ago is discounted about 50 |
| 584 // points, while the relevance of a search two weeks ago is discounted about | 584 // points, while the relevance of a search two weeks ago is discounted about |
| 585 // 450 points. | 585 // 450 points. |
| 586 const double elapsed_time = std::max((Time::Now() - time).InSecondsF(), 0.); | 586 const double elapsed_time = std::max((Time::Now() - time).InSecondsF(), 0.); |
| 587 const int score_discount = static_cast<int>(6.5 * pow(elapsed_time, 0.3)); | 587 const int score_discount = static_cast<int>(6.5 * pow(elapsed_time, 0.3)); |
| 588 | 588 |
| 589 // Don't let scores go below 0. Negative relevance scores are meaningful in | 589 // Don't let scores go below 0. Negative relevance scores are meaningful in |
| 590 // a different way. | 590 // a different way. |
| 591 int base_score; | 591 int base_score; |
| 592 bool is_primary = providers_.is_primary_provider(is_keyword); | 592 if (!providers_.is_primary_provider(is_keyword)) |
| 593 switch (input_.type()) { | 593 base_score = 200; |
| 594 case AutocompleteInput::UNKNOWN: | 594 else |
| 595 case AutocompleteInput::REQUESTED_URL: | 595 base_score = (input_.type() == AutocompleteInput::URL) ? 750 : 1050; |
| 596 base_score = is_primary ? 1050 : 200; | |
| 597 break; | |
| 598 | |
| 599 case AutocompleteInput::URL: | |
| 600 base_score = is_primary ? 750 : 200; | |
| 601 break; | |
| 602 | |
| 603 case AutocompleteInput::QUERY: | |
| 604 case AutocompleteInput::FORCED_QUERY: | |
| 605 base_score = is_primary ? 1250 : 200; | |
| 606 break; | |
| 607 | |
| 608 default: | |
| 609 NOTREACHED(); | |
| 610 base_score = 0; | |
| 611 break; | |
| 612 } | |
| 613 return std::max(0, base_score - score_discount); | 596 return std::max(0, base_score - score_discount); |
| 614 } | 597 } |
| 615 | 598 |
| 616 int SearchProvider::CalculateRelevanceForSuggestion( | 599 int SearchProvider::CalculateRelevanceForSuggestion(size_t num_results, |
| 617 const SuggestResults& suggest_results, | 600 size_t result_number, |
| 618 size_t suggestion_number, | 601 bool is_keyword) const { |
| 619 bool is_keyword) const { | 602 DCHECK(result_number < num_results); |
| 620 DCHECK(suggestion_number < suggest_results.size()); | 603 int base_score; |
| 621 bool is_primary = providers_.is_primary_provider(is_keyword); | 604 if (!providers_.is_primary_provider(is_keyword)) |
| 622 const int suggestion_value = | 605 base_score = 100; |
| 623 static_cast<int>(suggest_results.size() - 1 - suggestion_number); | 606 else |
| 624 switch (input_.type()) { | 607 base_score = (input_.type() == AutocompleteInput::URL) ? 300 : 600; |
| 625 case AutocompleteInput::UNKNOWN: | 608 return base_score + |
| 626 case AutocompleteInput::REQUESTED_URL: | 609 static_cast<int>(num_results - 1 - result_number); |
| 627 return suggestion_value + (is_primary ? 600 : 100); | |
| 628 | |
| 629 case AutocompleteInput::URL: | |
| 630 return suggestion_value + (is_primary ? 300 : 100); | |
| 631 | |
| 632 case AutocompleteInput::QUERY: | |
| 633 case AutocompleteInput::FORCED_QUERY: | |
| 634 return suggestion_value + (is_primary ? 800 : 100); | |
| 635 | |
| 636 default: | |
| 637 NOTREACHED(); | |
| 638 return 0; | |
| 639 } | |
| 640 } | 610 } |
| 641 | 611 |
| 642 int SearchProvider::CalculateRelevanceForNavigation( | 612 int SearchProvider::CalculateRelevanceForNavigation(size_t num_results, |
| 643 size_t suggestion_number, | 613 size_t result_number, |
| 644 bool is_keyword) const { | 614 bool is_keyword) const { |
| 645 DCHECK( | 615 DCHECK(result_number < num_results); |
| 646 (is_keyword && suggestion_number < keyword_navigation_results_.size()) || | |
| 647 (!is_keyword && suggestion_number < default_navigation_results_.size())); | |
| 648 // TODO(kochi): http://b/784900 Use relevance score from the NavSuggest | 616 // TODO(kochi): http://b/784900 Use relevance score from the NavSuggest |
| 649 // server if possible. | 617 // server if possible. |
| 650 bool is_primary = providers_.is_primary_provider(is_keyword); | 618 return (providers_.is_primary_provider(is_keyword) ? 800 : 150) + |
| 651 switch (input_.type()) { | 619 static_cast<int>(num_results - 1 - result_number); |
| 652 case AutocompleteInput::QUERY: | |
| 653 case AutocompleteInput::FORCED_QUERY: | |
| 654 return static_cast<int>(suggestion_number) + (is_primary ? 1000 : 150); | |
| 655 | |
| 656 default: | |
| 657 return static_cast<int>(suggestion_number) + (is_primary ? 800 : 150); | |
| 658 } | |
| 659 } | 620 } |
| 660 | 621 |
| 661 void SearchProvider::AddMatchToMap(const std::wstring& query_string, | 622 void SearchProvider::AddMatchToMap(const std::wstring& query_string, |
| 662 int relevance, | 623 int relevance, |
| 663 AutocompleteMatch::Type type, | 624 AutocompleteMatch::Type type, |
| 664 int accepted_suggestion, | 625 int accepted_suggestion, |
| 665 bool is_keyword, | 626 bool is_keyword, |
| 666 MatchMap* map) { | 627 MatchMap* map) { |
| 667 const std::wstring& input_text = | 628 const std::wstring& input_text = |
| 668 is_keyword ? keyword_input_text_ : input_.text(); | 629 is_keyword ? keyword_input_text_ : input_.text(); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 // values preserve that property. Otherwise, if the user starts editing a | 752 // values preserve that property. Otherwise, if the user starts editing a |
| 792 // suggestion, non-Search results will suddenly appear. | 753 // suggestion, non-Search results will suddenly appear. |
| 793 if (input_.type() == AutocompleteInput::FORCED_QUERY) | 754 if (input_.type() == AutocompleteInput::FORCED_QUERY) |
| 794 match.fill_into_edit.assign(L"?"); | 755 match.fill_into_edit.assign(L"?"); |
| 795 match.fill_into_edit.append(match.contents); | 756 match.fill_into_edit.append(match.contents); |
| 796 // TODO(pkasting): http://b/1112879 These should perhaps be | 757 // TODO(pkasting): http://b/1112879 These should perhaps be |
| 797 // inline-autocompletable? | 758 // inline-autocompletable? |
| 798 | 759 |
| 799 return match; | 760 return match; |
| 800 } | 761 } |
| OLD | NEW |