Remove instances of announce for alerts and comboboxes for Android a11y
This CL updates the treatment of alert dialogs and comboboxes for Android accessibility to label them as panes with a paneTitle, rather than forcing an announcement with TYPE_ANNOUNCEMENT. The content that was previously read by the announcement has been unchanged but moved to the paneTitle for the node. AX-Relnotes: N/A Bug: 371988580, 372427591 Change-Id: Ia729e80972406bf180caf6b8a367a475df04b27a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5991190 Reviewed-by: Aaron Leventhal <aleventhal@chromium.org> Commit-Queue: Aaron Leventhal <aleventhal@chromium.org> Cr-Commit-Position: refs/heads/main@{#1383074}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
835bae77d7
commit
67de4d99d0
content
browser
accessibility
public
android
java
src
org
chromium
content
browser
accessibility
test
data
accessibility
aria
event
@ -365,6 +365,12 @@ bool BrowserAccessibilityAndroid::IsVisibleToUser() const {
|
||||
return !IsInvisibleOrIgnored();
|
||||
}
|
||||
|
||||
bool BrowserAccessibilityAndroid::ShouldUsePaneTitle() const {
|
||||
// Dialogs should use paneTitles, as well as comboboxes but only when the
|
||||
// combobox is expanded.
|
||||
return ui::IsDialog(GetRole()) || (ui::IsComboBox(GetRole()) && IsExpanded());
|
||||
}
|
||||
|
||||
bool BrowserAccessibilityAndroid::IsInterestingOnAndroid() const {
|
||||
// The root is not interesting if it doesn't have a title, even
|
||||
// though it's focusable.
|
||||
@ -882,6 +888,16 @@ std::u16string BrowserAccessibilityAndroid::GetHint() const {
|
||||
return base::JoinString(strings, u" ");
|
||||
}
|
||||
|
||||
std::u16string BrowserAccessibilityAndroid::GetPaneTitle() const {
|
||||
if (ui::IsDialog(GetRole())) {
|
||||
return GetDialogModalMessageText();
|
||||
} else if (ui::IsComboBox(GetRole()) && IsExpanded()) {
|
||||
return GetComboboxExpandedText();
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
|
||||
std::u16string BrowserAccessibilityAndroid::GetDialogModalMessageText() const {
|
||||
// For a dialog/modal, first check for a name, and then a description. If
|
||||
// both are empty, fallback to a default "dialog opened." text.
|
||||
|
@ -72,6 +72,7 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid
|
||||
bool IsSlider() const;
|
||||
bool IsTableHeader() const;
|
||||
bool IsVisibleToUser() const;
|
||||
bool ShouldUsePaneTitle() const;
|
||||
|
||||
// This returns true for all nodes that we should navigate to.
|
||||
// Nodes that have a generic role, no accessible name, and aren't
|
||||
@ -136,6 +137,8 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid
|
||||
|
||||
std::string GetRoleString() const;
|
||||
|
||||
std::u16string GetPaneTitle() const;
|
||||
|
||||
std::u16string GetDialogModalMessageText() const;
|
||||
|
||||
std::u16string GetContentInvalidErrorMessage() const;
|
||||
|
@ -260,16 +260,7 @@ void BrowserAccessibilityManagerAndroid::FireGeneratedEvent(
|
||||
|
||||
switch (event_type) {
|
||||
case ui::AXEventGenerator::Event::ALERT: {
|
||||
// When an alertdialog is shown, we will announce the hint, which
|
||||
// (should) contain the description set by the author. If it is
|
||||
// empty, then we will try GetTextContentUTF16() as a fallback.
|
||||
std::u16string text = android_node->GetHint();
|
||||
if (text.empty()) {
|
||||
text = android_node->GetTextContentUTF16();
|
||||
}
|
||||
|
||||
wcax->AnnounceLiveRegionText(text);
|
||||
wcax->HandleDialogModalOpened(android_node->GetUniqueId());
|
||||
wcax->HandlePaneOpened(android_node->GetUniqueId());
|
||||
break;
|
||||
}
|
||||
case ui::AXEventGenerator::Event::CHECKED_STATE_CHANGED:
|
||||
@ -294,7 +285,7 @@ void BrowserAccessibilityManagerAndroid::FireGeneratedEvent(
|
||||
case ui::AXEventGenerator::Event::EXPANDED: {
|
||||
if (ui::IsComboBox(android_node->GetRole()) &&
|
||||
GetFocus()->IsDescendantOf(android_node)) {
|
||||
wcax->AnnounceLiveRegionText(android_node->GetComboboxExpandedText());
|
||||
wcax->HandlePaneOpened(android_node->GetUniqueId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -331,7 +322,7 @@ void BrowserAccessibilityManagerAndroid::FireGeneratedEvent(
|
||||
// When this happens, we want to generate a TYPE_WINDOW_STATE_CHANGED
|
||||
// event and populate the node's paneTitle with the dialog description.
|
||||
if (android_node->GetRole() == ax::mojom::Role::kDialog) {
|
||||
wcax->HandleDialogModalOpened(android_node->GetUniqueId());
|
||||
wcax->HandlePaneOpened(android_node->GetUniqueId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -574,16 +574,14 @@ void WebContentsAccessibilityAndroid::HandleScrolledToAnchor(
|
||||
Java_WebContentsAccessibilityImpl_handleScrolledToAnchor(env, obj, unique_id);
|
||||
}
|
||||
|
||||
void WebContentsAccessibilityAndroid::HandleDialogModalOpened(
|
||||
int32_t unique_id) {
|
||||
void WebContentsAccessibilityAndroid::HandlePaneOpened(int32_t unique_id) {
|
||||
JNIEnv* env = AttachCurrentThread();
|
||||
ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
|
||||
if (obj.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Java_WebContentsAccessibilityImpl_handleDialogModalOpened(env, obj,
|
||||
unique_id);
|
||||
Java_WebContentsAccessibilityImpl_handlePaneOpened(env, obj, unique_id);
|
||||
}
|
||||
|
||||
void WebContentsAccessibilityAndroid::AnnounceLiveRegionText(
|
||||
@ -1066,11 +1064,10 @@ jboolean WebContentsAccessibilityAndroid::PopulateAccessibilityNodeInfo(
|
||||
node->RangeMax(), node->RangeCurrentValue());
|
||||
}
|
||||
|
||||
if (ui::IsDialog(node->GetRole())) {
|
||||
if (node->ShouldUsePaneTitle()) {
|
||||
Java_AccessibilityNodeInfoBuilder_setAccessibilityNodeInfoPaneTitle(
|
||||
env, obj, info,
|
||||
base::android::ConvertUTF16ToJavaString(
|
||||
env, node->GetDialogModalMessageText()));
|
||||
base::android::ConvertUTF16ToJavaString(env, node->GetPaneTitle()));
|
||||
}
|
||||
|
||||
if (node->IsTextField()) {
|
||||
|
@ -375,7 +375,7 @@ class CONTENT_EXPORT WebContentsAccessibilityAndroid
|
||||
void HandleClicked(int32_t unique_id);
|
||||
void HandleScrollPositionChanged(int32_t unique_id);
|
||||
void HandleScrolledToAnchor(int32_t unique_id);
|
||||
void HandleDialogModalOpened(int32_t unique_id);
|
||||
void HandlePaneOpened(int32_t unique_id);
|
||||
void AnnounceLiveRegionText(const std::u16string& text);
|
||||
void HandleTextContentChanged(int32_t unique_id);
|
||||
void HandleTextSelectionChanged(int32_t unique_id);
|
||||
|
@ -1993,7 +1993,7 @@ public class WebContentsAccessibilityImpl extends AccessibilityNodeProviderCompa
|
||||
|
||||
@CalledByNative
|
||||
@SuppressLint("WrongConstant")
|
||||
protected void handleDialogModalOpened(int virtualViewId) {
|
||||
protected void handlePaneOpened(int virtualViewId) {
|
||||
if (isAccessibilityEnabled()) {
|
||||
AccessibilityEvent event =
|
||||
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
|
||||
|
@ -1,6 +1,6 @@
|
||||
WebView focusable actions:[FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea"]
|
||||
++TextView text:"State" viewIdResName:"state_label" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"]
|
||||
++EditText hint:"State" canOpenPopUp clickable editable disabled focusable focused inputType:1 textSelectionStart:0 textSelectionEnd:0 actions:[CLEAR_FOCUS, CLICK, AX_FOCUS, COLLAPSE] bundle:[chromeRole="textFieldWithComboBox", clickableScore="300", hint="State"]
|
||||
++EditText hint:"State" paneTitle:"expanded, 2 autocomplete options available." canOpenPopUp clickable editable disabled focusable focused inputType:1 textSelectionStart:0 textSelectionEnd:0 actions:[CLEAR_FOCUS, CLICK, AX_FOCUS, COLLAPSE] bundle:[chromeRole="textFieldWithComboBox", clickableScore="300", hint="State"]
|
||||
++ListView viewIdResName:"state_list" clickable CollectionInfo:[rows=2, cols=1] actions:[CLICK, AX_FOCUS] bundle:[chromeRole="listBox", clickableScore="300", roleDescription="list box"]
|
||||
++++View text:"Alabama" viewIdResName:"state1" clickable focusable CollectionItemInfo:[rowIndex=0, colIndex=0] actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="listBoxOption", clickableScore="200"]
|
||||
++++View text:"Alaska" viewIdResName:"state2" clickable focusable selected CollectionItemInfo:[rowIndex=1, colIndex=0] actions:[FOCUS, CLICK, AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="listBoxOption", clickableScore="200"]
|
||||
|
@ -1,2 +1 @@
|
||||
TYPE_ANNOUNCEMENT - [This is an alert]
|
||||
TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
|
||||
|
@ -1,2 +1,2 @@
|
||||
TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
|
||||
TYPE_ANNOUNCEMENT - [expanded, 3 autocomplete options available.]
|
||||
TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
|
||||
|
@ -1,2 +1,2 @@
|
||||
TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
|
||||
TYPE_ANNOUNCEMENT - [expanded, 3 autocomplete options available.]
|
||||
TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
|
||||
|
@ -1,3 +1,3 @@
|
||||
TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
|
||||
TYPE_ANNOUNCEMENT - [expanded, dialog opened.]
|
||||
TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
|
||||
TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
|
||||
|
@ -1,2 +1,2 @@
|
||||
TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
|
||||
TYPE_ANNOUNCEMENT - [expanded, 3 autocomplete options available.]
|
||||
TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
|
||||
|
@ -1,3 +1,2 @@
|
||||
TYPE_VIEW_TEXT_SELECTION_CHANGED - [0, 0]
|
||||
TYPE_ANNOUNCEMENT - [Please enter pet name]
|
||||
TYPE_WINDOW_STATE_CHANGED - [contentTypes=16]
|
||||
|
Reference in New Issue
Block a user