Commit ec072c3e authored by Mark Schillaci's avatar Mark Schillaci Committed by Commit Bot

Exposing link <a> nested structure to TalkBack on Android

This CL addresses issues with complex structures nested inside links
on Android. We now never consider a link as a leaf node to ensure
that the entire structure is traversable. We update the method
IsInterestingOnAndroid to make simple cases un-interesting to prevent
double navigation issues. We also change the AccessibilityNodeInfo
passed to TalkBack to prevent structure from being too verbose
when read.

Unit test expectations updated to account for change.

Bug: 1018555
Change-Id: I0b0d60f0ec69f400023c21ad92f3fbe69f08d378
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1955098
Commit-Queue: Mark Schillaci <mschillaci@google.com>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737936}
parent 3cbcdbe2
......@@ -139,6 +139,10 @@ bool BrowserAccessibilityAndroid::PlatformIsLeafIncludingIgnored() const {
break;
}
// Links are never a leaf
if (IsLink())
return false;
// If it has a focusable child, we definitely can't leave out children.
if (HasFocusableNonOptionChild())
return false;
......@@ -373,6 +377,14 @@ bool BrowserAccessibilityAndroid::IsInterestingOnAndroid() const {
if (ui::IsControl(GetRole()))
return true;
// If we are the direct descendant of a link and have no siblings/children,
// then we are not interesting, return false
parent = PlatformGetParent();
if (parent != nullptr && ui::IsLink(parent->GetRole()) &&
parent->PlatformChildCount() == 1 && PlatformChildCount() == 0) {
return false;
}
// Otherwise, the interesting nodes are leaf nodes with non-whitespace text.
return PlatformIsLeaf() &&
!base::ContainsOnlyChars(GetInnerText(), base::kWhitespaceUTF16);
......
......@@ -1313,7 +1313,13 @@ public class WebContentsAccessibilityImpl extends AccessibilityNodeProvider
int[] suggestionEnds, String[] suggestions) {
CharSequence computedText = computeText(
text, isEditableText, language, suggestionStarts, suggestionEnds, suggestions);
node.setText(computedText);
// We expose the nested structure of links, which results in the roles of all nested nodes
// being read. Use content description in the case of links to prevent verbose TalkBack
if (annotateAsLink) {
node.setContentDescription(computedText);
} else {
node.setText(computedText);
}
}
protected CharSequence computeText(String text, boolean annotateAsLink, String language,
......
android.webkit.WebView focusable focused scrollable
++android.view.View
++++android.view.View role_description='link' clickable link name='Group Link1'
++++android.view.View role_description='link' clickable link name='Group Link2'
\ No newline at end of file
++++++android.widget.TextView name='Group Link1'
++++android.view.View role_description='link' clickable link name='Group Link2'
++++++android.widget.TextView name='Group Link2'
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='link' clickable link name='ARIA Link'
\ No newline at end of file
++android.view.View role_description='link' clickable link name='ARIA Link'
++++android.widget.TextView name='ARIA Link'
......@@ -2,15 +2,21 @@ android.webkit.WebView focusable focused scrollable
++android.view.View role_description='tree' collection hierarchical item_count=2 row_count=2
++++android.view.View role_description='tree item' checkable clickable collection_item name='Animals'
++++++android.view.View role_description='link' clickable focusable link name='Animals'
++++++++android.widget.TextView name='Animals'
++++++android.view.View
++++++++android.view.View role_description='tree item' clickable collection_item name='Domesticated'
++++++++++android.view.View role_description='link' clickable focusable link name='Domesticated'
++++++++++++android.widget.TextView name='Domesticated'
++++++++++android.view.View
++++++++++++android.view.View role_description='tree item' checkable checked clickable collection_item name='Dog'
++++++++++++++android.view.View role_description='link' clickable focusable link name='Dog'
++++++++++++++++android.widget.TextView name='Dog'
++++++++++++android.view.View role_description='tree item' checkable clickable collection_item name='Cat' item_index=1 row_index=1
++++++++++++++android.view.View role_description='link' clickable focusable link name='Cat'
++++++++++++++++android.widget.TextView name='Cat'
++++++++android.view.View role_description='tree item' clickable collection_item name='Wild' item_index=1 row_index=1
++++++++++android.view.View role_description='link' clickable focusable link name='Wild'
++++++++++++android.widget.TextView name='Wild'
++++android.view.View role_description='tree item' clickable collection_item name='Plants' item_index=1 row_index=1
++++++android.view.View role_description='link' clickable focusable link name='Plants'
++++++++android.widget.TextView name='Plants'
android.webkit.WebView focusable focused scrollable
++android.view.View
++++android.view.View role_description='link' clickable focusable link name='normal link'
++++++android.widget.TextView name='normal link'
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='link' clickable focusable link name='InnerText0'
++++android.widget.TextView name='InnerText0'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='InnerText1' hint='Title1'
++++android.widget.TextView name='InnerText1'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Title2'
++++android.widget.TextView name='InnerText2'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='LabelledBy3'
++++android.widget.TextView name='InnerText3'
++android.view.View role_description='link' clickable focusable link name='Title4'
++android.view.View role_description='link' clickable focusable link name='Label5'
++android.view.View role_description='link' clickable focusable link name='LabelledBy6'
\ No newline at end of file
++android.view.View role_description='link' clickable focusable link name='LabelledBy6'
android.webkit.WebView focusable focused scrollable
++android.view.View clickable name='named anchor'
++android.view.View role_description='link' clickable focusable link name='both a named anchor and a link'
\ No newline at end of file
++android.view.View role_description='link' clickable focusable link name='both a named anchor and a link'
++++android.widget.TextView name='both a named anchor and a link'
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='link' clickable focusable link name='Header 1 List element 1 List element 2 List element 3'
++++android.view.View role_description='heading 1' heading name='Header 1'
++++android.widget.ListView collection item_count=3 row_count=3
++++++android.view.View collection_item
++++++++android.view.View name='• '
++++++++android.widget.TextView name='List element 1'
++++++android.view.View collection_item item_index=1 row_index=1
++++++++android.view.View name='• '
++++++++android.widget.TextView name='List element 2'
++++++android.view.View collection_item item_index=2 row_index=2
++++++++android.view.View name='• '
++++++++android.widget.TextView name='List element 3'
android.webkit.WebView focusable focused scrollable
++android.view.View
++++android.view.View role_description='link' clickable focusable link name='dest1'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='dest2'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='dest3'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='dest4'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='dest5'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='dest6'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='dest7'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='dest.8'
++++++android.widget.Image role_description='graphic'
++++android.view.View role_description='link' clickable focusable link name='greenbox'
++++++android.widget.Image role_description='graphic' name='greenbox'
++++android.widget.TextView name=' '
++++android.view.View role_description='link' clickable focusable link name='greenbox'
\ No newline at end of file
++++android.view.View role_description='link' clickable focusable link name='greenbox'
++++++android.widget.Image role_description='graphic' name='greenbox'
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='link' clickable link name='link with no href but onclick'
++android.view.View role_description='link' clickable link name='link with no href and click handler added via script'
\ No newline at end of file
++++android.widget.TextView name='link with no href but onclick'
++android.view.View role_description='link' clickable link name='link with no href and click handler added via script'
++++android.widget.TextView name='link with no href and click handler added via script'
android.webkit.WebView focusable focused scrollable
++android.view.View
++++android.view.View role_description='link' clickable focusable link name='Link with image at start.'
++++++android.widget.Image role_description='graphic' name='Link'
++++++android.widget.TextView name=' with image at start.'
++++android.widget.TextView name=' '
++++android.view.View role_description='link' clickable focusable link name='Link with image in the middle.'
++++++android.widget.TextView name='Link with '
++++++android.widget.Image role_description='graphic' name='image'
++++++android.widget.TextView name=' in the middle.'
++++android.widget.TextView name=' '
++++android.view.View role_description='link' clickable focusable link name='Link with broken in the middle.'
++++++android.widget.TextView name='Link with '
++++++android.widget.Image role_description='graphic' name='broken'
++++++android.widget.TextView name=' in the middle.'
++++android.widget.TextView name=' '
++++android.view.View role_description='link' clickable focusable link name='Link with image at the end'
\ No newline at end of file
++++android.view.View role_description='link' clickable focusable link name='Link with image at the end'
++++++android.widget.TextView name='Link with image at the '
++++++android.widget.Image role_description='graphic' name='end'
......@@ -6,3 +6,4 @@ android.webkit.WebView focusable focused has_character_locations scrollable name
++android.widget.EditText clickable editable_text focusable has_character_locations has_non_empty_value multiline name='Textarea' text_change_added_count=8
++android.widget.Image role_description='graphic' name='Image with alt text'
++android.view.View role_description='link' clickable focusable link name='Image inside link'
++++android.widget.Image role_description='graphic' name='Image inside link'
android.webkit.WebView focusable focused scrollable
++android.view.View
++++android.view.View role_description='link' clickable focusable link name='unread '
++++++android.widget.TextView name='unread '
++++android.view.View role_description='link' clickable focusable link name='read '
++++++android.widget.TextView name='read '
++++android.view.View role_description='link' clickable focusable link name='read '
++++++android.widget.TextView name='read '
++++android.view.View role_description='link' clickable focusable link name='read'
++++++android.widget.Image role_description='graphic' name='read'
++++++android.widget.TextView name='read'
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='link' clickable focusable link name='Empty anchor'
++++android.widget.TextView name='Empty anchor'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Anchor with content'
++++android.widget.TextView name='Anchor with content'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Anchor with ID'
++++android.widget.TextView name='Anchor with ID'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Empty span'
++++android.widget.TextView name='Empty span'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Span with content'
++++android.widget.TextView name='Span with content'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Paragraph with content'
++++android.widget.TextView name='Paragraph with content'
++android.view.View
++++android.view.View clickable
++++android.widget.TextView name='After empty anchor'
......@@ -22,4 +28,4 @@ android.webkit.WebView focusable focused scrollable
++++android.widget.TextView name='After empty span'
++android.view.View
++++android.view.View name='Span with content'
++android.view.View name='Paragraph with content'
\ No newline at end of file
++android.view.View name='Paragraph with content'
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='heading 1 link' clickable heading name='Link In Heading'
++++android.view.View role_description='heading 1 link' clickable focusable heading link name='Link In Heading'
++++++android.widget.TextView heading name='Link In Heading'
......@@ -2,4 +2,5 @@ android.webkit.WebView focusable scrollable
++android.view.View
++android.app.Dialog role_description='dialog'
++++android.widget.TextView name='The dialog subtree should be the only text content in the accessibility tree. '
++++android.view.View role_description='link' clickable focusable focused link name='Link inside the dialog.'
\ No newline at end of file
++++android.view.View role_description='link' clickable focusable focused link name='Link inside the dialog.'
++++++android.widget.TextView name='Link inside the dialog.'
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='navigation'
++++android.view.View role_description='link' clickable focusable link name='Don't click on me'
\ No newline at end of file
++++android.view.View role_description='link' clickable focusable link name='Don't click on me'
++++++android.widget.TextView name='Don't click on me'
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