Index: chrome/browser/autocomplete/autocomplete.cc |
diff --git a/chrome/browser/autocomplete/autocomplete.cc b/chrome/browser/autocomplete/autocomplete.cc |
index 4f87500830bd40e23c106072b9e2452f9e475de3..337241f9a3c1e9fdb034c0c384ad54f639c919a0 100644 |
--- a/chrome/browser/autocomplete/autocomplete.cc |
+++ b/chrome/browser/autocomplete/autocomplete.cc |
@@ -11,9 +11,11 @@ |
#include "base/basictypes.h" |
#include "base/command_line.h" |
#include "base/i18n/number_formatting.h" |
+#include "base/format_macros.h" |
#include "base/metrics/histogram.h" |
#include "base/string_number_conversions.h" |
#include "base/string_util.h" |
+#include "base/stringprintf.h" |
#include "base/utf_string_conversions.h" |
#include "chrome/browser/autocomplete/autocomplete_controller_delegate.h" |
#include "chrome/browser/autocomplete/autocomplete_match.h" |
@@ -53,6 +55,7 @@ |
using base::TimeDelta; |
+ |
// AutocompleteInput ---------------------------------------------------------- |
AutocompleteInput::AutocompleteInput() |
@@ -782,10 +785,15 @@ AutocompleteResult::iterator AutocompleteResult::end() { |
// Returns the match at the given index. |
const AutocompleteMatch& AutocompleteResult::match_at(size_t index) const { |
- DCHECK(index < matches_.size()); |
+ DCHECK_LT(index, matches_.size()); |
return matches_[index]; |
} |
+AutocompleteMatch* AutocompleteResult::match_at(size_t index) { |
+ DCHECK_LT(index, matches_.size()); |
+ return &matches_[index]; |
+} |
+ |
void AutocompleteResult::Reset() { |
matches_.clear(); |
default_match_ = end(); |
@@ -852,6 +860,39 @@ void AutocompleteResult::MergeMatchesByProvider(const ACMatches& old_matches, |
// AutocompleteController ----------------------------------------------------- |
+namespace { |
+ |
+// Converts the given type to an integer based on the AQS specification. |
+// For more details, See http://goto.google.com/binary-clients-logging . |
+int AutocompleteMatchToAssistedQueryType(const AutocompleteMatch::Type& type) { |
+ switch (type) { |
+ case AutocompleteMatch::SEARCH_SUGGEST: return 0; |
+ case AutocompleteMatch::NAVSUGGEST: return 5; |
+ case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: return 57; |
+ case AutocompleteMatch::URL_WHAT_YOU_TYPED: return 58; |
+ case AutocompleteMatch::SEARCH_HISTORY: return 59; |
+ case AutocompleteMatch::HISTORY_URL: return 60; |
+ case AutocompleteMatch::HISTORY_TITLE: return 61; |
+ case AutocompleteMatch::HISTORY_BODY: return 62; |
+ case AutocompleteMatch::HISTORY_KEYWORD: return 63; |
+ default: return 64; |
+ } |
+} |
+ |
+// Appends available autocompletion of the given type and number to the existing |
+// available autocompletions string, encoding according to the spec. |
+void AppendAvailableAutocompletion(int type, |
+ int count, |
+ std::string* autocompletions) { |
+ if (!autocompletions->empty()) |
+ autocompletions->append("j"); |
+ base::StringAppendF(autocompletions, "%d", type); |
+ if (count > 1) |
+ base::StringAppendF(autocompletions, "l%d", count); |
+} |
+ |
+} // namespace |
+ |
const int AutocompleteController::kNoItemSelected = -1; |
// Amount of time (in ms) between when the user stops typing and when we remove |
@@ -1044,6 +1085,7 @@ void AutocompleteController::UpdateResult(bool is_synchronous_pass) { |
UpdateKeywordDescriptions(&result_); |
UpdateAssociatedKeywords(&result_); |
+ UpdateAssistedQueryStats(&result_); |
bool notify_default_match = is_synchronous_pass; |
if (!is_synchronous_pass) { |
@@ -1100,6 +1142,43 @@ void AutocompleteController::UpdateAssociatedKeywords( |
} |
} |
+void AutocompleteController::UpdateAssistedQueryStats( |
+ AutocompleteResult* result) { |
+ if (result->empty()) |
+ return; |
+ |
+ // Build the impressions string (the AQS part after "."). |
+ std::string autocompletions; |
+ int count = 0; |
+ int last_type = -1; |
+ for (ACMatches::iterator match(result->begin()); match != result->end(); |
+ ++match) { |
+ int type = AutocompleteMatchToAssistedQueryType(match->type); |
+ if (last_type != -1 && type != last_type) { |
+ AppendAvailableAutocompletion(last_type, count, &autocompletions); |
+ count = 1; |
+ } else { |
+ count++; |
+ } |
+ last_type = type; |
+ } |
+ AppendAvailableAutocompletion(last_type, count, &autocompletions); |
+ |
+ // Go over all matches and set AQS if the match supports it. |
+ for (size_t index = 0; index < result->size(); ++index) { |
+ AutocompleteMatch* match = result->match_at(index); |
+ const TemplateURL* template_url = match->GetTemplateURL(profile_); |
+ if (!template_url || !match->search_terms_args.get()) |
+ continue; |
+ match->search_terms_args->assisted_query_stats = |
+ base::StringPrintf("chrome.%" PRIuS ".%s", |
+ index, |
+ autocompletions.c_str()); |
+ match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms( |
+ *match->search_terms_args)); |
+ } |
+} |
+ |
void AutocompleteController::UpdateKeywordDescriptions( |
AutocompleteResult* result) { |
string16 last_keyword; |