Commit a763080e authored by Brandon Wylie's avatar Brandon Wylie Committed by Commit Bot

Animate the search engine logo into view

Adds support for the dse icon in the un/focus animations.
* For the NTP,
  * animations have been added between the fakebox/locationbar
  * the locationbar --> fakebox has a special animation which slides
    the url text over the status icon while the status icon is fading.
* For non-NTP pages,
  * the dse icon experiments introduces an icon for every page.
  * as a result of above, no special animations have been added for
    non-NTP pages.

Bug: 988883
Change-Id: I5a8b02ef0d763797194d7e18b42494cec9b57001
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1783557Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Commit-Queue: Theresa  <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695867}
parent 2e5c78cf
......@@ -25,6 +25,9 @@ public class LocationBarPhone extends LocationBarLayout {
private static final int ACTION_BUTTON_TOUCH_OVERFLOW_LEFT = 15;
private View mFirstVisibleFocusedView;
private View mUrlBar;
private View mStatusView;
private View mIconView;
private Runnable mKeyboardResizeModeTask;
......@@ -41,8 +44,9 @@ public class LocationBarPhone extends LocationBarLayout {
// Assign the first visible view here only if it hasn't been set by the DSE icon experiment.
// See onNativeLibrary ready for when this variable is set for the DSE icon case.
mFirstVisibleFocusedView = mFirstVisibleFocusedView == null ? findViewById(R.id.url_bar)
: mFirstVisibleFocusedView;
mUrlBar = findViewById(R.id.url_bar);
mFirstVisibleFocusedView =
mFirstVisibleFocusedView == null ? mUrlBar : mFirstVisibleFocusedView;
Rect delegateArea = new Rect();
mUrlActionContainer.getHitRect(delegateArea);
......@@ -61,9 +65,15 @@ public class LocationBarPhone extends LocationBarLayout {
super.updateSearchEngineStatusIcon(
shouldShowSearchEngineLogo, isSearchEngineGoogle, searchEngineUrl);
// The search logo will be the first visible view when the google logo is showing.
// The search engine icon will be the first visible focused view when it's showing.
if (mShouldShowSearchEngineLogo) {
mFirstVisibleFocusedView = findViewById(R.id.location_bar_status);
mStatusView = findViewById(R.id.location_bar_status);
mIconView = mStatusView.findViewById(R.id.location_bar_status_icon);
mFirstVisibleFocusedView = mStatusView;
// When the search engine icon is enabled, icons are translations into the parent view's
// padding area. Set clip padding to false to prevent them from getting clipped.
if (SearchEngineLogoUtils.shouldShowSearchEngineLogo()) setClipToPadding(false);
}
setShowIconsWhenUrlFocused(shouldShowSearchEngineLogo);
}
......@@ -75,6 +85,85 @@ public class LocationBarPhone extends LocationBarLayout {
return mFirstVisibleFocusedView;
}
/**
* Calculates the offset required for the focused LocationBar to appear as it's still unfocused
* so it can animate to a focused state.
*
* @param hasFocus True if the LocationBar has focus, this will be true between the focus
* animation starting and the unfocus animation starting.
* @return The offset for the location bar when showing the dse icon.
*/
public int getLocationBarOffsetForFocusAnimation(boolean hasFocus) {
if (mStatusView == null) return 0;
// No offset is required if the experiment is disabled.
if (!SearchEngineLogoUtils.shouldShowSearchEngineLogo()) return 0;
// On non-NTP pages, there will always be an icon when unfocused.
if (mToolbarDataProvider.getNewTabPageForCurrentTab() == null) return 0;
// This offset is only required when the focus animation is running.
if (!hasFocus) return 0;
// The offset is only required when the fakebox on the NTP is showing.
if (mToolbarDataProvider.getNewTabPageForCurrentTab() != null
&& !mToolbarDataProvider.getNewTabPageForCurrentTab().isLocationBarShownInNTP()) {
return 0;
}
// We're on the NTP with the fakebox showing.
// The value returned changes based on if the layout is LTR OR RTL.
// For LTR, the value is negative because we are making space on the left-hand side.
// For RTL, the value is positive because we are pushing the icon further to the
// right-hand side.
int offset = mStatusViewCoordinator.getStatusIconWidth();
return getLayoutDirection() == LAYOUT_DIRECTION_RTL ? offset : -offset;
}
/**
* Function used to position the url bar inside the location bar during omnibox animation.
*
* @param urlExpansionPercent The current expansion percent, 1 is fully focused and 0 is
* completely unfocused.
* @param hasFocus True if the LocationBar has focus, this will be true between the focus
* animation starting and the unfocus animation starting.
* @return The X translation for the URL bar, used in the toolbar animation.
*/
public float getUrlBarTranslationXForToolbarAnimation(
float urlExpansionPercent, boolean hasFocus) {
// This will be called before status view is ready.
if (mStatusView == null) return 0;
// No offset is required if the experiment is disabled.
if (!SearchEngineLogoUtils.shouldShowSearchEngineLogo()) return 0;
// Only apply the below offset if the unfocus animation is running.
if (hasFocus) return 0;
// Only apply the below offset if we're transitioning between the fakebox and locationbar.
if (mToolbarDataProvider.getNewTabPageForCurrentTab() == null
|| !mToolbarDataProvider.getNewTabPageForCurrentTab().isLocationBarShownInNTP()) {
return 0;
}
// When:
// 1. unfocusing the LocationBar on the NTP.
// 2. scrolling the fakebox to the LocationBar on the NTP.
// The status icon and the URL bar text overlap in the animation.
//
// This branch calculates the negative distance the URL bar needs to travel to completely
// overlap the status icon and end up in a state that matches the fakebox.
float overStatusIconTranslation =
-(1f - urlExpansionPercent) * (mStatusViewCoordinator.getStatusIconWidth());
// The value returned changes based on if the layout is LTR or RTL.
// For LTR, the value is negative because the status icon is left of the url bar on the
// x/y plane.
// For RTL, the value is positive because the status icon is right of the url bar on the
// x/y plane.
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
return isRtl ? -overStatusIconTranslation : overStatusIconTranslation;
}
/**
* Updates percentage of current the URL focus change animation.
* @param percent 1.0 is 100% focused, 0 is completely unfocused.
......@@ -163,6 +252,7 @@ public class LocationBarPhone extends LocationBarLayout {
protected void updateButtonVisibility() {
super.updateButtonVisibility();
updateMicButtonVisibility(mUrlFocusChangePercent);
updateStatusButtonVisibility(mUrlFocusChangePercent);
}
@Override
......@@ -176,6 +266,20 @@ public class LocationBarPhone extends LocationBarLayout {
mStatusViewCoordinator.setShowIconsWhenUrlFocused(showIcon);
}
/**
* Updates the display of the status button.
*
* @param urlFocusChangePercent The completion percentage of the URL focus change animation.
*/
private void updateStatusButtonVisibility(float urlFocusChangePercent) {
if (mIconView == null || !SearchEngineLogoUtils.shouldShowSearchEngineLogo()) return;
if (mToolbarDataProvider.getNewTabPageForCurrentTab() != null
&& mToolbarDataProvider.getNewTabPageForCurrentTab().isLocationBarShownInNTP()) {
mIconView.setAlpha(urlFocusChangePercent);
}
}
/**
* @param softInputMode The software input resize mode.
* @param delay Delay the change in input mode.
......
......@@ -334,14 +334,14 @@ class StatusMediator {
if (SearchEngineLogoUtils.shouldShowSearchEngineLogo()
&& (showFocused || showUnfocusedNewTabPage || showUnfocusedSearchResultsPage)) {
mShouldCancelCustomFavicon = false;
mModel.set(StatusProperties.STATUS_ICON_TINT_RES, /* no tint */ 0);
mModel.set(StatusProperties.STATUS_ICON_TINT_RES, 0);
if (mIsSearchEngineGoogle) {
mModel.set(StatusProperties.STATUS_ICON_RES,
SearchEngineLogoUtils.shouldShowSearchLoupeEverywhere()
? R.drawable.omnibox_search
: R.drawable.ic_logo_googleg_24dp);
} else {
mModel.set(StatusProperties.STATUS_ICON_RES, R.drawable.omnibox_search);
mModel.set(StatusProperties.STATUS_ICON_RES, R.drawable.ic_search);
if (!SearchEngineLogoUtils.shouldShowSearchLoupeEverywhere()) {
SearchEngineLogoUtils.getSearchEngineLogoFavicon(
Profile.getLastUsedProfile().getOriginalProfile(), mResources,
......
......@@ -21,6 +21,7 @@ import android.support.v7.content.res.AppCompatResources;
import android.util.AttributeSet;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.LinearLayout;
......@@ -130,7 +131,7 @@ public class StatusView extends LinearLayout {
//
// Note: this will be compacted once we start using LayoutTransition with StatusView.
boolean isIconHidden = mIconView.getVisibility() == View.GONE;
boolean isIconHidden = mIconView.getVisibility() == View.GONE || mIconView.getAlpha() == 0f;
if (!wantIconHidden && (isIconHidden || mAnimatingStatusIconHide)) {
// Action 1: animate showing, if icon was either hidden or hiding.
......@@ -419,4 +420,13 @@ public class StatusView extends LinearLayout {
View getSecurityButton() {
return mIconView;
}
/**
* @return The width of the status icon including start/end margins.
*/
int getStatusIconWidth() {
ViewGroup.MarginLayoutParams lp =
(ViewGroup.MarginLayoutParams) mIconView.getLayoutParams();
return lp.getMarginStart() + mIconView.getMeasuredWidth() + lp.getMarginEnd();
}
}
......@@ -204,4 +204,11 @@ public class StatusViewCoordinator implements View.OnClickListener {
mMediator.updateSearchEngineStatusIcon(
shouldShowSearchEngineLogo, isSearchEngineGoogle, searchEngineUrl);
}
/**
* @return Width of the status icon including start/end margins.
*/
public int getStatusIconWidth() {
return mStatusView.getStatusIconWidth();
}
}
......@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.native_page.NativePageFactory;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer;
import org.chromium.chrome.browser.omnibox.SearchEngineLogoUtils;
import org.chromium.chrome.browser.omnibox.UrlBarData;
import org.chromium.chrome.browser.previews.PreviewsAndroidBridge;
import org.chromium.chrome.browser.profiles.Profile;
......@@ -397,7 +398,9 @@ public class LocationBarModel implements ToolbarDataProvider, ToolbarCommonPrope
switch (securityLevel) {
case ConnectionSecurityLevel.NONE:
return isSmallDevice ? 0 : R.drawable.omnibox_info;
return isSmallDevice && !SearchEngineLogoUtils.shouldShowSearchEngineLogo()
? 0
: R.drawable.omnibox_info;
case ConnectionSecurityLevel.HTTP_SHOW_WARNING:
return R.drawable.omnibox_info;
case ConnectionSecurityLevel.DANGEROUS:
......
......@@ -59,6 +59,7 @@ import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.omnibox.LocationBar;
import org.chromium.chrome.browser.omnibox.LocationBarPhone;
import org.chromium.chrome.browser.omnibox.SearchEngineLogoUtils;
import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
import org.chromium.chrome.browser.profiles.Profile;
......@@ -994,6 +995,15 @@ public class ToolbarPhone extends ToolbarLayout implements Invalidator.Client, O
getViewBoundsLeftOfLocationBar(mVisualState) - mUnfocusedLocationBarLayoutLeft;
}
// When the dse icon is visible, the LocationBar needs additional translation to compensate
// for the dse icon being laid out when focused. This also affects the UrlBar, which is
// handled below. See comments in LocationBar#getLocationBarOffsetForFocusAnimation() for
// implementation details.
if (SearchEngineLogoUtils.shouldShowSearchEngineLogo()) {
locationBarBaseTranslationX +=
mLocationBar.getLocationBarOffsetForFocusAnimation(hasFocus());
}
boolean isLocationBarRtl = mLocationBar.getLayoutDirection() == LAYOUT_DIRECTION_RTL;
if (isLocationBarRtl) {
locationBarBaseTranslationX += mUnfocusedLocationBarLayoutWidth - currentWidth;
......@@ -1032,6 +1042,15 @@ public class ToolbarPhone extends ToolbarLayout implements Invalidator.Client, O
}
mLocationBar.setTranslationX(locationBarTranslationX);
// When the dse icon is enabled, the UrlBar needs additional translation to compensate for
// the additional translation applied to the LocationBar. See comments in
// LocationBar#getUrlBarTranslationXForToolbarAnimation() for implementation details.
if (SearchEngineLogoUtils.shouldShowSearchEngineLogo()) {
mUrlBar.setTranslationX(mLocationBar.getUrlBarTranslationXForToolbarAnimation(
mUrlExpansionPercent, hasFocus()));
}
if (!mExperimentalButtonAnimationRunning) {
mUrlActionContainer.setTranslationX(getUrlActionsTranslationXForExpansionAnimation(
isLocationBarRtl, locationBarBaseTranslationX));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment