Modify Entity Suggestion support and Add Profile Suggest support

- Added new AutocompleteMatchType for the two, and additionally for personalized and infinite suggestion.
- Added logging for the new suggestion types.
- Annotation for entities is now used as description in the match. This allows multiline rendering in mobile easily.
- Profile suggestions also look like entity suggestion, and use title, annotation and query fields in response.

BUG=

Review URL: https://codereview.chromium.org/58003005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240174 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/autocomplete/autocomplete_controller.cc b/chrome/browser/autocomplete/autocomplete_controller.cc
index 3be1148..6e578521 100644
--- a/chrome/browser/autocomplete/autocomplete_controller.cc
+++ b/chrome/browser/autocomplete/autocomplete_controller.cc
@@ -57,6 +57,22 @@
       *type = 0;
       return;
     }
+    case AutocompleteMatchType::SEARCH_SUGGEST_ENTITY: {
+      *subtype = 46;
+      return;
+    }
+    case AutocompleteMatchType::SEARCH_SUGGEST_INFINITE: {
+      *subtype = 33;
+      return;
+    }
+    case AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED: {
+      *subtype = 35;
+      return;
+    }
+    case AutocompleteMatchType::SEARCH_SUGGEST_PROFILE: {
+      *subtype = 44;
+      return;
+    }
     case AutocompleteMatchType::NAVSUGGEST: {
       *type = 5;
       return;
@@ -127,6 +143,12 @@
       match.type == AutocompleteMatchType::SEARCH_OTHER_ENGINE;
 }
 
+// Whether this autocomplete match type supports custom descriptions.
+bool AutocompleteMatchHasCustomDescription(const AutocompleteMatch& match) {
+  return match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY ||
+      match.type == AutocompleteMatchType::SEARCH_SUGGEST_PROFILE;
+}
+
 }  // namespace
 
 const int AutocompleteController::kNoItemSelected = -1;
@@ -517,6 +539,8 @@
          !i->keyword.empty()) ||
         (i->provider->type() == AutocompleteProvider::TYPE_SEARCH &&
          AutocompleteMatch::IsSearchType(i->type))) {
+      if (AutocompleteMatchHasCustomDescription(*i))
+        continue;
       i->description.clear();
       i->description_class.clear();
       DCHECK(!i->keyword.empty());
diff --git a/chrome/browser/autocomplete/autocomplete_match.cc b/chrome/browser/autocomplete/autocomplete_match.cc
index 5c1c1941..2fc5e68 100644
--- a/chrome/browser/autocomplete/autocomplete_match.cc
+++ b/chrome/browser/autocomplete/autocomplete_match.cc
@@ -143,6 +143,10 @@
     IDR_OMNIBOX_SEARCH,
     IDR_OMNIBOX_SEARCH,
     IDR_OMNIBOX_SEARCH,
+    IDR_OMNIBOX_SEARCH,
+    IDR_OMNIBOX_SEARCH,
+    IDR_OMNIBOX_SEARCH,
+    IDR_OMNIBOX_SEARCH,
     IDR_OMNIBOX_EXTENSION_APP,
     // ContactProvider isn't used by the omnibox, so this icon is never
     // displayed.
diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc
index 6e81074..143e466 100644
--- a/chrome/browser/autocomplete/search_provider.cc
+++ b/chrome/browser/autocomplete/search_provider.cc
@@ -107,41 +107,21 @@
 void SetAndClassifyMatchContents(const base::string16& query_string,
                                  const base::string16& input_text,
                                  const base::string16& match_contents,
-                                 const base::string16& annotation,
                                  AutocompleteMatch* match) {
-  size_t match_contents_start = 0;
-  size_t annotation_start = match_contents.size();
-  // Append annotation if present.
-  if (annotation.empty()) {
-    match->contents = match_contents;
-  } else {
-    std::vector<size_t> positions;
-    match->contents = l10n_util::GetStringFUTF16(
-        IDS_ANNOTATED_SUGGESTION, match_contents, annotation, &positions);
-    match_contents_start = positions[0];
-    annotation_start = positions[1];
-  }
-  size_t match_contents_end = match_contents_start + match_contents.size();
-
-  if (!annotation.empty() && (annotation_start < match_contents_start))
-    match->contents_class.push_back(ACMatchClassification(
-        annotation_start, ACMatchClassification::DIM));
+  match->contents = match_contents.empty() ? query_string : match_contents;
 
   // We do intra-string highlighting for suggestions - the suggested segment
   // will be highlighted, e.g. for input_text = "you" the suggestion may be
   // "youtube", so we'll bold the "tube" section: you*tube*.
   if (input_text != match_contents) {
-    size_t input_position = match->contents.substr(
-        match_contents_start, match_contents.length()).find(input_text);
+    size_t input_position = match->contents.find(input_text);
     if (input_position == base::string16::npos) {
       // The input text is not a substring of the query string, e.g. input
       // text is "slasdot" and the query string is "slashdot", so we bold the
       // whole thing.
       match->contents_class.push_back(ACMatchClassification(
-          match_contents_start, ACMatchClassification::MATCH));
+          0, ACMatchClassification::MATCH));
     } else {
-      input_position += match_contents_start;
-
       // TODO(beng): ACMatchClassification::MATCH now seems to just mean
       //             "bold" this. Consider modifying the terminology.
       // We don't iterate over the string here annotating all matches because
@@ -149,9 +129,9 @@
       // short as a single character highlighted in a query suggestion result,
       // e.g. for input text "s" and query string "southwest airlines", it
       // looks odd if both the first and last s are highlighted.
-      if (input_position != match_contents_start) {
+      if (input_position != 0) {
         match->contents_class.push_back(ACMatchClassification(
-            match_contents_start, ACMatchClassification::MATCH));
+            0, ACMatchClassification::MATCH));
       }
       match->contents_class.push_back(
           ACMatchClassification(input_position, ACMatchClassification::NONE));
@@ -165,12 +145,20 @@
     // Otherwise, |match| is a verbatim (what-you-typed) match, either for the
     // default provider or a keyword search provider.
     match->contents_class.push_back(ACMatchClassification(
-        match_contents_start, ACMatchClassification::NONE));
+        0, ACMatchClassification::NONE));
   }
+}
 
-  if (!annotation.empty() && (annotation_start >= match_contents_start))
-    match->contents_class.push_back(ACMatchClassification(
-        match_contents_end, ACMatchClassification::DIM));
+AutocompleteMatchType::Type GetAutocompleteMatchType(const std::string& type) {
+  if (type == "ENTITY")
+    return AutocompleteMatchType::SEARCH_SUGGEST_ENTITY;
+  if (type == "INFINITE")
+    return AutocompleteMatchType::SEARCH_SUGGEST_INFINITE;
+  if (type == "PERSONALIZED")
+    return AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED;
+  if (type == "PROFILE")
+    return AutocompleteMatchType::SEARCH_SUGGEST_PROFILE;
+  return AutocompleteMatchType::SEARCH_SUGGEST;
 }
 
 }  // namespace
@@ -266,6 +254,7 @@
 
 SearchProvider::SuggestResult::SuggestResult(
     const base::string16& suggestion,
+    AutocompleteMatchType::Type type,
     const base::string16& match_contents,
     const base::string16& annotation,
     const std::string& suggest_query_params,
@@ -276,6 +265,7 @@
     bool should_prefetch)
     : Result(from_keyword_provider, relevance, relevance_from_server),
       suggestion_(suggestion),
+      type_(type),
       match_contents_(match_contents),
       annotation_(annotation),
       suggest_query_params_(suggest_query_params),
@@ -426,8 +416,10 @@
     return match;
   match.keyword = template_url->keyword();
 
-  SetAndClassifyMatchContents(
-      query_string, input_text, match_contents, annotation, &match);
+  SetAndClassifyMatchContents(query_string, input_text, match_contents, &match);
+
+  if (!annotation.empty())
+    match.description = annotation;
 
   match.allowed_to_be_default_match = (input_text == match_contents);
 
@@ -1179,6 +1171,7 @@
             *this, url, title, is_keyword, relevance, true));
       }
     } else {
+      AutocompleteMatchType::Type match_type = GetAutocompleteMatchType(type);
       bool should_prefetch = static_cast<int>(index) == prefetch_index;
       DictionaryValue* suggestion_detail = NULL;
       base::string16 match_contents = suggestion;
@@ -1190,24 +1183,20 @@
         suggestion_details->GetDictionary(index, &suggestion_detail);
         if (suggestion_detail) {
           suggestion_detail->GetString("du", &deletion_url);
-
-          if (type == "ENTITY") {
-            suggestion_detail->GetString("a", &annotation);
-
-            base::string16 disambiguating_query;
-            if (suggestion_detail->GetString("dq", &disambiguating_query) &&
-                !disambiguating_query.empty())
-              suggestion = disambiguating_query;
-
-            suggestion_detail->GetString("q", &suggest_query_params);
-          }
+          suggestion_detail->GetString("title", &match_contents) ||
+              suggestion_detail->GetString("t", &match_contents);
+          suggestion_detail->GetString("annotation", &annotation) ||
+              suggestion_detail->GetString("a", &annotation);
+          suggestion_detail->GetString("query_params", &suggest_query_params) ||
+              suggestion_detail->GetString("q", &suggest_query_params);
         }
       }
 
       // TODO(kochi): Improve calculator suggestion presentation.
       results->suggest_results.push_back(SuggestResult(
-          suggestion, match_contents, annotation, suggest_query_params,
-          deletion_url, is_keyword, relevance, true, should_prefetch));
+          suggestion, match_type, match_contents, annotation,
+          suggest_query_params, deletion_url, is_keyword, relevance, true,
+          should_prefetch));
     }
   }
 
@@ -1255,11 +1244,11 @@
       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE :
       TemplateURLRef::NO_SUGGESTION_CHOSEN;
   if (verbatim_relevance > 0) {
-    SuggestResult verbatim(input_.text(), input_.text(), base::string16(),
-                           std::string(), std::string(), false,
-                           verbatim_relevance, relevance_from_server, false);
+    SuggestResult verbatim(
+        input_.text(), AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
+        input_.text(), base::string16(), std::string(), std::string(),
+        false, verbatim_relevance, relevance_from_server, false);
     AddMatchToMap(verbatim, input_.text(), std::string(),
-                  AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
                   did_not_accept_default_suggestion, &map);
   }
   if (!keyword_input_.text().empty()) {
@@ -1276,12 +1265,12 @@
       const int keyword_verbatim_relevance =
           GetKeywordVerbatimRelevance(&keyword_relevance_from_server);
       if (keyword_verbatim_relevance > 0) {
-        SuggestResult verbatim(keyword_input_.text(), keyword_input_.text(),
-                               base::string16(), std::string(), std::string(),
-                               true, keyword_verbatim_relevance,
-                               keyword_relevance_from_server, false);
+        SuggestResult verbatim(
+            keyword_input_.text(), AutocompleteMatchType::SEARCH_OTHER_ENGINE,
+            keyword_input_.text(), base::string16(), std::string(),
+            std::string(), true, keyword_verbatim_relevance,
+            keyword_relevance_from_server, false);
         AddMatchToMap(verbatim, keyword_input_.text(), std::string(),
-                      AutocompleteMatchType::SEARCH_OTHER_ENGINE,
                       did_not_accept_keyword_suggestion, &map);
       }
     }
@@ -1579,7 +1568,6 @@
   for (SuggestResults::const_iterator i(scored_results.begin());
        i != scored_results.end(); ++i) {
     AddMatchToMap(*i, input_text, std::string(),
-                  AutocompleteMatchType::SEARCH_HISTORY,
                   did_not_accept_suggestion, map);
   }
   UMA_HISTOGRAM_TIMES("Omnibox.SearchProvider.AddHistoryResultsTime",
@@ -1628,9 +1616,10 @@
     int relevance = CalculateRelevanceForHistory(
         i->time, is_keyword, !prevent_inline_autocomplete,
         prevent_search_history_inlining);
-    scored_results.push_back(
-        SuggestResult(i->term, i->term, base::string16(), std::string(),
-                      std::string(), is_keyword, relevance, false, false));
+    scored_results.push_back(SuggestResult(
+        i->term, AutocompleteMatchType::SEARCH_HISTORY, i->term,
+        base::string16(), std::string(), std::string(), is_keyword, relevance,
+        false, false));
   }
 
   // History returns results sorted for us.  However, we may have docked some
@@ -1658,8 +1647,7 @@
     const bool is_keyword = results[i].from_keyword_provider();
     const base::string16& input = is_keyword ? keyword_input_.text()
                                              : input_.text();
-    AddMatchToMap(results[i], input, metadata,
-                  AutocompleteMatchType::SEARCH_SUGGEST, i, map);
+    AddMatchToMap(results[i], input, metadata, i, map);
   }
 }
 
@@ -1774,7 +1762,6 @@
 void SearchProvider::AddMatchToMap(const SuggestResult& result,
                                    const base::string16& input_text,
                                    const std::string& metadata,
-                                   AutocompleteMatch::Type type,
                                    int accepted_suggestion,
                                    MatchMap* map) {
   // On non-mobile, ask the instant controller for the appropriate start margin.
@@ -1795,7 +1782,7 @@
   const TemplateURL* template_url = result.from_keyword_provider() ?
       providers_.GetKeywordProviderURL() : providers_.GetDefaultProviderURL();
   AutocompleteMatch match = CreateSearchSuggestion(
-      this, input_, input_text, result.relevance(), type,
+      this, input_, input_text, result.relevance(), result.type(),
       result.from_keyword_provider(), result.match_contents(),
       result.annotation(), template_url, result.suggestion(),
       result.suggest_query_params(), accepted_suggestion, omnibox_start_margin,
diff --git a/chrome/browser/autocomplete/search_provider.h b/chrome/browser/autocomplete/search_provider.h
index 58aeacbe..a37ab42 100644
--- a/chrome/browser/autocomplete/search_provider.h
+++ b/chrome/browser/autocomplete/search_provider.h
@@ -240,6 +240,7 @@
   class SuggestResult : public Result {
    public:
     SuggestResult(const base::string16& suggestion,
+                  AutocompleteMatchType::Type type,
                   const base::string16& match_contents,
                   const base::string16& annotation,
                   const std::string& suggest_query_params,
@@ -251,6 +252,7 @@
     virtual ~SuggestResult();
 
     const base::string16& suggestion() const { return suggestion_; }
+    AutocompleteMatchType::Type type() const { return type_; }
     const base::string16& match_contents() const { return match_contents_; }
     const base::string16& annotation() const { return annotation_; }
     const std::string& suggest_query_params() const {
@@ -269,6 +271,8 @@
     // The search terms to be used for this suggestion.
     base::string16 suggestion_;
 
+    AutocompleteMatchType::Type type_;
+
     // The contents to be displayed in the autocomplete match.
     base::string16 match_contents_;
 
@@ -543,7 +547,6 @@
   void AddMatchToMap(const SuggestResult& result,
                      const base::string16& input_text,
                      const std::string& metadata,
-                     AutocompleteMatch::Type type,
                      int accepted_suggestion,
                      MatchMap* map);
 
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index f064792f..94964e7c 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -3383,11 +3383,11 @@
                 cases[i].results[j].relevance, false));
       } else {
         provider_->default_results_.suggest_results.push_back(
-            SearchProvider::SuggestResult(ASCIIToUTF16(suggestion), base::string16(),
-                                          base::string16(), std::string(),
-                                          std::string(), false,
-                                          cases[i].results[j].relevance,
-                                          false, false));
+            SearchProvider::SuggestResult(
+                ASCIIToUTF16(suggestion), AutocompleteMatchType::SEARCH_SUGGEST,
+                base::string16(), base::string16(), std::string(),
+                std::string(), false, cases[i].results[j].relevance, false,
+                false));
       }
     }
 
@@ -3432,19 +3432,14 @@
 TEST_F(SearchProviderTest, ParseEntitySuggestion) {
   struct Match {
     std::string contents;
+    std::string description;
     std::string query_params;
     std::string fill_into_edit;
     AutocompleteMatchType::Type type;
-    size_t classification_offsets[3];
-    int classification_styles[3];
   };
-  const size_t invalid_offset = 10;
-  const int invalid_style = -1;
   const Match kEmptyMatch = {
-    kNotApplicable, kNotApplicable, kNotApplicable,
-    AutocompleteMatchType::NUM_TYPES,
-    { invalid_offset, invalid_offset, invalid_offset },
-    { invalid_style, invalid_style, invalid_style } };
+    kNotApplicable, kNotApplicable, kNotApplicable, kNotApplicable,
+    AutocompleteMatchType::NUM_TYPES};
 
   struct {
     const std::string input_text;
@@ -3453,21 +3448,14 @@
   } cases[] = {
     // A query and an entity suggestion with different search terms.
     { "x",
-      "[\"x\",[\"xy\", \"xy\"],[\"\",\"\"],[],"
+      "[\"x\",[\"xy\", \"yy\"],[\"\",\"\"],[],"
       " {\"google:suggestdetail\":[{},"
-      "   {\"a\":\"A\",\"dq\":\"yy\",\"q\":\"p=v\"}],"
+      "   {\"a\":\"A\",\"t\":\"xy\",\"q\":\"p=v\"}],"
       "\"google:suggesttype\":[\"QUERY\",\"ENTITY\"]}]",
-      { { "x", "", "x", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
-          { 0, invalid_offset, invalid_offset },
-          { ACMatchClassification::NONE, invalid_style, invalid_style } },
-        { "xy", "", "xy", AutocompleteMatchType::SEARCH_SUGGEST,
-          { 0, 1, invalid_offset },
-          { ACMatchClassification::NONE, ACMatchClassification::MATCH,
-            invalid_style } },
-        { "xy - A", "p=v", "yy", AutocompleteMatchType::SEARCH_SUGGEST,
-          { 0, 1, 2 },
-          { ACMatchClassification::NONE, ACMatchClassification::MATCH,
-            ACMatchClassification::DIM } },
+      { { "x", "", "", "x", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
+        { "xy", "", "", "xy", AutocompleteMatchType::SEARCH_SUGGEST },
+        { "xy", "A", "p=v", "yy",
+          AutocompleteMatchType::SEARCH_SUGGEST_ENTITY },
         kEmptyMatch,
         kEmptyMatch
       },
@@ -3476,19 +3464,12 @@
     { "x",
       "[\"x\",[\"xy\", \"xy\"],[\"\",\"\"],[],"
       " {\"google:suggestdetail\":[{},"
-      "   {\"a\":\"A\",\"dq\":\"xy\",\"q\":\"p=v\"}],"
+      "   {\"a\":\"A\",\"t\":\"xy\",\"q\":\"p=v\"}],"
       "\"google:suggesttype\":[\"QUERY\",\"ENTITY\"]}]",
-      { { "x", "", "x", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED,
-          { 0, invalid_offset, invalid_offset },
-          { ACMatchClassification::NONE, invalid_style, invalid_style } },
-        { "xy", "", "xy", AutocompleteMatchType::SEARCH_SUGGEST,
-          { 0, 1, invalid_offset },
-          { ACMatchClassification::NONE, ACMatchClassification::MATCH,
-            invalid_style } },
-        { "xy - A", "p=v", "xy", AutocompleteMatchType::SEARCH_SUGGEST,
-          { 0, 1, 2 },
-          { ACMatchClassification::NONE, ACMatchClassification::MATCH,
-            ACMatchClassification::DIM } },
+      { { "x", "", "", "x", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED },
+        { "xy", "", "", "xy", AutocompleteMatchType::SEARCH_SUGGEST },
+        { "xy", "A", "p=v", "xy",
+          AutocompleteMatchType::SEARCH_SUGGEST_ENTITY },
         kEmptyMatch,
         kEmptyMatch
       },
@@ -3521,30 +3502,19 @@
       SCOPED_TRACE(" and match index: " + base::IntToString(j));
       EXPECT_EQ(match.contents,
                 UTF16ToUTF8(matches[j].contents));
+      EXPECT_EQ(match.description,
+                UTF16ToUTF8(matches[j].description));
       EXPECT_EQ(match.query_params,
                 matches[j].search_terms_args->suggest_query_params);
       EXPECT_EQ(match.fill_into_edit,
                 UTF16ToUTF8(matches[j].fill_into_edit));
       EXPECT_EQ(match.type, matches[j].type);
-
-      size_t k = 0;
-      for (; k < matches[j].contents_class.size(); k++) {
-        SCOPED_TRACE(" and contents class: " + base::IntToString(k));
-        EXPECT_EQ(match.classification_offsets[k],
-            matches[j].contents_class[k].offset);
-        EXPECT_EQ(match.classification_styles[k],
-            matches[j].contents_class[k].style);
-      }
-      for (; k < ARRAYSIZE_UNSAFE(match.classification_offsets); k++) {
-        SCOPED_TRACE(" and contents class: " + base::IntToString(k));
-        EXPECT_EQ(match.classification_offsets[k], invalid_offset);
-        EXPECT_EQ(match.classification_styles[k], invalid_style);
-      }
     }
     // Ensure that no expected matches are missing.
     for (; j < ARRAYSIZE_UNSAFE(cases[i].matches); ++j) {
       SCOPED_TRACE(" and match index: " + base::IntToString(j));
       EXPECT_EQ(cases[i].matches[j].contents, kNotApplicable);
+      EXPECT_EQ(cases[i].matches[j].description, kNotApplicable);
       EXPECT_EQ(cases[i].matches[j].query_params, kNotApplicable);
       EXPECT_EQ(cases[i].matches[j].fill_into_edit, kNotApplicable);
       EXPECT_EQ(cases[i].matches[j].type, AutocompleteMatchType::NUM_TYPES);
@@ -3553,96 +3523,6 @@
 }
 #endif  // !defined(OS_WIN)
 
-TEST_F(SearchProviderTest, SearchHistorySuppressesEntitySuggestion) {
-  struct Match {
-    std::string contents;
-    std::string query_params;
-    std::string fill_into_edit;
-    AutocompleteMatchType::Type type;
-  };
-  const Match kEmptyMatch = { kNotApplicable, kNotApplicable, kNotApplicable,
-                              AutocompleteMatchType::NUM_TYPES};
-
-  struct {
-    const std::string input_text;
-    const std::string history_search_term;
-    const std::string response_json;
-    const Match matches[5];
-  } cases[] = {
-    // Search history suppresses both query and entity suggestions.
-    { "x", "xy",
-      "[\"x\",[\"xy\", \"xy\"],[\"\",\"\"],[],"
-      " {\"google:suggestdetail\":[{},"
-      "   {\"a\":\"A\",\"dq\":\"xy\",\"q\":\"p=v\"}],"
-      "\"google:suggesttype\":[\"QUERY\",\"ENTITY\"]}]",
-      {
-        {"xy", "", "xy", AutocompleteMatchType::SEARCH_HISTORY},
-        {"x", "", "x", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED},
-        {"xy - A", "p=v", "xy", AutocompleteMatchType::SEARCH_SUGGEST},
-        kEmptyMatch,
-        kEmptyMatch,
-      },
-    },
-    // Search history suppresses only query suggestion.
-    { "x", "xyy",
-      "[\"x\",[\"xy\", \"xy\"],[\"\",\"\"],[],"
-      " {\"google:suggestdetail\":[{},"
-      "   {\"a\":\"A\",\"dq\":\"xyy\",\"q\":\"p=v\"}],"
-      "\"google:suggesttype\":[\"QUERY\",\"ENTITY\"]}]",
-      {
-        {"xyy", "", "xyy", AutocompleteMatchType::SEARCH_HISTORY},
-        {"xy", "", "xy", AutocompleteMatchType::SEARCH_HISTORY},
-        {"x", "", "x", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED},
-        {"xy - A", "p=v", "xyy", AutocompleteMatchType::SEARCH_SUGGEST},
-        kEmptyMatch,
-      },
-    }
-  };
-
-  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
-    GURL term_url(AddSearchToHistory(
-        default_t_url_, ASCIIToUTF16(cases[i].history_search_term), 10));
-    profile_.BlockUntilHistoryProcessesPendingRequests();
-    QueryForInput(ASCIIToUTF16(cases[i].input_text), false, false);
-
-    // Set up a default fetcher with provided results.
-    net::TestURLFetcher* fetcher =
-        test_factory_.GetFetcherByID(
-            SearchProvider::kDefaultProviderURLFetcherID);
-    ASSERT_TRUE(fetcher);
-    fetcher->set_response_code(200);
-    fetcher->SetResponseString(cases[i].response_json);
-    fetcher->delegate()->OnURLFetchComplete(fetcher);
-
-    RunTillProviderDone();
-
-    const ACMatches& matches = provider_->matches();
-    ASSERT_FALSE(matches.empty());
-    SCOPED_TRACE("for case: " + base::IntToString(i));
-
-    ASSERT_LE(matches.size(), ARRAYSIZE_UNSAFE(cases[i].matches));
-    size_t j = 0;
-    // Ensure that the returned matches equal the expectations.
-    for (; j < matches.size(); ++j) {
-      SCOPED_TRACE(" and match index: " + base::IntToString(j));
-      EXPECT_EQ(cases[i].matches[j].contents,
-                UTF16ToUTF8(matches[j].contents));
-      EXPECT_EQ(cases[i].matches[j].query_params,
-                matches[j].search_terms_args->suggest_query_params);
-      EXPECT_EQ(cases[i].matches[j].fill_into_edit,
-                UTF16ToUTF8(matches[j].fill_into_edit));
-      EXPECT_EQ(cases[i].matches[j].type, matches[j].type);
-    }
-    // Ensure that no expected matches are missing.
-    for (; j < ARRAYSIZE_UNSAFE(cases[i].matches); ++j) {
-      SCOPED_TRACE(" and match index: " + base::IntToString(j));
-      EXPECT_EQ(cases[i].matches[j].contents, kNotApplicable);
-      EXPECT_EQ(cases[i].matches[j].query_params, kNotApplicable);
-      EXPECT_EQ(cases[i].matches[j].fill_into_edit, kNotApplicable);
-      EXPECT_EQ(cases[i].matches[j].type, AutocompleteMatchType::NUM_TYPES);
-    }
-  }
-}
 
 // A basic test that verifies the prefetch metadata parsing logic.
 TEST_F(SearchProviderTest, PrefetchMetadataParsing) {
diff --git a/chrome/browser/autocomplete/zero_suggest_provider.cc b/chrome/browser/autocomplete/zero_suggest_provider.cc
index 8366ab9..3406219 100644
--- a/chrome/browser/autocomplete/zero_suggest_provider.cc
+++ b/chrome/browser/autocomplete/zero_suggest_provider.cc
@@ -266,8 +266,9 @@
       }
     } else {
       suggest_results->push_back(SearchProvider::SuggestResult(
-          result, result, base::string16(), std::string(), std::string(), false,
-          relevance, relevances != NULL, false));
+          result, AutocompleteMatchType::SEARCH_SUGGEST, result,
+          base::string16(), std::string(), std::string(), false, relevance,
+          relevances != NULL, false));
     }
   }
 }
diff --git a/chrome/browser/metrics/metrics_log.cc b/chrome/browser/metrics/metrics_log.cc
index 9ebf3bc..ba2117d 100644
--- a/chrome/browser/metrics/metrics_log.cc
+++ b/chrome/browser/metrics/metrics_log.cc
@@ -131,6 +131,14 @@
       return OmniboxEventProto::Suggestion::SEARCH_HISTORY;
     case AutocompleteMatchType::SEARCH_SUGGEST:
       return OmniboxEventProto::Suggestion::SEARCH_SUGGEST;
+    case AutocompleteMatchType::SEARCH_SUGGEST_ENTITY:
+      return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_ENTITY;
+    case AutocompleteMatchType::SEARCH_SUGGEST_INFINITE:
+      return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_INFINITE;
+    case AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED:
+      return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_PERSONALIZED;
+    case AutocompleteMatchType::SEARCH_SUGGEST_PROFILE:
+      return OmniboxEventProto::Suggestion::SEARCH_SUGGEST_PROFILE;
     case AutocompleteMatchType::SEARCH_OTHER_ENGINE:
       return OmniboxEventProto::Suggestion::SEARCH_OTHER_ENGINE;
     case AutocompleteMatchType::EXTENSION_APP: