Commit 2bfcd397 authored by Yue Zhang's avatar Yue Zhang Committed by Commit Bot

Enable undo closure snack bar for tab strip in accessibility mode

Currently, the undo closure snack bar is disabled when accessibility
mode is enabled, and undo closure is handled in accessibility tab
switcher. Since conditional tab strip allows users to close a tab
when overview mode is not showing, this CL enables undo closure snack
bar for accessibility users with this feature.

Bug: 1090067
Change-Id: I4427c8305f5706c4fc99f09393de1b323612a8f1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2231899
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775765}
parent 6a268710
......@@ -20,6 +20,8 @@ import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.chromium.chrome.browser.flags.ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID;
......@@ -38,6 +40,7 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.test.filters.MediumTest;
import android.view.View;
import android.widget.ListView;
import androidx.recyclerview.widget.RecyclerView;
......@@ -55,6 +58,9 @@ import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.TabsTest.SimulateClickOnMainThread;
import org.chromium.chrome.browser.TabsTest.SimulateTabSwipeOnMainThread;
import org.chromium.chrome.browser.accessibility_tab_switcher.AccessibilityTabModelListItem;
import org.chromium.chrome.browser.accessibility_tab_switcher.AccessibilityTabModelWrapper;
import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout;
import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome;
import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone;
import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
......@@ -67,6 +73,9 @@ import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
import org.chromium.chrome.browser.undo_tab_close_snackbar.UndoBarController;
import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
......@@ -591,6 +600,59 @@ public class ConditionalTabStripTest {
assertEquals(-1, ConditionalTabStripUtils.getContinuousDismissCount());
}
@Test
@MediumTest
public void testUndoClosure_AccessibilityMode() throws Exception {
TestThreadUtils.runOnUiThreadBlocking(
() -> ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(true));
ChromeTabbedActivity cta = mActivityTestRule.getActivity();
SnackbarManager snackbarManager = mActivityTestRule.getActivity().getSnackbarManager();
createTabs(cta, false, 3);
verifyShowingStrip(cta, false, 3);
verifyStripSelectedPosition(cta, 2);
assertNull(snackbarManager.getCurrentSnackbarForTesting());
// Click the selected item in strip to close a tab. The undo snack bar should show, and
// clicking on the snack bar button should undo the closure.
clickNthItemInStrip(2);
verifyShowingStrip(cta, false, 2);
assertTrue(snackbarManager.getCurrentSnackbarForTesting().getController()
instanceof UndoBarController);
CriteriaHelper.pollInstrumentationThread(TabUiTestHelper::verifyUndoBarShowingAndClickUndo);
verifyShowingStrip(cta, false, 3);
verifyStripSelectedPosition(cta, 2);
// The undo snack bar should still work after entering overview mode.
clickNthItemInStrip(2);
verifyShowingStrip(cta, false, 2);
assertTrue(snackbarManager.getCurrentSnackbarForTesting().getController()
instanceof UndoBarController);
enterTabSwitcher(cta);
verifyHidingStrip();
assertNotNull(snackbarManager.getCurrentSnackbarForTesting());
assertEquals(3, getAccessibilityOverviewList().getCount());
verifyAccessibilityTabClosing(2, true);
CriteriaHelper.pollInstrumentationThread(TabUiTestHelper::verifyUndoBarShowingAndClickUndo);
verifyAccessibilityTabClosing(2, false);
// The undo snack bar should not show when closure happens in accessibility tab switcher.
AccessibilityTabModelListItem item = getAccessibilityOverviewListItem(0);
verifyAccessibilityTabClosing(0, false);
TestThreadUtils.runOnUiThreadBlocking(
() -> item.findViewById(R.id.end_button).performClick());
assertNull(snackbarManager.getCurrentSnackbarForTesting());
verifyAccessibilityTabClosing(0, true);
assertEquals(3, getAccessibilityOverviewList().getCount());
}
private void verifyAccessibilityTabClosing(int index, boolean isClosing) {
CriteriaHelper.pollUiThread(() -> {
AccessibilityTabModelListItem item = getAccessibilityOverviewListItem(index);
assertEquals(isClosing ? View.VISIBLE : View.INVISIBLE,
item.findViewById(R.id.undo_contents).getVisibility());
});
}
private ChromeTabbedActivity restartChrome() throws Exception {
TabUiTestHelper.finishActivity(mActivityTestRule.getActivity());
mActivityTestRule.startMainActivityFromLauncher();
......@@ -776,4 +838,16 @@ public class ConditionalTabStripTest {
mTabsViewWidthDp = tabsView.getWidth() * mPxToDp;
return mActivityTestRule.getActivity().getLayoutManager();
}
// Utility methods from OverviewListLayoutTest.java.
private ListView getAccessibilityOverviewList() {
AccessibilityTabModelWrapper container =
((OverviewListLayout) mActivityTestRule.getActivity().getOverviewListLayout())
.getContainer();
return (ListView) container.findViewById(R.id.list_view);
}
private AccessibilityTabModelListItem getAccessibilityOverviewListItem(int index) {
return (AccessibilityTabModelListItem) getAccessibilityOverviewList().getChildAt(index);
}
}
......@@ -1553,8 +1553,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
mContentContainer = (ViewGroup) findViewById(android.R.id.content);
mControlContainer = (ToolbarControlContainer) findViewById(R.id.control_container);
mUndoBarPopupController =
new UndoBarController(this, mTabModelSelectorImpl, this::getSnackbarManager);
mUndoBarPopupController = new UndoBarController(
this, mTabModelSelectorImpl, this::getSnackbarManager, getOverviewModeBehavior());
mInactivityTracker = new ChromeInactivityTracker(
ChromePreferenceKeys.TABBED_ACTIVITY_LAST_BACKGROUNDED_TIME_MS_PREF);
......
......@@ -643,7 +643,7 @@ public class AccessibilityTabModelListItem extends FrameLayout implements OnClic
}
@VisibleForTesting
View getCloseButtonForTests() {
public View getCloseButtonForTests() {
return mCloseButton;
}
}
......@@ -8,11 +8,14 @@ import android.content.Context;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
import org.chromium.chrome.browser.device.DeviceClassManager;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tasks.ConditionalTabStripUtils;
import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
......@@ -53,15 +56,26 @@ public class UndoBarController implements SnackbarManager.SnackbarController {
* @param context The {@link Context} in which snackbar is shown.
* @param selector The {@link TabModelSelector} that will be used to commit and undo tab
* closures.
* @param snackbarManagable The holder class to get the manager that helps to show up snackbar.
* @param snackbarManageable The holder class to get the manager that helps to show up snackbar.
* @param overviewModeBehavior The {@link OverviewModeBehavior} to help check whether the
* overview is showing or not.
*/
public UndoBarController(Context context, TabModelSelector selector,
SnackbarManager.SnackbarManageable snackbarManagable) {
mSnackbarManagable = snackbarManagable;
SnackbarManager.SnackbarManageable snackbarManageable,
OverviewModeBehavior overviewModeBehavior) {
mSnackbarManagable = snackbarManageable;
mTabModelSelector = selector;
mContext = context;
mTabModelObserver = new TabModelObserver() {
private boolean disableUndo() {
// If the closure happens through conditional tab strip, show the undo snack bar
// regardless of whether accessibility mode is enabled.
if (TabUiFeatureUtilities.isConditionalTabStripEnabled()
&& ConditionalTabStripUtils.getFeatureStatus()
== ConditionalTabStripUtils.FeatureStatus.ACTIVATED
&& !overviewModeBehavior.overviewVisible()) {
return false;
}
return ChromeAccessibilityUtil.get().isAccessibilityEnabled()
|| DeviceClassManager.enableAccessibilityLayout();
}
......
......@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.ChromeTabUtils;
......@@ -133,6 +134,24 @@ public class UndoBarControllerTest {
Assert.assertEquals(0, mTabModel.getCount());
}
@Test
@SmallTest
public void testUndoSnackbarDisabled_AccessibilityEnabled() throws Exception {
TestThreadUtils.runOnUiThreadBlocking(
() -> ChromeAccessibilityUtil.get().setAccessibilityEnabledForTesting(true));
ChromeTabUtils.newTabFromMenu(
InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
Assert.assertNull("Snack bar should be null initially", getCurrentSnackbar());
Assert.assertEquals(2, mTabModel.getCount());
ChromeTabUtils.closeCurrentTab(
InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
Assert.assertNull(
"Undo snack bar should not be showing in accessibility mode", getCurrentSnackbar());
}
private void clickSnackbar() {
TestThreadUtils.runOnUiThreadBlocking(
()
......
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