#include "components/omnibox/autocomplete_result.h"
#include "components/omnibox/keyword_provider.h"
#include "components/omnibox/omnibox_field_trial.h"
+#include "components/omnibox/suggestion_answer.h"
#include "components/omnibox/url_prefix.h"
#include "components/search/search.h"
#include "components/search_engines/template_url_prepopulate_data.h"
#include "components/search_engines/template_url_service.h"
-#include "components/variations/variations_http_header_provider.h"
+#include "components/variations/net/variations_http_header_provider.h"
#include "grit/components_strings.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
// SearchProvider -------------------------------------------------------------
-// static
-int SearchProvider::kMinimumTimeBetweenSuggestQueriesMs = 100;
-
SearchProvider::SearchProvider(
AutocompleteProviderListener* listener,
TemplateURLService* template_url_service,
}
}
+base::TimeDelta SearchProvider::GetSuggestQueryDelay() const {
+ bool from_last_keystroke;
+ int polling_delay_ms;
+ OmniboxFieldTrial::GetSuggestPollingStrategy(&from_last_keystroke,
+ &polling_delay_ms);
+
+ base::TimeDelta delay(base::TimeDelta::FromMilliseconds(polling_delay_ms));
+ if (from_last_keystroke)
+ return delay;
+
+ base::TimeDelta time_since_last_suggest_request =
+ base::TimeTicks::Now() - time_suggest_request_sent_;
+ return std::max(base::TimeDelta(), delay - time_since_last_suggest_request);
+}
+
void SearchProvider::StartOrStopSuggestQuery(bool minimal_changes) {
if (!IsQuerySuitableForSuggest()) {
StopSuggest();
return;
}
+ if (OmniboxFieldTrial::DisableResultsCaching())
+ ClearAllResults();
+
// For the minimal_changes case, if we finished the previous query and still
// have its results, or are allowed to keep running it, just do that, rather
// than starting a new query.
if (!input_.want_asynchronous_matches())
return;
- // To avoid flooding the suggest server, don't send a query until at
- // least 100 ms since the last query.
- base::TimeTicks next_suggest_time(time_suggest_request_sent_ +
- base::TimeDelta::FromMilliseconds(kMinimumTimeBetweenSuggestQueriesMs));
- base::TimeTicks now(base::TimeTicks::Now());
- if (now >= next_suggest_time) {
+ // Kick off a timer that will start the URL fetch if it completes before
+ // the user types another character. Requests may be delayed to avoid
+ // flooding the server with requests that are likely to be thrown away later
+ // anyway.
+ const base::TimeDelta delay = GetSuggestQueryDelay();
+ if (delay <= base::TimeDelta()) {
Run();
return;
}
- timer_.Start(FROM_HERE, next_suggest_time - now, this, &SearchProvider::Run);
+ timer_.Start(FROM_HERE, delay, this, &SearchProvider::Run);
}
bool SearchProvider::IsQuerySuitableForSuggest() const {
// verbatim, and if so, copy over answer contents.
base::string16 answer_contents;
base::string16 answer_type;
+ scoped_ptr<SuggestionAnswer> answer;
for (ACMatches::iterator it = matches_.begin(); it != matches_.end();
++it) {
- if (!it->answer_contents.empty() &&
- it->fill_into_edit == trimmed_verbatim) {
+ if (it->answer && it->fill_into_edit == trimmed_verbatim) {
answer_contents = it->answer_contents;
answer_type = it->answer_type;
+ answer = SuggestionAnswer::copy(it->answer.get());
break;
}
}
SearchSuggestionParser::SuggestResult verbatim(
trimmed_verbatim, AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
trimmed_verbatim, base::string16(), base::string16(), answer_contents,
- answer_type, std::string(), std::string(), false, verbatim_relevance,
- relevance_from_server, false, trimmed_verbatim);
+ answer_type, answer.Pass(), std::string(), std::string(), false,
+ verbatim_relevance, relevance_from_server, false, trimmed_verbatim);
AddMatchToMap(verbatim, std::string(), did_not_accept_default_suggestion,
false, keyword_url != NULL, &map);
}
SearchSuggestionParser::SuggestResult verbatim(
trimmed_verbatim, AutocompleteMatchType::SEARCH_OTHER_ENGINE,
trimmed_verbatim, base::string16(), base::string16(),
- base::string16(), base::string16(), std::string(), std::string(),
- true, keyword_verbatim_relevance, keyword_relevance_from_server,
- false, trimmed_verbatim);
+ base::string16(), base::string16(), nullptr, std::string(),
+ std::string(), true, keyword_verbatim_relevance,
+ keyword_relevance_from_server, false, trimmed_verbatim);
AddMatchToMap(verbatim, std::string(),
did_not_accept_keyword_suggestion, false, true, &map);
}
void SearchProvider::RemoveExtraAnswers(ACMatches* matches) {
bool answer_seen = false;
for (ACMatches::iterator it = matches->begin(); it != matches->end(); ++it) {
- if (!it->answer_contents.empty()) {
+ if (it->answer) {
if (!answer_seen) {
answer_seen = true;
} else {
it->answer_contents.clear();
it->answer_type.clear();
+ it->answer.reset();
}
}
}
SearchSuggestionParser::SuggestResult history_suggestion(
trimmed_suggestion, AutocompleteMatchType::SEARCH_HISTORY,
trimmed_suggestion, base::string16(), base::string16(),
- base::string16(), base::string16(), std::string(), std::string(),
- is_keyword, relevance, false, false, trimmed_input);
+ base::string16(), base::string16(), nullptr, std::string(),
+ std::string(), is_keyword, relevance, false, false, trimmed_input);
// History results are synchronous; they are received on the last keystroke.
history_suggestion.set_received_after_last_keystroke(false);
scored_results.insert(insertion_position, history_suggestion);