Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(970)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java

Issue 2465403003: Android accessibility: automatically focus links (Closed)
Patch Set: Rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/accessibility/browser_accessibility_manager_android.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/public/android/java/src/org/chromium/content/browser/accessibility/BrowserAccessibilityManager.java
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 ce84964decaae1e9f9d1c85508cc257abe53f7e6..d386d6d91a950a2211dfaca269718e5636415f13 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
@@ -37,6 +37,9 @@ import java.util.Locale;
public class BrowserAccessibilityManager {
private static final String TAG = "BrowserAccessibilityManager";
+ private static final int WINDOW_CONTENT_CHANGED_DELAY_MS = 500;
+ private static final int ACCESSIBILITY_FOCUS_LOCATION_CHANGED_DELAY_MS = 100;
+
// Constants from AccessibilityNodeInfo defined in the K SDK.
private static final int ACTION_COLLAPSE = 0x00080000;
private static final int ACTION_EXPAND = 0x00040000;
@@ -45,7 +48,6 @@ public class BrowserAccessibilityManager {
private static final int ACTION_SET_TEXT = 0x200000;
private static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
"ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
- private static final int WINDOW_CONTENT_CHANGED_DELAY_MS = 500;
// Constants from AccessibilityNodeInfo defined in the M SDK.
// Source: https://developer.android.com/reference/android/R.id.html
@@ -75,6 +77,7 @@ public class BrowserAccessibilityManager {
private int mSelectionEndIndex;
protected int mAccessibilityFocusId;
private Runnable mSendWindowContentChangedRunnable;
+ private Runnable mAccessibilityFocusLocationChangedRunnable;
/**
* Create a BrowserAccessibilityManager object, which is owned by the C++
@@ -237,6 +240,12 @@ public class BrowserAccessibilityManager {
if (mAccessibilityFocusId == virtualViewId) {
mAccessibilityFocusId = View.NO_ID;
mAccessibilityFocusRect = null;
+ // If we had a pending callback to update the location of the previous object
+ // with accessibility focus, remove it.
+ if (mAccessibilityFocusLocationChangedRunnable != null) {
+ mView.removeCallbacks(mAccessibilityFocusLocationChangedRunnable);
+ mAccessibilityFocusLocationChangedRunnable = null;
+ }
}
return true;
case AccessibilityNodeInfo.ACTION_CLICK:
@@ -537,6 +546,20 @@ public class BrowserAccessibilityManager {
mSelectionStartIndex = 0;
mSelectionEndIndex = 0;
+ // If we had a pending callback to update the location of the previous object with
+ // accessibility focus, remove it.
+ if (mAccessibilityFocusLocationChangedRunnable != null) {
+ mView.removeCallbacks(mAccessibilityFocusLocationChangedRunnable);
+ mAccessibilityFocusLocationChangedRunnable = null;
+ }
+
+ // Call nativeSetAccessibilityFocus. For the most part Chrome doesn't have a
+ // concept of accessibility focus, but we do two things: (1) auto-focus certain
+ // roles like links when they get accessibility focus and (2) load inline text boxes
+ // for nodes when they get accessibility focus since inline text boxes are expensive
+ // to load and on Android they're only needed for nodes that have input focus or
+ // accessibility focus.
+ //
// Calling nativeSetAccessibilityFocus will asynchronously load inline text boxes for
// this node and its subtree. If accessibility focus is on anything other than
// the root, do it - otherwise set it to -1 so we don't load inline text boxes
@@ -566,6 +589,47 @@ public class BrowserAccessibilityManager {
}
/**
+ * Work around a bug in the Android framework where if the object with accessibility
+ * focus moves, the accessibility focus rect is not updated - both the visual highlight,
+ * and the location on the screen that's clicked if you double-tap. To work around this,
+ * when we know the object with accessibility focus moved, move focus away and then
+ * move focus right back to it, which tricks Android into updating its bounds.
+ *
+ * Do this after a short delay because sometimes the change to the object with accessibility
+ * focus happens just before navigating somewhere else.
+ */
+ private void updateAccessibilityFocusLocationAfterDelay() {
+ if (mNativeObj == 0) return;
+
+ if (mAccessibilityFocusLocationChangedRunnable != null) return;
+
+ mAccessibilityFocusLocationChangedRunnable = new Runnable() {
+ @Override
+ public void run() {
+ updateAccessibilityFocusLocation();
+ }
+ };
+
+ mView.postDelayed(mAccessibilityFocusLocationChangedRunnable,
+ ACCESSIBILITY_FOCUS_LOCATION_CHANGED_DELAY_MS);
+ }
+
+ /**
+ * See updateAccessibilityFocusLocationAfterDelay for details.
+ */
+ private void updateAccessibilityFocusLocation() {
+ // This can be called from a timeout, so we need to make sure we're still valid.
+ if (mNativeObj == 0 || mContentViewCore == null || mView == null) return;
+
+ if (mAccessibilityFocusLocationChangedRunnable != null) {
+ mView.removeCallbacks(mAccessibilityFocusLocationChangedRunnable);
+ mAccessibilityFocusLocationChangedRunnable = null;
+ }
+
+ moveAccessibilityFocusToIdAndRefocusIfNeeded(mAccessibilityFocusId);
+ }
+
+ /**
* Send a WINDOW_CONTENT_CHANGED event after a short delay. This helps throttle such
* events from firing too quickly during animations, for example.
*/
@@ -1001,17 +1065,14 @@ public class BrowserAccessibilityManager {
node.setBoundsInScreen(rect);
- // Work around a bug in the Android framework where if the object with accessibility
- // focus moves, the accessibility focus rect is not updated - both the visual highlight,
- // and the location on the screen that's clicked if you double-tap. To work around this,
- // when we know the object with accessibility focus moved, move focus away and then
- // move focus right back to it, which tricks Android into updating its bounds.
+ // If this is the node with accessibility focus, ensure that its location on-screen
+ // is up-to-date.
if (virtualViewId == mAccessibilityFocusId && virtualViewId != mCurrentRootId) {
if (mAccessibilityFocusRect == null) {
mAccessibilityFocusRect = rect;
} else if (!mAccessibilityFocusRect.equals(rect)) {
mAccessibilityFocusRect = rect;
- moveAccessibilityFocusToIdAndRefocusIfNeeded(virtualViewId);
+ updateAccessibilityFocusLocationAfterDelay();
}
}
}
« no previous file with comments | « content/browser/accessibility/browser_accessibility_manager_android.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698