Commit 9da4a16b authored by Mei Liang's avatar Mei Liang Committed by Commit Bot

[a11y] Add a11y support to TabSelectionEditor

This CL adds the following a11y support to the TabSelectionEditor:
  * Adds content description to the TabSelectionEditorLayout and
    announces the description when TabSelectionEditor shows to screen.
  * Update the TabSelectionEditorToolbar navigation button content
    description.

Everything introduced in this CL is gated by field trial under the
enable-tab-grid-layout flag and the enable-tab-groups-continuation flag.
All Java code is verified to be behind the gating function
TabUiFeatureUtilities#isLaunchPolishEnabled by formal equivalence
checking tool here: http://crrev.com/c/1934235. The changes in the
tab_selection_editor_layout.xml can't be verified by the tool, but it is
expected. Without both flags, it is a no-op.

Bug: 1124919
Change-Id: I2a4a7ff575808d71e8a4594ee158ca45a87a006f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2399314
Commit-Queue: Mei Liang <meiliang@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805848}
parent 51f122c8
...@@ -276,13 +276,11 @@ Still reading? ...@@ -276,13 +276,11 @@ Still reading?
<!-- crbug.com/1114311 remove this line and the following two lines after the bug is resolved --> <!-- crbug.com/1114311 remove this line and the following two lines after the bug is resolved -->
<ignore regexp="The resource `R.string.languages_set_application_language_prompt` appears to be unused"/> <ignore regexp="The resource `R.string.languages_set_application_language_prompt` appears to be unused"/>
<ignore regexp="The resource `R.string.languages_set_as_application_language` appears to be unused"/> <ignore regexp="The resource `R.string.languages_set_as_application_language` appears to be unused"/>
<!-- crbug.com/1111942 remove this line and following 10 lines after the bug is resolved --> <!-- crbug.com/1111942 remove this line and following 7 lines after the bug is resolved -->
<ignore regexp="The resource `R.string.accessibility_tab_switcher` appears to be unused"/> <ignore regexp="The resource `R.string.accessibility_tab_switcher` appears to be unused"/>
<ignore regexp="The resource `R.string.accessibility_close_tab_group_button` appears to be unused"/> <ignore regexp="The resource `R.string.accessibility_close_tab_group_button` appears to be unused"/>
<ignore regexp="The resource `R.string.accessibility_close_tab_group_button_with_group_name` appears to be unused"/> <ignore regexp="The resource `R.string.accessibility_close_tab_group_button_with_group_name` appears to be unused"/>
<ignore regexp="The resource `R.string.accessibility_expand_tab_group_with_group_name` appears to be unused"/> <ignore regexp="The resource `R.string.accessibility_expand_tab_group_with_group_name` appears to be unused"/>
<ignore regexp="The resource `R.string.accessibility_tab_selection_editor_back_button` appears to be unused"/>
<ignore regexp="The resource `R.string.accessibility_tab_selection_editor` appears to be unused"/>
<ignore regexp="The resource `R.plurals.accessibility_dialog_back_button` appears to be unused"/> <ignore regexp="The resource `R.plurals.accessibility_dialog_back_button` appears to be unused"/>
<ignore regexp="The resource `R.plurals.accessibility_dialog_back_button_with_group_name` appears to be unused"/> <ignore regexp="The resource `R.plurals.accessibility_dialog_back_button_with_group_name` appears to be unused"/>
<ignore regexp="The resource `R.string.tab_grid_dialog_toolbar_edit_group_name` appears to be unused"/> <ignore regexp="The resource `R.string.tab_grid_dialog_toolbar_edit_group_name` appears to be unused"/>
......
...@@ -8,4 +8,5 @@ ...@@ -8,4 +8,5 @@
android:id="@+id/selectable_list" android:id="@+id/selectable_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/default_bg_color"/> android:background="@color/default_bg_color"
\ No newline at end of file android:contentDescription="@string/accessibility_tab_selection_editor"/>
\ No newline at end of file
...@@ -11,6 +11,7 @@ import android.view.Gravity; ...@@ -11,6 +11,7 @@ import android.view.Gravity;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
...@@ -39,6 +40,13 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> { ...@@ -39,6 +40,13 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> {
super(context, attrs); super(context, attrs);
mWindow = new PopupWindow( mWindow = new PopupWindow(
this, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); this, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
if (TabUiFeatureUtilities.isLaunchPolishEnabled()) {
// TODO(crbug.com/1124919): Remove PopupWindow usage, the focusable PopupWindow messes
// up the TalkBack. Focusable PopupWindow always focuses the first item in the content
// view and announces the first item twice under Talkback mode.
mWindow.setFocusable(true);
}
} }
/** /**
...@@ -68,12 +76,21 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> { ...@@ -68,12 +76,21 @@ class TabSelectionEditorLayout extends SelectableListLayout<Integer> {
assert mIsInitialized; assert mIsInitialized;
if (mPositionRect == null) { if (mPositionRect == null) {
mWindow.showAtLocation(mParentView, Gravity.CENTER, 0, 0); mWindow.showAtLocation(mParentView, Gravity.CENTER, 0, 0);
if (TabUiFeatureUtilities.isLaunchPolishEnabled()) {
// TODO(crbug.com/1124919): The following line forces Talkback to announce the
// content description of this view. Remove after PopupWindow usage is removed.
sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT);
}
return; return;
} }
mWindow.setWidth(mPositionRect.width()); mWindow.setWidth(mPositionRect.width());
mWindow.setHeight(mPositionRect.height()); mWindow.setHeight(mPositionRect.height());
mWindow.showAtLocation( mWindow.showAtLocation(
mParentView, Gravity.NO_GRAVITY, mPositionRect.left, mPositionRect.top); mParentView, Gravity.NO_GRAVITY, mPositionRect.left, mPositionRect.top);
if (TabUiFeatureUtilities.isLaunchPolishEnabled()) {
// TODO(crbug.com/1124919): Remove after PopupWindow usage is removed.
sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT);
}
} }
/** /**
......
...@@ -53,7 +53,9 @@ class TabSelectionEditorToolbar extends SelectableListToolbar<Integer> { ...@@ -53,7 +53,9 @@ class TabSelectionEditorToolbar extends SelectableListToolbar<Integer> {
navigationIconDrawable.setTint(lightIconColorList); navigationIconDrawable.setTint(lightIconColorList);
setNavigationIcon(navigationIconDrawable); setNavigationIcon(navigationIconDrawable);
setNavigationContentDescription(R.string.close); setNavigationContentDescription(TabUiFeatureUtilities.isLaunchPolishEnabled()
? R.string.accessibility_tab_selection_editor_back_button
: R.string.close);
} }
@Override @Override
......
...@@ -538,6 +538,39 @@ public class TabSelectionEditorTest { ...@@ -538,6 +538,39 @@ public class TabSelectionEditorTest {
assertEquals("Group 2 selected tabs", actionButton.getContentDescription()); assertEquals("Group 2 selected tabs", actionButton.getContentDescription());
} }
@Test
@MediumTest
// clang-format off
@EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + "<Study"})
@CommandLineFlags.Add({"force-fieldtrials=Study/Group",
"force-fieldtrial-params=Study.Group:enable_launch_polish/true"})
public void testTabSelectionEditorContentDescription() {
// clang-format on
prepareBlankTab(2, false);
List<Tab> tabs = getTabsInCurrentTabModel();
TestThreadUtils.runOnUiThreadBlocking(() -> mTabSelectionEditorController.show(tabs));
mRobot.resultRobot.verifyTabSelectionEditorIsVisible();
assertEquals("Multi-select mode", mTabSelectionEditorLayout.getContentDescription());
}
@Test
@MediumTest
// clang-format off
@EnableFeatures({ChromeFeatureList.TAB_GRID_LAYOUT_ANDROID + "<Study"})
@CommandLineFlags.Add({"force-fieldtrials=Study/Group",
"force-fieldtrial-params=Study.Group:enable_launch_polish/true"})
public void testToolbarNavigationButtonContentDescription() {
// clang-format on
prepareBlankTab(2, false);
List<Tab> tabs = getTabsInCurrentTabModel();
TestThreadUtils.runOnUiThreadBlocking(() -> mTabSelectionEditorController.show(tabs));
mRobot.resultRobot.verifyTabSelectionEditorIsVisible();
assertEquals("Hide multi-select mode",
mTabSelectionEditorLayout.getToolbar().getNavigationContentDescription());
}
private List<Tab> getTabsInCurrentTabModel() { private List<Tab> getTabsInCurrentTabModel() {
List<Tab> tabs = new ArrayList<>(); List<Tab> tabs = new ArrayList<>();
......
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