Commit d5c16812 authored by Wei-Yin Chen (陳威尹)'s avatar Wei-Yin Chen (陳威尹) Committed by Commit Bot

Make transition animation in Grid Tab Switcher closer to spec

Updates in both Tab-to-Grid and Grid-to-Tab transition animations:
- Stops showing the tab decoration when the tab resizes
- Fade in/fade out the GTS in the background when the tab resizes
- Update interpolator for tab resizing

Updates in Tab-to-Grid transition animation:
- Duration of GTS final fading-in: 218ms -> 50ms
- Delay the fading-in of Tab Switcher top toolbar to the second half
  of the animation

Bug: 971522
Change-Id: Ifc34437cb6691b18f0e4c63439b464b637927310
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1646741
Commit-Queue: Wei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#667193}
parent 3efe6a78
...@@ -29,6 +29,7 @@ import org.chromium.ui.resources.dynamics.ViewResourceAdapter; ...@@ -29,6 +29,7 @@ import org.chromium.ui.resources.dynamics.ViewResourceAdapter;
*/ */
class TabListRecyclerView extends RecyclerView { class TabListRecyclerView extends RecyclerView {
public static final long BASE_ANIMATION_DURATION_MS = 218; public static final long BASE_ANIMATION_DURATION_MS = 218;
public static final long FINAL_FADE_IN_DURATION_MS = 50;
public static final long RESTORE_ANIMATION_DURATION_MS = 10; public static final long RESTORE_ANIMATION_DURATION_MS = 10;
public static final int ANIMATION_STATUS_RESTORE = 0; public static final int ANIMATION_STATUS_RESTORE = 0;
public static final int ANIMATION_STATUS_ZOOM_OUT = 1; public static final int ANIMATION_STATUS_ZOOM_OUT = 1;
...@@ -106,11 +107,15 @@ class TabListRecyclerView extends RecyclerView { ...@@ -106,11 +107,15 @@ class TabListRecyclerView extends RecyclerView {
assert mFadeOutAnimator == null; assert mFadeOutAnimator == null;
mListener.startedShowing(animate); mListener.startedShowing(animate);
long duration = ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
? FINAL_FADE_IN_DURATION_MS
: BASE_ANIMATION_DURATION_MS;
setAlpha(0); setAlpha(0);
setVisibility(View.VISIBLE); setVisibility(View.VISIBLE);
mFadeInAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1); mFadeInAnimator = ObjectAnimator.ofFloat(this, View.ALPHA, 1);
mFadeInAnimator.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE); mFadeInAnimator.setInterpolator(BakedBezierInterpolator.FADE_IN_CURVE);
mFadeInAnimator.setDuration(BASE_ANIMATION_DURATION_MS); mFadeInAnimator.setDuration(duration);
mFadeInAnimator.start(); mFadeInAnimator.start();
mFadeInAnimator.addListener(new AnimatorListenerAdapter() { mFadeInAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
......
...@@ -17,17 +17,23 @@ import android.view.View; ...@@ -17,17 +17,23 @@ import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.DisabledTest;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ui.DummyUiActivity; import org.chromium.chrome.test.ui.DummyUiActivity;
import org.chromium.chrome.test.ui.DummyUiActivityTestCase; import org.chromium.chrome.test.ui.DummyUiActivityTestCase;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
...@@ -39,6 +45,14 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor; ...@@ -39,6 +45,14 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
*/ */
@RunWith(ChromeJUnit4ClassRunner.class) @RunWith(ChromeJUnit4ClassRunner.class)
public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase { public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase {
/**
* DummyUiActivityTestCase also needs {@link ChromeFeatureList}'s
* internal test-only feature map, not the {@link CommandLine} provided by
* {@link Features.InstrumentationProcessor}.
*/
@Rule
public TestRule mProcessor = new Features.JUnitProcessor();
private static final int CONTAINER_HEIGHT = 56; private static final int CONTAINER_HEIGHT = 56;
private TabGridContainerViewBinder mTabGridContainerViewHolder; private TabGridContainerViewBinder mTabGridContainerViewHolder;
private PropertyModel mContainerModel; private PropertyModel mContainerModel;
...@@ -83,6 +97,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase { ...@@ -83,6 +97,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase {
@Override @Override
public void setUpTest() throws Exception { public void setUpTest() throws Exception {
super.setUpTest(); super.setUpTest();
FeatureUtilities.setGridTabSwitcherEnabledForTesting(true);
TestThreadUtils.runOnUiThreadBlocking( TestThreadUtils.runOnUiThreadBlocking(
() -> { mRecyclerView = getActivity().findViewById(R.id.tab_list_view); }); () -> { mRecyclerView = getActivity().findViewById(R.id.tab_list_view); });
...@@ -100,6 +115,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase { ...@@ -100,6 +115,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase {
@Test @Test
@MediumTest @MediumTest
@Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
@DisabledTest @DisabledTest
// Failed multiple times on Android CFI https://crbug.com/954145 // Failed multiple times on Android CFI https://crbug.com/954145
public void testShowWithAnimation() throws Exception { public void testShowWithAnimation() throws Exception {
...@@ -129,6 +145,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase { ...@@ -129,6 +145,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase {
@Test @Test
@MediumTest @MediumTest
@UiThreadTest @UiThreadTest
@Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
public void testShowWithoutAnimation() throws Exception { public void testShowWithoutAnimation() throws Exception {
mContainerModel.set( mContainerModel.set(
TabListContainerProperties.VISIBILITY_LISTENER, mMockVisibilityListener); TabListContainerProperties.VISIBILITY_LISTENER, mMockVisibilityListener);
...@@ -145,6 +162,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase { ...@@ -145,6 +162,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase {
@Test @Test
@MediumTest @MediumTest
@Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
public void testHidesWithAnimation() throws Exception { public void testHidesWithAnimation() throws Exception {
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
mContainerModel.set( mContainerModel.set(
...@@ -182,6 +200,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase { ...@@ -182,6 +200,7 @@ public class TabGridContainerViewBinderTest extends DummyUiActivityTestCase {
@Test @Test
@MediumTest @MediumTest
@UiThreadTest @UiThreadTest
@Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
public void testHidesWithoutAnimation() throws Exception { public void testHidesWithoutAnimation() throws Exception {
mContainerModel.set( mContainerModel.set(
TabListContainerProperties.VISIBILITY_LISTENER, mMockVisibilityListener); TabListContainerProperties.VISIBILITY_LISTENER, mMockVisibilityListener);
......
...@@ -13,7 +13,9 @@ import android.provider.Settings; ...@@ -13,7 +13,9 @@ import android.provider.Settings;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v4.view.animation.LinearOutSlowInInterpolator;
import android.view.animation.AccelerateInterpolator; import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator; import android.view.animation.LinearInterpolator;
...@@ -114,6 +116,10 @@ public class CompositorAnimator extends Animator { ...@@ -114,6 +116,10 @@ public class CompositorAnimator extends Animator {
new DecelerateInterpolator(); new DecelerateInterpolator();
public static final FastOutSlowInInterpolator FAST_OUT_SLOW_IN_INTERPOLATOR = public static final FastOutSlowInInterpolator FAST_OUT_SLOW_IN_INTERPOLATOR =
new FastOutSlowInInterpolator(); new FastOutSlowInInterpolator();
public static final LinearOutSlowInInterpolator LINEAR_OUT_SLOW_IN_INTERPOLATOR =
new LinearOutSlowInInterpolator();
public static final FastOutLinearInInterpolator FAST_OUT_LINEAR_IN_INTERPOLATOR =
new FastOutLinearInInterpolator();
public static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator(); public static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
/** /**
...@@ -157,6 +163,29 @@ public class CompositorAnimator extends Animator { ...@@ -157,6 +163,29 @@ public class CompositorAnimator extends Animator {
return animator; return animator;
} }
/**
* A utility for creating a basic animator.
* @param handler The {@link CompositorAnimationHandler} responsible for running the animation.
* @param target The object to modify.
* @param property The property of the object to modify.
* @param startValue The {@link Supplier} of the starting animation value.
* @param endValue The {@link Supplier} of the end animation value.
* @param durationMs The duration of the animation in ms.
* @param interpolator The time interpolator for the animation.
* @return A {@link CompositorAnimator} for the property.
*/
public static <T> CompositorAnimator ofFloatProperty(CompositorAnimationHandler handler,
final T target, final FloatProperty<T> property, Supplier<Float> startValue,
Supplier<Float> endValue, long durationMs, TimeInterpolator interpolator) {
CompositorAnimator animator = new CompositorAnimator(handler);
animator.setValues(startValue, endValue);
animator.setDuration(durationMs);
animator.addUpdateListener(
(CompositorAnimator a) -> property.setValue(target, a.getAnimatedValue()));
animator.setInterpolator(interpolator);
return animator;
}
/** /**
* A utility for creating a basic animator. * A utility for creating a basic animator.
* @param handler The {@link CompositorAnimationHandler} responsible for running the animation. * @param handler The {@link CompositorAnimationHandler} responsible for running the animation.
...@@ -187,12 +216,8 @@ public class CompositorAnimator extends Animator { ...@@ -187,12 +216,8 @@ public class CompositorAnimator extends Animator {
public static <T> CompositorAnimator ofFloatProperty(CompositorAnimationHandler handler, public static <T> CompositorAnimator ofFloatProperty(CompositorAnimationHandler handler,
final T target, final FloatProperty<T> property, Supplier<Float> startValue, final T target, final FloatProperty<T> property, Supplier<Float> startValue,
Supplier<Float> endValue, long durationMs) { Supplier<Float> endValue, long durationMs) {
CompositorAnimator animator = new CompositorAnimator(handler); return ofFloatProperty(handler, target, property, startValue, endValue, durationMs,
animator.setValues(startValue, endValue); DECELERATE_INTERPOLATOR);
animator.setDuration(durationMs);
animator.addUpdateListener(
(CompositorAnimator a) -> property.setValue(target, a.getAnimatedValue()));
return animator;
} }
/** An interface for listening for frames of an animation. */ /** An interface for listening for frames of an animation. */
......
...@@ -403,7 +403,7 @@ public class ToolbarSwipeLayout extends Layout { ...@@ -403,7 +403,7 @@ public class ToolbarSwipeLayout extends Layout {
// contentViewport is intentionally passed for both parameters below. // contentViewport is intentionally passed for both parameters below.
mSceneLayer.pushLayers(getContext(), contentViewport, contentViewport, this, mSceneLayer.pushLayers(getContext(), contentViewport, contentViewport, this,
layerTitleCache, tabContentManager, resourceManager, fullscreenManager, layerTitleCache, tabContentManager, resourceManager, fullscreenManager,
SceneLayer.INVALID_RESOURCE_ID); SceneLayer.INVALID_RESOURCE_ID, 0);
} }
/** /**
......
...@@ -457,6 +457,6 @@ public class SimpleAnimationLayout extends Layout { ...@@ -457,6 +457,6 @@ public class SimpleAnimationLayout extends Layout {
// The content viewport is intentionally sent as both params below. // The content viewport is intentionally sent as both params below.
mSceneLayer.pushLayers(getContext(), contentViewport, contentViewport, this, mSceneLayer.pushLayers(getContext(), contentViewport, contentViewport, this,
layerTitleCache, tabContentManager, resourceManager, fullscreenManager, layerTitleCache, tabContentManager, resourceManager, fullscreenManager,
SceneLayer.INVALID_RESOURCE_ID); SceneLayer.INVALID_RESOURCE_ID, 0);
} }
} }
...@@ -1621,7 +1621,7 @@ public abstract class StackLayoutBase extends Layout { ...@@ -1621,7 +1621,7 @@ public abstract class StackLayoutBase extends Layout {
mSceneLayer.pushLayers(getContext(), viewport, contentViewport, this, layerTitleCache, mSceneLayer.pushLayers(getContext(), viewport, contentViewport, this, layerTitleCache,
tabContentManager, resourceManager, fullscreenManager, tabContentManager, resourceManager, fullscreenManager,
SceneLayer.INVALID_RESOURCE_ID); SceneLayer.INVALID_RESOURCE_ID, 0);
} }
/** /**
......
...@@ -56,7 +56,7 @@ public class TabListSceneLayer extends SceneLayer { ...@@ -56,7 +56,7 @@ public class TabListSceneLayer extends SceneLayer {
public void pushLayers(Context context, RectF viewport, RectF contentViewport, Layout layout, public void pushLayers(Context context, RectF viewport, RectF contentViewport, Layout layout,
LayerTitleCache layerTitleCache, TabContentManager tabContentManager, LayerTitleCache layerTitleCache, TabContentManager tabContentManager,
ResourceManager resourceManager, ChromeFullscreenManager fullscreenManager, ResourceManager resourceManager, ChromeFullscreenManager fullscreenManager,
int backgroundResourceId) { int backgroundResourceId, float backgroundAlpha) {
if (mNativePtr == 0) return; if (mNativePtr == 0) return;
Resources res = context.getResources(); Resources res = context.getResources();
...@@ -72,7 +72,7 @@ public class TabListSceneLayer extends SceneLayer { ...@@ -72,7 +72,7 @@ public class TabListSceneLayer extends SceneLayer {
viewport.height(), layerTitleCache, tabContentManager, resourceManager); viewport.height(), layerTitleCache, tabContentManager, resourceManager);
if (backgroundResourceId != INVALID_RESOURCE_ID) { if (backgroundResourceId != INVALID_RESOURCE_ID) {
nativePutBackgroundLayer(mNativePtr, backgroundResourceId); nativePutBackgroundLayer(mNativePtr, backgroundResourceId, backgroundAlpha);
} }
boolean isHTSEnabled = boolean isHTSEnabled =
...@@ -207,5 +207,6 @@ public class TabListSceneLayer extends SceneLayer { ...@@ -207,5 +207,6 @@ public class TabListSceneLayer extends SceneLayer {
float toolbarTextBoxAlpha, float toolbarAlpha, float toolbarYOffset, float toolbarTextBoxAlpha, float toolbarAlpha, float toolbarYOffset,
float sideBorderScale, boolean insetVerticalBorder); float sideBorderScale, boolean insetVerticalBorder);
private native void nativePutBackgroundLayer(long nativeTabListSceneLayer, int resourceId); private native void nativePutBackgroundLayer(
long nativeTabListSceneLayer, int resourceId, float alpha);
} }
...@@ -146,10 +146,18 @@ public class TabSwitcherModeTTPhone extends OptimizedFrameLayout ...@@ -146,10 +146,18 @@ public class TabSwitcherModeTTPhone extends OptimizedFrameLayout
// TODO(twellington): Handle interrupted animations to avoid jumps to 1.0 or 0.f. // TODO(twellington): Handle interrupted animations to avoid jumps to 1.0 or 0.f.
setAlpha(inTabSwitcherMode ? 0.0f : 1.0f); setAlpha(inTabSwitcherMode ? 0.0f : 1.0f);
boolean showZoomingAnimation = FeatureUtilities.isGridTabSwitcherEnabled()
&& ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_TO_GTS_ANIMATION);
long duration = showZoomingAnimation
? TopToolbarCoordinator.TAB_SWITCHER_MODE_GTS_ANIMATION_DURATION_MS
: TopToolbarCoordinator.TAB_SWITCHER_MODE_NORMAL_ANIMATION_DURATION_MS;
mVisiblityAnimator = mVisiblityAnimator =
ObjectAnimator.ofFloat(this, View.ALPHA, inTabSwitcherMode ? 1.0f : 0.0f); ObjectAnimator.ofFloat(this, View.ALPHA, inTabSwitcherMode ? 1.0f : 0.0f);
mVisiblityAnimator.setDuration( mVisiblityAnimator.setDuration(duration);
TopToolbarCoordinator.TAB_SWITCHER_MODE_NORMAL_ANIMATION_DURATION_MS); if (showZoomingAnimation && inTabSwitcherMode) {
mVisiblityAnimator.setStartDelay(duration);
}
mVisiblityAnimator.setInterpolator(new LinearInterpolator()); mVisiblityAnimator.setInterpolator(new LinearInterpolator());
// TODO(https://crbug.com/914868): Use consistent logic here for setting clickable/enabled // TODO(https://crbug.com/914868): Use consistent logic here for setting clickable/enabled
......
...@@ -35,6 +35,7 @@ import org.chromium.chrome.browser.widget.ToolbarProgressBar; ...@@ -35,6 +35,7 @@ import org.chromium.chrome.browser.widget.ToolbarProgressBar;
*/ */
public class TopToolbarCoordinator implements Toolbar { public class TopToolbarCoordinator implements Toolbar {
static final int TAB_SWITCHER_MODE_NORMAL_ANIMATION_DURATION_MS = 200; static final int TAB_SWITCHER_MODE_NORMAL_ANIMATION_DURATION_MS = 200;
static final int TAB_SWITCHER_MODE_GTS_ANIMATION_DURATION_MS = 150;
/** /**
* Observes toolbar URL expansion percentage change. * Observes toolbar URL expansion percentage change.
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.widget; package org.chromium.chrome.browser.widget;
import static org.chromium.chrome.browser.compositor.animation.CompositorAnimator.FAST_OUT_SLOW_IN_INTERPOLATOR;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
...@@ -32,7 +34,6 @@ import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer; ...@@ -32,7 +34,6 @@ import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.GridTabSwitcher;
import org.chromium.ui.interpolators.BakedBezierInterpolator;
import org.chromium.ui.resources.ResourceManager; import org.chromium.ui.resources.ResourceManager;
import org.chromium.ui.widget.Toast; import org.chromium.ui.widget.Toast;
...@@ -50,6 +51,7 @@ public class GridTabSwitcherLayout ...@@ -50,6 +51,7 @@ public class GridTabSwitcherLayout
// Duration of the transition animation // Duration of the transition animation
@VisibleForTesting @VisibleForTesting
static final long ZOOMING_DURATION = 300; static final long ZOOMING_DURATION = 300;
private static final int BACKGROUND_FADING_DURATION_MS = 150;
/** Field trial parameter for whether skipping slow zooming animation */ /** Field trial parameter for whether skipping slow zooming animation */
private static final String SKIP_SLOW_ZOOMING_PARAM = "skip-slow-zooming"; private static final String SKIP_SLOW_ZOOMING_PARAM = "skip-slow-zooming";
...@@ -64,6 +66,8 @@ public class GridTabSwitcherLayout ...@@ -64,6 +66,8 @@ public class GridTabSwitcherLayout
// To force Toolbar finishes its animation when this Layout finished hiding. // To force Toolbar finishes its animation when this Layout finished hiding.
private final LayoutTab mDummyLayoutTab; private final LayoutTab mDummyLayoutTab;
private float mBackgroundAlpha;
private int mFrameCount; private int mFrameCount;
private long mStartTime; private long mStartTime;
private long mLastFrameTime; private long mLastFrameTime;
...@@ -204,6 +208,7 @@ public class GridTabSwitcherLayout ...@@ -204,6 +208,7 @@ public class GridTabSwitcherLayout
private void shrinkTab(Supplier<Rect> target) { private void shrinkTab(Supplier<Rect> target) {
LayoutTab sourceLayoutTab = createLayoutTab(mTabModelSelector.getCurrentTabId(), LayoutTab sourceLayoutTab = createLayoutTab(mTabModelSelector.getCurrentTabId(),
mTabModelSelector.isIncognitoSelected(), NO_CLOSE_BUTTON, NEED_TITLE); mTabModelSelector.isIncognitoSelected(), NO_CLOSE_BUTTON, NEED_TITLE);
sourceLayoutTab.setDecorationAlpha(0);
mLayoutTabs = new LayoutTab[] {sourceLayoutTab}; mLayoutTabs = new LayoutTab[] {sourceLayoutTab};
...@@ -216,18 +221,26 @@ public class GridTabSwitcherLayout ...@@ -216,18 +221,26 @@ public class GridTabSwitcherLayout
animationList.add(CompositorAnimator.ofFloatProperty( animationList.add(CompositorAnimator.ofFloatProperty(
handler, sourceLayoutTab, LayoutTab.SCALE, () -> 1f, () -> { handler, sourceLayoutTab, LayoutTab.SCALE, () -> 1f, () -> {
return target.get().width() / (getWidth() * mDpToPx); return target.get().width() / (getWidth() * mDpToPx);
}, ZOOMING_DURATION)); }, ZOOMING_DURATION, FAST_OUT_SLOW_IN_INTERPOLATOR));
animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, LayoutTab.X, animationList.add(CompositorAnimator.ofFloatProperty(
() -> 0f, () -> { return target.get().left / mDpToPx; }, ZOOMING_DURATION)); handler, sourceLayoutTab, LayoutTab.X, () -> 0f, () -> {
animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, LayoutTab.Y, return target.get().left / mDpToPx;
() -> 0f, () -> { return target.get().top / mDpToPx; }, ZOOMING_DURATION)); }, ZOOMING_DURATION, FAST_OUT_SLOW_IN_INTERPOLATOR));
animationList.add(CompositorAnimator.ofFloatProperty( animationList.add(CompositorAnimator.ofFloatProperty(
handler, sourceLayoutTab, LayoutTab.DECORATION_ALPHA, 1f, 0f, ZOOMING_DURATION)); handler, sourceLayoutTab, LayoutTab.Y, () -> 0f, () -> {
return target.get().top / mDpToPx;
}, ZOOMING_DURATION, FAST_OUT_SLOW_IN_INTERPOLATOR));
// TODO(crbug.com/964406): when shrinking to the bottom row, bottom of the tab goes up and // TODO(crbug.com/964406): when shrinking to the bottom row, bottom of the tab goes up and
// down, making the "create group" visible for a while. // down, making the "create group" visible for a while.
animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab,
LayoutTab.MAX_CONTENT_HEIGHT, sourceLayoutTab.getUnclampedOriginalContentHeight(), LayoutTab.MAX_CONTENT_HEIGHT, sourceLayoutTab.getUnclampedOriginalContentHeight(),
getWidth(), ZOOMING_DURATION, BakedBezierInterpolator.FADE_OUT_CURVE)); getWidth(), ZOOMING_DURATION, FAST_OUT_SLOW_IN_INTERPOLATOR));
CompositorAnimator backgroundAlpha =
CompositorAnimator.ofFloat(handler, 0f, 1f, BACKGROUND_FADING_DURATION_MS,
animator -> mBackgroundAlpha = animator.getAnimatedValue());
backgroundAlpha.setInterpolator(CompositorAnimator.FAST_OUT_LINEAR_IN_INTERPOLATOR);
animationList.add(backgroundAlpha);
mTabToSwitcherAnimation = new AnimatorSet(); mTabToSwitcherAnimation = new AnimatorSet();
mTabToSwitcherAnimation.playTogether(animationList); mTabToSwitcherAnimation.playTogether(animationList);
...@@ -255,6 +268,7 @@ public class GridTabSwitcherLayout ...@@ -255,6 +268,7 @@ public class GridTabSwitcherLayout
private void expandTab(Rect source) { private void expandTab(Rect source) {
LayoutTab sourceLayoutTab = createLayoutTab(mTabModelSelector.getCurrentTabId(), LayoutTab sourceLayoutTab = createLayoutTab(mTabModelSelector.getCurrentTabId(),
mTabModelSelector.isIncognitoSelected(), NO_CLOSE_BUTTON, NEED_TITLE); mTabModelSelector.isIncognitoSelected(), NO_CLOSE_BUTTON, NEED_TITLE);
sourceLayoutTab.setDecorationAlpha(0);
mLayoutTabs = new LayoutTab[] {sourceLayoutTab}; mLayoutTabs = new LayoutTab[] {sourceLayoutTab};
...@@ -265,19 +279,24 @@ public class GridTabSwitcherLayout ...@@ -265,19 +279,24 @@ public class GridTabSwitcherLayout
// Zoom in the source tab // Zoom in the source tab
animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab,
LayoutTab.SCALE, source.width() / (getWidth() * mDpToPx), 1, ZOOMING_DURATION)); LayoutTab.SCALE, source.width() / (getWidth() * mDpToPx), 1, ZOOMING_DURATION,
FAST_OUT_SLOW_IN_INTERPOLATOR));
animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, LayoutTab.X, animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, LayoutTab.X,
source.left / mDpToPx, 0f, ZOOMING_DURATION)); source.left / mDpToPx, 0f, ZOOMING_DURATION, FAST_OUT_SLOW_IN_INTERPOLATOR));
animationList.add(CompositorAnimator.ofFloatProperty( animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, LayoutTab.Y,
handler, sourceLayoutTab, LayoutTab.Y, source.top / mDpToPx, 0f, ZOOMING_DURATION)); source.top / mDpToPx, 0f, ZOOMING_DURATION, FAST_OUT_SLOW_IN_INTERPOLATOR));
animationList.add(CompositorAnimator.ofFloatProperty(
handler, sourceLayoutTab, LayoutTab.DECORATION_ALPHA, 0f, 1f, ZOOMING_DURATION));
// TODO(crbug.com/964406): when shrinking to the bottom row, bottom of the tab goes up and // TODO(crbug.com/964406): when shrinking to the bottom row, bottom of the tab goes up and
// down, making the "create group" visible for a while. // down, making the "create group" visible for a while.
animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab, animationList.add(CompositorAnimator.ofFloatProperty(handler, sourceLayoutTab,
LayoutTab.MAX_CONTENT_HEIGHT, getWidth(), LayoutTab.MAX_CONTENT_HEIGHT, getWidth(),
sourceLayoutTab.getUnclampedOriginalContentHeight(), ZOOMING_DURATION, sourceLayoutTab.getUnclampedOriginalContentHeight(), ZOOMING_DURATION,
BakedBezierInterpolator.FADE_IN_CURVE)); FAST_OUT_SLOW_IN_INTERPOLATOR));
CompositorAnimator backgroundAlpha =
CompositorAnimator.ofFloat(handler, 1f, 0f, BACKGROUND_FADING_DURATION_MS,
animator -> mBackgroundAlpha = animator.getAnimatedValue());
backgroundAlpha.setInterpolator(CompositorAnimator.FAST_OUT_LINEAR_IN_INTERPOLATOR);
animationList.add(backgroundAlpha);
mTabToSwitcherAnimation = new AnimatorSet(); mTabToSwitcherAnimation = new AnimatorSet();
mTabToSwitcherAnimation.playTogether(animationList); mTabToSwitcherAnimation.playTogether(animationList);
...@@ -355,7 +374,8 @@ public class GridTabSwitcherLayout ...@@ -355,7 +374,8 @@ public class GridTabSwitcherLayout
layerTitleCache, tabContentManager, resourceManager, fullscreenManager, layerTitleCache, tabContentManager, resourceManager, fullscreenManager,
ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_TO_GTS_ANIMATION) ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
? mGridTabSwitcher.getResourceId() ? mGridTabSwitcher.getResourceId()
: 0); : 0,
mBackgroundAlpha);
mFrameCount++; mFrameCount++;
if (mLastFrameTime != 0) { if (mLastFrameTime != 0) {
long elapsed = SystemClock.elapsedRealtime() - mLastFrameTime; long elapsed = SystemClock.elapsedRealtime() - mLastFrameTime;
......
...@@ -203,7 +203,8 @@ void TabListSceneLayer::PutTabLayer( ...@@ -203,7 +203,8 @@ void TabListSceneLayer::PutTabLayer(
void TabListSceneLayer::PutBackgroundLayer( void TabListSceneLayer::PutBackgroundLayer(
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj, const base::android::JavaParamRef<jobject>& jobj,
jint resource_id) { jint resource_id,
jfloat alpha) {
int ui_resource_id = resource_manager_->GetUIResourceId( int ui_resource_id = resource_manager_->GetUIResourceId(
ui::ANDROID_RESOURCE_TYPE_DYNAMIC, resource_id); ui::ANDROID_RESOURCE_TYPE_DYNAMIC, resource_id);
if (ui_resource_id == 0) if (ui_resource_id == 0)
...@@ -221,6 +222,7 @@ void TabListSceneLayer::PutBackgroundLayer( ...@@ -221,6 +222,7 @@ void TabListSceneLayer::PutBackgroundLayer(
->GetResource(ui::ANDROID_RESOURCE_TYPE_DYNAMIC, resource_id) ->GetResource(ui::ANDROID_RESOURCE_TYPE_DYNAMIC, resource_id)
->size(); ->size();
background_layer_->SetBounds(size); background_layer_->SetBounds(size);
background_layer_->SetOpacity(alpha);
} }
void TabListSceneLayer::OnDetach() { void TabListSceneLayer::OnDetach() {
......
...@@ -110,7 +110,8 @@ class TabListSceneLayer : public SceneLayer { ...@@ -110,7 +110,8 @@ class TabListSceneLayer : public SceneLayer {
void PutBackgroundLayer(JNIEnv* env, void PutBackgroundLayer(JNIEnv* env,
const base::android::JavaParamRef<jobject>& jobj, const base::android::JavaParamRef<jobject>& jobj,
jint resource_id); jint resource_id,
jfloat alpha);
void OnDetach() override; void OnDetach() override;
bool ShouldShowBackground() override; bool ShouldShowBackground() override;
......
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