[go: up one dir, main page]

IconOrFavicon metrics

(cherry picked from commit 666018f9e8a02ef6966ac1d63b9560fecc90956d)

Bug: 960469
Change-Id: I50845a7d20bd5b2e2a19f94c9e4d48cd1200ee6d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650793
Commit-Queue: Ender <ender@google.com>
Reviewed-by: Mark Pearson <mpearson@chromium.org>
Reviewed-by: Matthew Jones <mdjones@chromium.org>
Reviewed-by: Theresa <twellington@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1660692
Reviewed-by: Sky Malice <skym@chromium.org>
Cr-Commit-Position: refs/branch-heads/3809@{#366}
Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
index 70de7b7..818be3e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -41,7 +41,7 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
-import org.chromium.components.omnibox.AnswerType;
+import org.chromium.chrome.browser.util.UrlConstants;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.ui.base.PageTransition;
@@ -63,20 +63,20 @@
         implements OnSuggestionsReceivedListener, SuggestionHost, StartStopWithNativeObserver {
     /** A struct containing information about the suggestion and its view type. */
     private static class SuggestionViewInfo {
+        /** Processor managing the suggestion. */
+        public final SuggestionProcessor processor;
+
         /** The suggestion this info represents. */
         public final OmniboxSuggestion suggestion;
 
         /** The model the view uses to render the suggestion. */
         public final PropertyModel model;
 
-        /** The view type ID. */
-        public final int typeId;
-
-        public SuggestionViewInfo(
-                OmniboxSuggestion omniboxSuggestion, PropertyModel propertyModel, int id) {
+        public SuggestionViewInfo(SuggestionProcessor suggestionProcessor,
+                OmniboxSuggestion omniboxSuggestion, PropertyModel propertyModel) {
+            processor = suggestionProcessor;
             suggestion = omniboxSuggestion;
             model = propertyModel;
-            typeId = id;
         }
     }
 
@@ -177,7 +177,7 @@
 
     @Override
     public void onStopWithNative() {
-        recordAnswersHistogram();
+        recordSuggestionsShown();
     }
 
     /**
@@ -190,19 +190,14 @@
     }
 
     /**
-     * Record presence of AiS answers.
-     *
-     * Note: At the time of writing this functionality, AiS was offering at most one answer to any
-     * query. If this changes before the metric is expired, the code below may need either
-     * revisiting or a secondary metric telling us how many answer suggestions have been shown.
+     * Record histograms for presented suggestions.
      */
-    private void recordAnswersHistogram() {
+    private void recordSuggestionsShown() {
         int richEntitiesCount = 0;
         for (SuggestionViewInfo info : mCurrentModels) {
-            if (info.suggestion.hasAnswer()) {
-                RecordHistogram.recordEnumeratedHistogram("Omnibox.AnswerInSuggestShown",
-                        info.suggestion.getAnswer().getType(), AnswerType.TOTAL_COUNT);
-            } else if (mEntitySuggestionProcessor.doesProcessSuggestion(info.suggestion)) {
+            info.processor.recordSuggestionPresented(info.suggestion, info.model);
+
+            if (info.processor.getViewTypeId() == OmniboxSuggestionUiType.ENTITY_SUGGESTION) {
                 richEntitiesCount++;
             }
         }
@@ -239,7 +234,7 @@
         List<Pair<Integer, PropertyModel>> models = new ArrayList<>(mCurrentModels.size());
         for (int i = 0; i < mCurrentModels.size(); i++) {
             PropertyModel model = mCurrentModels.get(i).model;
-            models.add(new Pair<>(mCurrentModels.get(i).typeId, model));
+            models.add(new Pair<>(mCurrentModels.get(i).processor.getViewTypeId(), model));
         }
         mListPropertyModel.set(SuggestionListProperties.SUGGESTION_MODELS, models);
     }
@@ -398,9 +393,7 @@
                 });
             }
         } else {
-            // Record presence of answers as user stops interacting with omnibox.
-            // This covers actions such as pressing 'back' button or choosing an answer.
-            recordAnswersHistogram();
+            recordSuggestionsShown();
 
             mSuggestionVisibilityState = SuggestionVisibilityState.DISALLOWED;
             mHasStartedNewOmniboxEditSession = false;
@@ -540,6 +533,9 @@
             };
             return;
         }
+        SuggestionViewInfo info = mCurrentModels.get(position);
+        info.processor.recordSuggestionUsed(info.suggestion, info.model);
+
         loadUrlFromOmniboxMatch(position, suggestion, mLastActionUpTimestamp, true);
         mDelegate.hideKeyboard();
     }
@@ -827,8 +823,7 @@
             // Before populating the model, add it to the list of current models.  If the suggestion
             // has an image and the image was already cached, it will be updated synchronously and
             // the model will only have the image populated if it is tracked as a current model.
-            mCurrentModels.add(
-                    new SuggestionViewInfo(suggestion, model, processor.getViewTypeId()));
+            mCurrentModels.add(new SuggestionViewInfo(processor, suggestion, model));
 
             processor.populateModel(suggestion, model, i);
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java
index 16904e9..a91fff0c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java
@@ -46,4 +46,21 @@
      * @param position The position of the suggestion in the list.
      */
     void populateModel(OmniboxSuggestion suggestion, PropertyModel model, int position);
+
+    /**
+     * Record histograms for presented suggestion.
+     * Purpose of this function is bookkeeping of presented suggestions at the time user finishes
+     * interacting with omnibox (whether navigating somewhere, turning off screen, leaving omnibox
+     * or closing the app).
+     * This call is invoked only on Processor responsible for managing specific omnibox suggestion
+     * type.
+     */
+    void recordSuggestionPresented(OmniboxSuggestion suggestion, PropertyModel model);
+
+    /**
+     * Record histograms for used suggestion.
+     * Invoked whenever user uses particular suggestion to navigate somewhere.
+     * Only the processor responsible for managing specific suggestion receives this call.
+     */
+    void recordSuggestionUsed(OmniboxSuggestion suggestion, PropertyModel model);
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
index bb9f6e85..e2e1924f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
@@ -11,6 +11,7 @@
 import android.view.View;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.browser.ChromeApplication;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
@@ -114,6 +115,21 @@
         }
     }
 
+    @Override
+    public void recordSuggestionPresented(OmniboxSuggestion suggestion, PropertyModel model) {
+        // Note: At the time of writing this functionality, AiS was offering at most one answer to
+        // any query. If this changes before the metric is expired, the code below may need either
+        // revisiting or a secondary metric telling us how many answer suggestions have been shown.
+        RecordHistogram.recordEnumeratedHistogram("Omnibox.AnswerInSuggestShown",
+                suggestion.getAnswer().getType(), AnswerType.TOTAL_COUNT);
+    }
+
+    @Override
+    public void recordSuggestionUsed(OmniboxSuggestion suggestion, PropertyModel model) {
+        // Bookkeeping handled in C++:
+        // https://cs.chromium.org/Omnibox.SuggestionUsed.AnswerInSuggest
+    }
+
     private void maybeFetchAnswerIcon(OmniboxSuggestion suggestion, PropertyModel model) {
         ThreadUtils.assertOnUiThread();
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java
index 1569641..91b0f0d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java
@@ -15,6 +15,8 @@
 import android.view.View;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeFeatureList;
 import org.chromium.chrome.browser.favicon.LargeIconBridge;
@@ -83,6 +85,20 @@
     @Override
     public void onUrlFocusChange(boolean hasFocus) {}
 
+    @Override
+    public void recordSuggestionPresented(OmniboxSuggestion suggestion, PropertyModel model) {
+        RecordHistogram.recordEnumeratedHistogram("Omnibox.IconOrFaviconShown",
+                model.get(SuggestionViewProperties.SUGGESTION_ICON_TYPE),
+                SuggestionIcon.TOTAL_COUNT);
+    }
+
+    @Override
+    public void recordSuggestionUsed(OmniboxSuggestion suggestion, PropertyModel model) {
+        RecordHistogram.recordEnumeratedHistogram("Omnibox.SuggestionUsed.IconOrFaviconType",
+                model.get(SuggestionViewProperties.SUGGESTION_ICON_TYPE),
+                SuggestionIcon.TOTAL_COUNT);
+    }
+
     /**
      * Signals that native initialization has completed.
      */
@@ -105,23 +121,52 @@
         }
     }
 
+    /**
+     * Returns suggestion icon to be presented for specified omnibox suggestion.
+     *
+     * This method returns the stock icon type to be attached to the Suggestion.
+     * Note that the stock icons do not include Favicon - Favicon is only declared
+     * when we know we have a valid and large enough site favicon to present.
+     */
+    @VisibleForTesting
+    public @SuggestionIcon int getSuggestionIconType(OmniboxSuggestion suggestion) {
+        if (suggestion.isUrlSuggestion()) {
+            if (suggestion.isStarred()) {
+                return SuggestionIcon.BOOKMARK;
+            } else if (suggestion.getType() == OmniboxSuggestionType.HISTORY_URL) {
+                return mEnableSuggestionFavicons ? SuggestionIcon.GLOBE : SuggestionIcon.HISTORY;
+            } else {
+                return SuggestionIcon.GLOBE;
+            }
+        } else /* Search suggestion */ {
+            switch (suggestion.getType()) {
+                case OmniboxSuggestionType.VOICE_SUGGEST:
+                    return SuggestionIcon.VOICE;
+
+                case OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED:
+                case OmniboxSuggestionType.SEARCH_HISTORY:
+                    return mEnableSuggestionFavicons ? SuggestionIcon.MAGNIFIER
+                                                     : SuggestionIcon.HISTORY;
+
+                case OmniboxSuggestionType.CALCULATOR:
+                    return mEnableNewAnswerLayout ? SuggestionIcon.CALCULATOR
+                                                  : SuggestionIcon.MAGNIFIER;
+
+                default:
+                    return SuggestionIcon.MAGNIFIER;
+            }
+        }
+    }
+
     private void setStateForSuggestion(PropertyModel model, OmniboxSuggestion suggestion) {
         int suggestionType = suggestion.getType();
-        @SuggestionIcon
-        int suggestionIcon;
         Spannable textLine1;
 
         Spannable textLine2;
         int textLine2Color = 0;
         int textLine2Direction = View.TEXT_DIRECTION_INHERIT;
+
         if (suggestion.isUrlSuggestion()) {
-            suggestionIcon = SuggestionIcon.GLOBE;
-            if (suggestion.isStarred()) {
-                suggestionIcon = SuggestionIcon.BOOKMARK;
-            } else if (!mEnableSuggestionFavicons
-                    && suggestionType == OmniboxSuggestionType.HISTORY_URL) {
-                suggestionIcon = SuggestionIcon.HISTORY;
-            }
             boolean urlHighlighted = false;
             if (!TextUtils.isEmpty(suggestion.getUrl())) {
                 Spannable str = SpannableString.valueOf(suggestion.getDisplayText());
@@ -138,15 +183,6 @@
             }
             textLine1 = getSuggestedQuery(suggestion, true, !urlHighlighted);
         } else {
-            suggestionIcon = SuggestionIcon.MAGNIFIER;
-            if (suggestionType == OmniboxSuggestionType.VOICE_SUGGEST) {
-                suggestionIcon = SuggestionIcon.VOICE;
-            } else if (!mEnableSuggestionFavicons
-                    && ((suggestionType == OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED)
-                            || (suggestionType == OmniboxSuggestionType.SEARCH_HISTORY))) {
-                // Show history icon for suggestions based on user queries.
-                suggestionIcon = SuggestionIcon.HISTORY;
-            }
             textLine1 = getSuggestedQuery(suggestion, false, true);
             if ((suggestionType == OmniboxSuggestionType.SEARCH_SUGGEST_ENTITY)
                     || (suggestionType == OmniboxSuggestionType.SEARCH_SUGGEST_PROFILE)) {
@@ -158,7 +194,6 @@
                 textLine2Direction = View.TEXT_DIRECTION_INHERIT;
             } else if (mEnableNewAnswerLayout
                     && suggestionType == OmniboxSuggestionType.CALCULATOR) {
-                suggestionIcon = SuggestionIcon.CALCULATOR;
                 textLine2 = SpannableString.valueOf(
                         mUrlBarEditingTextProvider.getTextWithAutocomplete());
 
@@ -170,6 +205,9 @@
             }
         }
 
+        model.set(SuggestionViewProperties.SUGGESTION_ICON_TYPE, getSuggestionIconType(suggestion));
+        model.set(SuggestionViewProperties.SUGGESTION_ICON_BITMAP, null);
+
         model.set(SuggestionViewProperties.IS_ANSWER, false);
         model.set(SuggestionViewProperties.HAS_ANSWER_IMAGE, false);
         model.set(SuggestionViewProperties.ANSWER_IMAGE, null);
@@ -193,7 +231,6 @@
                                         .omnibox_suggestion_second_line_text_size)));
         model.set(SuggestionViewProperties.TEXT_LINE_1_MAX_LINES, 1);
         model.set(SuggestionViewProperties.TEXT_LINE_2_MAX_LINES, 1);
-        model.set(SuggestionViewProperties.SUGGESTION_ICON_BITMAP, null);
 
         // Include site favicon if we are presenting URL and have favicon available.
         if (mLargeIconBridge != null && suggestion.getUrl() != null) {
@@ -201,8 +238,12 @@
                     (Bitmap icon, int fallbackColor, boolean isFallbackColorDefault,
                             int iconType) -> {
                         if (!mSuggestionHost.isActiveModel(model)) return;
-                        model.set(SuggestionViewProperties.SUGGESTION_ICON_BITMAP, icon);
-                        mSuggestionHost.notifyPropertyModelsChanged();
+                        if (icon != null) {
+                            model.set(SuggestionViewProperties.SUGGESTION_ICON_BITMAP, icon);
+                            model.set(SuggestionViewProperties.SUGGESTION_ICON_TYPE,
+                                    SuggestionIcon.FAVICON);
+                            mSuggestionHost.notifyPropertyModelsChanged();
+                        }
                     });
         }
 
@@ -211,7 +252,6 @@
                         suggestion.getDisplayText());
         model.set(SuggestionViewProperties.REFINABLE, !sameAsTyped);
 
-        model.set(SuggestionViewProperties.SUGGESTION_ICON_TYPE, suggestionIcon);
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewProperties.java
index 576bbb1f..8844c949 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewProperties.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewProperties.java
@@ -25,18 +25,22 @@
  * The properties associated with rendering the suggestion view.
  */
 public class SuggestionViewProperties {
-    @IntDef({SuggestionIcon.UNDEFINED, SuggestionIcon.BOOKMARK, SuggestionIcon.HISTORY,
+    @IntDef({SuggestionIcon.UNSET, SuggestionIcon.BOOKMARK, SuggestionIcon.HISTORY,
             SuggestionIcon.GLOBE, SuggestionIcon.MAGNIFIER, SuggestionIcon.VOICE,
-            SuggestionIcon.CALCULATOR})
+            SuggestionIcon.CALCULATOR, SuggestionIcon.FAVICON, SuggestionIcon.TOTAL_COUNT})
     @Retention(RetentionPolicy.SOURCE)
     public @interface SuggestionIcon {
-        int UNDEFINED = -1;
-        int BOOKMARK = 0;
-        int HISTORY = 1;
-        int GLOBE = 2;
-        int MAGNIFIER = 3;
-        int VOICE = 4;
-        int CALCULATOR = 5;
+        // This enum is used to back UMA histograms, and should therefore be treated as append-only.
+        // See http://cs.chromium.org/SuggestionIconOrFaviconType
+        int UNSET = 0;
+        int BOOKMARK = 1;
+        int HISTORY = 2;
+        int GLOBE = 3;
+        int MAGNIFIER = 4;
+        int VOICE = 5;
+        int CALCULATOR = 6;
+        int FAVICON = 7;
+        int TOTAL_COUNT = 8;
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewViewBinder.java
index 1258b04c..c24d68d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/SuggestionViewViewBinder.java
@@ -156,6 +156,18 @@
 
             int drawableId = R.drawable.ic_omnibox_page;
             switch (type) {
+                case SuggestionIcon.UNSET:
+                case SuggestionIcon.FAVICON:
+                    // At this point there is no suggestion icon available - yet.
+                    // - UNSET indicates we have yet to identify adequate SuggestionIcon type,
+                    // - FAVICON indicates suggestion is about to receive a favicon bitmap, but
+                    //   that has not yet happened.
+                    // This path will be triggered as a result of USE_DARK_COLORS or
+                    // SHOW_SUGGESTION_ICONS properties being set before we had the chance to
+                    // update SUGGESTION_ICON_TYPE, or adapter copying keys to a new model.
+                    // This is not an error.
+                    return;
+
                 case SuggestionIcon.GLOBE:
                     drawableId = R.drawable.ic_globe_24dp;
                     break;
@@ -175,11 +187,6 @@
                     drawableId = R.drawable.ic_equals_sign_round;
                     allowTint = false;
                     break;
-                case SuggestionIcon.UNDEFINED:
-                    // Since SuggestionViews may be re-used, there is a risk we would be
-                    // presenting an stale favicon already.
-                    assert false : "Unknown suggestion icon type.";
-                    break;
                 default:
                     break;
             }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java
index ded877e..ac052e4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java
@@ -235,6 +235,12 @@
                 ChromeFeatureList.isEnabled(ChromeFeatureList.OMNIBOX_SHOW_SUGGESTION_FAVICONS);
     }
 
+    @Override
+    public void recordSuggestionPresented(OmniboxSuggestion suggestion, PropertyModel model) {}
+
+    @Override
+    public void recordSuggestionUsed(OmniboxSuggestion suggestion, PropertyModel model) {}
+
     /**
      * Updates the profile used for extracting website favicons.
      * @param profile The profile to be used.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java
index e3b2b6f..f4163521 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java
@@ -77,6 +77,17 @@
         if (mImageFetcher != null && !hasFocus) mImageFetcher.clear();
     }
 
+    @Override
+    public void recordSuggestionPresented(OmniboxSuggestion suggestion, PropertyModel model) {
+        // Not used.
+    }
+
+    @Override
+    public void recordSuggestionUsed(OmniboxSuggestion suggestion, PropertyModel model) {
+        // Bookkeeping handled in C++:
+        // http://cs.chromium.org/Omnibox.SuggestionUsed.RichEntity
+    }
+
     private void fetchEntityImage(OmniboxSuggestion suggestion, PropertyModel model) {
         ThreadUtils.assertOnUiThread();
         final String url = suggestion.getImageUrl();
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 8a6f8e48..257139d 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -54569,6 +54569,18 @@
   <int value="12" label="Play install"/>
 </enum>
 
+<enum name="SuggestionIconOrFaviconType">
+  <summary>Type of icon shown beside omnibox suggestion.</summary>
+  <int value="0" label="Invalid (unknown type)"/>
+  <int value="1" label="Bookmark"/>
+  <int value="2" label="History"/>
+  <int value="3" label="Globe"/>
+  <int value="4" label="Magnifying Glass"/>
+  <int value="5" label="Voice"/>
+  <int value="6" label="Calculator"/>
+  <int value="7" label="Favicon"/>
+</enum>
+
 <enum name="SuggestionsResponseState">
   <int value="0" label="Empty response received from the server."/>
   <int value="1" label="Invalid response received from the server."/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 1d49a96..ac666dc 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -84232,6 +84232,25 @@
   </summary>
 </histogram>
 
+<histogram name="Omnibox.IconOrFaviconShown" enum="SuggestionIconOrFaviconType"
+    expires_after="M83">
+  <owner>chrome-android-omnibox-team@google.com</owner>
+  <owner>ender@google.com</owner>
+  <owner>jdonnelly@google.com</owner>
+  <owner>mpearson@google.com</owner>
+  <summary>
+    Records suggestions decorated with specific icon or favicon at the time the
+    user exited the omnibox. Exiting the omnibox includes navigating (to entered
+    text or any suggestion), pressing the system back key, clearing omnibox,
+    blanking screen / locking the phone (whether intentionally or due to
+    inactivity), or closing the Chrome app. This metric is logged every time the
+    omnibox is exited, including when no answer is present in the list of
+    suggestions.
+
+    This histogram is related to Omnibox.SuggestionUsed.IconOrFaviconType.
+  </summary>
+</histogram>
+
 <histogram name="Omnibox.InputType" enum="OmniboxInputType">
   <owner>mpearson@chromium.org</owner>
   <owner>jdonnelly@chromium.org</owner>
@@ -84633,6 +84652,21 @@
   </summary>
 </histogram>
 
+<histogram name="Omnibox.SuggestionUsed.IconOrFaviconType"
+    enum="SuggestionIconOrFaviconType" expires_after="M83">
+  <owner>chrome-android-omnibox-team@google.com</owner>
+  <owner>ender@google.com</owner>
+  <owner>jdonnelly@google.com</owner>
+  <owner>mpearson@google.com</owner>
+  <summary>
+    Counts how often omnibox suggestions are used, and in the case a regular
+    search / url (not an Answer, Entity or any other specialized) suggestion was
+    selected - records how the suggestion was decorated.
+
+    This histogram is related to Omnibox.IconOrFaviconShown.
+  </summary>
+</histogram>
+
 <histogram name="Omnibox.SuggestionUsed.NearbyURLCount" units="URLs"
     expires_after="2017-02-23">
   <obsolete>