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

Make transition animation in Grid Tab Switcher closer to spec (2)

Updates in Tab-to-Grid transition animation:
- Do not show the selected blue border in the grid when the tab resizes
- Fade in the selected blue border along with the GTS final fading-in

Bug: 971522
Change-Id: If788855ce4659226900759517cf7f8e9ab536e9e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1648835
Commit-Queue: Wei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#667204}
parent c6c1ad32
...@@ -27,6 +27,10 @@ public interface GridTabSwitcher { ...@@ -27,6 +27,10 @@ public interface GridTabSwitcher {
*/ */
interface GridVisibilityObserver extends OverviewModeBehavior.OverviewModeObserver {} interface GridVisibilityObserver extends OverviewModeBehavior.OverviewModeObserver {}
/**
* @return GridController implementation that can be used for controlling
* grid visibility changes.
*/
GridController getGridController(); GridController getGridController();
/** /**
......
...@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.tasks.tab_management; ...@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.tasks.tab_management;
import android.content.Context; import android.content.Context;
import android.graphics.Rect; import android.graphics.Rect;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.CompositorViewHolder;
...@@ -19,7 +20,6 @@ import org.chromium.chrome.browser.lifecycle.Destroyable; ...@@ -19,7 +20,6 @@ import org.chromium.chrome.browser.lifecycle.Destroyable;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabList;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -97,10 +97,7 @@ public class GridTabSwitcherCoordinator ...@@ -97,10 +97,7 @@ public class GridTabSwitcherCoordinator
mLifecycleDispatcher.register(this); mLifecycleDispatcher.register(this);
} }
/** // GridTabSwitcher implementation.
* @return GridController implementation that will can be used for controlling
* grid visibility changes.
*/
@Override @Override
public GridController getGridController() { public GridController getGridController() {
return mMediator; return mMediator;
...@@ -108,8 +105,9 @@ public class GridTabSwitcherCoordinator ...@@ -108,8 +105,9 @@ public class GridTabSwitcherCoordinator
@Override @Override
public boolean prepareOverview() { public boolean prepareOverview() {
boolean quick = mMediator.prepareOverview();
mTabGridCoordinator.prepareOverview(); mTabGridCoordinator.prepareOverview();
return mMediator.prepareOverview(); return quick;
} }
@Override @Override
...@@ -135,12 +133,9 @@ public class GridTabSwitcherCoordinator ...@@ -135,12 +133,9 @@ public class GridTabSwitcherCoordinator
return mTabGridCoordinator.getLastDirtyTimeForTesting(); return mTabGridCoordinator.getLastDirtyTimeForTesting();
} }
/** // ResetHandler implementation.
* Reset the tab grid with the given {@link TabModel}. Can be null.
* @param tabList The current {@link TabList} to show the tabs for in the grid.
*/
@Override @Override
public boolean resetWithTabList(TabList tabList) { public boolean resetWithTabList(@Nullable TabList tabList, boolean quickMode) {
List<Tab> tabs = null; List<Tab> tabs = null;
if (tabList != null) { if (tabList != null) {
tabs = new ArrayList<>(); tabs = new ArrayList<>();
...@@ -148,7 +143,7 @@ public class GridTabSwitcherCoordinator ...@@ -148,7 +143,7 @@ public class GridTabSwitcherCoordinator
tabs.add(tabList.getTabAt(i)); tabs.add(tabList.getTabAt(i));
} }
} }
return mTabGridCoordinator.resetWithListOfTabs(tabs); return mTabGridCoordinator.resetWithListOfTabs(tabs, quickMode);
} }
@Override @Override
...@@ -156,6 +151,7 @@ public class GridTabSwitcherCoordinator ...@@ -156,6 +151,7 @@ public class GridTabSwitcherCoordinator
mTabGridCoordinator.softCleanup(); mTabGridCoordinator.softCleanup();
} }
// ResetHandler implementation.
@Override @Override
public void destroy() { public void destroy() {
mTabGridCoordinator.destroy(); mTabGridCoordinator.destroy();
......
...@@ -108,9 +108,12 @@ class GridTabSwitcherMediator ...@@ -108,9 +108,12 @@ class GridTabSwitcherMediator
*/ */
interface ResetHandler { interface ResetHandler {
/** /**
* Reset the tab grid with the given {@link TabList}, which can be null.
* @param tabList The {@link TabList} to show the tabs for in the grid.
* @param quickMode Whether to skip capturing the selected live tab for the thumbnail.
* @return Whether the {@link TabListRecyclerView} can be shown quickly. * @return Whether the {@link TabListRecyclerView} can be shown quickly.
*/ */
boolean resetWithTabList(TabList tabList); boolean resetWithTabList(@Nullable TabList tabList, boolean quickMode);
/** /**
* Release the thumbnail {@link Bitmap} but keep the {@link TabGridViewHolder}. * Release the thumbnail {@link Bitmap} but keep the {@link TabGridViewHolder}.
...@@ -143,7 +146,7 @@ class GridTabSwitcherMediator ...@@ -143,7 +146,7 @@ class GridTabSwitcherMediator
TabList currentTabModelFilter = TabList currentTabModelFilter =
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(); mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter();
mResetHandler.resetWithTabList(currentTabModelFilter); mResetHandler.resetWithTabList(currentTabModelFilter, false);
mContainerViewModel.set(IS_INCOGNITO, currentTabModelFilter.isIncognito()); mContainerViewModel.set(IS_INCOGNITO, currentTabModelFilter.isIncognito());
} }
}; };
...@@ -195,7 +198,7 @@ class GridTabSwitcherMediator ...@@ -195,7 +198,7 @@ class GridTabSwitcherMediator
mTabGridDialogResetHandler = tabGridDialogResetHandler; mTabGridDialogResetHandler = tabGridDialogResetHandler;
mSoftClearTabListRunnable = mResetHandler::softCleanup; mSoftClearTabListRunnable = mResetHandler::softCleanup;
mClearTabListRunnable = () -> mResetHandler.resetWithTabList(null); mClearTabListRunnable = () -> mResetHandler.resetWithTabList(null, false);
mHandler = new Handler(); mHandler = new Handler();
} }
...@@ -263,7 +266,7 @@ class GridTabSwitcherMediator ...@@ -263,7 +266,7 @@ class GridTabSwitcherMediator
mHandler.removeCallbacks(mSoftClearTabListRunnable); mHandler.removeCallbacks(mSoftClearTabListRunnable);
mHandler.removeCallbacks(mClearTabListRunnable); mHandler.removeCallbacks(mClearTabListRunnable);
boolean quick = mResetHandler.resetWithTabList( boolean quick = mResetHandler.resetWithTabList(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter()); mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), false);
int initialPosition = Math.max( int initialPosition = Math.max(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter().index() mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter().index()
- INITIAL_SCROLL_INDEX_OFFSET, - INITIAL_SCROLL_INDEX_OFFSET,
...@@ -274,6 +277,8 @@ class GridTabSwitcherMediator ...@@ -274,6 +277,8 @@ class GridTabSwitcherMediator
@Override @Override
public void showOverview(boolean animate) { public void showOverview(boolean animate) {
mResetHandler.resetWithTabList(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), true);
if (!animate) mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, false); if (!animate) mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, false);
setVisibility(true); setVisibility(true);
mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, true); mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, true);
......
...@@ -126,7 +126,7 @@ public class TabGridDialogMediator { ...@@ -126,7 +126,7 @@ public class TabGridDialogMediator {
private void updateGridTabSwitcher() { private void updateGridTabSwitcher() {
if (!mModel.get(TabGridSheetProperties.IS_DIALOG_VISIBLE)) return; if (!mModel.get(TabGridSheetProperties.IS_DIALOG_VISIBLE)) return;
mGridTabSwitcherResetHandler.resetWithTabList( mGridTabSwitcherResetHandler.resetWithTabList(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter()); mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), false);
} }
private void updateDialog() { private void updateDialog() {
......
...@@ -185,15 +185,18 @@ public class TabListCoordinator implements Destroyable { ...@@ -185,15 +185,18 @@ public class TabListCoordinator implements Destroyable {
} }
/** /**
* Reset the tab grid with the given List of Tabs. Can be null. * @see TabListMediator#resetWithListOfTabs(List, boolean)
* @param tabs List of Tabs to show for in the UI.
*/ */
public boolean resetWithListOfTabs(@Nullable List<Tab> tabs) { boolean resetWithListOfTabs(@Nullable List<Tab> tabs, boolean quickMode) {
if (mMode == TabListMode.STRIP && tabs != null && tabs.size() > 1) { if (mMode == TabListMode.STRIP && tabs != null && tabs.size() > 1) {
TabGroupUtils.maybeShowIPH( TabGroupUtils.maybeShowIPH(
FeatureConstants.TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE, mRecyclerView); FeatureConstants.TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE, mRecyclerView);
} }
return mMediator.resetWithListOfTabs(tabs); return mMediator.resetWithListOfTabs(tabs, quickMode);
}
boolean resetWithListOfTabs(@Nullable List<Tab> tabs) {
return resetWithListOfTabs(tabs, false);
} }
void softCleanup() { void softCleanup() {
...@@ -202,6 +205,7 @@ public class TabListCoordinator implements Destroyable { ...@@ -202,6 +205,7 @@ public class TabListCoordinator implements Destroyable {
void prepareOverview() { void prepareOverview() {
mRecyclerView.prepareOverview(); mRecyclerView.prepareOverview();
mMediator.prepareOverview();
} }
void postHiding() { void postHiding() {
......
...@@ -535,6 +535,21 @@ class TabListMediator { ...@@ -535,6 +535,21 @@ class TabListMediator {
return position != TabModel.INVALID_TAB_INDEX && position < mModel.size(); return position != TabModel.INVALID_TAB_INDEX && position < mModel.size();
} }
/**
* Hide the blue border for selected tab for the Tab-to-Grid resizing stage.
* The selected border should re-appear in the final fading-in stage.
*/
void prepareOverview() {
int count = 0;
for (int i = 0; i < mModel.size(); i++) {
if (mModel.get(i).get(TabProperties.IS_SELECTED)) count++;
mModel.get(i).set(TabProperties.IS_SELECTED, false);
}
assert (count == 1)
: "There should be exactly one selected tab when calling "
+ "TabListMediator.prepareOverview()";
}
private boolean areTabsUnchanged(@Nullable List<Tab> tabs) { private boolean areTabsUnchanged(@Nullable List<Tab> tabs) {
if (tabs == null) { if (tabs == null) {
return mModel.size() == 0; return mModel.size() == 0;
...@@ -549,9 +564,10 @@ class TabListMediator { ...@@ -549,9 +564,10 @@ class TabListMediator {
/** /**
* Initialize the component with a list of tabs to show in a grid. * Initialize the component with a list of tabs to show in a grid.
* @param tabs The list of tabs to be shown. * @param tabs The list of tabs to be shown.
* @param quickMode Whether to skip capturing the selected live tab for the thumbnail.
* @return Whether the {@link TabListRecyclerView} can be shown quickly. * @return Whether the {@link TabListRecyclerView} can be shown quickly.
*/ */
public boolean resetWithListOfTabs(@Nullable List<Tab> tabs) { boolean resetWithListOfTabs(@Nullable List<Tab> tabs, boolean quickMode) {
if (areTabsUnchanged(tabs)) { if (areTabsUnchanged(tabs)) {
if (tabs == null) return true; if (tabs == null) return true;
...@@ -563,7 +579,7 @@ class TabListMediator { ...@@ -563,7 +579,7 @@ class TabListMediator {
boolean isSelected = mTabModelSelector.getCurrentTab() == tab; boolean isSelected = mTabModelSelector.getCurrentTab() == tab;
mModel.get(i).set(TabProperties.IS_SELECTED, isSelected); mModel.get(i).set(TabProperties.IS_SELECTED, isSelected);
if (mThumbnailProvider != null && isSelected) { if (mThumbnailProvider != null && isSelected && !quickMode) {
ThumbnailFetcher callback = new ThumbnailFetcher(mThumbnailProvider, tab, true); ThumbnailFetcher callback = new ThumbnailFetcher(mThumbnailProvider, tab, true);
mModel.get(i).set(TabProperties.THUMBNAIL_FETCHER, callback); mModel.get(i).set(TabProperties.THUMBNAIL_FETCHER, callback);
} }
......
...@@ -286,7 +286,7 @@ public class GridTabSwitcherMediatorUnitTest { ...@@ -286,7 +286,7 @@ public class GridTabSwitcherMediatorUnitTest {
mMediator.setCleanupDelayForTesting(0); mMediator.setCleanupDelayForTesting(0);
mMediator.postHiding(); mMediator.postHiding();
verify(mResetHandler).softCleanup(); verify(mResetHandler).softCleanup();
verify(mResetHandler).resetWithTabList(eq(null)); verify(mResetHandler).resetWithTabList(eq(null), eq(false));
} }
@Test @Test
...@@ -295,7 +295,7 @@ public class GridTabSwitcherMediatorUnitTest { ...@@ -295,7 +295,7 @@ public class GridTabSwitcherMediatorUnitTest {
doReturn(true).when(mTabModelFilter).isIncognito(); doReturn(true).when(mTabModelFilter).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null); mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler).resetWithTabList(eq(mTabModelFilter)); verify(mResetHandler).resetWithTabList(eq(mTabModelFilter), eq(false));
assertThat(mModel.get(TabListContainerProperties.IS_INCOGNITO), equalTo(true)); assertThat(mModel.get(TabListContainerProperties.IS_INCOGNITO), equalTo(true));
// Switching TabModels by itself shouldn't cause visibility changes. // Switching TabModels by itself shouldn't cause visibility changes.
......
...@@ -578,7 +578,7 @@ public class TabListMediatorUnitTest { ...@@ -578,7 +578,7 @@ public class TabListMediatorUnitTest {
for (int i = 0; i < mTabModel.getCount(); i++) { for (int i = 0; i < mTabModel.getCount(); i++) {
tabs.add(mTabModel.getTabAt(i)); tabs.add(mTabModel.getTabAt(i));
} }
mMediator.resetWithListOfTabs(tabs); mMediator.resetWithListOfTabs(tabs, false);
for (Callback<Drawable> callback : mCallbackCaptor.getAllValues()) { for (Callback<Drawable> callback : mCallbackCaptor.getAllValues()) {
callback.onResult(new ColorDrawable(Color.RED)); callback.onResult(new ColorDrawable(Color.RED));
} }
......
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