Compute navigation icon from current state.

Send signals needed to determine which navigation icon to show to
the status component and let it determine the correct icon from the
current state.

Bug: 871798

Change-Id: Ib2183595b8b0eb5228fe25398c8a257b6ca5bad7
Reviewed-on: https://chromium-review.googlesource.com/c/1396305
Commit-Queue: Ender <ender@google.com>
Reviewed-by: Theresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#622202}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
index dbe45ff..f149575 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -421,7 +421,6 @@
     public void onUrlFocusChange(boolean hasFocus) {
         mUrlHasFocus = hasFocus;
         updateButtonVisibility();
-        updateNavigationButton();
         updateShouldAnimateIconChanges();
 
         if (hasFocus) {
@@ -495,7 +494,6 @@
     @Override
     public void onUrlTextChanged() {
         updateButtonVisibility();
-        updateNavigationButton();
     }
 
     @Override
@@ -573,14 +571,6 @@
     }
 
     /**
-     * Updates the navigation button based on the URL string.
-     */
-    protected void updateNavigationButton() {
-        mStatusViewCoordinator.setNavigationButtonType(
-                StatusViewCoordinator.NavigationButtonType.EMPTY);
-    }
-
-    /**
      * Updates the security icon displayed in the LocationBar.
      */
     @Override
@@ -692,16 +682,14 @@
     }
 
     @Override
-    public void onSuggestionsHidden() {
-        updateNavigationButton();
-    }
-
-    @Override
     public void hideKeyboard() {
         getWindowAndroid().getKeyboardDelegate().hideKeyboard(mUrlBar);
     }
 
     @Override
+    public void onSuggestionsHidden() {}
+
+    @Override
     public void onSuggestionsChanged(String autocompleteText) {
         String userText = mUrlCoordinator.getTextWithoutAutocomplete();
         if (mUrlCoordinator.shouldAutocomplete()) {
@@ -714,9 +702,6 @@
             handleUrlFocusAnimation(mUrlHasFocus);
         }
 
-        // Update the navigation button to show the default suggestion's icon.
-        updateNavigationButton();
-
         if (mNativeInitialized
                 && !CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_INSTANT)
                 && PrivacyPreferencesManager.getInstance().shouldPrerender()
@@ -948,7 +933,6 @@
     @Override
     public void updateLoadingState(boolean updateUrl) {
         if (updateUrl) setUrlToPageUrl();
-        updateNavigationButton();
         mStatusViewCoordinator.updateStatusIcon();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
index 9536f728..3d51233 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarTablet.java
@@ -19,8 +19,6 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.download.DownloadUtils;
 import org.chromium.chrome.browser.ntp.NewTabPage;
-import org.chromium.chrome.browser.omnibox.status.StatusViewCoordinator;
-import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.toolbar.top.ToolbarTablet;
 import org.chromium.chrome.browser.widget.animation.CancelAwareAnimatorListener;
@@ -34,7 +32,6 @@
  * Location bar for tablet form factors.
  */
 public class LocationBarTablet extends LocationBarLayout {
-
     private static final int KEYBOARD_MODE_CHANGE_DELAY_MS = 300;
     private static final long MAX_NTP_KEYBOARD_FOCUS_DURATION_MS = 200;
 
@@ -117,7 +114,8 @@
         mBookmarkButton = findViewById(R.id.bookmark_button);
         mSaveOfflineButton = findViewById(R.id.save_offline_button);
 
-        mTargets = new View[] { mUrlBar, mDeleteButton };
+        mTargets = new View[] {mUrlBar, mDeleteButton};
+        mStatusViewCoordinator.setShowIconsWhenUrlFocused(true);
     }
 
     @Override
@@ -136,10 +134,8 @@
             offsetDescendantRectToMyCoords(target, mCachedTargetBounds);
             float x = event.getX();
             float y = event.getY();
-            float dx = distanceToRange(
-                    mCachedTargetBounds.left, mCachedTargetBounds.right, x);
-            float dy = distanceToRange(
-                    mCachedTargetBounds.top, mCachedTargetBounds.bottom, y);
+            float dx = distanceToRange(mCachedTargetBounds.left, mCachedTargetBounds.right, x);
+            float dy = distanceToRange(mCachedTargetBounds.top, mCachedTargetBounds.bottom, y);
             float distance = Math.abs(dx) + Math.abs(dy);
             if (selectedTarget == null || distance < selectedDistance) {
                 selectedTarget = target;
@@ -263,26 +259,17 @@
     }
 
     @Override
-    protected void updateNavigationButton() {
-        @StatusViewCoordinator.NavigationButtonType
-        int type = StatusViewCoordinator.NavigationButtonType.PAGE;
-
-        if (mAutocompleteCoordinator.getSuggestionCount() > 0) {
-            // If there are suggestions showing, show the icon for the default suggestion.
-            type = suggestionTypeToNavigationButtonType(
-                    mAutocompleteCoordinator.getSuggestionAt(0));
-        }
-
-        mStatusViewCoordinator.setNavigationButtonType(type);
+    public void onSuggestionsHidden() {
+        super.onSuggestionsHidden();
+        mStatusViewCoordinator.setFirstSuggestionIsSearchType(false);
     }
 
-    private static @StatusViewCoordinator.NavigationButtonType
-    int suggestionTypeToNavigationButtonType(OmniboxSuggestion suggestion) {
-        if (suggestion.isUrlSuggestion()) {
-            return StatusViewCoordinator.NavigationButtonType.PAGE;
-        } else {
-            return StatusViewCoordinator.NavigationButtonType.MAGNIFIER;
-        }
+    @Override
+    public void onSuggestionsChanged(String autocompleteText) {
+        super.onSuggestionsChanged(autocompleteText);
+        mStatusViewCoordinator.setFirstSuggestionIsSearchType(
+                mAutocompleteCoordinator.getSuggestionCount() > 0
+                && !mAutocompleteCoordinator.getSuggestionAt(0).isUrlSuggestion());
     }
 
     @Override
@@ -350,8 +337,8 @@
 
         ArrayList<Animator> animators = new ArrayList<>();
 
-        Animator widthChangeAnimator = ObjectAnimator.ofFloat(
-                this, mWidthChangePercentProperty, 0f);
+        Animator widthChangeAnimator =
+                ObjectAnimator.ofFloat(this, mWidthChangePercentProperty, 0f);
         widthChangeAnimator.setDuration(WIDTH_CHANGE_ANIMATION_DURATION_MS);
         widthChangeAnimator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
         widthChangeAnimator.addListener(new AnimatorListenerAdapter() {
@@ -382,8 +369,8 @@
 
         if (shouldShowSaveOfflineButton()) {
             animators.add(createShowButtonAnimator(mSaveOfflineButton));
-        // If the microphone button is already fully visible, don't animate its appearance.
         } else if (mMicButton.getVisibility() != View.VISIBLE || mMicButton.getAlpha() != 1.f) {
+            // If the microphone button is already fully visible, don't animate its appearance.
             animators.add(createShowButtonAnimator(mMicButton));
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
index 1d69784..14de9d3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
@@ -9,6 +9,7 @@
 import android.support.annotation.StringRes;
 import android.view.View;
 
+import org.chromium.base.VisibleForTesting;
 import org.chromium.chrome.R;
 import org.chromium.ui.modelutil.PropertyModel;
 
@@ -19,11 +20,14 @@
     private final PropertyModel mModel;
     private boolean mDarkTheme;
     private boolean mUrlHasFocus;
+    private boolean mFirstSuggestionIsSearchQuery;
     private boolean mVerboseStatusAllowed;
     private boolean mVerboseStatusSpaceAvailable;
     private boolean mPageIsPreview;
     private boolean mPageIsOffline;
 
+    private boolean mShowStatusIconWhenUrlFocused;
+
     private int mUrlMinWidth;
     private int mSeparatorMinWidth;
     private int mVerboseStatusTextMinWidth;
@@ -31,10 +35,9 @@
     private @DrawableRes int mSecurityIconRes;
     private @DrawableRes int mSecurityIconTintRes;
     private @StringRes int mSecurityIconDescriptionRes;
-    private @DrawableRes int mNavigationIconRes;
     private @DrawableRes int mNavigationIconTintRes;
 
-    private boolean mTestingIsSecurityButtonShown;
+    private boolean mIsSecurityButtonShown;
 
     StatusMediator(PropertyModel model) {
         mModel = model;
@@ -48,14 +51,6 @@
     }
 
     /**
-     * Specify navigation button image type.
-     */
-    void setNavigationButtonType(@DrawableRes int imageRes) {
-        mNavigationIconRes = imageRes;
-        updateLocationBarIcon();
-    }
-
-    /**
      * Specify whether displayed page is an offline page.
      */
     void setPageIsOffline(boolean pageIsOffline) {
@@ -109,6 +104,14 @@
     }
 
     /**
+     * Specify whether status icon should be shown when URL is focused.
+     */
+    void setShowIconsWhenUrlFocused(boolean showIconWhenFocused) {
+        mShowStatusIconWhenUrlFocused = showIconWhenFocused;
+        updateLocationBarIcon();
+    }
+
+    /**
      * Specify object to receive status click events.
      *
      * @param listener Specifies target object to receive events.
@@ -151,6 +154,14 @@
     }
 
     /**
+     * Reports whether the first omnibox suggestion is a search query.
+     */
+    void setFirstSuggestionIsSearchType(boolean firstSuggestionIsSearchQuery) {
+        mFirstSuggestionIsSearchQuery = firstSuggestionIsSearchQuery;
+        updateLocationBarIcon();
+    }
+
+    /**
      * Specify minimum width of an URL field.
      */
     void setUrlMinWidth(int width) {
@@ -241,8 +252,9 @@
     /**
      * Reports whether security icon is shown.
      */
-    boolean testIsSecurityButtonShown() {
-        return mTestingIsSecurityButtonShown;
+    @VisibleForTesting
+    boolean isSecurityButtonShown() {
+        return mIsSecurityButtonShown;
     }
 
     /**
@@ -257,27 +269,31 @@
      *     - not shown if URL is focused.
      */
     private void updateLocationBarIcon() {
+        int icon = 0;
+        int tint = 0;
+        int description = 0;
+        int toast = 0;
+
+        mIsSecurityButtonShown = false;
+
         if (mUrlHasFocus) {
-            mModel.set(StatusProperties.STATUS_ICON_RES, mNavigationIconRes);
-            mModel.set(StatusProperties.STATUS_ICON_TINT_RES, mNavigationIconTintRes);
-            mModel.set(StatusProperties.STATUS_ICON_DESCRIPTION_RES,
-                    R.string.accessibility_toolbar_btn_site_info);
-            mModel.set(StatusProperties.STATUS_ICON_ACCESSIBILITY_TOAST_RES, 0);
-            mTestingIsSecurityButtonShown = false;
-            return;
+            if (mShowStatusIconWhenUrlFocused) {
+                icon = mFirstSuggestionIsSearchQuery ? R.drawable.omnibox_search
+                                                     : R.drawable.ic_omnibox_page;
+                tint = mNavigationIconTintRes;
+                description = R.string.accessibility_toolbar_btn_site_info;
+            }
+        } else if (mSecurityIconRes != 0) {
+            mIsSecurityButtonShown = true;
+            icon = mSecurityIconRes;
+            tint = mSecurityIconTintRes;
+            description = mSecurityIconDescriptionRes;
+            toast = R.string.menu_page_info;
         }
 
-        if (!mUrlHasFocus && mSecurityIconRes != 0) {
-            mModel.set(StatusProperties.STATUS_ICON_RES, mSecurityIconRes);
-            mModel.set(StatusProperties.STATUS_ICON_TINT_RES, mSecurityIconTintRes);
-            mModel.set(StatusProperties.STATUS_ICON_DESCRIPTION_RES, mSecurityIconDescriptionRes);
-            mModel.set(
-                    StatusProperties.STATUS_ICON_ACCESSIBILITY_TOAST_RES, R.string.menu_page_info);
-            mTestingIsSecurityButtonShown = true;
-            return;
-        }
-
-        mTestingIsSecurityButtonShown = false;
-        mModel.set(StatusProperties.STATUS_ICON_RES, 0);
+        mModel.set(StatusProperties.STATUS_ICON_RES, icon);
+        mModel.set(StatusProperties.STATUS_ICON_TINT_RES, tint);
+        mModel.set(StatusProperties.STATUS_ICON_DESCRIPTION_RES, description);
+        mModel.set(StatusProperties.STATUS_ICON_ACCESSIBILITY_TOAST_RES, toast);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java
index 610d14c..83395de 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java
@@ -8,7 +8,6 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.support.annotation.DrawableRes;
-import android.support.annotation.IntDef;
 import android.view.View;
 
 import org.chromium.base.VisibleForTesting;
@@ -18,25 +17,11 @@
 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
 import org.chromium.ui.modelutil.PropertyModel;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * A component for displaying a status icon (e.g. security icon or navigation icon) and optional
  * verbose status text.
  */
 public class StatusViewCoordinator implements View.OnClickListener {
-    /**
-     * Specifies the types of buttons shown to signify different types of navigation elements.
-     */
-    @IntDef({NavigationButtonType.PAGE, NavigationButtonType.MAGNIFIER, NavigationButtonType.EMPTY})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface NavigationButtonType {
-        int PAGE = 0;
-        int MAGNIFIER = 1;
-        int EMPTY = 2;
-    }
-
     private final StatusView mStatusView;
     private final StatusMediator mMediator;
     private final PropertyModel mModel;
@@ -135,7 +120,7 @@
      */
     @VisibleForTesting
     public boolean isSecurityButtonShown() {
-        return mMediator.testIsSecurityButtonShown();
+        return mMediator.isSecurityButtonShown();
     }
 
     /**
@@ -148,28 +133,6 @@
     }
 
     /**
-     * Sets the type of the current navigation type and updates the UI to match it.
-     * @param buttonType The type of navigation button to be shown.
-     */
-    public void setNavigationButtonType(@NavigationButtonType int buttonType) {
-        @DrawableRes
-        int imageRes = 0;
-        switch (buttonType) {
-            case NavigationButtonType.PAGE:
-                imageRes = R.drawable.ic_omnibox_page;
-                break;
-            case NavigationButtonType.MAGNIFIER:
-                imageRes = R.drawable.omnibox_search;
-                break;
-            case NavigationButtonType.EMPTY:
-                break;
-            default:
-                assert false : "Invalid navigation button type";
-        }
-        mMediator.setNavigationButtonType(imageRes);
-    }
-
-    /**
      * Update visibility of the verbose status based on the button type and focus state of the
      * omnibox.
      */
@@ -214,4 +177,18 @@
     public void setShouldAnimateIconChanges(boolean shouldAnimate) {
         mMediator.setAnimationsEnabled(shouldAnimate);
     }
+
+    /**
+     * Specify whether URL should present icons when focused.
+     */
+    public void setShowIconsWhenUrlFocused(boolean showIconsWithUrlFocused) {
+        mMediator.setShowIconsWhenUrlFocused(showIconsWithUrlFocused);
+    }
+
+    /**
+     * Specify whether suggestion for URL bar is a search action.
+     */
+    public void setFirstSuggestionIsSearchType(boolean firstSuggestionIsSearchQuery) {
+        mMediator.setFirstSuggestionIsSearchType(firstSuggestionIsSearchQuery);
+    }
 }