summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordmazzoni <dmazzoni@chromium.org>2014-11-19 11:19:22 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-19 19:19:48 +0000
commite22626b3944038b075b37f135c32bdbabe16fd28 (patch)
treec10bcdc2f24237a581e1487f072400b793fe5d16
parent91d93479d107ce77f761f78a085135b19d3e3294 (diff)
downloadchromium_src-e22626b3944038b075b37f135c32bdbabe16fd28.zip
chromium_src-e22626b3944038b075b37f135c32bdbabe16fd28.tar.gz
chromium_src-e22626b3944038b075b37f135c32bdbabe16fd28.tar.bz2
Support accessibility actions to increment / decrement sliders.
BUG=378799 Review URL: https://codereview.chromium.org/734933002 Cr-Commit-Position: refs/heads/master@{#304858}
-rw-r--r--content/browser/accessibility/browser_accessibility_android.cc46
-rw-r--r--content/browser/accessibility/browser_accessibility_android.h3
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_android.cc42
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_android.h1
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java26
-rw-r--r--content/renderer/accessibility/renderer_accessibility.cc1
-rw-r--r--content/test/data/accessibility/aria-valuemax-expected-android.txt6
-rw-r--r--content/test/data/accessibility/aria-valuemin-expected-android.txt6
-rw-r--r--content/test/data/accessibility/aria-valuenow-expected-android.txt2
-rw-r--r--content/test/data/accessibility/input-range-expected-android.txt2
10 files changed, 110 insertions, 25 deletions
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index 4ab0e6e..b80334f 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -92,6 +92,24 @@ bool BrowserAccessibilityAndroid::PlatformIsLeaf() const {
return BrowserAccessibility::PlatformIsLeaf();
}
+bool BrowserAccessibilityAndroid::CanScrollForward() const {
+ if (!IsSlider())
+ return false;
+
+ float value = GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ float max = GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE);
+ return value < max;
+}
+
+bool BrowserAccessibilityAndroid::CanScrollBackward() const {
+ if (!IsSlider())
+ return false;
+
+ float value = GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ float min = GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE);
+ return value > min;
+}
+
bool BrowserAccessibilityAndroid::IsCheckable() const {
bool checkable = false;
bool is_aria_pressed_defined;
@@ -208,6 +226,10 @@ bool BrowserAccessibilityAndroid::IsSelected() const {
return HasState(ui::AX_STATE_SELECTED);
}
+bool BrowserAccessibilityAndroid::IsSlider() const {
+ return GetRole() == ui::AX_ROLE_SLIDER;
+}
+
bool BrowserAccessibilityAndroid::IsVisibleToUser() const {
return !HasState(ui::AX_STATE_INVISIBLE);
}
@@ -383,11 +405,13 @@ int BrowserAccessibilityAndroid::GetItemIndex() const {
break;
case ui::AX_ROLE_SLIDER:
case ui::AX_ROLE_PROGRESS_INDICATOR: {
- float value_for_range;
- if (GetFloatAttribute(
- ui::AX_ATTR_VALUE_FOR_RANGE, &value_for_range)) {
- index = static_cast<int>(value_for_range);
- }
+ // Return a percentage here for live feedback in an AccessibilityEvent.
+ // The exact value is returned in RangeCurrentValue.
+ float min = GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE);
+ float max = GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE);
+ float value = GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ if (max > min && value >= min && value <= max)
+ index = static_cast<int>(((value - min)) * 100 / (max - min));
break;
}
}
@@ -403,14 +427,12 @@ int BrowserAccessibilityAndroid::GetItemCount() const {
count = PlatformChildCount();
break;
case ui::AX_ROLE_SLIDER:
- case ui::AX_ROLE_PROGRESS_INDICATOR: {
- float max_value_for_range;
- if (GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE,
- &max_value_for_range)) {
- count = static_cast<int>(max_value_for_range);
- }
+ case ui::AX_ROLE_PROGRESS_INDICATOR:
+ // An AccessibilityEvent can only return integer information about a
+ // seek control, so we return a percentage. The real range is returned
+ // in RangeMin and RangeMax.
+ count = 100;
break;
- }
}
return count;
}
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h
index 8dc2126..70579ab 100644
--- a/content/browser/accessibility/browser_accessibility_android.h
+++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -19,6 +19,8 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
virtual bool PlatformIsLeaf() const override;
+ bool CanScrollForward() const;
+ bool CanScrollBackward() const;
bool IsCheckable() const;
bool IsChecked() const;
bool IsClickable() const;
@@ -38,6 +40,7 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
bool IsRangeType() const;
bool IsScrollable() const;
bool IsSelected() const;
+ bool IsSlider() const;
bool IsVisibleToUser() const;
bool CanOpenPopup() const;
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 7dbc149..8bc13c8 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -116,6 +116,9 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
if (obj.is_null())
return;
+ BrowserAccessibilityAndroid* android_node =
+ static_cast<BrowserAccessibilityAndroid*>(node);
+
if (event_type == ui::AX_EVENT_HIDE)
return;
@@ -157,8 +160,6 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
case ui::AX_EVENT_SHOW: {
// This event is fired when an object appears in a live region.
// Speak its text.
- BrowserAccessibilityAndroid* android_node =
- static_cast<BrowserAccessibilityAndroid*>(node);
Java_BrowserAccessibilityManager_announceLiveRegionText(
env, obj.obj(),
base::android::ConvertUTF16ToJavaString(
@@ -175,6 +176,9 @@ void BrowserAccessibilityManagerAndroid::NotifyAccessibilityEvent(
if (node->IsEditableText()) {
Java_BrowserAccessibilityManager_handleEditableTextChanged(
env, obj.obj(), node->GetId());
+ } else if (android_node->IsSlider()) {
+ Java_BrowserAccessibilityManager_handleSliderChanged(
+ env, obj.obj(), node->GetId());
}
break;
default:
@@ -247,6 +251,8 @@ jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo(
Java_BrowserAccessibilityManager_setAccessibilityNodeInfoBooleanAttributes(
env, obj, info,
id,
+ node->CanScrollForward(),
+ node->CanScrollBackward(),
node->IsCheckable(),
node->IsChecked(),
node->IsClickable(),
@@ -465,6 +471,38 @@ void BrowserAccessibilityManagerAndroid::SetSelection(
SetTextSelection(*node, start, end);
}
+jboolean BrowserAccessibilityManagerAndroid::AdjustSlider(
+ JNIEnv* env, jobject obj, jint id, jboolean increment) {
+ BrowserAccessibility* node = GetFromID(id);
+ if (!node)
+ return false;
+
+ BrowserAccessibilityAndroid* android_node =
+ static_cast<BrowserAccessibilityAndroid*>(node);
+
+ if (!android_node->IsSlider() || !android_node->IsEnabled())
+ return false;
+
+ float value = node->GetFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE);
+ float min = node->GetFloatAttribute(ui::AX_ATTR_MIN_VALUE_FOR_RANGE);
+ float max = node->GetFloatAttribute(ui::AX_ATTR_MAX_VALUE_FOR_RANGE);
+ if (max <= min)
+ return false;
+
+ // To behave similarly to an Android SeekBar, move by an increment of
+ // approximately 20%.
+ float original_value = value;
+ float delta = (max - min) / 5.0f;
+ value += (increment ? delta : -delta);
+ value = std::max(std::min(value, max), min);
+ if (value != original_value) {
+ BrowserAccessibilityManager::SetValue(
+ *node, base::UTF8ToUTF16(base::DoubleToString(value)));
+ return true;
+ }
+ return false;
+}
+
void BrowserAccessibilityManagerAndroid::HandleHoverEvent(
BrowserAccessibility* node) {
JNIEnv* env = AttachCurrentThread();
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h
index 63d3268..eb860d4 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -79,6 +79,7 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
void ScrollToMakeNodeVisible(JNIEnv* env, jobject obj, jint id);
void SetTextFieldValue(JNIEnv* env, jobject obj, jint id, jstring value);
void SetSelection(JNIEnv* env, jobject obj, jint id, jint start, jint end);
+ jboolean AdjustSlider(JNIEnv* env, jobject obj, jint id, jboolean increment);
// Return the id of the next node in tree order in the direction given by
// |forwards|, starting with |start_id|, that matches |element_type|,
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
index 0888376..593c2e5 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
@@ -291,6 +291,10 @@ public class BrowserAccessibilityManager {
}
return previousAtGranularity(granularity, extend);
}
+ case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+ return nativeAdjustSlider(mNativeObj, virtualViewId, true);
+ case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+ return nativeAdjustSlider(mNativeObj, virtualViewId, false);
default:
break;
}
@@ -593,6 +597,11 @@ public class BrowserAccessibilityManager {
}
@CalledByNative
+ private void handleSliderChanged(int id) {
+ sendAccessibilityEvent(id, AccessibilityEvent.TYPE_VIEW_SCROLLED);
+ }
+
+ @CalledByNative
private void handleContentChanged(int id) {
int rootId = nativeGetRootId(mNativeObj);
if (rootId != mCurrentRootId) {
@@ -649,9 +658,10 @@ public class BrowserAccessibilityManager {
@CalledByNative
private void setAccessibilityNodeInfoBooleanAttributes(AccessibilityNodeInfo node,
- int virtualViewId, boolean checkable, boolean checked, boolean clickable,
- boolean editableText, boolean enabled, boolean focusable, boolean focused,
- boolean password, boolean scrollable, boolean selected, boolean visibleToUser) {
+ int virtualViewId, boolean canScrollForward, boolean canScrollBackward,
+ boolean checkable, boolean checked, boolean clickable, boolean editableText,
+ boolean enabled, boolean focusable, boolean focused, boolean password,
+ boolean scrollable, boolean selected, boolean visibleToUser) {
node.setCheckable(checkable);
node.setChecked(checked);
node.setClickable(clickable);
@@ -677,6 +687,14 @@ public class BrowserAccessibilityManager {
node.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
}
+ if (canScrollForward) {
+ node.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+ }
+
+ if (canScrollBackward) {
+ node.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ }
+
if (focusable) {
if (focused) {
node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
@@ -942,4 +960,6 @@ public class BrowserAccessibilityManager {
private native boolean nativePreviousAtGranularity(
long nativeBrowserAccessibilityManagerAndroid,
int selectionGranularity, boolean extendSelection, int id, int cursorIndex);
+ private native boolean nativeAdjustSlider(
+ long nativeBrowserAccessibilityManagerAndroid, int id, boolean increment);
}
diff --git a/content/renderer/accessibility/renderer_accessibility.cc b/content/renderer/accessibility/renderer_accessibility.cc
index 44bc64d..17bc571 100644
--- a/content/renderer/accessibility/renderer_accessibility.cc
+++ b/content/renderer/accessibility/renderer_accessibility.cc
@@ -464,6 +464,7 @@ void RendererAccessibility::OnSetValue(
}
obj.setValue(value);
+ HandleAXEvent(obj, ui::AX_EVENT_VALUE_CHANGED);
}
} // namespace content
diff --git a/content/test/data/accessibility/aria-valuemax-expected-android.txt b/content/test/data/accessibility/aria-valuemax-expected-android.txt
index 0c5f2444..20bfb69 100644
--- a/content/test/data/accessibility/aria-valuemax-expected-android.txt
+++ b/content/test/data/accessibility/aria-valuemax-expected-android.txt
@@ -1,5 +1,5 @@
android.webkit.WebView focusable focused scrollable
- android.widget.ProgressBar range item_index=51 item_count=101 range_min=1 range_max=101 range_current_value=51
+ android.widget.ProgressBar range item_index=50 item_count=100 range_min=1 range_max=101 range_current_value=51
android.view.View range range_min=2 range_max=102 range_current_value=52
- android.widget.SeekBar range item_index=53 item_count=103 range_min=3 range_max=103 range_current_value=53
- android.widget.EditText range_min=4 range_max=104 range_current_value=54
+ android.widget.SeekBar range item_index=50 item_count=100 range_min=3 range_max=103 range_current_value=53
+ android.widget.EditText range_min=4 range_max=104 range_current_value=54 \ No newline at end of file
diff --git a/content/test/data/accessibility/aria-valuemin-expected-android.txt b/content/test/data/accessibility/aria-valuemin-expected-android.txt
index 0c5f2444..20bfb69 100644
--- a/content/test/data/accessibility/aria-valuemin-expected-android.txt
+++ b/content/test/data/accessibility/aria-valuemin-expected-android.txt
@@ -1,5 +1,5 @@
android.webkit.WebView focusable focused scrollable
- android.widget.ProgressBar range item_index=51 item_count=101 range_min=1 range_max=101 range_current_value=51
+ android.widget.ProgressBar range item_index=50 item_count=100 range_min=1 range_max=101 range_current_value=51
android.view.View range range_min=2 range_max=102 range_current_value=52
- android.widget.SeekBar range item_index=53 item_count=103 range_min=3 range_max=103 range_current_value=53
- android.widget.EditText range_min=4 range_max=104 range_current_value=54
+ android.widget.SeekBar range item_index=50 item_count=100 range_min=3 range_max=103 range_current_value=53
+ android.widget.EditText range_min=4 range_max=104 range_current_value=54 \ No newline at end of file
diff --git a/content/test/data/accessibility/aria-valuenow-expected-android.txt b/content/test/data/accessibility/aria-valuenow-expected-android.txt
index 9d59be2..9bc7f1d 100644
--- a/content/test/data/accessibility/aria-valuenow-expected-android.txt
+++ b/content/test/data/accessibility/aria-valuenow-expected-android.txt
@@ -1,2 +1,2 @@
android.webkit.WebView focusable focused scrollable
- android.widget.ProgressBar range item_index=3 range_current_value=3
+ android.widget.ProgressBar range item_count=100 range_current_value=3 \ No newline at end of file
diff --git a/content/test/data/accessibility/input-range-expected-android.txt b/content/test/data/accessibility/input-range-expected-android.txt
index 8e8d7f4..db1b0c6 100644
--- a/content/test/data/accessibility/input-range-expected-android.txt
+++ b/content/test/data/accessibility/input-range-expected-android.txt
@@ -1,3 +1,3 @@
android.webkit.WebView focusable focused scrollable
android.view.View
- android.widget.SeekBar focusable range item_index=5 item_count=10 range_min=1 range_max=10 range_current_value=5
+ android.widget.SeekBar focusable range item_index=44 item_count=100 range_min=1 range_max=10 range_current_value=5 \ No newline at end of file