Commit 8698e421 authored by Mark Schillaci's avatar Mark Schillaci Committed by Commit Bot

Added a11y state description for aria-current nodes on Android

This CL updates the behavior of aria-current nodes on Android.

With this change, the value of aria-current (e.g. "date",
"page", "location", etc.) will be read as a part of the state
description for that node on Android. For example, if
aria-current="page", then the node will announce "current page".

We append this status as part of the state description in the
AccessibilityNodeInfo object.

This CL also updates associated unit test expectations.


AX-Relnotes: aria-current nodes now explicitly announce their state.
Bug: 1093578
Change-Id: I6028f235e663e7df5ce4e626db16f68acbbc9b65
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2493660Reviewed-by: default avatardanakj <danakj@chromium.org>
Reviewed-by: default avatarMark Schillaci <mschillaci@google.com>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Mark Schillaci <mschillaci@google.com>
Cr-Commit-Position: refs/heads/master@{#821323}
parent 65795bd7
...@@ -578,6 +578,10 @@ base::string16 BrowserAccessibilityAndroid::GetStateDescription() const { ...@@ -578,6 +578,10 @@ base::string16 BrowserAccessibilityAndroid::GetStateDescription() const {
if (GetRole() == ax::mojom::Role::kListBoxOption) if (GetRole() == ax::mojom::Role::kListBoxOption)
state_descs.push_back(GetListBoxItemStateDescription()); state_descs.push_back(GetListBoxItemStateDescription());
// For nodes with non-trivial aria-current values, communicate state.
if (HasAriaCurrent())
state_descs.push_back(GetAriaCurrentStateDescription());
// Concatenate all state descriptions and return. // Concatenate all state descriptions and return.
return base::JoinString(state_descs, base::ASCIIToUTF16(" ")); return base::JoinString(state_descs, base::ASCIIToUTF16(" "));
} }
...@@ -670,6 +674,47 @@ base::string16 BrowserAccessibilityAndroid::GetListBoxItemStateDescription() ...@@ -670,6 +674,47 @@ base::string16 BrowserAccessibilityAndroid::GetListBoxItemStateDescription()
nullptr); nullptr);
} }
base::string16 BrowserAccessibilityAndroid::GetAriaCurrentStateDescription()
const {
content::ContentClient* content_client = content::GetContentClient();
base::string16 aria_current_state;
switch (static_cast<ax::mojom::AriaCurrentState>(
GetIntAttribute(ax::mojom::IntAttribute::kAriaCurrentState))) {
case ax::mojom::AriaCurrentState::kPage:
aria_current_state =
content_client->GetLocalizedString(IDS_AX_ARIA_CURRENT_PAGE);
break;
case ax::mojom::AriaCurrentState::kStep:
aria_current_state =
content_client->GetLocalizedString(IDS_AX_ARIA_CURRENT_STEP);
break;
case ax::mojom::AriaCurrentState::kLocation:
aria_current_state =
content_client->GetLocalizedString(IDS_AX_ARIA_CURRENT_LOCATION);
break;
case ax::mojom::AriaCurrentState::kDate:
aria_current_state =
content_client->GetLocalizedString(IDS_AX_ARIA_CURRENT_DATE);
break;
case ax::mojom::AriaCurrentState::kTime:
aria_current_state =
content_client->GetLocalizedString(IDS_AX_ARIA_CURRENT_TIME);
break;
case ax::mojom::AriaCurrentState::kTrue:
default:
aria_current_state =
content_client->GetLocalizedString(IDS_AX_ARIA_CURRENT_TRUE);
break;
}
return base::ReplaceStringPlaceholders(
content_client->GetLocalizedString(
IDS_AX_ARIA_CURRENT_STATE_DESCRIPTION_BASE),
aria_current_state, nullptr);
}
std::string BrowserAccessibilityAndroid::GetRoleString() const { std::string BrowserAccessibilityAndroid::GetRoleString() const {
return ui::ToString(GetRole()); return ui::ToString(GetRole());
} }
...@@ -1908,6 +1953,17 @@ void BrowserAccessibilityAndroid::GetSuggestions( ...@@ -1908,6 +1953,17 @@ void BrowserAccessibilityAndroid::GetSuggestions(
} }
} }
bool BrowserAccessibilityAndroid::HasAriaCurrent() const {
if (!HasIntAttribute(ax::mojom::IntAttribute::kAriaCurrentState))
return false;
auto current = static_cast<ax::mojom::AriaCurrentState>(
GetIntAttribute(ax::mojom::IntAttribute::kAriaCurrentState));
return current != ax::mojom::AriaCurrentState::kNone &&
current != ax::mojom::AriaCurrentState::kFalse;
}
bool BrowserAccessibilityAndroid::HasNonEmptyValue() const { bool BrowserAccessibilityAndroid::HasNonEmptyValue() const {
return IsTextField() && !GetValueForControl().empty(); return IsTextField() && !GetValueForControl().empty();
} }
......
...@@ -73,6 +73,8 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility { ...@@ -73,6 +73,8 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
bool CanOpenPopup() const; bool CanOpenPopup() const;
bool HasAriaCurrent() const;
bool HasFocusableNonOptionChild() const; bool HasFocusableNonOptionChild() const;
bool HasNonEmptyValue() const; bool HasNonEmptyValue() const;
...@@ -96,6 +98,7 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility { ...@@ -96,6 +98,7 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
base::string16 GetCheckboxStateDescription() const; base::string16 GetCheckboxStateDescription() const;
base::string16 GetListBoxStateDescription() const; base::string16 GetListBoxStateDescription() const;
base::string16 GetListBoxItemStateDescription() const; base::string16 GetListBoxItemStateDescription() const;
base::string16 GetAriaCurrentStateDescription() const;
base::string16 GetRoleDescription() const; base::string16 GetRoleDescription() const;
......
android.webkit.WebView focusable focused scrollable
++android.view.View role_description='link' clickable focusable link name='Section one'
++++android.widget.TextView name='Section one'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Section two'
++++android.widget.TextView name='Section two'
++android.widget.TextView name=' '
++android.view.View role_description='link' clickable focusable link name='Section three' state_description='current location'
++++android.widget.TextView name='Section three'
++android.view.View name='<newline>'
++android.view.View role_description='heading 1' heading name='Section one heading'
++android.view.View role_description='heading 1' heading name='Section two heading'
++android.view.View role_description='heading 1' heading name='Section three heading'
++android.view.View name='<newline>'
++android.view.View
++++android.widget.TextView name='Span 1'
++++android.widget.TextView name=' '
++++android.view.View name='Span 2' state_description='current item'
++++android.widget.TextView name=' '
++++android.widget.TextView name='Span 3'
++android.view.View name='aria-current is true' state_description='current item'
++android.view.View name='aria-current is false'
++android.view.View name='aria-current is time' state_description='current time'
++android.view.View name='aria-current is date' state_description='current date'
++android.view.View name='aria-current is location' state_description='current location'
++android.view.View name='aria-current is step' state_description='current step'
++android.view.View name='aria-current is page' state_description='current page'
++android.view.View name='aria-current is empty string'
...@@ -22,3 +22,19 @@ ...@@ -22,3 +22,19 @@
++++++[static] name='Span 2' ++++++[static] name='Span 2'
++++[static] name=' ' ++++[static] name=' '
++++[static] name='Span 3' ++++[static] name='Span 3'
++[paragraph] current:true
++++[static] name='aria-current is true'
++[paragraph] current:false
++++[static] name='aria-current is false'
++[paragraph] current:time
++++[static] name='aria-current is time'
++[paragraph] current:date
++++[static] name='aria-current is date'
++[paragraph] current:location
++++[static] name='aria-current is location'
++[paragraph] current:step
++++[static] name='aria-current is step'
++[paragraph] current:page
++++[static] name='aria-current is page'
++[paragraph]
++++[static] name='aria-current is empty string'
\ No newline at end of file
...@@ -39,3 +39,27 @@ rootWebArea ...@@ -39,3 +39,27 @@ rootWebArea
++++++++++inlineTextBox name=' ' ++++++++++inlineTextBox name=' '
++++++++staticText name='Span 3' ++++++++staticText name='Span 3'
++++++++++inlineTextBox name='Span 3' ++++++++++inlineTextBox name='Span 3'
++++++paragraph ariaCurrentState=true
++++++++staticText name='aria-current is true'
++++++++++inlineTextBox name='aria-current is true'
++++++paragraph ariaCurrentState=false
++++++++staticText name='aria-current is false'
++++++++++inlineTextBox name='aria-current is false'
++++++paragraph ariaCurrentState=time
++++++++staticText name='aria-current is time'
++++++++++inlineTextBox name='aria-current is time'
++++++paragraph ariaCurrentState=date
++++++++staticText name='aria-current is date'
++++++++++inlineTextBox name='aria-current is date'
++++++paragraph ariaCurrentState=location
++++++++staticText name='aria-current is location'
++++++++++inlineTextBox name='aria-current is location'
++++++paragraph ariaCurrentState=step
++++++++staticText name='aria-current is step'
++++++++++inlineTextBox name='aria-current is step'
++++++paragraph ariaCurrentState=page
++++++++staticText name='aria-current is page'
++++++++++inlineTextBox name='aria-current is page'
++++++paragraph
++++++++staticText name='aria-current is empty string'
++++++++++inlineTextBox name='aria-current is empty string'
\ No newline at end of file
...@@ -21,4 +21,20 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ...@@ -21,4 +21,20 @@ ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++++IA2_ROLE_SECTION current:true ++++IA2_ROLE_SECTION current:true
++++++ROLE_SYSTEM_STATICTEXT name='Span 2' ++++++ROLE_SYSTEM_STATICTEXT name='Span 2'
++++ROLE_SYSTEM_STATICTEXT name=' ' ++++ROLE_SYSTEM_STATICTEXT name=' '
++++ROLE_SYSTEM_STATICTEXT name='Span 3' ++++ROLE_SYSTEM_STATICTEXT name='Span 3'
\ No newline at end of file ++IA2_ROLE_PARAGRAPH current:true
++++ROLE_SYSTEM_STATICTEXT name='aria-current is true'
++IA2_ROLE_PARAGRAPH current:false
++++ROLE_SYSTEM_STATICTEXT name='aria-current is false'
++IA2_ROLE_PARAGRAPH current:time
++++ROLE_SYSTEM_STATICTEXT name='aria-current is time'
++IA2_ROLE_PARAGRAPH current:date
++++ROLE_SYSTEM_STATICTEXT name='aria-current is date'
++IA2_ROLE_PARAGRAPH current:location
++++ROLE_SYSTEM_STATICTEXT name='aria-current is location'
++IA2_ROLE_PARAGRAPH current:step
++++ROLE_SYSTEM_STATICTEXT name='aria-current is step'
++IA2_ROLE_PARAGRAPH current:page
++++ROLE_SYSTEM_STATICTEXT name='aria-current is page'
++IA2_ROLE_PARAGRAPH
++++ROLE_SYSTEM_STATICTEXT name='aria-current is empty string'
\ No newline at end of file
...@@ -19,5 +19,13 @@ ...@@ -19,5 +19,13 @@
<span aria-current="true">Span 2</span> <span aria-current="true">Span 2</span>
<span>Span 3</span> <span>Span 3</span>
</div> </div>
<p aria-current="true">aria-current is true</p>
<p aria-current="false">aria-current is false</p>
<p aria-current="time">aria-current is time</p>
<p aria-current="date">aria-current is date</p>
<p aria-current="location">aria-current is location</p>
<p aria-current="step">aria-current is step</p>
<p aria-current="page">aria-current is page</p>
<p aria-current="">aria-current is empty string</p>
</body> </body>
</html> </html>
...@@ -805,6 +805,27 @@ below: ...@@ -805,6 +805,27 @@ below:
<message name="IDS_AX_LIST_BOX_ITEM_STATE_DESCRIPTION" desc="Accessibility state description for an item that is part of a list box"> <message name="IDS_AX_LIST_BOX_ITEM_STATE_DESCRIPTION" desc="Accessibility state description for an item that is part of a list box">
in list, item <ph name="INDEX">$1<ex>1</ex></ph> of <ph name="COUNT">$2<ex>3</ex></ph> in list, item <ph name="INDEX">$1<ex>1</ex></ph> of <ph name="COUNT">$2<ex>3</ex></ph>
</message> </message>
<message name="IDS_AX_ARIA_CURRENT_STATE_DESCRIPTION_BASE" desc="Accessibility state description for a node that has aria-current value set to something other than false">
current <ph name="TYPE">$1<ex>page</ex></ph>
</message>
<message name="IDS_AX_ARIA_CURRENT_PAGE" desc="Accessibility state description for aria-current value of page.">
page
</message>
<message name="IDS_AX_ARIA_CURRENT_STEP" desc="Accessibility state description for aria-current value of step.">
step
</message>
<message name="IDS_AX_ARIA_CURRENT_LOCATION" desc="Accessibility state description for aria-current value of location.">
location
</message>
<message name="IDS_AX_ARIA_CURRENT_DATE" desc="Accessibility state description for aria-current value of date.">
date
</message>
<message name="IDS_AX_ARIA_CURRENT_TIME" desc="Accessibility state description for aria-current value of time.">
time
</message>
<message name="IDS_AX_ARIA_CURRENT_TRUE" desc="Accessibility state description for aria-current value of true.">
item
</message>
</if> </if>
<!-- Automatic image annotations for accessibility --> <!-- Automatic image annotations for accessibility -->
......
5c5e9686c2277aa998a4a271e5166c8d0cba8b9e
\ No newline at end of file
59a0673045e1793e36f1312e11a330271f296f60
\ No newline at end of file
9ea85c50785469543867f7152f1c3be0489d95f4
\ No newline at end of file
42fe4f745cb09a95ecb4820c3c2abd8eb6c7d813
\ No newline at end of file
052c3ce2f0154d34fcf38469aaaf1c0532f7646e
\ No newline at end of file
de2faaa74be06d01cd11e3b910371ba665984ed0
\ 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