From 3a1d16d7412eab9916c29026d7df945574ab7aa6 Mon Sep 17 00:00:00 2001
From: Shailen Tuli
Date: Mon, 21 Nov 2022 19:16:32 +0000
Subject: [PATCH] Added ACTION_SCROLL_IN_DIRECTION
Also added TYPE_VIEW_TARGETED_BY_SCROLL event.
Test: see AccessibilityEndToEndTest.java
Bug: 249770245
Change-Id: I6ce4e0d881209dfcb33762437c04d52bce0235fb
---
core/api/current.txt | 4 ++
.../accessibility/AccessibilityEvent.java | 24 +++++++++-
.../accessibility/AccessibilityNodeInfo.java | 48 +++++++++++++++++++
core/res/res/values/ids.xml | 3 ++
core/res/res/values/public-staging.xml | 1 +
5 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/core/api/current.txt b/core/api/current.txt
index a7bca5a9e09cb..dc90746614be5 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -2115,6 +2115,7 @@ package android {
field public static final int accessibilityActionPageUp = 16908358; // 0x1020046
field public static final int accessibilityActionPressAndHold = 16908362; // 0x102004a
field public static final int accessibilityActionScrollDown = 16908346; // 0x102003a
+ field public static final int accessibilityActionScrollInDirection;
field public static final int accessibilityActionScrollLeft = 16908345; // 0x1020039
field public static final int accessibilityActionScrollRight = 16908347; // 0x102003b
field public static final int accessibilityActionScrollToPosition = 16908343; // 0x1020037
@@ -52771,6 +52772,7 @@ package android.view.accessibility {
field public static final int TYPE_VIEW_LONG_CLICKED = 2; // 0x2
field public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
field public static final int TYPE_VIEW_SELECTED = 4; // 0x4
+ field public static final int TYPE_VIEW_TARGETED_BY_SCROLL = 67108864; // 0x4000000
field public static final int TYPE_VIEW_TEXT_CHANGED = 16; // 0x10
field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
@@ -53011,6 +53013,7 @@ package android.view.accessibility {
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+ field public static final String ACTION_ARGUMENT_DIRECTION_INT = "android.view.accessibility.action.ARGUMENT_DIRECTION_INT";
field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
@@ -53103,6 +53106,7 @@ package android.view.accessibility {
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_BACKWARD;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_DOWN;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_FORWARD;
+ field @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_IN_DIRECTION;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_LEFT;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_RIGHT;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SCROLL_TO_POSITION;
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index a52a99bec5007..33b763bbf0c0f 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -304,6 +304,20 @@ import java.util.List;
*
*
*
+ * View scrolled to - represents the event of a target node brought on screen by
+ * ACTION_SCROLL_IN_DIRECTION.
+ * Type: {@link #TYPE_VIEW_TARGETED_BY_SCROLL}
+ * Properties:
+ *
+ * - {@link #getEventType()} - The type of the event.
+ * - {@link #getSource()} - The source info (for registered clients). This represents the node
+ * that is brought on screen as a result of the scroll.
+ * - {@link #getClassName()} - The class name of the source.
+ * - {@link #getPackageName()} - The package name of the source.
+ * - {@link #getEventTime()} - The event time.
+ *
+ *
+ *
* Touch interaction start - represents the event of starting a touch
* interaction, which is the user starts touching the screen.
* Type: {@link #TYPE_TOUCH_INTERACTION_START}
@@ -595,6 +609,11 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
*/
public static final int TYPE_SPEECH_STATE_CHANGE = 0x02000000;
+ /**
+ * Represents the event of a scroll having completed and brought the target node on screen.
+ */
+ public static final int TYPE_VIEW_TARGETED_BY_SCROLL = 0x04000000;
+
/**
* Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: The type of change is not
* defined.
@@ -899,7 +918,8 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
TYPE_WINDOWS_CHANGED,
TYPE_VIEW_CONTEXT_CLICKED,
TYPE_ASSIST_READING_CONTEXT,
- TYPE_SPEECH_STATE_CHANGE
+ TYPE_SPEECH_STATE_CHANGE,
+ TYPE_VIEW_TARGETED_BY_SCROLL
})
@Retention(RetentionPolicy.SOURCE)
public @interface EventType {}
@@ -929,6 +949,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
* @see #TYPE_TOUCH_INTERACTION_END
* @see #TYPE_WINDOWS_CHANGED
* @see #TYPE_VIEW_CONTEXT_CLICKED
+ * @see #TYPE_VIEW_TARGETED_BY_SCROLL
*/
public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
@@ -1729,6 +1750,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
case TYPE_VIEW_CONTEXT_CLICKED: return "TYPE_VIEW_CONTEXT_CLICKED";
case TYPE_ASSIST_READING_CONTEXT: return "TYPE_ASSIST_READING_CONTEXT";
case TYPE_SPEECH_STATE_CHANGE: return "TYPE_SPEECH_STATE_CHANGE";
+ case TYPE_VIEW_TARGETED_BY_SCROLL: return "TYPE_VIEW_TARGETED_BY_SCROLL";
default: return Integer.toHexString(eventType);
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index b91199dc0ae56..5629e0f150436 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -659,6 +659,25 @@ public class AccessibilityNodeInfo implements Parcelable {
public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT =
"android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
+ /**
+ *
Argument to represent the direction when using
+ * {@link AccessibilityAction#ACTION_SCROLL_IN_DIRECTION}.
+ *
+ *
+ * The value of this argument can be one of:
+ *
+ * - {@link View#FOCUS_DOWN}
+ * - {@link View#FOCUS_UP}
+ * - {@link View#FOCUS_LEFT}
+ * - {@link View#FOCUS_RIGHT}
+ * - {@link View#FOCUS_FORWARD}
+ * - {@link View#FOCUS_BACKWARD}
+ *
+ *
+ */
+ public static final String ACTION_ARGUMENT_DIRECTION_INT =
+ "android.view.accessibility.action.ARGUMENT_DIRECTION_INT";
+
// Focus types
/**
@@ -4682,6 +4701,9 @@ public class AccessibilityNodeInfo implements Parcelable {
if (action == R.id.accessibilityActionShowTextSuggestions) {
return "ACTION_SHOW_TEXT_SUGGESTIONS";
}
+ if (action == R.id.accessibilityActionScrollInDirection) {
+ return "ACTION_SCROLL_IN_DIRECTION";
+ }
return "ACTION_UNKNOWN";
}
}
@@ -5217,6 +5239,32 @@ public class AccessibilityNodeInfo implements Parcelable {
public static final AccessibilityAction ACTION_SCROLL_TO_POSITION =
new AccessibilityAction(R.id.accessibilityActionScrollToPosition);
+ /**
+ * Action that brings fully on screen the next node in the specified direction.
+ *
+ *
+ * This should include wrapping around to the next/previous row, column, etc. in a
+ * collection if one is available. If there is no node in that direction, the action
+ * should fail and return false.
+ *
+ *
+ * This action should be used instead of
+ * {@link AccessibilityAction#ACTION_SCROLL_TO_POSITION} when a widget does not have
+ * clear row and column semantics or if a directional search is needed to find a node in
+ * a complex ViewGroup where individual nodes may span multiple rows or columns. The
+ * implementing widget must send a
+ * {@link AccessibilityEvent#TYPE_VIEW_TARGETED_BY_SCROLL} accessibility event with the
+ * scroll target as the source. An accessibility service can listen for this event,
+ * inspect its source, and use the result when determining where to place accessibility
+ * focus.
+ *
+ * Arguments: {@link #ACTION_ARGUMENT_DIRECTION_INT}. This is a
+ * required argument.
+ *
+ */
+ @NonNull public static final AccessibilityAction ACTION_SCROLL_IN_DIRECTION =
+ new AccessibilityAction(R.id.accessibilityActionScrollInDirection);
+
/**
* Action to scroll the node content up.
*/
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 4ddbf58757b8a..e71277dc04147 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -279,6 +279,9 @@
+
+
+
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 90141e57ce8dd..1f2529392afa6 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -124,6 +124,7 @@
+