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 "components/omnibox/search_provider.h" | 5 #include "components/omnibox/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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 bool operator()(const SearchSuggestionParser::Result& a, | 109 bool operator()(const SearchSuggestionParser::Result& a, |
110 const SearchSuggestionParser::Result& b) { | 110 const SearchSuggestionParser::Result& b) { |
111 // Sort in descending relevance order. | 111 // Sort in descending relevance order. |
112 return a.relevance() > b.relevance(); | 112 return a.relevance() > b.relevance(); |
113 } | 113 } |
114 }; | 114 }; |
115 | 115 |
116 | 116 |
117 // SearchProvider ------------------------------------------------------------- | 117 // SearchProvider ------------------------------------------------------------- |
118 | 118 |
119 // static | |
120 int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100; | |
121 | |
122 SearchProvider::SearchProvider( | 119 SearchProvider::SearchProvider( |
123 AutocompleteProviderListener* listener, | 120 AutocompleteProviderListener* listener, |
124 TemplateURLService* template_url_service, | 121 TemplateURLService* template_url_service, |
125 scoped_ptr<AutocompleteProviderClient> client) | 122 scoped_ptr<AutocompleteProviderClient> client) |
126 : BaseSearchProvider(template_url_service, client.Pass(), | 123 : BaseSearchProvider(template_url_service, client.Pass(), |
127 AutocompleteProvider::TYPE_SEARCH), | 124 AutocompleteProvider::TYPE_SEARCH), |
128 listener_(listener), | 125 listener_(listener), |
129 suggest_results_pending_(0), | 126 suggest_results_pending_(0), |
130 providers_(template_url_service), | 127 providers_(template_url_service), |
131 answers_cache_(10) { | 128 answers_cache_(10) { |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 } | 569 } |
573 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | 570 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); |
574 if (keyword_url) { | 571 if (keyword_url) { |
575 url_db->GetMostRecentKeywordSearchTerms(keyword_url->id(), | 572 url_db->GetMostRecentKeywordSearchTerms(keyword_url->id(), |
576 keyword_input_.text(), | 573 keyword_input_.text(), |
577 num_matches, | 574 num_matches, |
578 &raw_keyword_history_results_); | 575 &raw_keyword_history_results_); |
579 } | 576 } |
580 } | 577 } |
581 | 578 |
| 579 base::TimeDelta SearchProvider::GetSuggestQueryDelay() const { |
| 580 bool from_last_keystroke; |
| 581 int polling_delay_ms; |
| 582 OmniboxFieldTrial::GetSuggestPollingStrategy(&from_last_keystroke, |
| 583 &polling_delay_ms); |
| 584 |
| 585 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(polling_delay_ms)); |
| 586 if (from_last_keystroke) |
| 587 return delay; |
| 588 |
| 589 base::TimeDelta time_since_last_suggest_request = |
| 590 base::TimeTicks::Now() - time_suggest_request_sent_; |
| 591 return std::max(base::TimeDelta(), delay - time_since_last_suggest_request); |
| 592 } |
| 593 |
582 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { | 594 void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) { |
583 if (!IsQuerySuitableForSuggest()) { | 595 if (!IsQuerySuitableForSuggest()) { |
584 StopSuggest(); | 596 StopSuggest(); |
585 ClearAllResults(); | 597 ClearAllResults(); |
586 return; | 598 return; |
587 } | 599 } |
588 | 600 |
| 601 if (OmniboxFieldTrial::DisableResultsCaching()) |
| 602 ClearAllResults(); |
| 603 |
589 // For the minimal_changes case, if we finished the previous query and still | 604 // For the minimal_changes case, if we finished the previous query and still |
590 // have its results, or are allowed to keep running it, just do that, rather | 605 // have its results, or are allowed to keep running it, just do that, rather |
591 // than starting a new query. | 606 // than starting a new query. |
592 if (minimal_changes && | 607 if (minimal_changes && |
593 (!default_results_.suggest_results.empty() || | 608 (!default_results_.suggest_results.empty() || |
594 !default_results_.navigation_results.empty() || | 609 !default_results_.navigation_results.empty() || |
595 !keyword_results_.suggest_results.empty() || | 610 !keyword_results_.suggest_results.empty() || |
596 !keyword_results_.navigation_results.empty() || | 611 !keyword_results_.navigation_results.empty() || |
597 (!done_ && input_.want_asynchronous_matches()))) | 612 (!done_ && input_.want_asynchronous_matches()))) |
598 return; | 613 return; |
599 | 614 |
600 // We can't keep running any previous query, so halt it. | 615 // We can't keep running any previous query, so halt it. |
601 StopSuggest(); | 616 StopSuggest(); |
602 | 617 |
603 UpdateAllOldResults(minimal_changes); | 618 UpdateAllOldResults(minimal_changes); |
604 | 619 |
605 // Update the content classifications of remaining results so they look good | 620 // Update the content classifications of remaining results so they look good |
606 // against the current input. | 621 // against the current input. |
607 UpdateMatchContentsClass(input_.text(), &default_results_); | 622 UpdateMatchContentsClass(input_.text(), &default_results_); |
608 if (!keyword_input_.text().empty()) | 623 if (!keyword_input_.text().empty()) |
609 UpdateMatchContentsClass(keyword_input_.text(), &keyword_results_); | 624 UpdateMatchContentsClass(keyword_input_.text(), &keyword_results_); |
610 | 625 |
611 // We can't start a new query if we're only allowed synchronous results. | 626 // We can't start a new query if we're only allowed synchronous results. |
612 if (!input_.want_asynchronous_matches()) | 627 if (!input_.want_asynchronous_matches()) |
613 return; | 628 return; |
614 | 629 |
615 // To avoid flooding the suggest server, don't send a query until at | 630 // Kick off a timer that will start the URL fetch if it completes before |
616 // least 100 ms since the last query. | 631 // the user types another character. Requests may be delayed to avoid |
617 base::TimeTicks next_suggest_time(time_suggest_request_sent_ + | 632 // flooding the server with requests that are likely to be thrown away later |
618 base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenSuggestQueriesMs)); | 633 // anyway. |
619 base::TimeTicks now(base::TimeTicks::Now()); | 634 const base::TimeDelta delay = GetSuggestQueryDelay(); |
620 if (now >= next_suggest_time) { | 635 if (delay <= base::TimeDelta()) { |
621 Run(); | 636 Run(); |
622 return; | 637 return; |
623 } | 638 } |
624 timer_.Start(FROM_HERE, next_suggest_time - now, this, &SearchProvider::Run); | 639 timer_.Start(FROM_HERE, delay, this, &SearchProvider::Run); |
625 } | 640 } |
626 | 641 |
627 bool SearchProvider::IsQuerySuitableForSuggest() const { | 642 bool SearchProvider::IsQuerySuitableForSuggest() const { |
628 // Don't run Suggest in incognito mode, if the engine doesn't support it, or | 643 // Don't run Suggest in incognito mode, if the engine doesn't support it, or |
629 // if the user has disabled it. | 644 // if the user has disabled it. |
630 const TemplateURL* default_url = providers_.GetDefaultProviderURL(); | 645 const TemplateURL* default_url = providers_.GetDefaultProviderURL(); |
631 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); | 646 const TemplateURL* keyword_url = providers_.GetKeywordProviderURL(); |
632 if (client_->IsOffTheRecord() || | 647 if (client_->IsOffTheRecord() || |
633 ((!default_url || default_url->suggestions_url().empty()) && | 648 ((!default_url || default_url->suggestions_url().empty()) && |
634 (!keyword_url || keyword_url->suggestions_url().empty())) || | 649 (!keyword_url || keyword_url->suggestions_url().empty())) || |
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) | 1446 for (MatchMap::const_iterator i(map.begin()); i != map.end(); ++i) |
1432 matches.push_back(i->second); | 1447 matches.push_back(i->second); |
1433 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); | 1448 std::sort(matches.begin(), matches.end(), &AutocompleteMatch::MoreRelevant); |
1434 | 1449 |
1435 // If there is a top scoring entry, find the corresponding answer. | 1450 // If there is a top scoring entry, find the corresponding answer. |
1436 if (!matches.empty()) | 1451 if (!matches.empty()) |
1437 return answers_cache_.GetTopAnswerEntry(matches[0].contents); | 1452 return answers_cache_.GetTopAnswerEntry(matches[0].contents); |
1438 | 1453 |
1439 return AnswersQueryData(); | 1454 return AnswersQueryData(); |
1440 } | 1455 } |
OLD | NEW |