summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordmazzoni <dmazzoni@chromium.org>2014-11-04 21:16:29 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-05 05:17:50 +0000
commitab9f8645f966c4d01a8009ac6a67a7c7f082e273 (patch)
treebd9282e8bb000b5cf5ba0e1cd5382bc1e3d40cc3
parentfcffcb17a43f6d0ac30cc5b8260028ad6489d6e9 (diff)
downloadchromium_src-ab9f8645f966c4d01a8009ac6a67a7c7f082e273.zip
chromium_src-ab9f8645f966c4d01a8009ac6a67a7c7f082e273.tar.gz
chromium_src-ab9f8645f966c4d01a8009ac6a67a7c7f082e273.tar.bz2
Add Android AX functions to set the value and selection of a text field.
BUG=414571 Review URL: https://codereview.chromium.org/681503002 Cr-Commit-Position: refs/heads/master@{#302756}
-rw-r--r--content/browser/accessibility/browser_accessibility_android.cc6
-rw-r--r--content/browser/accessibility/browser_accessibility_android.h1
-rw-r--r--content/browser/accessibility/browser_accessibility_manager.cc11
-rw-r--r--content/browser/accessibility/browser_accessibility_manager.h6
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_android.cc17
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_android.h4
-rw-r--r--content/browser/accessibility/browser_accessibility_manager_unittest.cc2
-rw-r--r--content/browser/frame_host/render_frame_host_impl.cc5
-rw-r--r--content/browser/frame_host/render_frame_host_impl.h2
-rw-r--r--content/common/accessibility_messages.h6
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java46
-rw-r--r--content/renderer/accessibility/renderer_accessibility.cc28
-rw-r--r--content/renderer/accessibility/renderer_accessibility.h1
13 files changed, 119 insertions, 16 deletions
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc
index abc37d8..c57c40e 100644
--- a/content/browser/accessibility/browser_accessibility_android.cc
+++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -143,6 +143,12 @@ bool BrowserAccessibilityAndroid::IsDismissable() const {
return false; // No concept of "dismissable" on the web currently.
}
+bool BrowserAccessibilityAndroid::IsEditableText() const {
+ return (GetRole() == ui::AX_ROLE_EDITABLE_TEXT ||
+ GetRole() == ui::AX_ROLE_TEXT_AREA ||
+ GetRole() == ui::AX_ROLE_TEXT_FIELD);
+}
+
bool BrowserAccessibilityAndroid::IsEnabled() const {
return HasState(ui::AX_STATE_ENABLED);
}
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h
index 17c7c46..2f6d1af 100644
--- a/content/browser/accessibility/browser_accessibility_android.h
+++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -26,6 +26,7 @@ class BrowserAccessibilityAndroid : public BrowserAccessibility {
bool IsCollectionItem() const;
bool IsContentInvalid() const;
bool IsDismissable() const;
+ bool IsEditableText() const;
bool IsEnabled() const;
bool IsFocusable() const;
bool IsFocused() const;
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index bd745cd..cb392cb 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -284,8 +284,17 @@ void BrowserAccessibilityManager::ScrollToPoint(
}
}
+void BrowserAccessibilityManager::SetValue(
+ const BrowserAccessibility& node,
+ const base::string16& value) {
+ if (delegate_)
+ delegate_->AccessibilitySetValue(node.GetId(), value);
+}
+
void BrowserAccessibilityManager::SetTextSelection(
- const BrowserAccessibility& node, int start_offset, int end_offset) {
+ const BrowserAccessibility& node,
+ int start_offset,
+ int end_offset) {
if (delegate_) {
delegate_->AccessibilitySetTextSelection(
node.GetId(), start_offset, end_offset);
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index 3760141..4b637cd 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -61,6 +61,8 @@ class CONTENT_EXPORT BrowserAccessibilityDelegate {
int acc_obj_id, const gfx::Point& point) = 0;
virtual void AccessibilitySetTextSelection(
int acc_obj_id, int start_offset, int end_offset) = 0;
+ virtual void AccessibilitySetValue(
+ int acc_obj_id, const base::string16& value) = 0;
virtual bool AccessibilityViewHasFocus() const = 0;
virtual gfx::Rect AccessibilityGetViewBounds() const = 0;
virtual gfx::Point AccessibilityOriginInScreen(
@@ -146,6 +148,10 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXTreeDelegate {
void ScrollToPoint(
const BrowserAccessibility& node, gfx::Point point);
+ // Tell the renderer to set the value of an editable text node.
+ void SetValue(
+ const BrowserAccessibility& node, const base::string16& value);
+
// Tell the renderer to set the text selection on a node.
void SetTextSelection(
const BrowserAccessibility& node, int start_offset, int end_offset);
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 3a31ff7..ce27954 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -224,6 +224,7 @@ jboolean BrowserAccessibilityManagerAndroid::PopulateAccessibilityNodeInfo(
node->IsCheckable(),
node->IsChecked(),
node->IsClickable(),
+ node->IsEditableText(),
node->IsEnabled(),
node->IsFocusable(),
node->IsFocused(),
@@ -406,6 +407,22 @@ void BrowserAccessibilityManagerAndroid::ScrollToMakeNodeVisible(
ScrollToMakeVisible(*node, gfx::Rect(node->GetLocation().size()));
}
+void BrowserAccessibilityManagerAndroid::SetTextFieldValue(
+ JNIEnv* env, jobject obj, jint id, jstring value) {
+ BrowserAccessibility* node = GetFromID(id);
+ if (node) {
+ BrowserAccessibilityManager::SetValue(
+ *node, base::android::ConvertJavaStringToUTF16(env, value));
+ }
+}
+
+void BrowserAccessibilityManagerAndroid::SetSelection(
+ JNIEnv* env, jobject obj, jint id, jint start, jint end) {
+ BrowserAccessibility* node = GetFromID(id);
+ if (node)
+ SetTextSelection(*node, start, end);
+}
+
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 0946e5e..720f175 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.h
+++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -55,7 +55,9 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAndroid
void Click(JNIEnv* env, jobject obj, jint id);
void Focus(JNIEnv* env, jobject obj, jint id);
void Blur(JNIEnv* env, jobject obj);
- void ScrollToMakeNodeVisible(JNIEnv* env, jobject obj, int id);
+ 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);
// 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/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
index a104defa..b71187c 100644
--- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -73,6 +73,8 @@ class TestBrowserAccessibilityDelegate
void AccessibilitySetTextSelection(int acc_obj_id,
int start_offset,
int end_offset) override {}
+ void AccessibilitySetValue(int acc_obj_id, const base::string16& value)
+ override {}
bool AccessibilityViewHasFocus() const override { return false; }
gfx::Rect AccessibilityGetViewBounds() const override { return gfx::Rect(); }
gfx::Point AccessibilityOriginInScreen(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 0baac98..fe9b110 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -434,6 +434,11 @@ void RenderFrameHostImpl::AccessibilitySetTextSelection(
routing_id_, object_id, start_offset, end_offset));
}
+void RenderFrameHostImpl::AccessibilitySetValue(
+ int object_id, const base::string16& value) {
+ Send(new AccessibilityMsg_SetValue(routing_id_, object_id, value));
+}
+
bool RenderFrameHostImpl::AccessibilityViewHasFocus() const {
RenderWidgetHostView* view = render_view_host_->GetView();
if (view)
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 0f5d57a..d406a85 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -134,6 +134,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
void AccessibilitySetTextSelection(int acc_obj_id,
int start_offset,
int end_offset) override;
+ void AccessibilitySetValue(int acc_obj_id, const base::string16& value)
+ override;
bool AccessibilityViewHasFocus() const override;
gfx::Rect AccessibilityGetViewBounds() const override;
gfx::Point AccessibilityOriginInScreen(
diff --git a/content/common/accessibility_messages.h b/content/common/accessibility_messages.h
index d88d88f..55b8d2b 100644
--- a/content/common/accessibility_messages.h
+++ b/content/common/accessibility_messages.h
@@ -122,6 +122,12 @@ IPC_MESSAGE_ROUTED3(AccessibilityMsg_SetTextSelection,
int /* New start offset */,
int /* New end offset */)
+// Relay a request from assistive technology to set the value of an
+// editable text element.
+IPC_MESSAGE_ROUTED2(AccessibilityMsg_SetValue,
+ int /* object id */,
+ base::string16 /* Value */)
+
// Determine the accessibility object under a given point and reply with
// a AccessibilityHostMsg_HitTestResult with the same id.
IPC_MESSAGE_ROUTED1(AccessibilityMsg_HitTest,
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 3d55f43..5f1ed45 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
@@ -40,6 +40,11 @@ import java.util.Locale;
public class BrowserAccessibilityManager {
private static final String TAG = "BrowserAccessibilityManager";
+ // Constants from AccessibilityNodeInfo defined in the L SDK.
+ private static final int ACTION_SET_TEXT = 0x200000;
+ private static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
+ "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+
private ContentViewCore mContentViewCore;
private final AccessibilityManager mAccessibilityManager;
private final RenderCoordinates mRenderCoordinates;
@@ -194,7 +199,6 @@ public class BrowserAccessibilityManager {
case AccessibilityNodeInfo.ACTION_CLEAR_FOCUS:
nativeBlur(mNativeObj);
return true;
-
case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT: {
if (arguments == null) return false;
String elementType = arguments.getString(
@@ -211,7 +215,28 @@ public class BrowserAccessibilityManager {
elementType = elementType.toUpperCase(Locale.US);
return jumpToElementType(elementType, false);
}
-
+ case ACTION_SET_TEXT: {
+ if (arguments == null) return false;
+ String newText = arguments.getString(
+ ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE);
+ if (newText == null) return false;
+ nativeSetTextFieldValue(mNativeObj, virtualViewId, newText);
+ // Match Android framework and set the cursor to the end of the text field.
+ nativeSetSelection(mNativeObj, virtualViewId, newText.length(), newText.length());
+ break;
+ }
+ case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
+ int selectionStart = 0;
+ int selectionEnd = 0;
+ if (arguments != null) {
+ selectionStart = arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT);
+ selectionEnd = arguments.getInt(
+ AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT);
+ }
+ nativeSetSelection(mNativeObj, virtualViewId, selectionStart, selectionEnd);
+ break;
+ }
default:
break;
}
@@ -388,8 +413,8 @@ public class BrowserAccessibilityManager {
* gets initialized first.
*/
private boolean isFrameInfoInitialized() {
- return mRenderCoordinates.getContentWidthCss() != 0.0 ||
- mRenderCoordinates.getContentHeightCss() != 0.0;
+ return mRenderCoordinates.getContentWidthCss() != 0.0
+ || mRenderCoordinates.getContentHeightCss() != 0.0;
}
@CalledByNative
@@ -480,8 +505,8 @@ public class BrowserAccessibilityManager {
@CalledByNative
private void setAccessibilityNodeInfoBooleanAttributes(AccessibilityNodeInfo node,
int virtualViewId, boolean checkable, boolean checked, boolean clickable,
- boolean enabled, boolean focusable, boolean focused, boolean password,
- boolean scrollable, boolean selected, boolean visibleToUser) {
+ 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);
@@ -496,6 +521,11 @@ public class BrowserAccessibilityManager {
node.addAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT);
node.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT);
+ if (editableText && enabled) {
+ node.addAction(ACTION_SET_TEXT);
+ node.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
+ }
+
if (focusable) {
if (focused) {
node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
@@ -739,4 +769,8 @@ public class BrowserAccessibilityManager {
long nativeBrowserAccessibilityManagerAndroid, int id);
private native int nativeFindElementType(long nativeBrowserAccessibilityManagerAndroid,
int startId, String elementType, boolean forwards);
+ private native void nativeSetTextFieldValue(long nativeBrowserAccessibilityManagerAndroid,
+ int id, String newValue);
+ private native void nativeSetSelection(long nativeBrowserAccessibilityManagerAndroid,
+ int id, int start, int end);
}
diff --git a/content/renderer/accessibility/renderer_accessibility.cc b/content/renderer/accessibility/renderer_accessibility.cc
index 18fb07f..e8da448 100644
--- a/content/renderer/accessibility/renderer_accessibility.cc
+++ b/content/renderer/accessibility/renderer_accessibility.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.h"
#include "content/renderer/accessibility/blink_ax_enum_conversion.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_view_impl.h"
@@ -71,6 +72,7 @@ bool RendererAccessibility::OnMessageReceived(const IPC::Message& message) {
OnScrollToMakeVisible)
IPC_MESSAGE_HANDLER(AccessibilityMsg_ScrollToPoint, OnScrollToPoint)
IPC_MESSAGE_HANDLER(AccessibilityMsg_SetTextSelection, OnSetTextSelection)
+ IPC_MESSAGE_HANDLER(AccessibilityMsg_SetValue, OnSetValue)
IPC_MESSAGE_HANDLER(AccessibilityMsg_HitTest, OnHitTest)
IPC_MESSAGE_HANDLER(AccessibilityMsg_Reset, OnReset)
IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError)
@@ -425,15 +427,25 @@ void RendererAccessibility::OnSetTextSelection(
return;
}
- // TODO(dmazzoni): support elements other than <input>.
- blink::WebNode node = obj.node();
- if (!node.isNull() && node.isElementNode()) {
- blink::WebElement element = node.to<blink::WebElement>();
- blink::WebInputElement* input_element =
- blink::toWebInputElement(&element);
- if (input_element && input_element->isTextField())
- input_element->setSelectionRange(start_offset, end_offset);
+ obj.setSelectedTextRange(start_offset, end_offset);
+}
+
+void RendererAccessibility::OnSetValue(
+ int acc_obj_id,
+ base::string16 value) {
+ const WebDocument& document = GetMainDocument();
+ if (document.isNull())
+ return;
+
+ WebAXObject obj = document.accessibilityObjectFromID(acc_obj_id);
+ if (obj.isDetached()) {
+#ifndef NDEBUG
+ LOG(WARNING) << "SetTextSelection on invalid object id " << acc_obj_id;
+#endif
+ return;
}
+
+ obj.setValue(value);
}
} // namespace content
diff --git a/content/renderer/accessibility/renderer_accessibility.h b/content/renderer/accessibility/renderer_accessibility.h
index d757c5a..6bac56e 100644
--- a/content/renderer/accessibility/renderer_accessibility.h
+++ b/content/renderer/accessibility/renderer_accessibility.h
@@ -92,6 +92,7 @@ class CONTENT_EXPORT RendererAccessibility : public RenderFrameObserver {
void OnScrollToPoint(int acc_obj_id, gfx::Point point);
void OnSetFocus(int acc_obj_id);
void OnSetTextSelection(int acc_obj_id, int start_offset, int end_offset);
+ void OnSetValue(int acc_obj_id, base::string16 value);
// Events from Blink are collected until they are ready to be
// sent to the browser.