Commit 7a142877 authored by Yue Zhang's avatar Yue Zhang Committed by Commit Bot

TabGridDialog selection mode polish

* Tint the toolbar menu button properly.
* When rotation happens, update the position of selection editor
  PopupWindow instead of re-showing it.
* Calculate the dialog position instead of using getGlobalVisibleRect
  which doesn't deterministically happen early enough when rotating.
* Pull out positioning-related logics from TabSelectionEditorLayout
  to TabSelectionEditorMediator and add tests.

Bug: 1011269, 1011271
Change-Id: Iff3b5d993030f7798981b5ff5d945b28a2655188
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1846246
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarMei Liang <meiliang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#706608}
parent 9a93075a
...@@ -31,6 +31,7 @@ import android.widget.RelativeLayout; ...@@ -31,6 +31,7 @@ import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
...@@ -47,7 +48,7 @@ import java.lang.annotation.RetentionPolicy; ...@@ -47,7 +48,7 @@ import java.lang.annotation.RetentionPolicy;
* Parent for TabGridDialog component. * Parent for TabGridDialog component.
*/ */
public class TabGridDialogParent public class TabGridDialogParent
implements TabSelectionEditorLayout.TabSelectionEditorLayoutPositionProvider { implements TabSelectionEditorMediator.TabSelectionEditorPositionProvider {
private static final int DIALOG_ANIMATION_DURATION = 300; private static final int DIALOG_ANIMATION_DURATION = 300;
private static final int DIALOG_ALPHA_ANIMATION_DURATION = 150; private static final int DIALOG_ALPHA_ANIMATION_DURATION = 150;
private static final int CARD_FADE_ANIMATION_DURATION = 50; private static final int CARD_FADE_ANIMATION_DURATION = 50;
...@@ -654,19 +655,17 @@ public class TabGridDialogParent ...@@ -654,19 +655,17 @@ public class TabGridDialogParent
} }
/** /**
* {@link TabSelectionEditorLayout.TabSelectionEditorLayoutPositionProvider} implementation. * {@link TabSelectionEditorMediator.TabSelectionEditorPositionProvider} implementation.
* Returns a {@link Rect} that indicates the current position of dialog. * Returns a {@link Rect} that indicates the current position of dialog.
*/ */
@Override @Override
@NonNull
public Rect getSelectionEditorPositionRect() { public Rect getSelectionEditorPositionRect() {
Rect positionRect = new Rect(); // Get the status bar height as offset.
mDialogContainerView.getGlobalVisibleRect(positionRect);
Rect parentRect = new Rect(); Rect parentRect = new Rect();
mParent.getGlobalVisibleRect(parentRect); mParent.getGlobalVisibleRect(parentRect);
return new Rect(mSideMargin, mTopMargin + parentRect.top, mCurrentScreenWidth - mSideMargin,
// Offset by the status bar height. mCurrentScreenHeight - mTopMargin);
positionRect.offset(0, parentRect.top);
return positionRect;
} }
/** /**
......
...@@ -103,6 +103,9 @@ public class TabGroupUiToolbarView extends FrameLayout { ...@@ -103,6 +103,9 @@ public class TabGroupUiToolbarView extends FrameLayout {
ApiCompatibilityUtils.setImageTintList(mLeftButton, tint); ApiCompatibilityUtils.setImageTintList(mLeftButton, tint);
ApiCompatibilityUtils.setImageTintList(mRightButton, tint); ApiCompatibilityUtils.setImageTintList(mRightButton, tint);
if (mTitleTextView != null) mTitleTextView.setTextColor(tint); if (mTitleTextView != null) mTitleTextView.setTextColor(tint);
if (mMenuButton != null) {
ApiCompatibilityUtils.setImageTintList(mMenuButton, tint);
}
} }
/** /**
......
...@@ -74,7 +74,8 @@ class TabSelectionEditorCoordinator { ...@@ -74,7 +74,8 @@ class TabSelectionEditorCoordinator {
public TabSelectionEditorCoordinator(Context context, View parentView, public TabSelectionEditorCoordinator(Context context, View parentView,
TabModelSelector tabModelSelector, TabContentManager tabContentManager, TabModelSelector tabModelSelector, TabContentManager tabContentManager,
TabSelectionEditorLayout.TabSelectionEditorLayoutPositionProvider positionProvider) { @Nullable TabSelectionEditorMediator
.TabSelectionEditorPositionProvider positionProvider) {
mContext = context; mContext = context;
mParentView = parentView; mParentView = parentView;
mTabModelSelector = tabModelSelector; mTabModelSelector = tabModelSelector;
...@@ -87,15 +88,14 @@ class TabSelectionEditorCoordinator { ...@@ -87,15 +88,14 @@ class TabSelectionEditorCoordinator {
.inflate(R.layout.tab_selection_editor_layout, null) .inflate(R.layout.tab_selection_editor_layout, null)
.findViewById(R.id.selectable_list); .findViewById(R.id.selectable_list);
mTabSelectionEditorLayout.initialize(mParentView, mTabListCoordinator.getContainerView(), mTabSelectionEditorLayout.initialize(mParentView, mTabListCoordinator.getContainerView(),
mTabListCoordinator.getContainerView().getAdapter(), mSelectionDelegate, mTabListCoordinator.getContainerView().getAdapter(), mSelectionDelegate);
positionProvider);
mSelectionDelegate.setSelectionModeEnabledForZeroItems(true); mSelectionDelegate.setSelectionModeEnabledForZeroItems(true);
mTabSelectionEditorLayoutChangeProcessor = PropertyModelChangeProcessor.create( mTabSelectionEditorLayoutChangeProcessor = PropertyModelChangeProcessor.create(
mModel, mTabSelectionEditorLayout, TabSelectionEditorLayoutBinder::bind); mModel, mTabSelectionEditorLayout, TabSelectionEditorLayoutBinder::bind);
mTabSelectionEditorMediator = new TabSelectionEditorMediator( mTabSelectionEditorMediator = new TabSelectionEditorMediator(mContext, mTabModelSelector,
mContext, mTabModelSelector, this::resetWithListOfTabs, mModel, mSelectionDelegate); this::resetWithListOfTabs, mModel, mSelectionDelegate, positionProvider);
} }
/** /**
......
...@@ -14,8 +14,10 @@ import android.view.ViewGroup; ...@@ -14,8 +14,10 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.widget.selection.SelectableListLayout; import org.chromium.chrome.browser.widget.selection.SelectableListLayout;
import org.chromium.chrome.browser.widget.selection.SelectionDelegate; import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.tab_ui.R;
...@@ -27,22 +29,10 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> { ...@@ -27,22 +29,10 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> {
private final PopupWindow mWindow; private final PopupWindow mWindow;
private TabSelectionEditorToolbar mToolbar; private TabSelectionEditorToolbar mToolbar;
private View mParentView; private View mParentView;
private TabSelectionEditorLayoutPositionProvider mPositionProvider;
private ViewTreeObserver.OnGlobalLayoutListener mParentLayoutListener; private ViewTreeObserver.OnGlobalLayoutListener mParentLayoutListener;
private @Nullable Rect mPositionRect;
private boolean mIsInitialized; private boolean mIsInitialized;
/**
* An interface to provide the {@link Rect} used to position the selection editor layout on
* screen.
*/
public interface TabSelectionEditorLayoutPositionProvider {
/**
* This method fetches the {@link Rect} used to position the selection editor layout.
* @return The {@link Rect} indicates where to show the selection editor layout.
*/
Rect getSelectionEditorPositionRect();
}
// TODO(meiliang): inflates R.layout.tab_selection_editor_layout in // TODO(meiliang): inflates R.layout.tab_selection_editor_layout in
// TabSelectionEditorCoordinator. // TabSelectionEditorCoordinator.
public TabSelectionEditorLayout(Context context, AttributeSet attrs) { public TabSelectionEditorLayout(Context context, AttributeSet attrs) {
...@@ -60,28 +50,15 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> { ...@@ -60,28 +50,15 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> {
* @param adapter The adapter that provides views that represent items in the recycler view. * @param adapter The adapter that provides views that represent items in the recycler view.
* @param selectionDelegate The {@link SelectionDelegate} that will inform the toolbar of * @param selectionDelegate The {@link SelectionDelegate} that will inform the toolbar of
* selection changes. * selection changes.
* @param positionProvider The {@link TabSelectionEditorLayoutPositionProvider} that provides
* the position rect to show the selection editor layout.
*/ */
void initialize(View parentView, RecyclerView recyclerView, RecyclerView.Adapter adapter, void initialize(View parentView, RecyclerView recyclerView, RecyclerView.Adapter adapter,
SelectionDelegate<Integer> selectionDelegate, SelectionDelegate<Integer> selectionDelegate) {
@Nullable TabSelectionEditorLayoutPositionProvider positionProvider) {
mIsInitialized = true; mIsInitialized = true;
initializeRecyclerView(adapter, recyclerView); initializeRecyclerView(adapter, recyclerView);
mToolbar = mToolbar =
(TabSelectionEditorToolbar) initializeToolbar(R.layout.tab_selection_editor_toolbar, (TabSelectionEditorToolbar) initializeToolbar(R.layout.tab_selection_editor_toolbar,
selectionDelegate, 0, 0, 0, null, false, true); selectionDelegate, 0, 0, 0, null, false, true);
mParentView = parentView; mParentView = parentView;
mPositionProvider = positionProvider;
// Re-fetch the position rect and re-show the selection editor in case there is a global
// layout change on parent view, e.g. re-layout caused by orientation change.
mParentLayoutListener = () -> {
if (mWindow.isShowing() && mPositionProvider != null) {
hide();
show();
}
};
mParentView.getViewTreeObserver().addOnGlobalLayoutListener(mParentLayoutListener);
} }
/** /**
...@@ -89,14 +66,14 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> { ...@@ -89,14 +66,14 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> {
*/ */
public void show() { public void show() {
assert mIsInitialized; assert mIsInitialized;
if (mPositionProvider == null) { if (mPositionRect == null) {
mWindow.showAtLocation(mParentView, Gravity.CENTER, 0, 0); mWindow.showAtLocation(mParentView, Gravity.CENTER, 0, 0);
return; return;
} }
Rect rect = mPositionProvider.getSelectionEditorPositionRect(); mWindow.setWidth(mPositionRect.width());
mWindow.setWidth(rect.width()); mWindow.setHeight(mPositionRect.height());
mWindow.setHeight(rect.height()); mWindow.showAtLocation(
mWindow.showAtLocation(mParentView, Gravity.NO_GRAVITY, rect.left, rect.top); mParentView, Gravity.NO_GRAVITY, mPositionRect.left, mPositionRect.top);
} }
/** /**
...@@ -114,6 +91,32 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> { ...@@ -114,6 +91,32 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> {
return mToolbar; return mToolbar;
} }
/**
* Register a {@link ViewTreeObserver.OnGlobalLayoutListener} handling TabSelectionEditor
* related changes when parent view global layout changed.
*/
public void registerGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener listener) {
if (mParentView == null || listener == null) return;
if (mParentLayoutListener != null) {
mParentView.getViewTreeObserver().removeOnGlobalLayoutListener(mParentLayoutListener);
}
mParentLayoutListener = listener;
mParentView.getViewTreeObserver().addOnGlobalLayoutListener(listener);
}
/**
* Update the {@link Rect} used to show the selection editor. If the editor is currently
* showing, update its positioning.
* @param rect The {@link Rect} to update mPositionRect.
*/
public void updateTabSelectionEditorPositionRect(@NonNull Rect rect) {
assert rect != null;
mPositionRect = rect;
if (mWindow.isShowing()) {
mWindow.update(rect.left, rect.top, rect.width(), rect.height());
}
}
/** /**
* Destroy any members that needs clean up. * Destroy any members that needs clean up.
*/ */
...@@ -122,4 +125,9 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> { ...@@ -122,4 +125,9 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> {
mParentView.getViewTreeObserver().removeOnGlobalLayoutListener(mParentLayoutListener); mParentView.getViewTreeObserver().removeOnGlobalLayoutListener(mParentLayoutListener);
} }
} }
@VisibleForTesting
Rect getPositionRectForTesting() {
return mPositionRect;
}
} }
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.tasks.tab_management; package org.chromium.chrome.browser.tasks.tab_management;
import android.graphics.Rect;
import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -49,6 +51,17 @@ public class TabSelectionEditorLayoutBinder { ...@@ -49,6 +51,17 @@ public class TabSelectionEditorLayoutBinder {
== propertyKey) { == propertyKey) {
view.getToolbar().setActionButtonEnablingThreshold(model.get( view.getToolbar().setActionButtonEnablingThreshold(model.get(
TabSelectionEditorProperties.TOOLBAR_ACTION_BUTTON_ENABLING_THRESHOLD)); TabSelectionEditorProperties.TOOLBAR_ACTION_BUTTON_ENABLING_THRESHOLD));
} else if (TabSelectionEditorProperties.SELECTION_EDITOR_POSITION_RECT == propertyKey) {
Rect positionRect =
model.get(TabSelectionEditorProperties.SELECTION_EDITOR_POSITION_RECT);
if (positionRect == null) {
return;
}
view.updateTabSelectionEditorPositionRect(positionRect);
} else if (TabSelectionEditorProperties.SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER
== propertyKey) {
view.registerGlobalLayoutListener(model.get(
TabSelectionEditorProperties.SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER));
} }
} }
} }
...@@ -6,10 +6,12 @@ package org.chromium.chrome.browser.tasks.tab_management; ...@@ -6,10 +6,12 @@ package org.chromium.chrome.browser.tasks.tab_management;
import android.content.Context; import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Rect;
import android.support.annotation.ColorInt; import android.support.annotation.ColorInt;
import android.support.v7.content.res.AppCompatResources; import android.support.v7.content.res.AppCompatResources;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
...@@ -47,6 +49,19 @@ class TabSelectionEditorMediator ...@@ -47,6 +49,19 @@ class TabSelectionEditorMediator
void resetWithListOfTabs(@Nullable List<Tab> tabs); void resetWithListOfTabs(@Nullable List<Tab> tabs);
} }
/**
* An interface to provide the {@link Rect} used to position the selection editor on screen.
*/
public interface TabSelectionEditorPositionProvider {
/**
* This method fetches the {@link Rect} used to position the selection editor layout.
* @return The {@link Rect} indicates where to show the selection editor layout. This Rect
* should never be null.
*/
@NonNull
Rect getSelectionEditorPositionRect();
}
private final Context mContext; private final Context mContext;
private final TabModelSelector mTabModelSelector; private final TabModelSelector mTabModelSelector;
private final ResetHandler mResetHandler; private final ResetHandler mResetHandler;
...@@ -54,6 +69,7 @@ class TabSelectionEditorMediator ...@@ -54,6 +69,7 @@ class TabSelectionEditorMediator
private final SelectionDelegate<Integer> mSelectionDelegate; private final SelectionDelegate<Integer> mSelectionDelegate;
private final TabModelSelectorTabModelObserver mTabModelObserver; private final TabModelSelectorTabModelObserver mTabModelObserver;
private final TabModelSelectorObserver mTabModelSelectorObserver; private final TabModelSelectorObserver mTabModelSelectorObserver;
private final TabSelectionEditorPositionProvider mPositionProvider;
private TabSelectionEditorActionProvider mActionProvider; private TabSelectionEditorActionProvider mActionProvider;
private final View.OnClickListener mNavigationClickListener = new View.OnClickListener() { private final View.OnClickListener mNavigationClickListener = new View.OnClickListener() {
...@@ -81,12 +97,15 @@ class TabSelectionEditorMediator ...@@ -81,12 +97,15 @@ class TabSelectionEditorMediator
TabSelectionEditorMediator(Context context, TabModelSelector tabModelSelector, TabSelectionEditorMediator(Context context, TabModelSelector tabModelSelector,
ResetHandler resetHandler, PropertyModel model, ResetHandler resetHandler, PropertyModel model,
SelectionDelegate<Integer> selectionDelegate) { SelectionDelegate<Integer> selectionDelegate,
@Nullable TabSelectionEditorMediator
.TabSelectionEditorPositionProvider positionProvider) {
mContext = context; mContext = context;
mTabModelSelector = tabModelSelector; mTabModelSelector = tabModelSelector;
mResetHandler = resetHandler; mResetHandler = resetHandler;
mModel = model; mModel = model;
mSelectionDelegate = selectionDelegate; mSelectionDelegate = selectionDelegate;
mPositionProvider = positionProvider;
mModel.set( mModel.set(
TabSelectionEditorProperties.TOOLBAR_NAVIGATION_LISTENER, mNavigationClickListener); TabSelectionEditorProperties.TOOLBAR_NAVIGATION_LISTENER, mNavigationClickListener);
...@@ -144,6 +163,14 @@ class TabSelectionEditorMediator ...@@ -144,6 +163,14 @@ class TabSelectionEditorMediator
// Default action for action button is to group selected tabs. // Default action for action button is to group selected tabs.
mActionProvider = new TabSelectionEditorActionProvider(mTabModelSelector, this, mActionProvider = new TabSelectionEditorActionProvider(mTabModelSelector, this,
TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP); TabSelectionEditorActionProvider.TabSelectionEditorAction.GROUP);
if (mPositionProvider != null) {
mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER,
()
-> mModel.set(
TabSelectionEditorProperties.SELECTION_EDITOR_POSITION_RECT,
mPositionProvider.getSelectionEditorPositionRect()));
}
} }
private boolean isEditorVisible() { private boolean isEditorVisible() {
...@@ -157,6 +184,10 @@ class TabSelectionEditorMediator ...@@ -157,6 +184,10 @@ class TabSelectionEditorMediator
public void show(List<Tab> tabs) { public void show(List<Tab> tabs) {
mResetHandler.resetWithListOfTabs(tabs); mResetHandler.resetWithListOfTabs(tabs);
mSelectionDelegate.setSelectionModeEnabledForZeroItems(true); mSelectionDelegate.setSelectionModeEnabledForZeroItems(true);
if (mPositionProvider != null) {
mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_POSITION_RECT,
mPositionProvider.getSelectionEditorPositionRect());
}
mModel.set(TabSelectionEditorProperties.IS_VISIBLE, true); mModel.set(TabSelectionEditorProperties.IS_VISIBLE, true);
} }
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
package org.chromium.chrome.browser.tasks.tab_management; package org.chromium.chrome.browser.tasks.tab_management;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Rect;
import android.view.View; import android.view.View;
import android.view.ViewTreeObserver;
import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -45,8 +47,17 @@ public class TabSelectionEditorProperties { ...@@ -45,8 +47,17 @@ public class TabSelectionEditorProperties {
public static final PropertyModel.WritableIntPropertyKey TOOLBAR_TEXT_APPEARANCE = public static final PropertyModel.WritableIntPropertyKey TOOLBAR_TEXT_APPEARANCE =
new PropertyModel.WritableIntPropertyKey(); new PropertyModel.WritableIntPropertyKey();
public static final PropertyModel
.WritableObjectPropertyKey<Rect> SELECTION_EDITOR_POSITION_RECT =
new PropertyModel.WritableObjectPropertyKey<>();
public static final PropertyModel.WritableObjectPropertyKey<
ViewTreeObserver.OnGlobalLayoutListener> SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER =
new PropertyModel.WritableObjectPropertyKey<>();
public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {IS_VISIBLE, public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {IS_VISIBLE,
TOOLBAR_ACTION_BUTTON_LISTENER, TOOLBAR_ACTION_BUTTON_TEXT, TOOLBAR_ACTION_BUTTON_LISTENER, TOOLBAR_ACTION_BUTTON_TEXT,
TOOLBAR_ACTION_BUTTON_ENABLING_THRESHOLD, TOOLBAR_NAVIGATION_LISTENER, PRIMARY_COLOR, TOOLBAR_ACTION_BUTTON_ENABLING_THRESHOLD, TOOLBAR_NAVIGATION_LISTENER, PRIMARY_COLOR,
TOOLBAR_BACKGROUND_COLOR, TOOLBAR_GROUP_BUTTON_TINT, TOOLBAR_TEXT_APPEARANCE}; TOOLBAR_BACKGROUND_COLOR, TOOLBAR_GROUP_BUTTON_TINT, TOOLBAR_TEXT_APPEARANCE,
SELECTION_EDITOR_POSITION_RECT, SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER};
} }
...@@ -4,16 +4,26 @@ ...@@ -4,16 +4,26 @@
package org.chromium.chrome.browser.tasks.tab_management; package org.chromium.chrome.browser.tasks.tab_management;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import android.graphics.Rect;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.test.annotation.UiThreadTest; import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.chrome.browser.widget.selection.SelectionDelegate; import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
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;
...@@ -21,17 +31,11 @@ import org.chromium.chrome.test.ui.DummyUiActivityTestCase; ...@@ -21,17 +31,11 @@ import org.chromium.chrome.test.ui.DummyUiActivityTestCase;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
/** /**
* Tests for {@link TabSelectionEditorLayoutBinder}. * Tests for {@link TabSelectionEditorLayoutBinder}.
*/ */
...@@ -41,21 +45,20 @@ public class TabSelectionEditorLayoutBinderTest extends DummyUiActivityTestCase ...@@ -41,21 +45,20 @@ public class TabSelectionEditorLayoutBinderTest extends DummyUiActivityTestCase
private PropertyModel mModel = new PropertyModel(TabSelectionEditorProperties.ALL_KEYS); private PropertyModel mModel = new PropertyModel(TabSelectionEditorProperties.ALL_KEYS);
private PropertyModelChangeProcessor mMCP; private PropertyModelChangeProcessor mMCP;
private SelectionDelegate<Integer> mSelectionDelegate = new SelectionDelegate<>(); private SelectionDelegate<Integer> mSelectionDelegate = new SelectionDelegate<>();
private ViewGroup mParentView;
@Override @Override
public void setUpTest() throws Exception { public void setUpTest() throws Exception {
super.setUpTest(); super.setUpTest();
ViewGroup view = new LinearLayout(getActivity()); mParentView = new LinearLayout(getActivity());
TabSelectionEditorLayout.TabSelectionEditorLayoutPositionProvider positionProvider =
() -> null;
TestThreadUtils.runOnUiThreadBlocking(() -> { TestThreadUtils.runOnUiThreadBlocking(() -> {
getActivity().setContentView(view); getActivity().setContentView(mParentView);
mEditorLayoutView = mEditorLayoutView =
(TabSelectionEditorLayout) getActivity().getLayoutInflater().inflate( (TabSelectionEditorLayout) getActivity().getLayoutInflater().inflate(
R.layout.tab_selection_editor_layout, null); R.layout.tab_selection_editor_layout, null);
mEditorLayoutView.initialize(view, null, new RecyclerView.Adapter() { mEditorLayoutView.initialize(mParentView, null, new RecyclerView.Adapter() {
@NonNull @NonNull
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder( public RecyclerView.ViewHolder onCreateViewHolder(
...@@ -70,7 +73,7 @@ public class TabSelectionEditorLayoutBinderTest extends DummyUiActivityTestCase ...@@ -70,7 +73,7 @@ public class TabSelectionEditorLayoutBinderTest extends DummyUiActivityTestCase
public int getItemCount() { public int getItemCount() {
return 0; return 0;
} }
}, mSelectionDelegate, positionProvider); }, mSelectionDelegate);
}); });
mMCP = PropertyModelChangeProcessor.create( mMCP = PropertyModelChangeProcessor.create(
mModel, mEditorLayoutView, TabSelectionEditorLayoutBinder::bind); mModel, mEditorLayoutView, TabSelectionEditorLayoutBinder::bind);
...@@ -121,4 +124,30 @@ public class TabSelectionEditorLayoutBinderTest extends DummyUiActivityTestCase ...@@ -121,4 +124,30 @@ public class TabSelectionEditorLayoutBinderTest extends DummyUiActivityTestCase
mSelectionDelegate.setSelectedItems(selectedItem); mSelectionDelegate.setSelectedItems(selectedItem);
assertFalse(button.isEnabled()); assertFalse(button.isEnabled());
} }
}
\ No newline at end of file @Test
@SmallTest
@UiThreadTest
public void testSetPositionRect() {
Assert.assertNull(mEditorLayoutView.getPositionRectForTesting());
Rect rect = new Rect();
mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_POSITION_RECT, rect);
assertEquals(rect, mModel.get(TabSelectionEditorProperties.SELECTION_EDITOR_POSITION_RECT));
}
@Test
@SmallTest
@UiThreadTest
public void testRegisterGlobalLayoutListener() {
AtomicBoolean globalLayoutChanged = new AtomicBoolean();
globalLayoutChanged.set(false);
ViewTreeObserver.OnGlobalLayoutListener listener = () -> globalLayoutChanged.set(true);
mModel.set(TabSelectionEditorProperties.SELECTION_EDITOR_GLOBAL_LAYOUT_LISTENER, listener);
mParentView.getViewTreeObserver().dispatchOnGlobalLayout();
assertTrue(globalLayoutChanged.get());
}
}
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