Commit a232eeb7 authored by Mei Liang's avatar Mei Liang Committed by Commit Bot

[a11y] Enable GTS for accessibility (1/2)

This CL enables Grid Tab Switcher for TalkBack for HighEnd Phone.

Change-Id: I06afbd2dc4649db56b8fa2dd16b505e8c9bb64f7
Bug: 1019489
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1982241Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Wei-Yin Chen (陳威尹) <wychen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747620}
parent 37e8c112
...@@ -45,6 +45,7 @@ import android.support.test.InstrumentationRegistry; ...@@ -45,6 +45,7 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso; import android.support.test.espresso.Espresso;
import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.ViewAssertion; import android.support.test.espresso.ViewAssertion;
import android.support.test.espresso.contrib.AccessibilityChecks;
import android.support.test.espresso.contrib.RecyclerViewActions; import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.GridLayoutManager;
...@@ -154,6 +155,7 @@ public class StartSurfaceLayoutTest { ...@@ -154,6 +155,7 @@ public class StartSurfaceLayoutTest {
@Before @Before
public void setUp() { public void setUp() {
AccessibilityChecks.enable();
// After setUp, Chrome is launched and has one NTP. // After setUp, Chrome is launched and has one NTP.
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, true); CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, true);
...@@ -1377,6 +1379,27 @@ public class StartSurfaceLayoutTest { ...@@ -1377,6 +1379,27 @@ public class StartSurfaceLayoutTest {
} }
} }
@Test
@MediumTest
// clang-format off
@CommandLineFlags.Add({BASE_PARAMS})
@Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID})
public void testCloseTabViaCloseButton() throws Exception {
// clang-format on
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, true);
// Restart Chrome to have Group.
ApplicationTestUtils.finishActivity(mActivityTestRule.getActivity());
mActivityTestRule.startMainActivityFromLauncher();
mActivityTestRule.getActivity().getSnackbarManager().disableForTesting();
prepareTabs(1, 0, null);
enterGTSWithThumbnailChecking();
onView(allOf(withId(R.id.action_button), withParent(withId(R.id.content_view))))
.perform(click());
}
private static class TabCountAssertion implements ViewAssertion { private static class TabCountAssertion implements ViewAssertion {
private int mExpectedCount; private int mExpectedCount;
......
...@@ -37,9 +37,8 @@ ...@@ -37,9 +37,8 @@
android:layout_gravity="center"/> android:layout_gravity="center"/>
<org.chromium.ui.widget.ChromeImageView <org.chromium.ui.widget.ChromeImageView
android:id="@+id/close_button" android:id="@+id/close_button"
android:layout_width="0dp" android:layout_width="48dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1"
style="@style/BottomToolbarButton" style="@style/BottomToolbarButton"
android:contentDescription="@string/close" android:contentDescription="@string/close"
android:tint="@color/default_icon_color" /> android:tint="@color/default_icon_color" />
......
...@@ -101,7 +101,10 @@ class TabGridViewBinder { ...@@ -101,7 +101,10 @@ class TabGridViewBinder {
@Nullable PropertyKey propertyKey) { @Nullable PropertyKey propertyKey) {
if (TabProperties.TITLE == propertyKey) { if (TabProperties.TITLE == propertyKey) {
String title = model.get(TabProperties.TITLE); String title = model.get(TabProperties.TITLE);
((TextView) view.fastFindViewById(R.id.tab_title)).setText(title); TextView tabTitleView = (TextView) view.fastFindViewById(R.id.tab_title);
tabTitleView.setText(title);
tabTitleView.setContentDescription(
view.getResources().getString(R.string.accessibility_tabstrip_tab, title));
} else if (TabProperties.IS_SELECTED == propertyKey) { } else if (TabProperties.IS_SELECTED == propertyKey) {
int selectedTabBackground = int selectedTabBackground =
model.get(TabProperties.SELECTED_TAB_BACKGROUND_DRAWABLE_ID); model.get(TabProperties.SELECTED_TAB_BACKGROUND_DRAWABLE_ID);
......
...@@ -160,6 +160,14 @@ class TabListMediator { ...@@ -160,6 +160,14 @@ class TabListMediator {
* @return {@link Pair} that contains previous and target position of this action. * @return {@link Pair} that contains previous and target position of this action.
*/ */
Pair<Integer, Integer> getPositionsOfReorderAction(View view, int action); Pair<Integer, Integer> getPositionsOfReorderAction(View view, int action);
/**
* This method returns whether the given action is a type of the reordering actions.
*
* @param action The accessibility action.
* @return Whether the given action is a reordering action.
*/
boolean isReorderAction(int action);
} }
/** /**
...@@ -1103,6 +1111,10 @@ class TabListMediator { ...@@ -1103,6 +1111,10 @@ class TabListMediator {
@Override @Override
public boolean performAccessibilityAction(View host, int action, Bundle args) { public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (!helper.isReorderAction(action)) {
return super.performAccessibilityAction(host, action, args);
}
Pair<Integer, Integer> positions = helper.getPositionsOfReorderAction(host, action); Pair<Integer, Integer> positions = helper.getPositionsOfReorderAction(host, action);
int currentPosition = positions.first; int currentPosition = positions.first;
int targetPosition = positions.second; int targetPosition = positions.second;
......
...@@ -539,4 +539,10 @@ class TabListRecyclerView ...@@ -539,4 +539,10 @@ class TabListRecyclerView
} }
return new Pair<>(currentPosition, targetPosition); return new Pair<>(currentPosition, targetPosition);
} }
@Override
public boolean isReorderAction(int action) {
return action == R.id.move_tab_left || action == R.id.move_tab_right
|| action == R.id.move_tab_up || action == R.id.move_tab_down;
}
} }
...@@ -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 static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.ACTION_CLICK;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.not;
...@@ -1576,6 +1578,7 @@ public class TabListMediatorUnitTest { ...@@ -1576,6 +1578,7 @@ public class TabListMediatorUnitTest {
doReturn(new Pair<>(1, 0)) doReturn(new Pair<>(1, 0))
.when(mTabGridAccessibilityHelper) .when(mTabGridAccessibilityHelper)
.getPositionsOfReorderAction(mItemView1, action); .getPositionsOfReorderAction(mItemView1, action);
doReturn(true).when(mTabGridAccessibilityHelper).isReorderAction(action);
assertNull(mMediator.getAccessibilityDelegateForTesting()); assertNull(mMediator.getAccessibilityDelegateForTesting());
mMediator.setupAccessibilityDelegate(mTabGridAccessibilityHelper); mMediator.setupAccessibilityDelegate(mTabGridAccessibilityHelper);
View.AccessibilityDelegate delegate = mMediator.getAccessibilityDelegateForTesting(); View.AccessibilityDelegate delegate = mMediator.getAccessibilityDelegateForTesting();
...@@ -1587,6 +1590,28 @@ public class TabListMediatorUnitTest { ...@@ -1587,6 +1590,28 @@ public class TabListMediatorUnitTest {
assertThat(mModel.get(0).model.get(TabProperties.TAB_ID), equalTo(TAB2_ID)); assertThat(mModel.get(0).model.get(TabProperties.TAB_ID), equalTo(TAB2_ID));
} }
@Test
@Features.EnableFeatures({TAB_GROUPS_CONTINUATION_ANDROID})
public void testPerformAccessibilityAction_defaultAccessibilityAction() {
setUpForTabGroupOperation(TabListMediatorType.TAB_SWITCHER);
assertThat(mModel.get(0).model.get(TabProperties.TAB_ID), equalTo(TAB1_ID));
assertThat(mModel.get(1).model.get(TabProperties.TAB_ID), equalTo(TAB2_ID));
// Setup related mocks and initialize needed components.
Bundle args = mock(Bundle.class);
int action = ACTION_CLICK;
// Mock that the action indicates that tab2 will move to position 2 which is invalid.
doReturn(false).when(mTabGridAccessibilityHelper).isReorderAction(action);
assertNull(mMediator.getAccessibilityDelegateForTesting());
mMediator.setupAccessibilityDelegate(mTabGridAccessibilityHelper);
View.AccessibilityDelegate delegate = mMediator.getAccessibilityDelegateForTesting();
assertNotNull(delegate);
delegate.performAccessibilityAction(mItemView1, action, args);
verify(mTabGridAccessibilityHelper, never())
.getPositionsOfReorderAction(mItemView1, action);
}
@Test @Test
@Features.EnableFeatures({TAB_GROUPS_CONTINUATION_ANDROID}) @Features.EnableFeatures({TAB_GROUPS_CONTINUATION_ANDROID})
public void testPerformAccessibilityAction_InvalidIndex() { public void testPerformAccessibilityAction_InvalidIndex() {
......
...@@ -87,6 +87,9 @@ public class DeviceClassManager { ...@@ -87,6 +87,9 @@ public class DeviceClassManager {
* @return Whether or not should use the accessibility tab switcher. * @return Whether or not should use the accessibility tab switcher.
*/ */
public static boolean enableAccessibilityLayout() { public static boolean enableAccessibilityLayout() {
if (ChromeFeatureList.isEnabled(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID)) {
return false;
}
if (getInstance().mEnableAccessibilityLayout) return true; if (getInstance().mEnableAccessibilityLayout) return true;
if (!AccessibilityUtil.isAccessibilityEnabled()) return false; if (!AccessibilityUtil.isAccessibilityEnabled()) return false;
return SharedPreferencesManager.getInstance().readBoolean( return SharedPreferencesManager.getInstance().readBoolean(
......
...@@ -19,6 +19,7 @@ import android.view.MotionEvent.PointerCoords; ...@@ -19,6 +19,7 @@ import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties; import android.view.MotionEvent.PointerProperties;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
...@@ -49,6 +50,7 @@ import org.chromium.chrome.browser.tabmodel.TabModel; ...@@ -49,6 +50,7 @@ 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.tabmodel.TabModelUtils; import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator; import org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator;
import org.chromium.chrome.browser.util.AccessibilityUtil;
import org.chromium.chrome.features.start_surface.StartSurfaceLayout; import org.chromium.chrome.features.start_surface.StartSurfaceLayout;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
...@@ -537,6 +539,26 @@ public class LayoutManagerTest implements MockTabModelDelegate { ...@@ -537,6 +539,26 @@ public class LayoutManagerTest implements MockTabModelDelegate {
}); });
} }
@Test
@MediumTest
@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
@Feature({"Android-TabSwitcher"})
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Features.DisableFeatures({ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID})
public void testStartSurfaceLayoutDisabled_Accessibility() {
// clang-format on
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, true);
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, true);
AccessibilityUtil.setAccessibilityEnabledForTesting(true);
launchedChromeAndEnterTabSwitcher();
TestThreadUtils.runOnUiThreadBlocking(() -> {
Layout activeLayout = getActiveLayout();
Assert.assertTrue(activeLayout instanceof OverviewListLayout);
});
}
@Test @Test
@MediumTest @MediumTest
@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
...@@ -561,18 +583,46 @@ public class LayoutManagerTest implements MockTabModelDelegate { ...@@ -561,18 +583,46 @@ public class LayoutManagerTest implements MockTabModelDelegate {
.getListModeForTesting()); .getListModeForTesting());
}); });
} }
@Test
@MediumTest
@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
@Feature({"Android-TabSwitcher"})
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Features.EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID,
ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID})
public void testStartSurfaceLayoutEnabled_Grid_Accessibility() {
// clang-format on
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, true);
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, true);
AccessibilityUtil.setAccessibilityEnabledForTesting(true);
launchedChromeAndEnterTabSwitcher();
TestThreadUtils.runOnUiThreadBlocking(() -> {
Layout activeLayout = getActiveLayout();
Assert.assertTrue(activeLayout instanceof StartSurfaceLayout);
StartSurfaceLayout startSurfaceLayout = (StartSurfaceLayout) activeLayout;
Assert.assertEquals(TabListCoordinator.TabListMode.GRID,
startSurfaceLayout.getStartSurfaceForTesting()
.getTabListDelegate()
.getListModeForTesting());
});
}
@Test @Test
@MediumTest @MediumTest
@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_LOW_END_DEVICE}) @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_LOW_END_DEVICE})
@Feature({"Android-TabSwitcher"}) @Feature({"Android-TabSwitcher"})
@CommandLineFlags // clang-format off
.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Features @Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
.EnableFeatures({ChromeFeatureList.TAB_GROUPS_ANDROID,
ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID}) ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID})
@Features.DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION) @Features.DisableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
public void public void testStartSurfaceLayoutEnabled_List() {
testStartSurfaceLayoutEnabled_List() { // clang-format on
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, true); CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, true);
launchedChromeAndEnterTabSwitcher(); launchedChromeAndEnterTabSwitcher();
...@@ -596,6 +646,13 @@ public class LayoutManagerTest implements MockTabModelDelegate { ...@@ -596,6 +646,13 @@ public class LayoutManagerTest implements MockTabModelDelegate {
() -> { ChromeBrowserInitializer.getInstance().handleSynchronousStartup(); }); () -> { ChromeBrowserInitializer.getInstance().handleSynchronousStartup(); });
} }
@After
public void tearDown() {
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID, null);
CachedFeatureFlags.setForTesting(ChromeFeatureList.TAB_GROUPS_ANDROID, null);
AccessibilityUtil.setAccessibilityEnabledForTesting(null);
}
private void launchedChromeAndEnterTabSwitcher() { private void launchedChromeAndEnterTabSwitcher() {
mActivityTestRule.startMainActivityOnBlankPage(); mActivityTestRule.startMainActivityOnBlankPage();
CriteriaHelper.pollUiThread(Criteria.equals(true, CriteriaHelper.pollUiThread(Criteria.equals(true,
......
d042754b31261730a99f1ab48b8d2be8da49da3f 3658acf6c513bbd6bb721e35d0e9f1ed2fd5f9a8
\ No newline at end of file \ No newline at end of file
bb0917985d1b2966460727b5073794aef03a2785 236e00bcc45cb47de9cca93e29a8e4d9b7475f50
\ No newline at end of file \ No newline at end of file
9da492922e5f75bb701c41ea8541ff6635e94a70 5687e3199646a34e553b9c2f8c1338caaea9a515
\ No newline at end of file \ No newline at end of file
a9ffabcd7e6f2a8c02bbc74d4f5e9819d9ce29e1 4b993838cf4c79cce3bf08914041d1a7bc4f3e00
\ No newline at end of file \ No newline at end of file
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