java.lang.Object
↳androidx.core.view.accessibility.AccessibilityNodeInfoCompat
Gradle dependencies
compile group: 'androidx.core', name: 'core', version: '1.15.0-alpha02'
- groupId: androidx.core
- artifactId: core
- version: 1.15.0-alpha02
Artifact androidx.core:core:1.15.0-alpha02 it located at Google repository (https://maven.google.com/)
Androidx artifact mapping:
androidx.core:core com.android.support:support-compat
Androidx class mapping:
androidx.core.view.accessibility.AccessibilityNodeInfoCompat android.support.v4.view.accessibility.AccessibilityNodeInfoCompat
Overview
Helper for accessing android.view.accessibility.AccessibilityNodeInfo
in a backwards
compatible fashion.
Summary
Constructors |
---|
public | AccessibilityNodeInfoCompat(java.lang.Object info)
Creates a new instance wrapping an
android.view.accessibility.AccessibilityNodeInfo . |
Methods |
---|
public void | addAction(AccessibilityNodeInfoCompat.AccessibilityActionCompat action)
Adds an action that can be performed on the node. |
public void | addAction(int action)
Adds an action that can be performed on the node. |
public void | addChild(View child)
Adds a child. |
public void | addChild(View root, int virtualDescendantId)
Adds a virtual child which is a descendant of the given root . |
public void | addSpansToExtras(java.lang.CharSequence text, View view)
|
public boolean | canOpenPopup()
Gets if this node opens a popup or a dialog. |
public boolean | equals(java.lang.Object obj)
|
public java.util.List<AccessibilityNodeInfoCompat> | findAccessibilityNodeInfosByText(java.lang.String text)
Finds android.view.accessibility.AccessibilityNodeInfo s by text. |
public java.util.List<AccessibilityNodeInfoCompat> | findAccessibilityNodeInfosByViewId(java.lang.String viewId)
Finds AccessibilityNodeInfoCompats by the fully qualified view id's resource
name where a fully qualified id is of the from "package:id/id_resource_name". |
public AccessibilityNodeInfoCompat | findFocus(int focus)
Find the view that has the specified focus type. |
public AccessibilityNodeInfoCompat | focusSearch(int direction)
Searches for the nearest view in the specified direction that can take
input focus. |
public java.util.List<AccessibilityNodeInfoCompat.AccessibilityActionCompat> | getActionList()
Gets the actions that can be performed on the node. |
public int | getActions()
Gets the actions that can be performed on the node. |
public java.util.List<java.lang.String> | getAvailableExtraData()
Get the extra data available for this node. |
public void | getBoundsInParent(Rect outBounds)
Gets the node bounds in the viewParent's coordinates. |
public void | getBoundsInScreen(Rect outBounds)
Gets the node bounds in screen coordinates. |
public void | getBoundsInWindow(Rect outBounds)
Gets the node bounds in window coordinates. |
public AccessibilityNodeInfoCompat | getChild(int index)
Get the child at given index. |
public AccessibilityNodeInfoCompat | getChild(int index, int prefetchingStrategy)
Get the child at given index. |
public int | getChildCount()
Gets the number of children. |
public java.lang.CharSequence | getClassName()
Gets the class this node comes from. |
public static ClickableSpan | getClickableSpans(java.lang.CharSequence text)
|
public AccessibilityNodeInfoCompat.CollectionInfoCompat | getCollectionInfo()
Gets the collection info if the node is a collection. |
public AccessibilityNodeInfoCompat.CollectionItemInfoCompat | getCollectionItemInfo()
Gets the collection item info if the node is a collection item. |
public java.lang.CharSequence | getContainerTitle()
Returns the container title. |
public java.lang.CharSequence | getContentDescription()
Gets the content description of this node. |
public int | getDrawingOrder()
Get the drawing order of the view corresponding it this node. |
public java.lang.CharSequence | getError()
Gets the error text of this node. |
public AccessibilityNodeInfo.ExtraRenderingInfo | getExtraRenderingInfo()
Gets the if the node is meant to be refreshed with extra data
to examine rendering related accessibility issues. |
public Bundle | getExtras()
Gets an optional bundle with extra data. |
public java.lang.CharSequence | getHintText()
Gets the hint text of this node. |
public java.lang.Object | getInfo()
|
public int | getInputType()
Gets the input type of the source as defined by . |
public AccessibilityNodeInfoCompat | getLabeledBy()
Gets the node info which serves as the label of the view represented by
this info for accessibility purposes. |
public AccessibilityNodeInfoCompat | getLabelFor()
Gets the node info for which the view represented by this info serves as
a label for accessibility purposes. |
public int | getLiveRegion()
Gets the node's live region mode. |
public int | getMaxTextLength()
Returns the maximum text length for this node. |
public long | getMinDurationBetweenContentChangesMillis()
Gets the minimum time duration between two content change events. |
public int | getMovementGranularities()
Gets the movement granularities for traversing the text of this node. |
public java.lang.CharSequence | getPackageName()
Gets the package this node comes from. |
public java.lang.CharSequence | getPaneTitle()
Get the title of the pane represented by this node. |
public AccessibilityNodeInfoCompat | getParent()
Gets the parent. |
public AccessibilityNodeInfoCompat | getParent(int prefetchingStrategy)
Gets the parent. |
public AccessibilityNodeInfoCompat.RangeInfoCompat | getRangeInfo()
Gets the range info if this node is a range. |
public java.lang.CharSequence | getRoleDescription()
Gets the custom role description. |
public java.lang.CharSequence | getStateDescription()
Gets the state description of this node. |
public java.lang.CharSequence | getText()
Gets the text of this node. |
public int | getTextSelectionEnd()
Gets the text selection end. |
public int | getTextSelectionStart()
Gets the text selection start. |
public java.lang.CharSequence | getTooltipText()
Gets the tooltip text of this node. |
public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat | getTouchDelegateInfo()
Get the AccessibilityNodeInfoCompat.TouchDelegateInfoCompat for touch delegate behavior with the represented
view. |
public AccessibilityNodeInfoCompat | getTraversalAfter()
Gets the node after which this one is visited in accessibility traversal. |
public AccessibilityNodeInfoCompat | getTraversalBefore()
Gets the node before which this one is visited during traversal. |
public java.lang.String | getUniqueId()
Gets the unique id of this node. |
public java.lang.String | getViewIdResourceName()
Gets the fully qualified resource name of the source view's id. |
public AccessibilityWindowInfoCompat | getWindow()
Gets the window to which this node belongs. |
public int | getWindowId()
Gets the id of the window from which the info comes from. |
public int | hashCode()
|
public boolean | hasRequestInitialAccessibilityFocus()
Gets whether the node has AccessibilityNodeInfoCompat.setRequestInitialAccessibilityFocus(boolean). |
public boolean | isAccessibilityDataSensitive()
Gets if the node's accessibility data is considered sensitive. |
public boolean | isAccessibilityFocused()
Gets whether this node is accessibility focused. |
public boolean | isCheckable()
Gets whether this node is checkable. |
public boolean | isChecked()
Gets whether this node is checked. |
public boolean | isClickable()
Gets whether this node is clickable. |
public boolean | isContentInvalid()
Gets if the content of this node is invalid. |
public boolean | isContextClickable()
Gets whether this node is context clickable. |
public boolean | isDismissable()
Gets if the node can be dismissed. |
public boolean | isEditable()
Gets if the node is editable. |
public boolean | isEnabled()
Gets whether this node is enabled. |
public boolean | isFocusable()
Gets whether this node is focusable. |
public boolean | isFocused()
Gets whether this node is focused. |
public boolean | isGranularScrollingSupported()
Gets if the node supports granular scrolling. |
public boolean | isHeading()
Returns whether node represents a heading. |
public boolean | isImportantForAccessibility()
Returns whether the node originates from a view considered important for accessibility. |
public boolean | isLongClickable()
Gets whether this node is long clickable. |
public boolean | isMultiLine()
Gets if the node is a multi line editable text. |
public boolean | isPassword()
Gets whether this node is a password. |
public boolean | isScreenReaderFocusable()
Returns whether the node is explicitly marked as a focusable unit by a screen reader. |
public boolean | isScrollable()
Gets if the node is scrollable. |
public boolean | isSelected()
Gets whether this node is selected. |
public boolean | isShowingHintText()
Returns whether the node's text represents a hint for the user to enter text. |
public boolean | isTextEntryKey()
Returns whether node represents a text entry key that is part of a keyboard or keypad. |
public boolean | isTextSelectable()
Gets if the node has selectable text. |
public boolean | isVisibleToUser()
Gets whether this node is visible to the user. |
public static AccessibilityNodeInfoCompat | obtain()
Returns a cached instance if such is available otherwise a new one. |
public static AccessibilityNodeInfoCompat | obtain(View source)
Returns a cached instance if such is available otherwise a new one and
sets the source. |
public static AccessibilityNodeInfoCompat | obtain(View root, int virtualDescendantId)
Returns a cached instance if such is available otherwise a new one
and sets the source. |
public boolean | performAction(int action)
Performs an action on the node. |
public boolean | performAction(int action, Bundle arguments)
Performs an action on the node. |
public void | recycle()
Return an instance back to be reused. |
public boolean | refresh()
Refreshes this info with the latest state of the view it represents. |
public boolean | removeAction(AccessibilityNodeInfoCompat.AccessibilityActionCompat action)
Removes an action that can be performed on the node. |
public boolean | removeChild(View child)
Removes a child. |
public boolean | removeChild(View root, int virtualDescendantId)
Removes a virtual child which is a descendant of the given
root . |
public void | setAccessibilityDataSensitive(boolean accessibilityDataSensitive)
Sets whether this node's accessibility data is considered sensitive. |
public void | setAccessibilityFocused(boolean focused)
Sets whether this node is accessibility focused. |
public void | setAvailableExtraData(java.util.List<java.lang.String> extraDataKeys)
Set the extra data available for this node. |
public void | setBoundsInParent(Rect bounds)
Sets the node bounds in the viewParent's coordinates. |
public void | setBoundsInScreen(Rect bounds)
Sets the node bounds in screen coordinates. |
public void | setBoundsInWindow(Rect bounds)
Sets the node bounds in window coordinates. |
public void | setCanOpenPopup(boolean opensPopup)
Sets if this node opens a popup or a dialog. |
public void | setCheckable(boolean checkable)
Sets whether this node is checkable. |
public void | setChecked(boolean checked)
Sets whether this node is checked. |
public void | setClassName(java.lang.CharSequence className)
Sets the class this node comes from. |
public void | setClickable(boolean clickable)
Sets whether this node is clickable. |
public void | setCollectionInfo(java.lang.Object collectionInfo)
|
public void | setCollectionItemInfo(java.lang.Object collectionItemInfo)
|
public void | setContainerTitle(java.lang.CharSequence containerTitle)
Sets the container title for app-developer-defined container which can be any type of
ViewGroup or layout. |
public void | setContentDescription(java.lang.CharSequence contentDescription)
Sets the content description of this node. |
public void | setContentInvalid(boolean contentInvalid)
Sets if the content of this node is invalid. |
public void | setContextClickable(boolean contextClickable)
Sets whether this node is context clickable. |
public void | setDismissable(boolean dismissable)
Sets if the node can be dismissed. |
public void | setDrawingOrder(int drawingOrderInParent)
Set the drawing order of the view corresponding it this node. |
public void | setEditable(boolean editable)
Sets whether this node is editable. |
public void | setEnabled(boolean enabled)
Sets whether this node is enabled. |
public void | setError(java.lang.CharSequence error)
Sets the error text of this node. |
public void | setFocusable(boolean focusable)
Sets whether this node is focusable. |
public void | setFocused(boolean focused)
Sets whether this node is focused. |
public void | setGranularScrollingSupported(boolean granularScrollingSupported)
Sets if the node supports granular scrolling. |
public void | setHeading(boolean isHeading)
Sets whether the node represents a heading. |
public void | setHintText(java.lang.CharSequence hintText)
Sets the hint text of this node. |
public void | setImportantForAccessibility(boolean important)
Sets whether the node is considered important for accessibility. |
public void | setInputType(int inputType)
Sets the input type of the source as defined by . |
public void | setLabeledBy(View label)
Sets the view which serves as the label of the view represented by
this info for accessibility purposes. |
public void | setLabeledBy(View root, int virtualDescendantId)
Sets the view which serves as the label of the view represented by
this info for accessibility purposes. |
public void | setLabelFor(View labeled)
Sets the view for which the view represented by this info serves as a
label for accessibility purposes. |
public void | setLabelFor(View root, int virtualDescendantId)
Sets the view for which the view represented by this info serves as a
label for accessibility purposes. |
public void | setLiveRegion(int mode)
Sets the node's live region mode. |
public void | setLongClickable(boolean longClickable)
Sets whether this node is long clickable. |
public void | setMaxTextLength(int max)
Sets the maximum text length, or -1 for no limit. |
public void | setMinDurationBetweenContentChangesMillis(long duration)
Sets the minimum time duration between two content change events, which is used in throttling
content change events in accessibility services. |
public void | setMovementGranularities(int granularities)
Sets the movement granularities for traversing the text of this node. |
public void | setMultiLine(boolean multiLine)
Sets if the node is a multi line editable text. |
public void | setPackageName(java.lang.CharSequence packageName)
Sets the package this node comes from. |
public void | setPaneTitle(java.lang.CharSequence paneTitle)
If this node represents a visually distinct region of the screen that may update separately
from the rest of the window, it is considered a pane. |
public void | setParent(View parent)
Sets the parent. |
public void | setParent(View root, int virtualDescendantId)
Sets the parent to be a virtual descendant of the given root . |
public void | setPassword(boolean password)
Sets whether this node is a password. |
public void | setQueryFromAppProcessEnabled(View view, boolean enabled)
Connects this node to the View's root so that operations on this node can query the entire
AccessibilityNodeInfoCompat tree and perform accessibility actions on nodes. |
public void | setRangeInfo(AccessibilityNodeInfoCompat.RangeInfoCompat rangeInfo)
Sets the range info if this node is a range. |
public void | setRequestInitialAccessibilityFocus(boolean requestInitialAccessibilityFocus)
Sets whether the node has requested initial accessibility focus. |
public void | setRoleDescription(java.lang.CharSequence roleDescription)
Sets the custom role description. |
public void | setScreenReaderFocusable(boolean screenReaderFocusable)
Sets whether the node should be considered a focusable unit by a screen reader. |
public void | setScrollable(boolean scrollable)
Sets if the node is scrollable. |
public void | setSelected(boolean selected)
Sets whether this node is selected. |
public void | setShowingHintText(boolean showingHintText)
Sets whether the node's text represents a hint for the user to enter text. |
public void | setSource(View source)
Sets the source. |
public void | setSource(View root, int virtualDescendantId)
Sets the source to be a virtual descendant of the given root . |
public void | setStateDescription(java.lang.CharSequence stateDescription)
Sets the state description of this node. |
public void | setText(java.lang.CharSequence text)
Sets the text of this node. |
public void | setTextEntryKey(boolean isTextEntryKey)
Sets whether the node represents a text entry key that is part of a keyboard or keypad. |
public void | setTextSelectable(boolean selectableText)
Sets if the node has selectable text. |
public void | setTextSelection(int start, int end)
Sets the text selection start and end. |
public void | setTooltipText(java.lang.CharSequence tooltipText)
Sets the tooltip text of this node. |
public void | setTouchDelegateInfo(AccessibilityNodeInfoCompat.TouchDelegateInfoCompat delegatedInfo)
Set touch delegate info if the represented view has a . |
public void | setTraversalAfter(View view)
Sets the view whose node is visited after this one in accessibility traversal. |
public void | setTraversalAfter(View root, int virtualDescendantId)
Sets the node after which this one is visited in accessibility traversal. |
public void | setTraversalBefore(View view)
Sets the view before whose node this one should be visited during traversal. |
public void | setTraversalBefore(View root, int virtualDescendantId)
Sets the node before which this one is visited during traversal. |
public void | setUniqueId(java.lang.String uniqueId)
Sets the unique id of this node. |
public void | setViewIdResourceName(java.lang.String viewId)
Sets the fully qualified resource name of the source view's id. |
public void | setVisibleToUser(boolean visibleToUser)
Sets whether this node is visible to the user. |
public java.lang.String | toString()
|
public AccessibilityNodeInfo | unwrap()
|
public static AccessibilityNodeInfoCompat | wrap(AccessibilityNodeInfo info)
Creates a new instance wrapping an
android.view.accessibility.AccessibilityNodeInfo . |
from java.lang.Object | clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
Fields
public int
mParentVirtualDescendantIdandroidx.customview.widget.ExploreByTouchHelper.HOST_ID = -1;
public static final int
ACTION_FOCUSAction that focuses the node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_FOCUS
public static final int
ACTION_CLEAR_FOCUSAction that unfocuses the node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_FOCUS
public static final int
ACTION_SELECTAction that selects the node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SELECT
public static final int
ACTION_CLEAR_SELECTIONAction that unselects the node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLEAR_SELECTION
public static final int
ACTION_CLICKAction that clicks on the node info.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK
public static final int
ACTION_LONG_CLICKAction that long clicks on the node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK
public static final int
ACTION_ACCESSIBILITY_FOCUSAction that gives accessibility focus to the node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_ACCESSIBILITY_FOCUS
public static final int
ACTION_CLEAR_ACCESSIBILITY_FOCUSAction that clears accessibility focus of the node.
public static final int
ACTION_NEXT_AT_MOVEMENT_GRANULARITYAction that requests to go to the next entity in this node's text
at a given movement granularity. For example, move to the next character,
word, etc.
Arguments: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT<,
AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
Example: Move to the previous character and do not extend selection.
Bundle arguments = new Bundle();
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
false);
info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
See also: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, AccessibilityNodeInfoCompat.setMovementGranularities(int), AccessibilityNodeInfoCompat.getMovementGranularities(), AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
public static final int
ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITYAction that requests to go to the previous entity in this node's text
at a given movement granularity. For example, move to the next character,
word, etc.
Arguments: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT<,
AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
Example: Move to the next character and do not extend selection.
Bundle arguments = new Bundle();
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
false);
info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
arguments);
See also: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, AccessibilityNodeInfoCompat.setMovementGranularities(int), AccessibilityNodeInfoCompat.getMovementGranularities(), AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH, AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
public static final int
ACTION_NEXT_HTML_ELEMENTAction to move to the next HTML element of a given type. For example, move
to the BUTTON, INPUT, TABLE, etc.
Arguments: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING
Example:
Bundle arguments = new Bundle();
arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
info.performAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT, arguments);
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT
public static final int
ACTION_PREVIOUS_HTML_ELEMENTAction to move to the previous HTML element of a given type. For example, move
to the BUTTON, INPUT, TABLE, etc.
Arguments: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING
Example:
Bundle arguments = new Bundle();
arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT, arguments);
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT
public static final int
ACTION_SCROLL_FORWARDAction to scroll the node content forward.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD
public static final int
ACTION_SCROLL_BACKWARDAction to scroll the node content backward.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD
public static final int
ACTION_COPYAction to copy the current selection to the clipboard.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COPY
public static final int
ACTION_PASTEAction to paste the current clipboard content.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PASTE
public static final int
ACTION_CUTAction to cut the current selection and place it to the clipboard.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CUT
public static final int
ACTION_SET_SELECTIONAction to set the selection. Performing this action with no arguments
clears the selection.
Arguments: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT,
AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT
Example:
Bundle arguments = new Bundle();
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 1);
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 2);
info.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments);
See also: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_SELECTION
public static final int
ACTION_EXPANDAction to expand an expandable node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_EXPAND
public static final int
ACTION_COLLAPSEAction to collapse an expandable node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_COLLAPSE
public static final int
ACTION_DISMISSAction to dismiss a dismissible node.
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_DISMISS
public static final int
ACTION_SET_TEXTAction that sets the text of the node. Performing the action without argument, using
null
or empty java.lang.CharSequence
will clear the text. This action will also put the
cursor at the end of text.
Arguments: AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE
Example:
Bundle arguments = new Bundle();
arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
"android");
info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_TEXT
public static final java.lang.String
ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INTArgument for which movement granularity to be used when traversing the node text.
Type: int
Actions: AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
public static final java.lang.String
ACTION_ARGUMENT_HTML_ELEMENT_STRINGArgument for which HTML element to get moving to the next/previous HTML element.
Type: String
Actions: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT,
AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT
public static final java.lang.String
ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEANArgument for whether when moving at granularity to extend the selection
or to move it otherwise.
Type: boolean
Actions: AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
public static final java.lang.String
ACTION_ARGUMENT_SELECTION_START_INTArgument for specifying the selection start.
Type: int
Actions: AccessibilityNodeInfoCompat.ACTION_SET_SELECTION
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_SELECTION
public static final java.lang.String
ACTION_ARGUMENT_SELECTION_END_INTArgument for specifying the selection end.
Type: int
Actions: AccessibilityNodeInfoCompat.ACTION_SET_SELECTION
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_SELECTION
public static final java.lang.String
ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCEArgument for specifying the text content to set
Type: CharSequence
Actions: AccessibilityNodeInfoCompat.ACTION_SET_TEXT
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_TEXT
public static final java.lang.String
ACTION_ARGUMENT_ROW_INTArgument for specifying the collection row to make visible on screen.
Type: int
Actions:
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION
public static final java.lang.String
ACTION_ARGUMENT_COLUMN_INTArgument for specifying the collection column to make visible on screen.
Type: int
Actions:
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION
public static final java.lang.String
ACTION_ARGUMENT_PROGRESS_VALUEArgument for specifying the progress value to set.
Type: float
Actions:
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SET_PROGRESS
public static final java.lang.String
ACTION_ARGUMENT_MOVE_WINDOW_XArgument for specifying the x coordinate to which to move a window.
Type: int
Actions:
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_MOVE_WINDOW
public static final java.lang.String
ACTION_ARGUMENT_MOVE_WINDOW_YArgument for specifying the y coordinate to which to move a window.
Type: int
Actions:
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_MOVE_WINDOW
public static final java.lang.String
ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INTArgument to represent the duration in milliseconds to press and hold a node.
Type: int
Actions:
See also: AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_PRESS_AND_HOLD
public static final java.lang.String
ACTION_ARGUMENT_DIRECTION_INTArgument to represent the direction when using
AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION.
The value of this argument can be one of:
View
View
View
View
View
View
public static final java.lang.String
ACTION_ARGUMENT_SCROLL_AMOUNT_FLOATArgument to represent the scroll amount as a percent of the visible area of a node, with
1.0F as the default. Values smaller than 1.0F represent a partial scroll of the node, and
values larger than 1.0F represent a scroll that extends beyond the currently visible node
Rect. Setting this to POSITIVE_INFINITY
or to another "too large" value should
scroll to the end of the node. Negative values should not be used with this argument.
This argument should be used with the following scroll actions:
Example: if a view representing a list of items implements
AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD to scroll forward by an entire
screen
(one "page"), then passing a value of .25F via this argument should scroll that view
only by 1/4th of a screen. Passing a value of 1.50F via this argument should scroll the
view by 1 1/2 screens or to end of the node if the node doesn't extend to 1 1/2 screens.
This argument should not be used with the following scroll actions, which don't cleanly
conform to granular scroll semantics:
Views that support this argument should set
AccessibilityNodeInfoCompat.setGranularScrollingSupported(boolean) to true. Clients should use
AccessibilityNodeInfoCompat.isGranularScrollingSupported() to check if granular scrolling is supported.
public static final int
FOCUS_INPUTThe input focus.
public static final int
FOCUS_ACCESSIBILITYThe accessibility focus.
public static final int
MOVEMENT_GRANULARITY_CHARACTERMovement granularity bit for traversing the text of a node by character.
public static final int
MOVEMENT_GRANULARITY_WORDMovement granularity bit for traversing the text of a node by word.
public static final int
MOVEMENT_GRANULARITY_LINEMovement granularity bit for traversing the text of a node by line.
public static final int
MOVEMENT_GRANULARITY_PARAGRAPHMovement granularity bit for traversing the text of a node by paragraph.
public static final int
MOVEMENT_GRANULARITY_PAGEMovement granularity bit for traversing the text of a node by page.
public static final java.lang.String
EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEYKey used to request and locate extra data for text character location. This key requests that
an array of s be added to the extras. This request is made with
AccessibilityNodeInfoCompat. The arguments taken by this request are two
integers: AccessibilityNodeInfoCompat.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX and
AccessibilityNodeInfoCompat.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH. The starting index must be valid
inside the CharSequence returned by AccessibilityNodeInfoCompat.getText(), and the length must be positive.
The data can be retrieved from the Bundle returned by AccessibilityNodeInfoCompat.getExtras() using this
string as a key for . The
will be null for characters that either do not exist or are
off the screen.
AccessibilityNodeInfoCompat
public static final java.lang.String
EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEXInteger argument specifying the start index of the requested text location data. Must be
valid inside the CharSequence returned by AccessibilityNodeInfoCompat.getText().
See also: AccessibilityNodeInfoCompat.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
public static final java.lang.String
EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTHInteger argument specifying the end index of the requested text location data. Must be
positive and no larger than AccessibilityNodeInfoCompat.EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH.
See also: AccessibilityNodeInfoCompat.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
public static final int
EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_MAX_LENGTHThe maximum allowed length of the requested text location data.
public static final int
FLAG_PREFETCH_ANCESTORSPrefetching strategy that prefetches the ancestors of the requested node.
Ancestors will be prefetched before siblings and descendants.
See also: AccessibilityNodeInfoCompat.getChild(int, int), AccessibilityNodeInfoCompat.getParent(int), AccessibilityWindowInfoCompat.getRoot(int)
public static final int
FLAG_PREFETCH_SIBLINGSPrefetching strategy that prefetches the siblings of the requested node.
To avoid disconnected trees, this flag will also prefetch the parent. Siblings will be
prefetched before descendants.
See also: for where to use these flags.
public static final int
FLAG_PREFETCH_DESCENDANTS_HYBRIDPrefetching strategy that prefetches the descendants in a hybrid depth first and breadth
first approach.
The children of the root node is prefetched before recursing on the children. This
must not be combined with AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST or
AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST or this will trigger an
IllegalArgumentException.
See also: for where to use these flags.
public static final int
FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRSTPrefetching strategy that prefetches the descendants of the requested node depth-first.
This must not be combined with AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_HYBRID or
AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST or this will trigger an
IllegalArgumentException.
See also: for where to use these flags.
public static final int
FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRSTPrefetching strategy that prefetches the descendants of the requested node breadth-first.
This must not be combined with AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_HYBRID or
AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST or this will trigger an
IllegalArgumentException.
See also: for where to use these flags.
public static final int
FLAG_PREFETCH_UNINTERRUPTIBLEPrefetching flag that specifies prefetching should not be interrupted by a request to
retrieve a node or perform an action on a node.
See also: for where to use these flags.
public static final int
MAX_NUMBER_OF_PREFETCHED_NODESMaximum batch size of prefetched nodes for a request.
Constructors
public
AccessibilityNodeInfoCompat(java.lang.Object info)
Deprecated: Use AccessibilityNodeInfoCompat.wrap(AccessibilityNodeInfo) instead.
Creates a new instance wrapping an
android.view.accessibility.AccessibilityNodeInfo
.
Parameters:
info: The info.
Methods
Creates a new instance wrapping an
android.view.accessibility.AccessibilityNodeInfo
.
Parameters:
info: The info.
public AccessibilityNodeInfo
unwrap()
Returns:
The unwrapped android.view.accessibility.AccessibilityNodeInfo
.
public java.lang.Object
getInfo()
Deprecated: Use AccessibilityNodeInfoCompat.unwrap() instead.
Returns:
The wrapped android.view.accessibility.AccessibilityNodeInfo
.
Returns a cached instance if such is available otherwise a new one and
sets the source.
Returns:
An instance.
See also: AccessibilityNodeInfoCompat.setSource(View)
Returns a cached instance if such is available otherwise a new one
and sets the source.
Parameters:
root: The root of the virtual subtree.
virtualDescendantId: The id of the virtual descendant.
Returns:
An instance.
See also: AccessibilityNodeInfoCompat.setSource(View, int)
Returns a cached instance if such is available otherwise a new one.
Returns:
An instance.
public void
setSource(View source)
Sets the source.
Parameters:
source: The info source.
public void
setSource(View root, int virtualDescendantId)
Sets the source to be a virtual descendant of the given root
.
If virtualDescendantId
is View
the root
is set as the source.
A virtual descendant is an imaginary View that is reported as a part of the view
hierarchy for accessibility purposes. This enables custom views that draw complex
content to report themselves as a tree of virtual views, thus conveying their
logical structure.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
This method is not supported on devices running API level < 16 since the platform did
not support virtual descendants of real views.
Parameters:
root: The root of the virtual subtree.
virtualDescendantId: The id of the virtual descendant.
Find the view that has the specified focus type. The search starts from
the view represented by this node info.
Parameters:
focus: The focus to find. One of AccessibilityNodeInfoCompat.FOCUS_INPUT or
AccessibilityNodeInfoCompat.FOCUS_ACCESSIBILITY.
Returns:
The node info of the focused view or null.
See also: AccessibilityNodeInfoCompat.FOCUS_INPUT, AccessibilityNodeInfoCompat.FOCUS_ACCESSIBILITY
Searches for the nearest view in the specified direction that can take
input focus.
Parameters:
direction: The direction. Can be one of:
View
,
View
,
View
,
View
,
View
,
View
.
Returns:
The node info for the view that can take accessibility focus.
Gets the id of the window from which the info comes from.
Returns:
The window id.
public int
getChildCount()
Gets the number of children.
Returns:
The child count.
Get the child at given index.
Parameters:
index: The child index.
Returns:
The child node.
Get the child at given index.
Parameters:
index: The child index.
prefetchingStrategy: the prefetching strategy.
Returns:
The child node.
See also: for a description of prefetching.
public void
addChild(View child)
Adds a child.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
child: The child.
public void
addChild(View root, int virtualDescendantId)
Adds a virtual child which is a descendant of the given root
.
If virtualDescendantId
is View
the root
is added as a child.
A virtual descendant is an imaginary View that is reported as a part of the view
hierarchy for accessibility purposes. This enables custom views that draw complex
content to report them selves as a tree of virtual views, thus conveying their
logical structure.
Parameters:
root: The root of the virtual subtree.
virtualDescendantId: The id of the virtual child.
public boolean
removeChild(View child)
Removes a child. If the child was not previously added to the node,
calling this method has no effect.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
child: The child.
Returns:
true if the child was present
public boolean
removeChild(View root, int virtualDescendantId)
Removes a virtual child which is a descendant of the given
root
. If the child was not previously added to the node,
calling this method has no effect.
Parameters:
root: The root of the virtual subtree.
virtualDescendantId: The id of the virtual child.
Returns:
true if the child was present
See also: AccessibilityNodeInfoCompat.addChild(View, int)
Deprecated: Use AccessibilityNodeInfoCompat.getActionList() instead.
Gets the actions that can be performed on the node.
Returns:
The bit mask of with actions.
See also: android.view.accessibility.AccessibilityNodeInfo
, android.view.accessibility.AccessibilityNodeInfo
, android.view.accessibility.AccessibilityNodeInfo
, android.view.accessibility.AccessibilityNodeInfo
public void
addAction(int action)
Adds an action that can be performed on the node.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
action: The action.
Adds an action that can be performed on the node.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
action: The action.
Removes an action that can be performed on the node. If the action was
not already added to the node, calling this method has no effect.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
action: The action to be removed.
Returns:
The action removed from the list of actions.
public boolean
performAction(int action)
Performs an action on the node.
Note: An action can be performed only if the request is
made from an .
Parameters:
action: The action to perform.
Returns:
True if the action was performed.
public boolean
performAction(int action, Bundle arguments)
Performs an action on the node.
Note: An action can be performed only if the request is made
from an .
Parameters:
action: The action to perform.
arguments: A bundle with additional arguments.
Returns:
True if the action was performed.
public void
setMovementGranularities(int granularities)
Sets the movement granularities for traversing the text of this node.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
granularities: The bit mask with granularities.
public int
getMovementGranularities()
Gets the movement granularities for traversing the text of this node.
Returns:
The bit mask with granularities.
public java.util.List<AccessibilityNodeInfoCompat>
findAccessibilityNodeInfosByText(java.lang.String text)
Finds android.view.accessibility.AccessibilityNodeInfo
s by text. The match
is case insensitive containment. The search is relative to this info i.e. this
info is the root of the traversed tree.
Parameters:
text: The searched text.
Returns:
A list of node info.
Gets the parent.
Returns:
The parent.
Gets the parent.
Use prefetchingStrategy to determine the types of
nodes prefetched from the app if the requested node is not in the cache and must be retrieved
by the app. The default strategy for AccessibilityNodeInfoCompat.getParent() is a combination of ancestor and
sibling strategies. The app will prefetch until all nodes fulfilling the strategies are
fetched, another node request is sent, or the maximum prefetch batch size of
AccessibilityNodeInfoCompat.MAX_NUMBER_OF_PREFETCHED_NODES nodes is reached. To prevent interruption by another
request and to force prefetching of the max batch size, use
AccessibilityNodeInfoCompat.FLAG_PREFETCH_UNINTERRUPTIBLE.
Parameters:
prefetchingStrategy: the prefetching strategy.
Returns:
The parent.
See also: AccessibilityNodeInfoCompat.FLAG_PREFETCH_ANCESTORS, AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST, AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST, AccessibilityNodeInfoCompat.FLAG_PREFETCH_DESCENDANTS_HYBRID, AccessibilityNodeInfoCompat.FLAG_PREFETCH_SIBLINGS, AccessibilityNodeInfoCompat.FLAG_PREFETCH_UNINTERRUPTIBLE
public void
setParent(View parent)
Sets the parent.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
parent: The parent.
public void
setParent(View root, int virtualDescendantId)
Sets the parent to be a virtual descendant of the given root
.
If virtualDescendantId
equals to View
the root
is set as the parent.
A virtual descendant is an imaginary View that is reported as a part of the view
hierarchy for accessibility purposes. This enables custom views that draw complex
content to report them selves as a tree of virtual views, thus conveying their
logical structure.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
This method is not supported on devices running API level < 16 since the platform did
not support virtual descendants of real views.
Parameters:
root: The root of the virtual subtree.
virtualDescendantId: The id of the virtual descendant.
public void
getBoundsInParent(Rect outBounds)
Deprecated: Use AccessibilityNodeInfoCompat.getBoundsInScreen(Rect) instead.
Gets the node bounds in the viewParent's coordinates.
AccessibilityNodeInfoCompat.getParent() does not represent the source's viewParent.
Instead it represents the result of View
,
which returns the closest ancestor where View
is true.
So this method is not reliable.
Parameters:
outBounds: The output node bounds.
public void
setBoundsInParent(Rect bounds)
Deprecated: Accessibility services should not care about these bounds.
Sets the node bounds in the viewParent's coordinates.
AccessibilityNodeInfoCompat.getParent() does not represent the source's viewParent.
Instead it represents the result of View
,
which returns the closest ancestor where View
is true.
So this method is not reliable.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
bounds: The node bounds.
public void
getBoundsInScreen(Rect outBounds)
Gets the node bounds in screen coordinates.
Parameters:
outBounds: The output node bounds.
public void
setBoundsInScreen(Rect bounds)
Sets the node bounds in screen coordinates.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
bounds: The node bounds.
public void
getBoundsInWindow(Rect outBounds)
Gets the node bounds in window coordinates.
When magnification is enabled, the bounds in window are scaled up by magnification scale
and the positions are also adjusted according to the offset of magnification viewport.
For example, it returns Rect(-180, -180, 0, 0) for original bounds Rect(10, 10, 100, 100),
when the magnification scale is 2 and offsets for X and Y are both 200.
Compatibility:
Parameters:
outBounds: The output node bounds.
public void
setBoundsInWindow(Rect bounds)
Sets the node bounds in window coordinates.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Compatibility:
Parameters:
bounds: The node bounds.
public boolean
isCheckable()
Gets whether this node is checkable.
Returns:
True if the node is checkable.
public void
setCheckable(boolean checkable)
Sets whether this node is checkable.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
checkable: True if the node is checkable.
public boolean
isChecked()
Gets whether this node is checked.
Returns:
True if the node is checked.
public void
setChecked(boolean checked)
Sets whether this node is checked.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
checked: True if the node is checked.
public boolean
isFocusable()
Gets whether this node is focusable.
Returns:
True if the node is focusable.
public void
setFocusable(boolean focusable)
Sets whether this node is focusable.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
focusable: True if the node is focusable.
public boolean
isFocused()
Gets whether this node is focused.
Returns:
True if the node is focused.
public void
setFocused(boolean focused)
Sets whether this node is focused.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
focused: True if the node is focused.
public boolean
isVisibleToUser()
Gets whether this node is visible to the user.
Returns:
Whether the node is visible to the user.
public void
setVisibleToUser(boolean visibleToUser)
Sets whether this node is visible to the user.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
visibleToUser: Whether the node is visible to the user.
public boolean
isAccessibilityFocused()
Gets whether this node is accessibility focused.
Returns:
True if the node is accessibility focused.
public void
setAccessibilityFocused(boolean focused)
Sets whether this node is accessibility focused.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
focused: True if the node is accessibility focused.
public boolean
isSelected()
Gets whether this node is selected.
Returns:
True if the node is selected.
public void
setSelected(boolean selected)
Sets whether this node is selected.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
selected: True if the node is selected.
public boolean
isClickable()
Gets whether this node is clickable.
Returns:
True if the node is clickable.
public void
setClickable(boolean clickable)
Sets whether this node is clickable.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
clickable: True if the node is clickable.
public boolean
isLongClickable()
Gets whether this node is long clickable.
Returns:
True if the node is long clickable.
public void
setLongClickable(boolean longClickable)
Sets whether this node is long clickable.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
longClickable: True if the node is long clickable.
public boolean
isEnabled()
Gets whether this node is enabled.
Returns:
True if the node is enabled.
public void
setEnabled(boolean enabled)
Sets whether this node is enabled.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
enabled: True if the node is enabled.
public boolean
isPassword()
Gets whether this node is a password.
Returns:
True if the node is a password.
public void
setPassword(boolean password)
Sets whether this node is a password.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
password: True if the node is a password.
public boolean
isScrollable()
Gets if the node is scrollable.
Returns:
True if the node is scrollable, false otherwise.
public void
setScrollable(boolean scrollable)
Sets if the node is scrollable.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
scrollable: True if the node is scrollable, false otherwise.
public boolean
isGranularScrollingSupported()
Gets if the node supports granular scrolling.
Compatibility:
Returns:
True if all scroll actions that could support
AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT have done so, false otherwise.
public void
setGranularScrollingSupported(boolean granularScrollingSupported)
Sets if the node supports granular scrolling. This should be set to true if all scroll
actions which could support AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT have done so.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Compatibility:
Parameters:
granularScrollingSupported: True if the node supports granular scrolling, false
otherwise.
public boolean
isTextSelectable()
Gets if the node has selectable text.
Services should use AccessibilityNodeInfoCompat.ACTION_SET_SELECTION for selection. Editable text nodes must
also be selectable. But not all UIs will populate this field, so services should consider
'isTextSelectable | isEditable' to ensure they don't miss nodes with selectable text.
Compatibility:
Returns:
True if the node has selectable text.
See also: AccessibilityNodeInfoCompat.isEditable()
public void
setTextSelectable(boolean selectableText)
Sets if the node has selectable text.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Compatibility:
- Api < 19: Does not operate.
Parameters:
selectableText: True if the node has selectable text, false otherwise.
public long
getMinDurationBetweenContentChangesMillis()
Gets the minimum time duration between two content change events.
public void
setMinDurationBetweenContentChangesMillis(long duration)
Sets the minimum time duration between two content change events, which is used in throttling
content change events in accessibility services.
Example: An app can set MinDurationBetweenContentChanges as 1 min for a view which sends
content change events to accessibility services one event per second.
Accessibility service will throttle those content change events and only handle one event
per minute for that view.
Parameters:
duration: the minimum duration between content change events.
See also: for all content change types.
public boolean
isImportantForAccessibility()
Returns whether the node originates from a view considered important for accessibility.
Returns:
true if the node originates from a view considered important for
accessibility, false otherwise
See also: View
public void
setImportantForAccessibility(boolean important)
Sets whether the node is considered important for accessibility.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
important: true if the node is considered important for accessibility,
false otherwise
public boolean
isAccessibilityDataSensitive()
Gets if the node's accessibility data is considered sensitive.
Returns:
True if the node's data is considered sensitive, false otherwise.
See also: View
public void
setAccessibilityDataSensitive(boolean accessibilityDataSensitive)
Sets whether this node's accessibility data is considered sensitive.
For SDK 34 and higher: when set to true the framework will hide this node from
accessibility services with the
property set to false.
Otherwise, for SDK 19 and higher: the framework cannot hide this node but this property may
be read by accessibility services to provide modified behavior for sensitive nodes.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
accessibilityDataSensitive: True if the node's accessibility data is considered
sensitive.
public java.lang.CharSequence
getPackageName()
Gets the package this node comes from.
Returns:
The package name.
public void
setPackageName(java.lang.CharSequence packageName)
Sets the package this node comes from.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
packageName: The package name.
public java.lang.CharSequence
getClassName()
Gets the class this node comes from.
Returns:
The class name.
public void
setClassName(java.lang.CharSequence className)
Sets the class this node comes from.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
className: The class name.
public java.lang.CharSequence
getText()
Gets the text of this node.
Returns:
The text.
public void
setText(java.lang.CharSequence text)
Sets the text of this node.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
text: The text.
public void
addSpansToExtras(java.lang.CharSequence text, View view)
public static ClickableSpan
getClickableSpans(java.lang.CharSequence text)
public java.lang.CharSequence
getContentDescription()
Gets the content description of this node.
Returns:
The content description.
public java.lang.CharSequence
getStateDescription()
Gets the state description of this node.
Returns:
the state description or null if android version smaller
than 19.
public void
setContentDescription(java.lang.CharSequence contentDescription)
Sets the content description of this node.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
contentDescription: The content description.
public void
setStateDescription(java.lang.CharSequence stateDescription)
Sets the state description of this node.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
stateDescription: the state description of this node.
public java.lang.String
getUniqueId()
Gets the unique id of this node.
Returns:
the unique id or null if android version smaller
than 19.
public void
setUniqueId(java.lang.String uniqueId)
Sets the unique id of this node.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
uniqueId: the unique id of this node.
public void
setContainerTitle(java.lang.CharSequence containerTitle)
Sets the container title for app-developer-defined container which can be any type of
ViewGroup or layout.
Container title will be used to group together related controls, similar to HTML fieldset.
Or container title may identify a large piece of the UI that is visibly grouped together,
such as a toolbar or a card, etc.
Container title helps to assist in navigation across containers and other groups.
For example, a screen reader may use this to determine where to put accessibility focus.
Container title is different from pane titleAccessibilityNodeInfoCompat.setPaneTitle(CharSequence) which indicates that the
node represents a window or activity.
Example: An app can set container titles on several non-modal menus, containing TextViews
or ImageButtons that have content descriptions, text, etc. Screen readers can quickly
switch accessibility focus among menus instead of child views. Other accessibility-services
can easily find the menu.
Compatibility:
Parameters:
containerTitle: The container title that is associated with a ViewGroup/Layout on the
screen.
public java.lang.CharSequence
getContainerTitle()
Returns the container title.
Compatibility:
See also: for details.
Deprecated: Accessibility Object recycling is no longer necessary or functional.
Return an instance back to be reused.
Note: You must not touch the object after calling this function.
public void
setViewIdResourceName(java.lang.String viewId)
Sets the fully qualified resource name of the source view's id.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
viewId: The id resource name.
public java.lang.String
getViewIdResourceName()
Gets the fully qualified resource name of the source view's id.
Note: The primary usage of this API is for UI test automation
and in order to report the source view id of an AccessibilityNodeInfoCompat
the client has to set the AccessibilityServiceInfoCompat.FLAG_REPORT_VIEW_IDS
flag when configuring their .
Returns:
The id resource name.
public int
getLiveRegion()
Gets the node's live region mode.
A live region is a node that contains information that is important for
the user and when it changes the user should be notified. For example,
in a login screen with a TextView that displays an "incorrect password"
notification, that view should be marked as a live region with mode
ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE.
It is the responsibility of the accessibility service to monitor
AccessibilityEventCompat.TYPE_WINDOW_CONTENT_CHANGED events
indicating changes to live region nodes and their children.
Returns:
The live region mode, or
ViewCompat.ACCESSIBILITY_LIVE_REGION_NONE if the view is
not a live region.
See also: ViewCompat.getAccessibilityLiveRegion(View)
public void
setLiveRegion(int mode)
Sets the node's live region mode.
Note: Cannot be called from an
. This class is
made immutable before being delivered to an AccessibilityService.
Parameters:
mode: The live region mode, or
ViewCompat.ACCESSIBILITY_LIVE_REGION_NONE if the view is
not a live region.
See also: ViewCompat.setAccessibilityLiveRegion(View, int)
public int
getDrawingOrder()
Get the drawing order of the view corresponding it this node.
Drawing order is determined only within the node's parent, so this index is only relative
to its siblings.
In some cases, the drawing order is essentially simultaneous, so it is possible for two
siblings to return the same value. It is also possible that values will be skipped.
Returns:
The drawing position of the view corresponding to this node relative to its siblings.
public void
setDrawingOrder(int drawingOrderInParent)
Set the drawing order of the view corresponding it this node.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
drawingOrderInParent:
Gets the collection info if the node is a collection. A collection
child is always a collection item.
Returns:
The collection info.
public void
setCollectionInfo(java.lang.Object collectionInfo)
public void
setCollectionItemInfo(java.lang.Object collectionItemInfo)
Gets the collection item info if the node is a collection item. A collection
item is always a child of a collection.
Returns:
The collection item info.
Gets the range info if this node is a range.
Returns:
The range.
Sets the range info if this node is a range.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
rangeInfo: The range info.
public AccessibilityNodeInfo.ExtraRenderingInfo
getExtraRenderingInfo()
Gets the if the node is meant to be refreshed with extra data
to examine rendering related accessibility issues.
Returns:
The .
public java.util.List<AccessibilityNodeInfoCompat.AccessibilityActionCompat>
getActionList()
Gets the actions that can be performed on the node.
Returns:
A list of AccessibilityActions.
Compatibility:
- API < 21: Always returns null
public void
setContentInvalid(boolean contentInvalid)
Sets if the content of this node is invalid. For example,
a date is not well-formed.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
contentInvalid: If the node content is invalid.
public boolean
isContentInvalid()
Gets if the content of this node is invalid. For example,
a date is not well-formed.
Returns:
If the node content is invalid.
public boolean
isContextClickable()
Gets whether this node is context clickable.
Returns:
True if the node is context clickable.
public void
setContextClickable(boolean contextClickable)
Sets whether this node is context clickable.
Note: Cannot be called from an
. This class is made immutable
before being delivered to an AccessibilityService.
Parameters:
contextClickable: True if the node is context clickable.
public java.lang.CharSequence
getHintText()
Gets the hint text of this node. Only applies to nodes where text can be entered.
Returns:
The hint text.
public void
setHintText(java.lang.CharSequence hintText)
Sets the hint text of this node. Only applies to nodes where text can be entered.
This method has no effect below API 19
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
hintText: The hint text for this mode.
public void
setError(java.lang.CharSequence error)
Sets the error text of this node.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
error: The error text.
public java.lang.CharSequence
getError()
Gets the error text of this node.
Returns:
The error text.
public void
setLabelFor(View labeled)
Sets the view for which the view represented by this info serves as a
label for accessibility purposes.
Parameters:
labeled: The view for which this info serves as a label.
public void
setLabelFor(View root, int virtualDescendantId)
Sets the view for which the view represented by this info serves as a
label for accessibility purposes. If virtualDescendantId
is View
the root is set as the labeled.
A virtual descendant is an imaginary View that is reported as a part of the view
hierarchy for accessibility purposes. This enables custom views that draw complex
content to report themselves as a tree of virtual views, thus conveying their
logical structure.
Parameters:
root: The root whose virtual descendant serves as a label.
virtualDescendantId: The id of the virtual descendant.
Gets the node info for which the view represented by this info serves as
a label for accessibility purposes.
Returns:
The labeled info.
public void
setLabeledBy(View label)
Sets the view which serves as the label of the view represented by
this info for accessibility purposes.
Parameters:
label: The view that labels this node's source.
public void
setLabeledBy(View root, int virtualDescendantId)
Sets the view which serves as the label of the view represented by
this info for accessibility purposes. If virtualDescendantId
is View
the root is set as the label.
A virtual descendant is an imaginary View that is reported as a part of the view
hierarchy for accessibility purposes. This enables custom views that draw complex
content to report themselves as a tree of virtual views, thus conveying their
logical structure.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
root: The root whose virtual descendant labels this node's source.
virtualDescendantId: The id of the virtual descendant.
Gets the node info which serves as the label of the view represented by
this info for accessibility purposes.
Returns:
The label.
public boolean
canOpenPopup()
Gets if this node opens a popup or a dialog.
Returns:
If the the node opens a popup.
public void
setCanOpenPopup(boolean opensPopup)
Sets if this node opens a popup or a dialog.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
opensPopup: If the the node opens a popup.
public java.util.List<AccessibilityNodeInfoCompat>
findAccessibilityNodeInfosByViewId(java.lang.String viewId)
Finds AccessibilityNodeInfoCompats by the fully qualified view id's resource
name where a fully qualified id is of the from "package:id/id_resource_name".
For example, if the target application's package is "foo.bar" and the id
resource name is "baz", the fully qualified resource id is "foo.bar:id/baz".
Note: The primary usage of this API is for UI test automation
and in order to report the fully qualified view id if an
AccessibilityNodeInfoCompat the client has to set the
flag when configuring their .
Parameters:
viewId: The fully qualified resource name of the view id to find.
Returns:
A list of node info.
public Bundle
getExtras()
Gets an optional bundle with extra data. The bundle
is lazily created and never null
.
Note: It is recommended to use the package
name of your application as a prefix for the keys to avoid
collisions which may confuse an accessibility service if the
same key has different meaning when emitted from different
applications.
Returns:
The bundle.
public int
getInputType()
Gets the input type of the source as defined by .
Returns:
The input type.
public void
setInputType(int inputType)
Sets the input type of the source as defined by .
Note: Cannot be called from an
.
This class is made immutable before being delivered to an
AccessibilityService.
Parameters:
inputType: The input type.
public java.util.List<java.lang.String>
getAvailableExtraData()
Get the extra data available for this node.
Some data that is useful for some accessibility services is expensive to compute, and would
place undue overhead on apps to compute all the time. That data can be requested with
AccessibilityNodeInfoCompat.
Returns:
An unmodifiable list of keys corresponding to extra data that can be requested.
See also: AccessibilityNodeInfoCompat, AccessibilityNodeInfoCompat.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
public void
setAvailableExtraData(java.util.List<java.lang.String> extraDataKeys)
Set the extra data available for this node.
Note: When a View passes in a non-empty list, it promises that
it will populate the node's extras with corresponding pieces of information in
View
.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
extraDataKeys: A list of types of extra data that are available.
See also: AccessibilityNodeInfoCompat.getAvailableExtraData()
public void
setMaxTextLength(int max)
Sets the maximum text length, or -1 for no limit.
Typically used to indicate that an editable text field has a limit on
the number of characters entered.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
max: The maximum text length.
See also: AccessibilityNodeInfoCompat.getMaxTextLength()
public int
getMaxTextLength()
Returns the maximum text length for this node.
Returns:
The maximum text length, or -1 for no limit.
See also: AccessibilityNodeInfoCompat.setMaxTextLength(int)
public void
setTextSelection(int start, int end)
Sets the text selection start and end.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
start: The text selection start.
end: The text selection end.
public int
getTextSelectionStart()
Gets the text selection start.
Returns:
The text selection start if there is selection or -1.
public int
getTextSelectionEnd()
Gets the text selection end.
Returns:
The text selection end if there is selection or -1.
Gets the node before which this one is visited during traversal. A screen-reader
must visit the content of this node before the content of the one it precedes.
Returns:
The succeeding node if such or null
.
See also: AccessibilityNodeInfoCompat, AccessibilityNodeInfoCompat
public void
setTraversalBefore(View view)
Sets the view before whose node this one should be visited during traversal. A
screen-reader must visit the content of this node before the content of the one
it precedes.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
view: The view providing the preceding node.
See also: AccessibilityNodeInfoCompat.getTraversalBefore()
public void
setTraversalBefore(View root, int virtualDescendantId)
Sets the node before which this one is visited during traversal. A screen-reader
must visit the content of this node before the content of the one it precedes.
The successor is a virtual descendant of the given root
. If
virtualDescendantId
equals to View
the root is set
as the successor.
A virtual descendant is an imaginary View that is reported as a part of the view
hierarchy for accessibility purposes. This enables custom views that draw complex
content to report them selves as a tree of virtual views, thus conveying their
logical structure.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
root: The root of the virtual subtree.
virtualDescendantId: The id of the virtual descendant.
Gets the node after which this one is visited in accessibility traversal.
A screen-reader must visit the content of the other node before the content
of this one.
Returns:
The succeeding node if such or null
.
See also: AccessibilityNodeInfoCompat, AccessibilityNodeInfoCompat
public void
setTraversalAfter(View view)
Sets the view whose node is visited after this one in accessibility traversal.
A screen-reader must visit the content of the other node before the content
of this one.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
view: The previous view.
See also: AccessibilityNodeInfoCompat.getTraversalAfter()
public void
setTraversalAfter(View root, int virtualDescendantId)
Sets the node after which this one is visited in accessibility traversal.
A screen-reader must visit the content of the other node before the content
of this one. If virtualDescendantId
equals to View
the root is set as the predecessor.
A virtual descendant is an imaginary View that is reported as a part of the view
hierarchy for accessibility purposes. This enables custom views that draw complex
content to report them selves as a tree of virtual views, thus conveying their
logical structure.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
root: The root of the virtual subtree.
virtualDescendantId: The id of the virtual descendant.
Gets the window to which this node belongs.
Returns:
The window.
See also:
public boolean
isDismissable()
Gets if the node can be dismissed.
Returns:
If the node can be dismissed.
public void
setDismissable(boolean dismissable)
Sets if the node can be dismissed.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
dismissable: If the node can be dismissed.
public boolean
isEditable()
Gets if the node is editable.
Returns:
True if the node is editable, false otherwise.
public void
setEditable(boolean editable)
Sets whether this node is editable.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
editable: True if the node is editable.
public boolean
isMultiLine()
Gets if the node is a multi line editable text.
Returns:
True if the node is multi line.
public void
setMultiLine(boolean multiLine)
Sets if the node is a multi line editable text.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
multiLine: True if the node is multi line.
public java.lang.CharSequence
getTooltipText()
Gets the tooltip text of this node.
Returns:
The tooltip text.
public void
setTooltipText(java.lang.CharSequence tooltipText)
Sets the tooltip text of this node.
This method has no effect below API 19
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
tooltipText: The tooltip text.
public void
setPaneTitle(java.lang.CharSequence paneTitle)
If this node represents a visually distinct region of the screen that may update separately
from the rest of the window, it is considered a pane. Set the pane title to indicate that
the node is a pane, and to provide a title for it.
This method has no effect below API 19
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
paneTitle: The title of the window represented by this node.
public java.lang.CharSequence
getPaneTitle()
Get the title of the pane represented by this node.
Returns:
The title of the pane represented by this node, or null if this node does
not represent a pane.
public boolean
isScreenReaderFocusable()
Returns whether the node is explicitly marked as a focusable unit by a screen reader. Note
that false indicates that it is not explicitly marked, not that the node is not
a focusable unit. Screen readers should generally use other signals, such as
AccessibilityNodeInfoCompat.isFocusable(), or the presence of text in a node, to determine what should receive
focus.
Returns:
true if the node is specifically marked as a focusable unit for screen
readers, false otherwise.
public void
setScreenReaderFocusable(boolean screenReaderFocusable)
Sets whether the node should be considered a focusable unit by a screen reader.
This method has no effect below API 19
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
screenReaderFocusable: true if the node is a focusable unit for screen readers,
false otherwise.
public boolean
isShowingHintText()
Returns whether the node's text represents a hint for the user to enter text. It should only
be true if the node has editable text.
Returns:
true if the text in the node represents a hint to the user, false
otherwise.
public void
setShowingHintText(boolean showingHintText)
Sets whether the node's text represents a hint for the user to enter text. It should only
be true if the node has editable text.
This method has no effect below API 19
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
showingHintText: true if the text in the node represents a hint to the user,
false otherwise.
public boolean
isHeading()
Returns whether node represents a heading.
Note: Returns true if either AccessibilityNodeInfoCompat.setHeading(boolean)
marks this node as a heading or if the node has a AccessibilityNodeInfoCompat.CollectionItemInfoCompat that marks
it as such, to accommodate apps that use the now-deprecated API.
Returns:
true if the node is a heading, false otherwise.
public void
setHeading(boolean isHeading)
Sets whether the node represents a heading.
This method has no effect below API 19
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
isHeading: true if the node is a heading, false otherwise.
public boolean
isTextEntryKey()
Returns whether node represents a text entry key that is part of a keyboard or keypad.
Returns:
true if the node is a text entry key, false otherwise.
public void
setTextEntryKey(boolean isTextEntryKey)
Sets whether the node represents a text entry key that is part of a keyboard or keypad.
This method has no effect below API 19
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
isTextEntryKey: true if the node is a text entry key, false otherwise.
public boolean
hasRequestInitialAccessibilityFocus()
Gets whether the node has AccessibilityNodeInfoCompat.setRequestInitialAccessibilityFocus(boolean).
Returns:
True if the node has requested initial accessibility focus.
public void
setRequestInitialAccessibilityFocus(boolean requestInitialAccessibilityFocus)
Sets whether the node has requested initial accessibility focus.
If the node AccessibilityNodeInfoCompat.hasRequestInitialAccessibilityFocus(), this node would be one of
candidates to be accessibility focused when the window appears.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
requestInitialAccessibilityFocus: True if the node requests to receive initial
accessibility focus.
Refreshes this info with the latest state of the view it represents.
Note: If this method returns false this info is obsolete
since it represents a view that is no longer in the view tree.
Returns:
Whether the refresh succeeded.
public java.lang.CharSequence
getRoleDescription()
Gets the custom role description.
Returns:
The role description.
public void
setRoleDescription(java.lang.CharSequence roleDescription)
Sets the custom role description.
The role description allows you to customize the name for the view's semantic
role. For example, if you create a custom subclass of android.view.View
to display a menu bar, you could assign it the role description of "menu bar".
Warning: For consistency with other applications, you should
not use the role description to force accessibility services to describe
standard views (such as buttons or checkboxes) using specific wording. For
example, you should not set a role description of "check box" or "tick box" for
a standard . Instead let accessibility services
decide what feedback to provide.
Note: Cannot be called from an
.
This class is made immutable before being delivered to an AccessibilityService.
Parameters:
roleDescription: The role description.
Get the AccessibilityNodeInfoCompat.TouchDelegateInfoCompat for touch delegate behavior with the represented
view. It is possible for the same node to be pointed to by several regions. Use
AccessibilityNodeInfoCompat.TouchDelegateInfoCompat.getRegionAt(int) to get touch delegate target
, and AccessibilityNodeInfoCompat.TouchDelegateInfoCompat.getTargetForRegion(Region)
for AccessibilityNodeInfoCompat from the given region.
Compatibility:
- API < 29: Always returns null
Returns:
AccessibilityNodeInfoCompat.TouchDelegateInfoCompat or null if there are no touch delegates
in this node.
Set touch delegate info if the represented view has a .
Note: Cannot be called from an
.
This class is made immutable before being delivered to an
AccessibilityService.
Compatibility:
Parameters:
delegatedInfo: AccessibilityNodeInfoCompat.TouchDelegateInfoCompat
public void
setQueryFromAppProcessEnabled(View view, boolean enabled)
Connects this node to the View's root so that operations on this node can query the entire
AccessibilityNodeInfoCompat tree and perform accessibility actions on nodes.
Testing or debugging tools should create this AccessibilityNodeInfoCompat node using
ViewCompat.onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)
or AccessibilityNodeProviderCompat and call this
method, then navigate and interact with the node tree by calling methods on the node.
Calling this method more than once on the same node is a no-op. After calling this method,
all nodes linked to this node (children, ancestors, etc.) are also queryable.
Here "query" refers to the following node operations:
This is intended for short-lived inspections from testing or debugging tools in the app
process, as operations on this node tree will only succeed as long as the associated
view hierarchy remains attached to a window. AccessibilityNodeInfoCompat objects can
quickly become out of sync with their corresponding View
objects; if you wish to
inspect a changed or different view hierarchy then create a new node from any view in that
hierarchy and call this method on that new node, instead of disabling & re-enabling the
connection on the previous node.
Compatibility:
Parameters:
view: The view that generated this node, or any view in the same view-root hierarchy.
enabled: Whether to enable (true) or disable (false) querying from the app process.
public boolean
equals(java.lang.Object obj)
public java.lang.String
toString()
Source
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.core.view.accessibility;
import static android.view.View.NO_ID;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
import static java.util.Collections.emptyList;
import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.core.R;
import androidx.core.accessibilityservice.AccessibilityServiceInfoCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments;
import androidx.core.view.accessibility.AccessibilityViewCommand.MoveAtGranularityArguments;
import androidx.core.view.accessibility.AccessibilityViewCommand.MoveHtmlArguments;
import androidx.core.view.accessibility.AccessibilityViewCommand.MoveWindowArguments;
import androidx.core.view.accessibility.AccessibilityViewCommand.ScrollToPositionArguments;
import androidx.core.view.accessibility.AccessibilityViewCommand.SetProgressArguments;
import androidx.core.view.accessibility.AccessibilityViewCommand.SetSelectionArguments;
import androidx.core.view.accessibility.AccessibilityViewCommand.SetTextArguments;
import java.lang.ref.WeakReference;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Helper for accessing {@link android.view.accessibility.AccessibilityNodeInfo} in a backwards
* compatible fashion.
*/
public class AccessibilityNodeInfoCompat {
/**
* A class defining an action that can be performed on an {@link AccessibilityNodeInfo}.
* Each action has a unique id and a label.
* <p>
* There are three categories of actions:
* <ul>
* <li><strong>Standard actions</strong> - These are actions that are reported and
* handled by the standard UI widgets in the platform. Each standard action is associated with
* a resource id, e.g. {@link android.R.id#accessibilityActionScrollUp}. Note that actions were
* formerly associated with static constants defined in this class, e.g.
* {@link #ACTION_FOCUS}. These actions will have {@code null} labels.
* </li>
* <li><strong>Custom actions action</strong> - These are actions that are reported
* and handled by custom widgets. i.e. ones that are not part of the UI toolkit. For
* example, an application may define a custom action for clearing the user history.
* </li>
* <li><strong>Overriden standard actions</strong> - These are actions that override
* standard actions to customize them. For example, an app may add a label to the
* standard {@link #ACTION_CLICK} action to indicate to the user that this action clears
* browsing history.
* </ul>
* </p>
* <p class="note">
* <strong>Note:</strong> Views which support these actions should invoke
* {@link ViewCompat#setImportantForAccessibility(View, int)} with
* {@link ViewCompat#IMPORTANT_FOR_ACCESSIBILITY_YES} to ensure an
* {@link android.accessibilityservice.AccessibilityService} can discover the set of supported
* actions.
* </p>
*/
public static class AccessibilityActionCompat {
private static final String TAG = "A11yActionCompat";
/**
* Action that gives input focus to the node.
* <p>The focus request sends an event of {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
* if successful. In the View system, this is handled by {@link View#requestFocus}.
*
* <p>The node that is focused should return {@code true} for
* {@link AccessibilityNodeInfoCompat#isFocused()}.
*
* @see #ACTION_ACCESSIBILITY_FOCUS for the difference between system focus and
* accessibility focus.
*/
public static final AccessibilityActionCompat ACTION_FOCUS =
new AccessibilityActionCompat(AccessibilityNodeInfoCompat.ACTION_FOCUS, null);
/**
* Action that clears input focus of the node.
* <p>The node that is cleared should return {@code false} for
* {@link AccessibilityNodeInfoCompat#isFocused()}.
*/
public static final AccessibilityActionCompat ACTION_CLEAR_FOCUS =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_CLEAR_FOCUS, null);
/**
* Action that selects the node.
*/
public static final AccessibilityActionCompat ACTION_SELECT =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_SELECT, null);
/**
* Action that deselects the node.
*/
public static final AccessibilityActionCompat ACTION_CLEAR_SELECTION =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_CLEAR_SELECTION, null);
/**
* Action that clicks on the node info.
*
* <p>The UI element that implements this should send a
* {@link AccessibilityEvent#TYPE_VIEW_CLICKED} event. In the View system,
* the default handling of this action when performed by a service is to call
* {@link View#performClick()}, and setting a
* {@link View#setOnClickListener(View.OnClickListener)} automatically adds this action.
*
* <p>{@link #isClickable()} should return true if this action is available.
*/
public static final AccessibilityActionCompat ACTION_CLICK =
new AccessibilityActionCompat(AccessibilityNodeInfoCompat.ACTION_CLICK, null);
/**
* Action that long clicks on the node.
*
* <p>The UI element that implements this should send a
* {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED} event. In the View system,
* the default handling of this action when performed by a service is to call
* {@link View#performLongClick()}, and setting a
* {@link View#setOnLongClickListener(View.OnLongClickListener)} automatically adds this
* action.
*
* <p>{@link #isLongClickable()} should return true if this action is available.
*/
public static final AccessibilityActionCompat ACTION_LONG_CLICK =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, null);
/**
* Action that gives accessibility focus to the node.
* <p>The UI element that implements this should send a
* {@link AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED} event
* if successful. The node that is focused should return {@code true} for
* {@link AccessibilityNodeInfoCompat#isAccessibilityFocused()}.
*
* <p>This is intended to be used by screen readers to assist with user navigation. Apps
* changing focus can confuse screen readers, so the resulting behavior can vary by device
* and screen reader version.
* <p>This is distinct from {@link #ACTION_FOCUS}, which refers to system focus. System
* focus is typically used to convey targets for keyboard navigation.
*/
public static final AccessibilityActionCompat ACTION_ACCESSIBILITY_FOCUS =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null);
/**
* Action that clears accessibility focus of the node.
* <p>The UI element that implements this should send a
* {@link AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED} event if successful. The
* node that is cleared should return {@code false} for
* {@link AccessibilityNodeInfoCompat#isAccessibilityFocused()}.
*/
public static final AccessibilityActionCompat ACTION_CLEAR_ACCESSIBILITY_FOCUS =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
/**
* Action that requests to go to the next entity in this node's text
* at a given movement granularity. For example, move to the next character,
* word, etc.
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT},
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
* <strong>Example:</strong> Move to the previous character and do not extend selection.
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER);
* arguments.putBoolean(
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false);
* info.performAction(
* AccessibilityActionCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY.getId(),
* arguments);
* </code></pre></p>
* </p>
*
* @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
*
* @see AccessibilityNodeInfoCompat#setMovementGranularities(int)
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
* @see AccessibilityNodeInfoCompat#getMovementGranularities()
* AccessibilityNodeInfoCompat.getMovementGranularities()
*
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_CHARACTER
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_WORD
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_LINE
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PARAGRAPH
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PAGE
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE
*/
public static final AccessibilityActionCompat ACTION_NEXT_AT_MOVEMENT_GRANULARITY =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, null,
MoveAtGranularityArguments.class);
/**
* Action that requests to go to the previous entity in this node's text
* at a given movement granularity. For example, move to the next character,
* word, etc.
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT},
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
* <strong>Example:</strong> Move to the next character and do not extend selection.
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER);
* arguments.putBoolean(
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN, false);
* info.performAction(
* AccessibilityActionCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY.getId(),
* arguments);
* </code></pre></p>
* </p>
*
* @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
*
* @see AccessibilityNodeInfoCompat#setMovementGranularities(int)
* AccessibilityNodeInfoCompat.setMovementGranularities(int)
* @see AccessibilityNodeInfoCompat#getMovementGranularities()
* AccessibilityNodeInfoCompat.getMovementGranularities()
*
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_CHARACTER
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_CHARACTER
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_WORD
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_LINE
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_LINE
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PARAGRAPH
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH
* @see AccessibilityNodeInfoCompat#MOVEMENT_GRANULARITY_PAGE
* AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PAGE
*/
public static final AccessibilityActionCompat ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, null,
MoveAtGranularityArguments.class);
/**
* Action to move to the next HTML element of a given type. For example, move
* to the BUTTON, INPUT, TABLE, etc.
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_HTML_ELEMENT_STRING
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putString(
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
* info.performAction(
* AccessibilityActionCompat.ACTION_NEXT_HTML_ELEMENT.getId(), arguments);
* </code></pre></p>
* </p>
*/
public static final AccessibilityActionCompat ACTION_NEXT_HTML_ELEMENT =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_NEXT_HTML_ELEMENT, null,
MoveHtmlArguments.class);
/**
* Action to move to the previous HTML element of a given type. For example, move
* to the BUTTON, INPUT, TABLE, etc.
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_HTML_ELEMENT_STRING
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putString(
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
* info.performAction(
* AccessibilityActionCompat.ACTION_PREVIOUS_HTML_ELEMENT.getId(), arguments);
* </code></pre></p>
* </p>
*/
public static final AccessibilityActionCompat ACTION_PREVIOUS_HTML_ELEMENT =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_PREVIOUS_HTML_ELEMENT, null,
MoveHtmlArguments.class);
/**
* Action to scroll the node content forward.
*/
public static final AccessibilityActionCompat ACTION_SCROLL_FORWARD =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
/**
* Action to scroll the node content backward.
*/
public static final AccessibilityActionCompat ACTION_SCROLL_BACKWARD =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
/**
* Action to copy the current selection to the clipboard.
*/
public static final AccessibilityActionCompat ACTION_COPY =
new AccessibilityActionCompat(AccessibilityNodeInfoCompat.ACTION_COPY, null);
/**
* Action to paste the current clipboard content.
*/
public static final AccessibilityActionCompat ACTION_PASTE =
new AccessibilityActionCompat(AccessibilityNodeInfoCompat.ACTION_PASTE, null);
/**
* Action to cut the current selection and place it to the clipboard.
*/
public static final AccessibilityActionCompat ACTION_CUT =
new AccessibilityActionCompat(AccessibilityNodeInfoCompat.ACTION_CUT, null);
/**
* Action to set the selection. Performing this action with no arguments
* clears the selection.
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_START_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT},
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_END_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT, 1);
* arguments.putInt(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT, 2);
* info.performAction(AccessibilityActionCompat.ACTION_SET_SELECTION.getId(), arguments);
* </code></pre></p>
* </p>
*
* <p> If this is a text selection, the UI element that implements this should send a
* {@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED} event if its selection is
* updated. This element should also return {@code true} for
* {@link AccessibilityNodeInfoCompat#isTextSelectable()}.
*
* @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_START_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_START_INT
* @see AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SELECTION_END_INT
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SELECTION_END_INT
*/
public static final AccessibilityActionCompat ACTION_SET_SELECTION =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_SET_SELECTION, null,
SetSelectionArguments.class);
/**
* Action to expand an expandable node.
*/
public static final AccessibilityActionCompat ACTION_EXPAND =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_EXPAND, null);
/**
* Action to collapse an expandable node.
*/
public static final AccessibilityActionCompat ACTION_COLLAPSE =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_COLLAPSE, null);
/**
* Action to dismiss a dismissable node.
*/
public static final AccessibilityActionCompat ACTION_DISMISS =
new AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_DISMISS, null);
/**
* Action that sets the text of the node. Performing the action without argument,
* using <code> null</code> or empty {@link CharSequence} will clear the text. This
* action will also put the cursor at the end of text.
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE
* AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putCharSequence(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
* "android");
* info.performAction(AccessibilityActionCompat.ACTION_SET_TEXT.getId(), arguments);
* </code></pre></p>
* <p>The UI element that implements this should send a
* {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} event if its text is updated.
* This element should also return {@code true} for
* {@link AccessibilityNodeInfoCompat#isEditable()}.
*/
public static final AccessibilityActionCompat ACTION_SET_TEXT =
new AccessibilityActionCompat(AccessibilityNodeInfoCompat.ACTION_SET_TEXT, null,
SetTextArguments.class);
/**
* Action that requests the node make its bounding rectangle visible
* on the screen, scrolling if necessary just enough.
*
* @see View#requestRectangleOnScreen(Rect)
*/
public static final AccessibilityActionCompat ACTION_SHOW_ON_SCREEN =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_ON_SCREEN : null,
android.R.id.accessibilityActionShowOnScreen, null, null, null);
/**
* Action that scrolls the node to make the specified collection
* position visible on screen.
* <p>
* <strong>Arguments:</strong>
* <ul>
* <li>{@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_ROW_INT}</li>
* <li>{@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_COLUMN_INT}</li>
* <ul>
*
* @see AccessibilityNodeInfoCompat#getCollectionInfo()
*/
public static final AccessibilityActionCompat ACTION_SCROLL_TO_POSITION =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_TO_POSITION
: null, android.R.id.accessibilityActionScrollToPosition, null, null,
ScrollToPositionArguments.class);
/**
* Action to scroll the node content up.
*/
public static final AccessibilityActionCompat ACTION_SCROLL_UP =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP : null,
android.R.id.accessibilityActionScrollUp, null, null, null);
/**
* Action to scroll the node content left.
*/
public static final AccessibilityActionCompat ACTION_SCROLL_LEFT =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_LEFT : null,
android.R.id.accessibilityActionScrollLeft, null, null, null);
/**
* Action to scroll the node content down.
*/
public static final AccessibilityActionCompat ACTION_SCROLL_DOWN =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN : null,
android.R.id.accessibilityActionScrollDown, null, null, null);
/**
* Action to scroll the node content right.
*/
public static final AccessibilityActionCompat ACTION_SCROLL_RIGHT =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_RIGHT : null,
android.R.id.accessibilityActionScrollRight, null, null, null);
/**
* Action to move to the page above.
*/
@NonNull
public static final AccessibilityActionCompat ACTION_PAGE_UP =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
? AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_UP : null,
android.R.id.accessibilityActionPageUp, null, null, null);
/**
* Action to move to the page below.
*/
@NonNull
public static final AccessibilityActionCompat ACTION_PAGE_DOWN =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
? AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_DOWN : null,
android.R.id.accessibilityActionPageDown, null, null, null);
/**
* Action to move to the page left.
*/
@NonNull
public static final AccessibilityActionCompat ACTION_PAGE_LEFT =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
? AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT : null,
android.R.id.accessibilityActionPageLeft, null, null, null);
/**
* Action to move to the page right.
*/
@NonNull
public static final AccessibilityActionCompat ACTION_PAGE_RIGHT =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 29
? AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT : null,
android.R.id.accessibilityActionPageRight, null, null, null);
/**
* Action that context clicks the node.
*
* <p>The UI element that implements this should send a
* {@link AccessibilityEvent#TYPE_VIEW_CONTEXT_CLICKED} event. In the View system,
* the default handling of this action when performed by a service is to call
* {@link View#performContextClick()}, and setting a
* {@link View#setOnContextClickListener(View.OnContextClickListener)} automatically adds
* this action.
*
* <p>A context click usually occurs from a mouse pointer right-click or a stylus button
* press.
*
* <p>{@link #isContextClickable()} should return true if this action is available.
*/
public static final AccessibilityActionCompat ACTION_CONTEXT_CLICK =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 23
? AccessibilityNodeInfo.AccessibilityAction.ACTION_CONTEXT_CLICK : null,
android.R.id.accessibilityActionContextClick, null, null, null);
/**
* Action that sets progress between {@link RangeInfoCompat#getMin() RangeInfo.getMin()} and
* {@link RangeInfoCompat#getMax() RangeInfo.getMax()}. It should use the same value type as
* {@link RangeInfoCompat#getType() RangeInfo.getType()}
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_PROGRESS_VALUE}
*
* @see RangeInfoCompat
*/
public static final AccessibilityActionCompat ACTION_SET_PROGRESS =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 24
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS : null,
android.R.id.accessibilityActionSetProgress, null, null,
SetProgressArguments.class);
/**
* Action to move a window to a new location.
* <p>
* <strong>Arguments:</strong>
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVE_WINDOW_X}
* {@link AccessibilityNodeInfoCompat#ACTION_ARGUMENT_MOVE_WINDOW_Y}
*/
public static final AccessibilityActionCompat ACTION_MOVE_WINDOW =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 26
? AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW : null,
android.R.id.accessibilityActionMoveWindow, null, null,
MoveWindowArguments.class);
/**
* Action to show a tooltip.
*/
public static final AccessibilityActionCompat ACTION_SHOW_TOOLTIP =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 28
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_TOOLTIP : null,
android.R.id.accessibilityActionShowTooltip, null, null, null);
/**
* Action to hide a tooltip. A node should expose this action only for views that are
* currently showing a tooltip.
*/
public static final AccessibilityActionCompat ACTION_HIDE_TOOLTIP =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 28
? AccessibilityNodeInfo.AccessibilityAction.ACTION_HIDE_TOOLTIP : null,
android.R.id.accessibilityActionHideTooltip, null, null, null);
/**
* Action that presses and holds a node.
* <p>
* This action is for nodes that have distinct behavior that depends on how long a press is
* held. Nodes having a single action for long press should use {@link #ACTION_LONG_CLICK}
* instead of this action, and nodes should not expose both actions.
* <p>
* When calling {@code performAction(ACTION_PRESS_AND_HOLD, bundle}, use
* {@link #ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT} to specify how long the
* node is pressed. The first time an accessibility service performs ACTION_PRES_AND_HOLD
* on a node, it must specify 0 as ACTION_ARGUMENT_PRESS_AND_HOLD, so the application is
* notified that the held state has started. To ensure reasonable behavior, the values
* must be increased incrementally and may not exceed 10,000. UIs requested
* to hold for times outside of this range should ignore the action.
* <p>
* The total time the element is held could be specified by an accessibility user up-front,
* or may depend on what happens on the UI as the user continues to request the hold.
* <p>
* <strong>Note:</strong> The time between dispatching the action and it arriving in the
* UI process is not guaranteed. It is possible on a busy system for the time to expire
* unexpectedly. For the case of holding down a key for a repeating action, a delayed
* arrival should be benign. Please do not use this sort of action in cases where such
* delays will lead to unexpected UI behavior.
* <p>
*/
@NonNull public static final AccessibilityActionCompat ACTION_PRESS_AND_HOLD =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 30
? AccessibilityNodeInfo.AccessibilityAction.ACTION_PRESS_AND_HOLD : null,
android.R.id.accessibilityActionPressAndHold, null, null, null);
/**
* Action to send an ime actionId which is from
* {@link android.view.inputmethod.EditorInfo#actionId}. This ime actionId sets by
* {@link android.widget.TextView#setImeActionLabel(CharSequence, int)}, or it would be
* {@link android.view.inputmethod.EditorInfo#IME_ACTION_UNSPECIFIED} if no specific
* actionId has set. A node should expose this action only for views that are currently
* with input focus and editable.
*/
@NonNull public static final AccessibilityActionCompat ACTION_IME_ENTER =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 30
? AccessibilityNodeInfo.AccessibilityAction.ACTION_IME_ENTER : null,
android.R.id.accessibilityActionImeEnter, null, null, null);
/**
* Action to start a drag.
* <p>
* This action initiates a drag & drop within the system. The source's dragged content is
* prepared before the drag begins. In View, this action should prepare the arguments to
* {@link View#startDragAndDrop(ClipData, View.DragShadowBuilder, Object, int)}} and then
* call the method. The equivalent should be performed for other UI toolkits.
* </p>
*
* @see AccessibilityEventCompat#CONTENT_CHANGE_TYPE_DRAG_STARTED
*/
@NonNull
public static final AccessibilityActionCompat ACTION_DRAG_START =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 32
? AccessibilityNodeInfo.AccessibilityAction.ACTION_DRAG_START : null,
android.R.id.accessibilityActionDragStart, null, null, null);
/**
* Action to trigger a drop of the content being dragged.
* <p>
* This action is added to potential drop targets if the source started a drag with
* {@link #ACTION_DRAG_START}. In View, these targets are Views that accepted
* {@link android.view.DragEvent#ACTION_DRAG_STARTED} and have an
* {@link View.OnDragListener}.
* </p>
*
* @see AccessibilityEventCompat#CONTENT_CHANGE_TYPE_DRAG_DROPPED
*/
@NonNull
public static final AccessibilityActionCompat ACTION_DRAG_DROP =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 32
? AccessibilityNodeInfo.AccessibilityAction.ACTION_DRAG_DROP : null,
android.R.id.accessibilityActionDragDrop, null, null, null);
/**
* Action to cancel a drag.
* <p>
* This action is added to the source that started a drag with {@link #ACTION_DRAG_START}.
* </p>
*
* @see AccessibilityEventCompat#CONTENT_CHANGE_TYPE_DRAG_CANCELLED
*/
@NonNull
public static final AccessibilityActionCompat ACTION_DRAG_CANCEL =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 32
? AccessibilityNodeInfo.AccessibilityAction.ACTION_DRAG_CANCEL : null,
android.R.id.accessibilityActionDragCancel, null, null, null);
/**
* Action to show suggestions for editable text.
*/
@NonNull
public static final AccessibilityActionCompat ACTION_SHOW_TEXT_SUGGESTIONS =
new AccessibilityActionCompat(Build.VERSION.SDK_INT >= 33
? AccessibilityNodeInfo.AccessibilityAction.ACTION_SHOW_TEXT_SUGGESTIONS
: null, android.R.id.accessibilityActionShowTextSuggestions, null,
null, null);
/**
* Action that brings fully on screen the next node in the specified direction.
*
* <p>
* 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.
* </p>
* <p>
* This action should be used instead of
* {@link AccessibilityActionCompat#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 AccessibilityEventCompat#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.
* <p>
* <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_DIRECTION_INT}. This is a
* required argument.<br>
* </p>
*/
@NonNull
@OptIn(markerClass = androidx.core.os.BuildCompat.PrereleaseSdkCheck.class)
public static final AccessibilityActionCompat ACTION_SCROLL_IN_DIRECTION =
new AccessibilityActionCompat(
Build.VERSION.SDK_INT >= 34 ? Api34Impl.getActionScrollInDirection() : null,
android.R.id.accessibilityActionScrollInDirection, null, null, null);
final Object mAction;
private final int mId;
private final Class<? extends CommandArguments> mViewCommandArgumentClass;
/**
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
protected final AccessibilityViewCommand mCommand;
/**
* Creates a new instance.
*
* @param actionId The action id.
* @param label The action label.
*/
public AccessibilityActionCompat(int actionId, CharSequence label) {
this(null, actionId, label, null, null);
}
/**
* Creates a new instance.
*
* @param actionId The action id.
* @param label The action label.
* @param command The command performed when the service requests the action
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public AccessibilityActionCompat(int actionId, CharSequence label,
AccessibilityViewCommand command) {
this(null, actionId, label, command, null);
}
AccessibilityActionCompat(Object action) {
this(action, 0, null, null, null);
}
private AccessibilityActionCompat(int actionId, CharSequence label,
Class<? extends CommandArguments> viewCommandArgumentClass) {
this(null, actionId, label, null, viewCommandArgumentClass);
}
AccessibilityActionCompat(Object action, int id, CharSequence label,
AccessibilityViewCommand command,
Class<? extends CommandArguments> viewCommandArgumentClass) {
mId = id;
mCommand = command;
if (Build.VERSION.SDK_INT >= 21 && action == null) {
mAction = new AccessibilityNodeInfo.AccessibilityAction(id, label);
} else {
mAction = action;
}
mViewCommandArgumentClass = viewCommandArgumentClass;
}
/**
* Gets the id for this action.
*
* @return The action id.
*/
public int getId() {
if (Build.VERSION.SDK_INT >= 21) {
return ((AccessibilityNodeInfo.AccessibilityAction) mAction).getId();
} else {
return 0;
}
}
/**
* Gets the label for this action. Its purpose is to describe the
* action to user.
*
* @return The label.
*/
public CharSequence getLabel() {
if (Build.VERSION.SDK_INT >= 21) {
return ((AccessibilityNodeInfo.AccessibilityAction) mAction).getLabel();
} else {
return null;
}
}
/**
* Performs the action.
* @return If the action was handled.
* @param view View to act upon.
* @param arguments Optional action arguments.
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public boolean perform(View view, Bundle arguments) {
if (mCommand != null) {
CommandArguments viewCommandArgument = null;
if (mViewCommandArgumentClass != null) {
try {
viewCommandArgument =
mViewCommandArgumentClass.getDeclaredConstructor().newInstance();
viewCommandArgument.setBundle(arguments);
} catch (Exception e) {
final String className = mViewCommandArgumentClass == null
? "null" : mViewCommandArgumentClass.getName();
Log.e(TAG, "Failed to execute command with argument class "
+ "ViewCommandArgument: " + className, e);
}
}
return mCommand.perform(view, viewCommandArgument);
}
return false;
}
/**
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public AccessibilityActionCompat createReplacementAction(CharSequence label,
AccessibilityViewCommand command) {
return new AccessibilityActionCompat(null, mId, label, command,
mViewCommandArgumentClass);
}
@Override
public int hashCode() {
return mAction != null ? mAction.hashCode() : 0;
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof AccessibilityNodeInfoCompat.AccessibilityActionCompat)) {
return false;
}
AccessibilityNodeInfoCompat.AccessibilityActionCompat other =
(AccessibilityNodeInfoCompat.AccessibilityActionCompat) obj;
if (mAction == null) {
if (other.mAction != null) {
return false;
}
} else if (!mAction.equals(other.mAction)) {
return false;
}
return true;
}
@NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("AccessibilityActionCompat: ");
// Mirror AccessibilityNodeInfoCompat.toString's action string.
String actionName = getActionSymbolicName(mId);
if (actionName.equals("ACTION_UNKNOWN") && getLabel() != null) {
actionName = getLabel().toString();
}
builder.append(actionName);
return builder.toString();
}
}
/**
* Class with information if a node is a collection.
* <p>
* A collection of items has rows and columns and may be marked as hierarchical.
*
* <p>
* For example, a list where the items are placed in a vertical layout is a collection with one
* column and as many rows as the list items. This collection has 3 rows and 1 column and should
* not be marked as hierarchical since items do not exist at different levels/ranks and there
* are no nested collections.
* <ul>
* <li>Item 1</li>
* <li>Item 2</li>
* <li>Item 3</li>
* </ul>
*
* <p>
* A table is a collection with several rows and several columns. This collection has 2 rows and
* 3 columns and is not marked as hierarchical:
*<table>
* <tr>
* <td>Item 1</td>
* <td>Item 2</td>
* <td>Item 3</td>
* </tr>
* <tr>
* <td>Item 4</td>
* <td>Item 5</td>
* <td>Item 6</td>
* </tr>
* </table>
*
* <p>
* Nested collections could be marked as hierarchical. To add outer and inner collections to the
* same hierarchy, mark them both as hierarchical.
*
* <p> For example, if you have a collection with two lists - this collection has an outer
* list with 3 rows and 1 column and an inner list within "Item 2" with 2 rows and 1 -
* you can mark both the outer list and the inner list as hierarchical to make them part of
* the same hierarchy. If a collection does not have any ancestor or descendant hierarchical
* collections, it does not need to be marked as hierarchical.
* <ul>
* <li>Item 1</li>
* <li> Item 2
* <ul>
* <li>Item 2A</li>
* <li>Item 2B</li>
* </ul>
* </li>
* <li>Item 3</li>
* </ul>
*
* <p>
* To be a valid list, a collection has 1 row and any number of columns or 1 column and any
* number of rows.
* </p>
*/
public static class CollectionInfoCompat {
/** Selection mode where items are not selectable. */
public static final int SELECTION_MODE_NONE = 0;
/** Selection mode where a single item may be selected. */
public static final int SELECTION_MODE_SINGLE = 1;
/** Selection mode where multiple items may be selected. */
public static final int SELECTION_MODE_MULTIPLE = 2;
final Object mInfo;
/**
* Returns a cached instance if such is available otherwise a new one.
*
* @param rowCount The number of rows.
* @param columnCount The number of columns.
* @param hierarchical Whether the collection is hierarchical.
* @param selectionMode The collection's selection mode, one of:
* <ul>
* <li>{@link #SELECTION_MODE_NONE}
* <li>{@link #SELECTION_MODE_SINGLE}
* <li>{@link #SELECTION_MODE_MULTIPLE}
* </ul>
*
* @return An instance.
*/
public static CollectionInfoCompat obtain(int rowCount, int columnCount,
boolean hierarchical, int selectionMode) {
if (Build.VERSION.SDK_INT >= 21) {
return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain(
rowCount, columnCount, hierarchical, selectionMode));
} else {
return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain(
rowCount, columnCount, hierarchical));
}
}
/**
* Returns a cached instance if such is available otherwise a new one.
*
* @param rowCount The number of rows, or -1 if count is unknown.
* @param columnCount The number of columns , or -1 if count is unknown.
* @param hierarchical Whether the collection is hierarchical.
*
* @return An instance.
*/
public static CollectionInfoCompat obtain(int rowCount, int columnCount,
boolean hierarchical) {
return new CollectionInfoCompat(AccessibilityNodeInfo.CollectionInfo.obtain(
rowCount, columnCount, hierarchical));
}
CollectionInfoCompat(Object info) {
mInfo = info;
}
/**
* Gets the number of columns.
*
* @return The column count, or -1 if count is unknown.
*/
public int getColumnCount() {
return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getColumnCount();
}
/**
* Gets the number of rows.
*
* @return The row count, or -1 if count is unknown.
*/
public int getRowCount() {
return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getRowCount();
}
/**
* Gets if the collection is a hierarchically ordered.
*
* @return Whether the collection is hierarchical.
*/
public boolean isHierarchical() {
return ((AccessibilityNodeInfo.CollectionInfo) mInfo).isHierarchical();
}
/**
* Gets the collection's selection mode.
*
* @return The collection's selection mode, one of:
* <ul>
* <li>{@link #SELECTION_MODE_NONE}
* <li>{@link #SELECTION_MODE_SINGLE}
* <li>{@link #SELECTION_MODE_MULTIPLE}
* </ul>
*/
public int getSelectionMode() {
if (Build.VERSION.SDK_INT >= 21) {
return ((AccessibilityNodeInfo.CollectionInfo) mInfo).getSelectionMode();
} else {
return 0;
}
}
}
/**
* Class with information if a node is a collection item.
* <p>
* A collection item is contained in a collection, it starts at
* a given row and column in the collection, and spans one or
* more rows and columns. For example, a header of two related
* table columns starts at the first row and the first column,
* spans one row and two columns.
* </p>
*/
public static class CollectionItemInfoCompat {
final Object mInfo;
/**
* Returns a cached instance if such is available otherwise a new one.
*
* @param rowIndex The row index at which the item is located.
* @param rowSpan The number of rows the item spans.
* @param columnIndex The column index at which the item is located.
* @param columnSpan The number of columns the item spans.
* @param heading Whether the item is a heading. This should be set to false and the newer
* {@link AccessibilityNodeInfoCompat#setHeading(boolean)} used to identify
* headings.
* @param selected Whether the item is selected.
* @return An instance.
*/
public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan,
int columnIndex, int columnSpan, boolean heading, boolean selected) {
if (Build.VERSION.SDK_INT >= 21) {
return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain(
rowIndex, rowSpan, columnIndex, columnSpan, heading, selected));
} else {
return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain(
rowIndex, rowSpan, columnIndex, columnSpan, heading));
}
}
/**
* Returns a cached instance if such is available otherwise a new one.
*
* @param rowIndex The row index at which the item is located.
* @param rowSpan The number of rows the item spans.
* @param columnIndex The column index at which the item is located.
* @param columnSpan The number of columns the item spans.
* @param heading Whether the item is a heading. This should be set to false and the newer
* {@link AccessibilityNodeInfoCompat#setHeading(boolean)} used to identify
* headings.
* @return An instance.
*/
public static CollectionItemInfoCompat obtain(int rowIndex, int rowSpan,
int columnIndex, int columnSpan, boolean heading) {
return new CollectionItemInfoCompat(AccessibilityNodeInfo.CollectionItemInfo.obtain(
rowIndex, rowSpan, columnIndex, columnSpan, heading));
}
CollectionItemInfoCompat(Object info) {
mInfo = info;
}
/**
* Gets the column index at which the item is located.
*
* @return The column index.
*/
public int getColumnIndex() {
return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnIndex();
}
/**
* Gets the number of columns the item spans.
*
* @return The column span.
*/
public int getColumnSpan() {
return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getColumnSpan();
}
/**
* Gets the row index at which the item is located.
*
* @return The row index.
*/
public int getRowIndex() {
return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowIndex();
}
/**
* Gets the number of rows the item spans.
*
* @return The row span.
*/
public int getRowSpan() {
return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).getRowSpan();
}
/**
* Gets if the collection item is a heading. For example, section
* heading, table header, etc.
*
* @return If the item is a heading.
* @deprecated Use {@link AccessibilityNodeInfoCompat#isHeading()}
*/
@SuppressWarnings("deprecation")
@Deprecated
public boolean isHeading() {
return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).isHeading();
}
/**
* Gets if the collection item is selected.
*
* @return If the item is selected.
*/
public boolean isSelected() {
if (Build.VERSION.SDK_INT >= 21) {
return ((AccessibilityNodeInfo.CollectionItemInfo) mInfo).isSelected();
} else {
return false;
}
}
/**
* Gets the row title at which the item is located.
*
* @return The row title.
*/
@Nullable
public String getRowTitle() {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.getCollectionItemRowTitle(mInfo);
} else {
return null;
}
}
/**
* Gets the column title at which the item is located.
*
* @return The column title.
*/
@Nullable
public String getColumnTitle() {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.getCollectionItemColumnTitle(mInfo);
} else {
return null;
}
}
/**
* Builder for creating {@link CollectionItemInfoCompat} objects.
*/
public static final class Builder {
private boolean mHeading;
private int mColumnIndex;
private int mRowIndex;
private int mColumnSpan;
private int mRowSpan;
private boolean mSelected;
private String mRowTitle;
private String mColumnTitle;
/**
* Creates a new Builder.
*/
public Builder() {
}
/**
* Sets the collection item is a heading.
*
* @param heading The heading state
* @return This builder
*/
@NonNull
public Builder setHeading(boolean heading) {
mHeading = heading;
return this;
}
/**
* Sets the column index at which the item is located.
*
* @param columnIndex The column index
* @return This builder
*/
@NonNull
public Builder setColumnIndex(int columnIndex) {
mColumnIndex = columnIndex;
return this;
}
/**
* Sets the row index at which the item is located.
*
* @param rowIndex The row index
* @return This builder
*/
@NonNull
public Builder setRowIndex(int rowIndex) {
mRowIndex = rowIndex;
return this;
}
/**
* Sets the number of columns the item spans.
*
* @param columnSpan The number of columns spans
* @return This builder
*/
@NonNull
public Builder setColumnSpan(int columnSpan) {
mColumnSpan = columnSpan;
return this;
}
/**
* Sets the number of rows the item spans.
*
* @param rowSpan The number of rows spans
* @return This builder
*/
@NonNull
public Builder setRowSpan(int rowSpan) {
mRowSpan = rowSpan;
return this;
}
/**
* Sets the collection item is selected.
*
* @param selected The number of rows spans
* @return This builder
*/
@NonNull
public Builder setSelected(boolean selected) {
mSelected = selected;
return this;
}
/**
* Sets the row title at which the item is located.
*
* @param rowTitle The row title
* @return This builder
*/
@NonNull
public Builder setRowTitle(@Nullable String rowTitle) {
mRowTitle = rowTitle;
return this;
}
/**
* Sets the column title at which the item is located.
*
* @param columnTitle The column title
* @return This builder
*/
@NonNull
public Builder setColumnTitle(@Nullable String columnTitle) {
mColumnTitle = columnTitle;
return this;
}
/**
* Builds and returns a {@link AccessibilityNodeInfo.CollectionItemInfo}.
*/
@NonNull
public CollectionItemInfoCompat build() {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.buildCollectionItemInfoCompat(mHeading, mColumnIndex,
mRowIndex, mColumnSpan, mRowSpan, mSelected, mRowTitle, mColumnTitle);
} else if (Build.VERSION.SDK_INT >= 21) {
return Api21Impl.createCollectionItemInfo(mRowIndex, mRowSpan, mColumnIndex,
mColumnSpan, mHeading, mSelected);
} else {
return new CollectionItemInfoCompat(
AccessibilityNodeInfo.CollectionItemInfo.obtain(mRowIndex, mRowSpan,
mColumnIndex,
mColumnSpan, mHeading));
}
}
}
}
/**
* Class with information if a node is a range.
*/
public static class RangeInfoCompat {
/** Range type: integer. */
public static final int RANGE_TYPE_INT = 0;
/** Range type: float. */
public static final int RANGE_TYPE_FLOAT = 1;
/** Range type: percent with values from zero to one.*/
public static final int RANGE_TYPE_PERCENT = 2;
/**
* Obtains a cached instance if such is available otherwise a new one.
*
* @param type The type of the range.
* @param min The min value.
* @param max The max value.
* @param current The current value.
* @return The instance
*/
public static RangeInfoCompat obtain(int type, float min, float max, float current) {
return new RangeInfoCompat(
AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current));
}
final Object mInfo;
RangeInfoCompat(Object info) {
mInfo = info;
}
/**
* Creates a new range.
*
* @param type The type of the range.
* @param min The minimum value. Use {@code Float.NEGATIVE_INFINITY} if the range has no
* minimum.
* @param max The maximum value. Use {@code Float.POSITIVE_INFINITY} if the range has no
* maximum.
* @param current The current value.
*/
public RangeInfoCompat(int type, float min, float max, float current) {
if (Build.VERSION.SDK_INT >= 30) {
mInfo = Api30Impl.createRangeInfo(type, min, max, current);
} else {
mInfo = AccessibilityNodeInfo.RangeInfo.obtain(type, min, max, current);
}
}
/**
* Gets the current value.
*
* @return The current value.
*/
public float getCurrent() {
return ((AccessibilityNodeInfo.RangeInfo) mInfo).getCurrent();
}
/**
* Gets the max value.
*
* @return The max value.
*/
public float getMax() {
return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMax();
}
/**
* Gets the min value.
*
* @return The min value.
*/
public float getMin() {
return ((AccessibilityNodeInfo.RangeInfo) mInfo).getMin();
}
/**
* Gets the range type.
*
* @return The range type.
*
* @see #RANGE_TYPE_INT
* @see #RANGE_TYPE_FLOAT
* @see #RANGE_TYPE_PERCENT
*/
public int getType() {
return ((AccessibilityNodeInfo.RangeInfo) mInfo).getType();
}
}
/**
* Class with information of touch delegated views and regions.
*/
public static final class TouchDelegateInfoCompat {
final TouchDelegateInfo mInfo;
/**
* Create a new instance of {@link TouchDelegateInfoCompat}.
*
* @param targetMap A map from regions (in view coordinates) to delegated views.
*/
public TouchDelegateInfoCompat(@NonNull Map<Region, View> targetMap) {
if (Build.VERSION.SDK_INT >= 29) {
mInfo = new TouchDelegateInfo(targetMap);
} else {
mInfo = null;
}
}
TouchDelegateInfoCompat(@NonNull TouchDelegateInfo info) {
mInfo = info;
}
/**
* Returns the number of touch delegate target region.
* <p>
* Compatibility:
* <ul>
* <li>API < 29: Always returns {@code 0}</li>
* </ul>
*
* @return Number of touch delegate target region.
*/
public @IntRange(from = 0) int getRegionCount() {
if (Build.VERSION.SDK_INT >= 29) {
return mInfo.getRegionCount();
}
return 0;
}
/**
* Return the {@link Region} at the given index.
* <p>
* Compatibility:
* <ul>
* <li>API < 29: Always returns {@code null}</li>
* </ul>
*
* @param index The desired index, must be between 0 and {@link #getRegionCount()}-1.
* @return Returns the {@link Region} stored at the given index.
*/
@Nullable
public Region getRegionAt(@IntRange(from = 0) int index) {
if (Build.VERSION.SDK_INT >= 29) {
return mInfo.getRegionAt(index);
}
return null;
}
/**
* Return the target {@link AccessibilityNodeInfoCompat} for the given {@link Region}.
* <p>
* <strong>Note:</strong> This api can only be called from
* {@link android.accessibilityservice.AccessibilityService}.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>API < 29: Always returns {@code null}</li>
* </ul>
*
* @param region The region retrieved from {@link #getRegionAt(int)}.
* @return The target node associates with the given region.
*/
@Nullable
public AccessibilityNodeInfoCompat getTargetForRegion(@NonNull Region region) {
if (Build.VERSION.SDK_INT >= 29) {
AccessibilityNodeInfo info = mInfo.getTargetForRegion(region);
if (info != null) {
return AccessibilityNodeInfoCompat.wrap(info);
}
}
return null;
}
}
private static final String ROLE_DESCRIPTION_KEY =
"AccessibilityNodeInfo.roleDescription";
private static final String PANE_TITLE_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.PANE_TITLE_KEY";
private static final String TOOLTIP_TEXT_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.TOOLTIP_TEXT_KEY";
private static final String HINT_TEXT_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.HINT_TEXT_KEY";
private static final String BOOLEAN_PROPERTY_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.BOOLEAN_PROPERTY_KEY";
private static final String SPANS_ID_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.SPANS_ID_KEY";
private static final String SPANS_START_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.SPANS_START_KEY";
private static final String SPANS_END_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.SPANS_END_KEY";
private static final String SPANS_FLAGS_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.SPANS_FLAGS_KEY";
private static final String SPANS_ACTION_ID_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.SPANS_ACTION_ID_KEY";
private static final String STATE_DESCRIPTION_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.STATE_DESCRIPTION_KEY";
private static final String UNIQUE_ID_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.UNIQUE_ID_KEY";
private static final String CONTAINER_TITLE_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.CONTAINER_TITLE_KEY";
private static final String BOUNDS_IN_WINDOW_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat.BOUNDS_IN_WINDOW_KEY";
private static final String MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY =
"androidx.view.accessibility.AccessibilityNodeInfoCompat."
+ "MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY";
// These don't line up with the internal framework constants, since they are independent
// and we might as well get all 32 bits of utility here.
private static final int BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE = 0x00000001;
private static final int BOOLEAN_PROPERTY_IS_HEADING = 0x00000002;
private static final int BOOLEAN_PROPERTY_IS_SHOWING_HINT = 0x00000004;
private static final int BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY = 0x00000008;
private static final int BOOLEAN_PROPERTY_HAS_REQUEST_INITIAL_ACCESSIBILITY_FOCUS = 1 << 5;
private static final int BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE = 1 << 6;
private static final int BOOLEAN_PROPERTY_TEXT_SELECTABLE = 1 << 23;
private static final int BOOLEAN_PROPERTY_SUPPORTS_GRANULAR_SCROLLING = 1 << 26;
private final AccessibilityNodeInfo mInfo;
/**
* androidx.customview.widget.ExploreByTouchHelper.HOST_ID = -1;
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public int mParentVirtualDescendantId = NO_ID;
private int mVirtualDescendantId = NO_ID;
// Actions introduced in IceCreamSandwich
/**
* Action that focuses the node.
* @see AccessibilityActionCompat#ACTION_FOCUS
*/
public static final int ACTION_FOCUS = 0x00000001;
/**
* Action that unfocuses the node.
* @see AccessibilityActionCompat#ACTION_CLEAR_FOCUS
*/
public static final int ACTION_CLEAR_FOCUS = 0x00000002;
/**
* Action that selects the node.
* @see AccessibilityActionCompat#ACTION_SELECT
*/
public static final int ACTION_SELECT = 0x00000004;
/**
* Action that unselects the node.
* @see AccessibilityActionCompat#ACTION_CLEAR_SELECTION
*/
public static final int ACTION_CLEAR_SELECTION = 0x00000008;
/**
* Action that clicks on the node info.
* @see AccessibilityActionCompat#ACTION_CLICK
*/
public static final int ACTION_CLICK = 0x00000010;
/**
* Action that long clicks on the node.
* @see AccessibilityActionCompat#ACTION_LONG_CLICK
*/
public static final int ACTION_LONG_CLICK = 0x00000020;
// Actions introduced in JellyBean
/**
* Action that gives accessibility focus to the node.
* @see AccessibilityActionCompat#ACTION_ACCESSIBILITY_FOCUS
*/
public static final int ACTION_ACCESSIBILITY_FOCUS = 0x00000040;
/**
* Action that clears accessibility focus of the node.
*/
public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 0x00000080;
/**
* Action that requests to go to the next entity in this node's text
* at a given movement granularity. For example, move to the next character,
* word, etc.
* <p>
* <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<,
* {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
* <strong>Example:</strong> Move to the previous character and do not extend selection.
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
* AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
* arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
* false);
* info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
* </code></pre></p>
* </p>
*
* @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
*
* @see #setMovementGranularities(int)
* @see #getMovementGranularities()
*
* @see #MOVEMENT_GRANULARITY_CHARACTER
* @see #MOVEMENT_GRANULARITY_WORD
* @see #MOVEMENT_GRANULARITY_LINE
* @see #MOVEMENT_GRANULARITY_PARAGRAPH
* @see #MOVEMENT_GRANULARITY_PAGE
* @see AccessibilityActionCompat#ACTION_NEXT_AT_MOVEMENT_GRANULARITY
*/
public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 0x00000100;
/**
* Action that requests to go to the previous entity in this node's text
* at a given movement granularity. For example, move to the next character,
* word, etc.
* <p>
* <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<,
* {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
* <strong>Example:</strong> Move to the next character and do not extend selection.
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
* AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
* arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
* false);
* info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
* arguments);
* </code></pre></p>
* </p>
*
* @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
* @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
*
* @see #setMovementGranularities(int)
* @see #getMovementGranularities()
*
* @see #MOVEMENT_GRANULARITY_CHARACTER
* @see #MOVEMENT_GRANULARITY_WORD
* @see #MOVEMENT_GRANULARITY_LINE
* @see #MOVEMENT_GRANULARITY_PARAGRAPH
* @see #MOVEMENT_GRANULARITY_PAGE
* @see AccessibilityActionCompat#ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
*/
public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 0x00000200;
/**
* Action to move to the next HTML element of a given type. For example, move
* to the BUTTON, INPUT, TABLE, etc.
* <p>
* <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
* info.performAction(AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT, arguments);
* </code></pre></p>
* </p>
* @see AccessibilityActionCompat#ACTION_NEXT_HTML_ELEMENT
*/
public static final int ACTION_NEXT_HTML_ELEMENT = 0x00000400;
/**
* Action to move to the previous HTML element of a given type. For example, move
* to the BUTTON, INPUT, TABLE, etc.
* <p>
* <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_HTML_ELEMENT_STRING}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putString(AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING, "BUTTON");
* info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT, arguments);
* </code></pre></p>
* </p>
*
* @see AccessibilityActionCompat#ACTION_PREVIOUS_HTML_ELEMENT
*/
public static final int ACTION_PREVIOUS_HTML_ELEMENT = 0x00000800;
/**
* Action to scroll the node content forward.
* @see AccessibilityActionCompat#ACTION_SCROLL_FORWARD
*/
public static final int ACTION_SCROLL_FORWARD = 0x00001000;
/**
* Action to scroll the node content backward.
* @see AccessibilityActionCompat#ACTION_SCROLL_BACKWARD
*/
public static final int ACTION_SCROLL_BACKWARD = 0x00002000;
// Actions introduced in JellyBeanMr2
/**
* Action to copy the current selection to the clipboard.
* @see AccessibilityActionCompat#ACTION_COPY
*/
public static final int ACTION_COPY = 0x00004000;
/**
* Action to paste the current clipboard content.
* @see AccessibilityActionCompat#ACTION_PASTE
*/
public static final int ACTION_PASTE = 0x00008000;
/**
* Action to cut the current selection and place it to the clipboard.
* @see AccessibilityActionCompat#ACTION_CUT
*/
public static final int ACTION_CUT = 0x00010000;
/**
* Action to set the selection. Performing this action with no arguments
* clears the selection.
* <p>
* <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SELECTION_START_INT},
* {@link #ACTION_ARGUMENT_SELECTION_END_INT}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 1);
* arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 2);
* info.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments);
* </code></pre></p>
* </p>
*
* @see #ACTION_ARGUMENT_SELECTION_START_INT
* @see #ACTION_ARGUMENT_SELECTION_END_INT
* @see AccessibilityActionCompat#ACTION_SET_SELECTION
*/
public static final int ACTION_SET_SELECTION = 0x00020000;
/**
* Action to expand an expandable node.
* @see AccessibilityActionCompat#ACTION_EXPAND
*/
public static final int ACTION_EXPAND = 0x00040000;
/**
* Action to collapse an expandable node.
* @see AccessibilityActionCompat#ACTION_COLLAPSE
*/
public static final int ACTION_COLLAPSE = 0x00080000;
/**
* Action to dismiss a dismissible node.
* @see AccessibilityActionCompat#ACTION_DISMISS
*/
public static final int ACTION_DISMISS = 0x00100000;
/**
* Action that sets the text of the node. Performing the action without argument, using <code>
* null</code> or empty {@link CharSequence} will clear the text. This action will also put the
* cursor at the end of text.
* <p>
* <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
* <strong>Example:</strong>
* <code><pre><p>
* Bundle arguments = new Bundle();
* arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
* "android");
* info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
* </code></pre></p>
* @see AccessibilityActionCompat#ACTION_SET_TEXT
*/
public static final int ACTION_SET_TEXT = 0x00200000;
// Action arguments
/**
* Argument for which movement granularity to be used when traversing the node text.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY},
* {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
* </p>
*/
public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT =
"ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
/**
* Argument for which HTML element to get moving to the next/previous HTML element.
* <p>
* <strong>Type:</strong> String<br>
* <strong>Actions:</strong> {@link AccessibilityActionCompat#ACTION_NEXT_HTML_ELEMENT},
* {@link AccessibilityActionCompat#ACTION_PREVIOUS_HTML_ELEMENT}
* </p>
*/
public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING =
"ACTION_ARGUMENT_HTML_ELEMENT_STRING";
/**
* Argument for whether when moving at granularity to extend the selection
* or to move it otherwise.
* <p>
* <strong>Type:</strong> boolean<br>
* <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY},
* {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
* </p>
*
* @see AccessibilityActionCompat#ACTION_NEXT_AT_MOVEMENT_GRANULARITY
* @see AccessibilityActionCompat#ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
*/
public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN =
"ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
/**
* Argument for specifying the selection start.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong> {@link #ACTION_SET_SELECTION}
* </p>
*
* @see AccessibilityActionCompat#ACTION_SET_SELECTION
*/
public static final String ACTION_ARGUMENT_SELECTION_START_INT =
"ACTION_ARGUMENT_SELECTION_START_INT";
/**
* Argument for specifying the selection end.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong> {@link #ACTION_SET_SELECTION}
* </p>
*
* @see AccessibilityActionCompat#ACTION_SET_SELECTION
*/
public static final String ACTION_ARGUMENT_SELECTION_END_INT =
"ACTION_ARGUMENT_SELECTION_END_INT";
/**
* Argument for specifying the text content to set
* <p>
* <strong>Type:</strong> CharSequence<br>
* <strong>Actions:</strong> {@link #ACTION_SET_TEXT}
* </p>
*
* @see AccessibilityActionCompat#ACTION_SET_TEXT
*/
public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
"ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
/**
* Argument for specifying the collection row to make visible on screen.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong>
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li>
* </ul>
*
* @see AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION
*/
public static final String ACTION_ARGUMENT_ROW_INT =
"android.view.accessibility.action.ARGUMENT_ROW_INT";
/**
* Argument for specifying the collection column to make visible on screen.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong>
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li>
* </ul>
*
* @see AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION
*/
public static final String ACTION_ARGUMENT_COLUMN_INT =
"android.view.accessibility.action.ARGUMENT_COLUMN_INT";
/**
* Argument for specifying the progress value to set.
* <p>
* <strong>Type:</strong> float<br>
* <strong>Actions:</strong>
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_SET_PROGRESS}</li>
* </ul>
*
* @see AccessibilityActionCompat#ACTION_SET_PROGRESS
*/
public static final String ACTION_ARGUMENT_PROGRESS_VALUE =
"android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
/**
* Argument for specifying the x coordinate to which to move a window.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong>
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_MOVE_WINDOW}</li>
* </ul>
*
* @see AccessibilityActionCompat#ACTION_MOVE_WINDOW
*/
public static final String ACTION_ARGUMENT_MOVE_WINDOW_X =
"ACTION_ARGUMENT_MOVE_WINDOW_X";
/**
* Argument for specifying the y coordinate to which to move a window.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong>
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_MOVE_WINDOW}</li>
* </ul>
*
* @see AccessibilityActionCompat#ACTION_MOVE_WINDOW
*/
public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y =
"ACTION_ARGUMENT_MOVE_WINDOW_Y";
/**
* Argument to represent the duration in milliseconds to press and hold a node.
* <p>
* <strong>Type:</strong> int<br>
* <strong>Actions:</strong>
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_PRESS_AND_HOLD}</li>
* </ul>
*
* @see AccessibilityActionCompat#ACTION_PRESS_AND_HOLD
*/
@SuppressLint("ActionValue")
public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT =
"android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
/**
* <p>Argument to represent the direction when using
* {@link AccessibilityActionCompat#ACTION_SCROLL_IN_DIRECTION}.</p>
*
* <p>
* The value of this argument can be one of:
* <ul>
* <li>{@link View#FOCUS_DOWN}</li>
* <li>{@link View#FOCUS_UP}</li>
* <li>{@link View#FOCUS_LEFT}</li>
* <li>{@link View#FOCUS_RIGHT}</li>
* <li>{@link View#FOCUS_FORWARD}</li>
* <li>{@link View#FOCUS_BACKWARD}</li>
* </ul>
* </p>
*/
public static final String ACTION_ARGUMENT_DIRECTION_INT =
"androidx.core.view.accessibility.action.ARGUMENT_DIRECTION_INT";
/**
* <p>Argument to represent the scroll amount as a percent of the visible area of a node, with
* 1.0F as the default. Values smaller than 1.0F represent a partial scroll of the node, and
* values larger than 1.0F represent a scroll that extends beyond the currently visible node
* Rect. Setting this to {@link Float#POSITIVE_INFINITY} or to another "too large" value should
* scroll to the end of the node. Negative values should not be used with this argument.
* </p>
*
* <p>
* This argument should be used with the following scroll actions:
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_FORWARD}</li>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_BACKWARD}</li>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_UP}</li>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_DOWN}</li>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_LEFT}</li>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_RIGHT}</li>
* </ul>
* </p>
* <p>
* Example: if a view representing a list of items implements
* {@link AccessibilityActionCompat#ACTION_SCROLL_FORWARD} to scroll forward by an entire
* screen
* (one "page"), then passing a value of .25F via this argument should scroll that view
* only by 1/4th of a screen. Passing a value of 1.50F via this argument should scroll the
* view by 1 1/2 screens or to end of the node if the node doesn't extend to 1 1/2 screens.
* </p>
*
* <p>
* This argument should not be used with the following scroll actions, which don't cleanly
* conform to granular scroll semantics:
* <ul>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_IN_DIRECTION}</li>
* <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li>
* </ul>
* </p>
*
* <p>
* Views that support this argument should set
* {@link #setGranularScrollingSupported(boolean)} to true. Clients should use
* {@link #isGranularScrollingSupported()} to check if granular scrolling is supported.
* </p>
*/
public static final String ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT =
"androidx.core.view.accessibility.action.ARGUMENT_SCROLL_AMOUNT_FLOAT";
// Focus types
/**
* The input focus.
*/
public static final int FOCUS_INPUT = 1;
/**
* The accessibility focus.
*/
public static final int FOCUS_ACCESSIBILITY = 2;
// Movement granularities
/**
* Movement granularity bit for traversing the text of a node by character.
*/
public static final int MOVEMENT_GRANULARITY_CHARACTER = 0x00000001;
/**
* Movement granularity bit for traversing the text of a node by word.
*/
public static final int MOVEMENT_GRANULARITY_WORD = 0x00000002;
/**
* Movement granularity bit for traversing the text of a node by line.
*/
public static final int MOVEMENT_GRANULARITY_LINE = 0x00000004;
/**
* Movement granularity bit for traversing the text of a node by paragraph.
*/
public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 0x00000008;
/**
* Movement granularity bit for traversing the text of a node by page.
*/
public static final int MOVEMENT_GRANULARITY_PAGE = 0x00000010;
/**
* Key used to request and locate extra data for text character location. This key requests that
* an array of {@link android.graphics.RectF}s be added to the extras. This request is made with
* {@link #refreshWithExtraData(String, Bundle)}. The arguments taken by this request are two
* integers: {@link #EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX} and
* {@link #EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH}. The starting index must be valid
* inside the CharSequence returned by {@link #getText()}, and the length must be positive.
* <p>
* The data can be retrieved from the {@code Bundle} returned by {@link #getExtras()} using this
* string as a key for {@link Bundle#getParcelableArray(String)}. The
* {@link android.graphics.RectF} will be null for characters that either do not exist or are
* off the screen.
*
* {@see #refreshWithExtraData(String, Bundle)}
*/
@SuppressWarnings("ActionValue")
public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY =
"android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY";
/**
* Integer argument specifying the start index of the requested text location data. Must be
* valid inside the CharSequence returned by {@link #getText()}.
*
* @see #EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
*/
@SuppressWarnings("ActionValue")
public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX =
"android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX";
/**
* Integer argument specifying the end index of the requested text location data. Must be
* positive and no larger than {@link #EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH}.
*
* @see #EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
*/
@SuppressWarnings("ActionValue")
public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH =
"android.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH";
/**
* The maximum allowed length of the requested text location data.
*/
public static final int EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_MAX_LENGTH = 20000;
/**
* Prefetching strategy that prefetches the ancestors of the requested node.
* <p> Ancestors will be prefetched before siblings and descendants.
*
* @see #getChild(int, int)
* @see #getParent(int)
* @see AccessibilityWindowInfoCompat#getRoot(int)
* @see AccessibilityService#getRootInActiveWindow(int)
* @see AccessibilityEvent#getSource(int)
*/
public static final int FLAG_PREFETCH_ANCESTORS = 0x00000001;
/**
* Prefetching strategy that prefetches the siblings of the requested node.
* <p> To avoid disconnected trees, this flag will also prefetch the parent. Siblings will be
* prefetched before descendants.
*
* @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
*/
public static final int FLAG_PREFETCH_SIBLINGS = 0x00000002;
/**
* Prefetching strategy that prefetches the descendants in a hybrid depth first and breadth
* first approach.
* <p> The children of the root node is prefetched before recursing on the children. This
* must not be combined with {@link #FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST} or
* {@link #FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST} or this will trigger an
* IllegalArgumentException.
*
* @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
*/
public static final int FLAG_PREFETCH_DESCENDANTS_HYBRID = 0x00000004;
/**
* Prefetching strategy that prefetches the descendants of the requested node depth-first.
* <p> This must not be combined with {@link #FLAG_PREFETCH_DESCENDANTS_HYBRID} or
* {@link #FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST} or this will trigger an
* IllegalArgumentException.
*
* @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
*/
public static final int FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST = 0x00000008;
/**
* Prefetching strategy that prefetches the descendants of the requested node breadth-first.
* <p> This must not be combined with {@link #FLAG_PREFETCH_DESCENDANTS_HYBRID} or
* {@link #FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST} or this will trigger an
* IllegalArgumentException.
*
* @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
*/
public static final int FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST = 0x00000010;
/**
* Prefetching flag that specifies prefetching should not be interrupted by a request to
* retrieve a node or perform an action on a node.
*
* @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
*/
public static final int FLAG_PREFETCH_UNINTERRUPTIBLE = 0x00000020;
/**
* Maximum batch size of prefetched nodes for a request.
*/
@SuppressLint("MinMaxConstant")
public static final int MAX_NUMBER_OF_PREFETCHED_NODES = 50;
private static int sClickableSpanId = 0;
/**
* Creates a wrapper for info implementation.
*
* @param object The info to wrap.
* @return A wrapper for if the object is not null, null otherwise.
*/
@SuppressWarnings("deprecation")
static AccessibilityNodeInfoCompat wrapNonNullInstance(Object object) {
if (object != null) {
return new AccessibilityNodeInfoCompat(object);
}
return null;
}
/**
* Creates a new instance wrapping an
* {@link android.view.accessibility.AccessibilityNodeInfo}.
*
* @param info The info.
*
* @deprecated Use {@link #wrap(AccessibilityNodeInfo)} instead.
*/
@Deprecated
public AccessibilityNodeInfoCompat(Object info) {
mInfo = (AccessibilityNodeInfo) info;
}
private AccessibilityNodeInfoCompat(AccessibilityNodeInfo info) {
mInfo = info;
}
/**
* Creates a new instance wrapping an
* {@link android.view.accessibility.AccessibilityNodeInfo}.
*
* @param info The info.
*/
public static AccessibilityNodeInfoCompat wrap(@NonNull AccessibilityNodeInfo info) {
return new AccessibilityNodeInfoCompat(info);
}
/**
* @return The unwrapped {@link android.view.accessibility.AccessibilityNodeInfo}.
*/
public AccessibilityNodeInfo unwrap() {
return mInfo;
}
/**
* @return The wrapped {@link android.view.accessibility.AccessibilityNodeInfo}.
*
* @deprecated Use {@link #unwrap()} instead.
*/
@Deprecated
public Object getInfo() {
return mInfo;
}
/**
* Returns a cached instance if such is available otherwise a new one and
* sets the source.
*
* @return An instance.
* @see #setSource(View)
*/
public static AccessibilityNodeInfoCompat obtain(View source) {
return AccessibilityNodeInfoCompat.wrap(AccessibilityNodeInfo.obtain(source));
}
/**
* Returns a cached instance if such is available otherwise a new one
* and sets the source.
*
* @param root The root of the virtual subtree.
* @param virtualDescendantId The id of the virtual descendant.
* @return An instance.
*
* @see #setSource(View, int)
*/
public static AccessibilityNodeInfoCompat obtain(View root, int virtualDescendantId) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(
AccessibilityNodeInfo.obtain(root, virtualDescendantId));
}
/**
* Returns a cached instance if such is available otherwise a new one.
*
* @return An instance.
*/
public static AccessibilityNodeInfoCompat obtain() {
return AccessibilityNodeInfoCompat.wrap(AccessibilityNodeInfo.obtain());
}
/**
* Returns a cached instance if such is available or a new one is create.
* The returned instance is initialized from the given <code>info</code>.
*
* @param info The other info.
* @return An instance.
*/
public static AccessibilityNodeInfoCompat obtain(AccessibilityNodeInfoCompat info) {
return AccessibilityNodeInfoCompat.wrap(AccessibilityNodeInfo.obtain(info.mInfo));
}
/**
* Sets the source.
*
* @param source The info source.
*/
public void setSource(View source) {
mVirtualDescendantId = NO_ID;
mInfo.setSource(source);
}
/**
* Sets the source to be a virtual descendant of the given <code>root</code>.
* If <code>virtualDescendantId</code> is {@link View#NO_ID} the root
* is set as the source.
* <p>
* A virtual descendant is an imaginary View that is reported as a part of the view
* hierarchy for accessibility purposes. This enables custom views that draw complex
* content to report themselves as a tree of virtual views, thus conveying their
* logical structure.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* <p>
* This method is not supported on devices running API level < 16 since the platform did
* not support virtual descendants of real views.
*
* @param root The root of the virtual subtree.
* @param virtualDescendantId The id of the virtual descendant.
*/
public void setSource(View root, int virtualDescendantId) {
// Store the ID anyway, since we may need it for equality checks.
mVirtualDescendantId = virtualDescendantId;
mInfo.setSource(root, virtualDescendantId);
}
/**
* Find the view that has the specified focus type. The search starts from
* the view represented by this node info.
*
* @param focus The focus to find. One of {@link #FOCUS_INPUT} or
* {@link #FOCUS_ACCESSIBILITY}.
* @return The node info of the focused view or null.
*
* @see #FOCUS_INPUT
* @see #FOCUS_ACCESSIBILITY
*/
public AccessibilityNodeInfoCompat findFocus(int focus) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.findFocus(focus));
}
/**
* Searches for the nearest view in the specified direction that can take
* input focus.
*
* @param direction The direction. 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}.
*
* @return The node info for the view that can take accessibility focus.
*/
public AccessibilityNodeInfoCompat focusSearch(int direction) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.focusSearch(direction));
}
/**
* Gets the id of the window from which the info comes from.
*
* @return The window id.
*/
public int getWindowId() {
return mInfo.getWindowId();
}
/**
* Gets the number of children.
*
* @return The child count.
*/
public int getChildCount() {
return mInfo.getChildCount();
}
/**
* Get the child at given index.
*
* @param index The child index.
* @return The child node.
* @throws IllegalStateException If called outside of an
* AccessibilityService.
*/
public AccessibilityNodeInfoCompat getChild(int index) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getChild(index));
}
/**
* Get the child at given index.
*
* @param index The child index.
* @param prefetchingStrategy the prefetching strategy.
* @return The child node.
*
* @throws IllegalStateException If called outside of an {@link AccessibilityService} and before
* calling {@link #setQueryFromAppProcessEnabled}.
*
* @see AccessibilityNodeInfoCompat#getParent(int) for a description of prefetching.
*/
@Nullable
public AccessibilityNodeInfoCompat getChild(int index, int prefetchingStrategy) {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.getChild(mInfo, index, prefetchingStrategy);
}
return getChild(index);
}
/**
* Adds a child.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param child The child.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void addChild(View child) {
mInfo.addChild(child);
}
/**
* Adds a virtual child which is a descendant of the given <code>root</code>.
* If <code>virtualDescendantId</code> is {@link View#NO_ID} the root
* is added as a child.
* <p>
* A virtual descendant is an imaginary View that is reported as a part of the view
* hierarchy for accessibility purposes. This enables custom views that draw complex
* content to report them selves as a tree of virtual views, thus conveying their
* logical structure.
* </p>
*
* @param root The root of the virtual subtree.
* @param virtualDescendantId The id of the virtual child.
*/
public void addChild(View root, int virtualDescendantId) {
mInfo.addChild(root, virtualDescendantId);
}
/**
* Removes a child. If the child was not previously added to the node,
* calling this method has no effect.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param child The child.
* @return true if the child was present
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public boolean removeChild(View child) {
if (Build.VERSION.SDK_INT >= 21) {
return mInfo.removeChild(child);
} else {
return false;
}
}
/**
* Removes a virtual child which is a descendant of the given
* <code>root</code>. If the child was not previously added to the node,
* calling this method has no effect.
*
* @param root The root of the virtual subtree.
* @param virtualDescendantId The id of the virtual child.
* @return true if the child was present
* @see #addChild(View, int)
*/
public boolean removeChild(View root, int virtualDescendantId) {
if (Build.VERSION.SDK_INT >= 21) {
return mInfo.removeChild(root, virtualDescendantId);
} else {
return false;
}
}
/**
* Gets the actions that can be performed on the node.
*
* @return The bit mask of with actions.
* @see android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS
* @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_FOCUS
* @see android.view.accessibility.AccessibilityNodeInfo#ACTION_SELECT
* @see android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_SELECTION
*
* @deprecated Use {@link #getActionList()} instead.
*/
@Deprecated
public int getActions() {
return mInfo.getActions();
}
/**
* Adds an action that can be performed on the node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param action The action.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void addAction(int action) {
mInfo.addAction(action);
}
private List<Integer> extrasIntList(String key) {
ArrayList<Integer> list = mInfo.getExtras()
.getIntegerArrayList(key);
if (list == null) {
list = new ArrayList<Integer>();
mInfo.getExtras().putIntegerArrayList(key, list);
}
return list;
}
/**
* Adds an action that can be performed on the node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param action The action.
* @throws IllegalStateException If called from an AccessibilityService.
* <p>
* Compatibility:
* <ul>
* <li>API < 21: No-op</li>
* </ul>
*/
public void addAction(AccessibilityActionCompat action) {
if (Build.VERSION.SDK_INT >= 21) {
mInfo.addAction((AccessibilityNodeInfo.AccessibilityAction) action.mAction);
}
}
/**
* Removes an action that can be performed on the node. If the action was
* not already added to the node, calling this method has no effect.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param action The action to be removed.
* @return The action removed from the list of actions.
*
* @throws IllegalStateException If called from an AccessibilityService.
* <p>
* Compatibility:
* <ul>
* <li>API < 21: Always returns {@code false}</li>
* </ul>
*/
public boolean removeAction(AccessibilityActionCompat action) {
if (Build.VERSION.SDK_INT >= 21) {
return mInfo.removeAction((AccessibilityNodeInfo.AccessibilityAction) action.mAction);
} else {
return false;
}
}
/**
* Performs an action on the node.
* <p>
* <strong>Note:</strong> An action can be performed only if the request is
* made from an {@link android.accessibilityservice.AccessibilityService}.
* </p>
*
* @param action The action to perform.
* @return True if the action was performed.
* @throws IllegalStateException If called outside of an
* AccessibilityService.
*/
public boolean performAction(int action) {
return mInfo.performAction(action);
}
/**
* Performs an action on the node.
* <p>
* <strong>Note:</strong> An action can be performed only if the request is made
* from an {@link android.accessibilityservice.AccessibilityService}.
* </p>
*
* @param action The action to perform.
* @param arguments A bundle with additional arguments.
* @return True if the action was performed.
*
* @throws IllegalStateException If called outside of an AccessibilityService.
*/
public boolean performAction(int action, Bundle arguments) {
return mInfo.performAction(action, arguments);
}
/**
* Sets the movement granularities for traversing the text of this node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param granularities The bit mask with granularities.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setMovementGranularities(int granularities) {
mInfo.setMovementGranularities(granularities);
}
/**
* Gets the movement granularities for traversing the text of this node.
*
* @return The bit mask with granularities.
*/
public int getMovementGranularities() {
return mInfo.getMovementGranularities();
}
/**
* Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by text. The match
* is case insensitive containment. The search is relative to this info i.e. this
* info is the root of the traversed tree.
*
* @param text The searched text.
* @return A list of node info.
*/
public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text) {
List<AccessibilityNodeInfoCompat> result = new ArrayList<AccessibilityNodeInfoCompat>();
List<AccessibilityNodeInfo> infos = mInfo.findAccessibilityNodeInfosByText(text);
final int infoCount = infos.size();
for (int i = 0; i < infoCount; i++) {
AccessibilityNodeInfo info = infos.get(i);
result.add(AccessibilityNodeInfoCompat.wrap(info));
}
return result;
}
/**
* Gets the parent.
*
* @return The parent.
*/
public AccessibilityNodeInfoCompat getParent() {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getParent());
}
/**
* Gets the parent.
*
* <p>
* Use {@code prefetchingStrategy} to determine the types of
* nodes prefetched from the app if the requested node is not in the cache and must be retrieved
* by the app. The default strategy for {@link #getParent()} is a combination of ancestor and
* sibling strategies. The app will prefetch until all nodes fulfilling the strategies are
* fetched, another node request is sent, or the maximum prefetch batch size of
* {@link #MAX_NUMBER_OF_PREFETCHED_NODES} nodes is reached. To prevent interruption by another
* request and to force prefetching of the max batch size, use
* {@link AccessibilityNodeInfoCompat#FLAG_PREFETCH_UNINTERRUPTIBLE}.
* </p>
*
* @param prefetchingStrategy the prefetching strategy.
* @return The parent.
*
* @throws IllegalStateException If called outside of an {@link AccessibilityService} and before
* calling {@link #setQueryFromAppProcessEnabled}.
*
* @see #FLAG_PREFETCH_ANCESTORS
* @see #FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST
* @see #FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST
* @see #FLAG_PREFETCH_DESCENDANTS_HYBRID
* @see #FLAG_PREFETCH_SIBLINGS
* @see #FLAG_PREFETCH_UNINTERRUPTIBLE
*/
@Nullable
public AccessibilityNodeInfoCompat getParent(int prefetchingStrategy) {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.getParent(mInfo, prefetchingStrategy);
}
return getParent();
}
/**
* Sets the parent.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param parent The parent.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setParent(View parent) {
mParentVirtualDescendantId = NO_ID;
mInfo.setParent(parent);
}
/**
* Sets the parent to be a virtual descendant of the given <code>root</code>.
* If <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root
* is set as the parent.
* <p>
* A virtual descendant is an imaginary View that is reported as a part of the view
* hierarchy for accessibility purposes. This enables custom views that draw complex
* content to report them selves as a tree of virtual views, thus conveying their
* logical structure.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* <p>
* This method is not supported on devices running API level < 16 since the platform did
* not support virtual descendants of real views.
*
* @param root The root of the virtual subtree.
* @param virtualDescendantId The id of the virtual descendant.
*/
public void setParent(View root, int virtualDescendantId) {
// Store the ID anyway, since we may need it for equality checks.
mParentVirtualDescendantId = virtualDescendantId;
mInfo.setParent(root, virtualDescendantId);
}
/**
* Gets the node bounds in the viewParent's coordinates.
* {@link #getParent()} does not represent the source's viewParent.
* Instead it represents the result of {@link View#getParentForAccessibility()},
* which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true.
* So this method is not reliable.
*
* @param outBounds The output node bounds.
*
* @deprecated Use {@link #getBoundsInScreen(Rect)} instead.
*/
@Deprecated
public void getBoundsInParent(Rect outBounds) {
mInfo.getBoundsInParent(outBounds);
}
/**
* Sets the node bounds in the viewParent's coordinates.
* {@link #getParent()} does not represent the source's viewParent.
* Instead it represents the result of {@link View#getParentForAccessibility()},
* which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true.
* So this method is not reliable.
*
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param bounds The node bounds.
* @throws IllegalStateException If called from an AccessibilityService.
*
* @deprecated Accessibility services should not care about these bounds.
*/
@Deprecated
public void setBoundsInParent(Rect bounds) {
mInfo.setBoundsInParent(bounds);
}
/**
* Gets the node bounds in screen coordinates.
*
* @param outBounds The output node bounds.
*/
public void getBoundsInScreen(Rect outBounds) {
mInfo.getBoundsInScreen(outBounds);
}
/**
* Sets the node bounds in screen coordinates.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param bounds The node bounds.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setBoundsInScreen(Rect bounds) {
mInfo.setBoundsInScreen(bounds);
}
/**
* Gets the node bounds in window coordinates.
* <p>
* When magnification is enabled, the bounds in window are scaled up by magnification scale
* and the positions are also adjusted according to the offset of magnification viewport.
* For example, it returns Rect(-180, -180, 0, 0) for original bounds Rect(10, 10, 100, 100),
* when the magnification scale is 2 and offsets for X and Y are both 200.
* <p/>
* <p>
* Compatibility:
* <ul>
* <li>API < 19: No-op</li>
* </ul>
* @param outBounds The output node bounds.
*/
public void getBoundsInWindow(@NonNull Rect outBounds) {
if (Build.VERSION.SDK_INT >= 34) {
Api34Impl.getBoundsInWindow(mInfo, outBounds);
} else {
Rect extraBounds = mInfo.getExtras().getParcelable(BOUNDS_IN_WINDOW_KEY);
if (extraBounds != null) {
outBounds.set(extraBounds.left, extraBounds.top, extraBounds.right,
extraBounds.bottom);
}
}
}
/**
* Sets the node bounds in window coordinates.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>API < 19: No-op</li>
* </ul>
* @param bounds The node bounds.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setBoundsInWindow(@NonNull Rect bounds) {
if (Build.VERSION.SDK_INT >= 34) {
Api34Impl.setBoundsInWindow(mInfo, bounds);
} else {
mInfo.getExtras().putParcelable(BOUNDS_IN_WINDOW_KEY, bounds);
}
}
/**
* Gets whether this node is checkable.
*
* @return True if the node is checkable.
*/
public boolean isCheckable() {
return mInfo.isCheckable();
}
/**
* Sets whether this node is checkable.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param checkable True if the node is checkable.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setCheckable(boolean checkable) {
mInfo.setCheckable(checkable);
}
/**
* Gets whether this node is checked.
*
* @return True if the node is checked.
*/
public boolean isChecked() {
return mInfo.isChecked();
}
/**
* Sets whether this node is checked.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param checked True if the node is checked.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setChecked(boolean checked) {
mInfo.setChecked(checked);
}
/**
* Gets whether this node is focusable.
*
* @return True if the node is focusable.
*/
public boolean isFocusable() {
return mInfo.isFocusable();
}
/**
* Sets whether this node is focusable.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param focusable True if the node is focusable.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setFocusable(boolean focusable) {
mInfo.setFocusable(focusable);
}
/**
* Gets whether this node is focused.
*
* @return True if the node is focused.
*/
public boolean isFocused() {
return mInfo.isFocused();
}
/**
* Sets whether this node is focused.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param focused True if the node is focused.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setFocused(boolean focused) {
mInfo.setFocused(focused);
}
/**
* Gets whether this node is visible to the user.
*
* @return Whether the node is visible to the user.
*/
public boolean isVisibleToUser() {
return mInfo.isVisibleToUser();
}
/**
* Sets whether this node is visible to the user.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param visibleToUser Whether the node is visible to the user.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setVisibleToUser(boolean visibleToUser) {
mInfo.setVisibleToUser(visibleToUser);
}
/**
* Gets whether this node is accessibility focused.
*
* @return True if the node is accessibility focused.
*/
public boolean isAccessibilityFocused() {
return mInfo.isAccessibilityFocused();
}
/**
* Sets whether this node is accessibility focused.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param focused True if the node is accessibility focused.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setAccessibilityFocused(boolean focused) {
mInfo.setAccessibilityFocused(focused);
}
/**
* Gets whether this node is selected.
*
* @return True if the node is selected.
*/
public boolean isSelected() {
return mInfo.isSelected();
}
/**
* Sets whether this node is selected.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param selected True if the node is selected.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setSelected(boolean selected) {
mInfo.setSelected(selected);
}
/**
* Gets whether this node is clickable.
*
* @return True if the node is clickable.
*/
public boolean isClickable() {
return mInfo.isClickable();
}
/**
* Sets whether this node is clickable.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param clickable True if the node is clickable.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setClickable(boolean clickable) {
mInfo.setClickable(clickable);
}
/**
* Gets whether this node is long clickable.
*
* @return True if the node is long clickable.
*/
public boolean isLongClickable() {
return mInfo.isLongClickable();
}
/**
* Sets whether this node is long clickable.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param longClickable True if the node is long clickable.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setLongClickable(boolean longClickable) {
mInfo.setLongClickable(longClickable);
}
/**
* Gets whether this node is enabled.
*
* @return True if the node is enabled.
*/
public boolean isEnabled() {
return mInfo.isEnabled();
}
/**
* Sets whether this node is enabled.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param enabled True if the node is enabled.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setEnabled(boolean enabled) {
mInfo.setEnabled(enabled);
}
/**
* Gets whether this node is a password.
*
* @return True if the node is a password.
*/
public boolean isPassword() {
return mInfo.isPassword();
}
/**
* Sets whether this node is a password.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param password True if the node is a password.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setPassword(boolean password) {
mInfo.setPassword(password);
}
/**
* Gets if the node is scrollable.
*
* @return True if the node is scrollable, false otherwise.
*/
public boolean isScrollable() {
return mInfo.isScrollable();
}
/**
* Sets if the node is scrollable.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param scrollable True if the node is scrollable, false otherwise.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setScrollable(boolean scrollable) {
mInfo.setScrollable(scrollable);
}
/**
* Gets if the node supports granular scrolling.
* <p>
* Compatibility:
* <ul>
* <li>Api < 19: Returns false.</li>
* </ul>
* @return True if all scroll actions that could support
* {@link #ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT} have done so, false otherwise.
*/
public boolean isGranularScrollingSupported() {
return getBooleanProperty(BOOLEAN_PROPERTY_SUPPORTS_GRANULAR_SCROLLING);
}
/**
* Sets if the node supports granular scrolling. This should be set to true if all scroll
* actions which could support {@link #ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT} have done so.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>Api < 19: No-op.</li>
* </ul>
* @param granularScrollingSupported True if the node supports granular scrolling, false
* otherwise.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setGranularScrollingSupported(boolean granularScrollingSupported) {
setBooleanProperty(BOOLEAN_PROPERTY_SUPPORTS_GRANULAR_SCROLLING,
granularScrollingSupported);
}
/**
* Gets if the node has selectable text.
*
* <p>
* Services should use {@link #ACTION_SET_SELECTION} for selection. Editable text nodes must
* also be selectable. But not all UIs will populate this field, so services should consider
* 'isTextSelectable | isEditable' to ensure they don't miss nodes with selectable text.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>Api < 19: Returns false.</li>
* </ul>
*
* @see #isEditable
* @return True if the node has selectable text.
*/
public boolean isTextSelectable() {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.isTextSelectable(mInfo);
} else {
return getBooleanProperty(BOOLEAN_PROPERTY_TEXT_SELECTABLE);
}
}
/**
* Sets if the node has selectable text.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>Api < 19: Does not operate.</li>
* </ul>
* </p>
*
* @param selectableText True if the node has selectable text, false otherwise.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setTextSelectable(boolean selectableText) {
if (Build.VERSION.SDK_INT >= 33) {
Api33Impl.setTextSelectable(mInfo, selectableText);
} else {
setBooleanProperty(BOOLEAN_PROPERTY_TEXT_SELECTABLE, selectableText);
}
}
/**
* Gets the minimum time duration between two content change events.
*/
public long getMinDurationBetweenContentChangesMillis() {
if (Build.VERSION.SDK_INT >= 34) {
return Api34Impl.getMinDurationBetweenContentChangeMillis(mInfo);
} else {
return mInfo.getExtras().getLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY);
}
}
/**
* Sets the minimum time duration between two content change events, which is used in throttling
* content change events in accessibility services.
*
* <p>
* Example: An app can set MinDurationBetweenContentChanges as 1 min for a view which sends
* content change events to accessibility services one event per second.
* Accessibility service will throttle those content change events and only handle one event
* per minute for that view.
* </p>
*
* @see AccessibilityEventCompat#getContentChangeTypes for all content change types.
* @param duration the minimum duration between content change events.
*/
public void setMinDurationBetweenContentChangesMillis(long duration) {
if (Build.VERSION.SDK_INT >= 34) {
Api34Impl.setMinDurationBetweenContentChangeMillis(mInfo, duration);
} else {
mInfo.getExtras().putLong(MIN_DURATION_BETWEEN_CONTENT_CHANGES_KEY, duration);
}
}
/**
* Returns whether the node originates from a view considered important for accessibility.
*
* @return {@code true} if the node originates from a view considered important for
* accessibility, {@code false} otherwise
*
* @see View#isImportantForAccessibility()
*/
public boolean isImportantForAccessibility() {
if (Build.VERSION.SDK_INT >= 24) {
return mInfo.isImportantForAccessibility();
} else {
return true;
}
}
/**
* Sets whether the node is considered important for accessibility.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param important {@code true} if the node is considered important for accessibility,
* {@code false} otherwise
*/
public void setImportantForAccessibility(boolean important) {
if (Build.VERSION.SDK_INT >= 24) {
mInfo.setImportantForAccessibility(important);
}
}
/**
* Gets if the node's accessibility data is considered sensitive.
*
* @return True if the node's data is considered sensitive, false otherwise.
* @see View#isAccessibilityDataSensitive()
*/
public boolean isAccessibilityDataSensitive() {
if (Build.VERSION.SDK_INT >= 34) {
return Api34Impl.isAccessibilityDataSensitive(mInfo);
} else {
return getBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE);
}
}
/**
* Sets whether this node's accessibility data is considered sensitive.
*
* <p>
* For SDK 34 and higher: when set to true the framework will hide this node from
* accessibility services with the
* {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool}
* property set to false.
* </p>
* <p>
* Otherwise, for SDK 19 and higher: the framework cannot hide this node but this property may
* be read by accessibility services to provide modified behavior for sensitive nodes.
* </p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param accessibilityDataSensitive True if the node's accessibility data is considered
* sensitive.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setAccessibilityDataSensitive(boolean accessibilityDataSensitive) {
if (Build.VERSION.SDK_INT >= 34) {
Api34Impl.setAccessibilityDataSensitive(mInfo, accessibilityDataSensitive);
} else {
setBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE,
accessibilityDataSensitive);
}
}
/**
* Gets the package this node comes from.
*
* @return The package name.
*/
public CharSequence getPackageName() {
return mInfo.getPackageName();
}
/**
* Sets the package this node comes from.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param packageName The package name.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setPackageName(CharSequence packageName) {
mInfo.setPackageName(packageName);
}
/**
* Gets the class this node comes from.
*
* @return The class name.
*/
public CharSequence getClassName() {
return mInfo.getClassName();
}
/**
* Sets the class this node comes from.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param className The class name.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setClassName(CharSequence className) {
mInfo.setClassName(className);
}
/**
* Gets the text of this node.
*
* @return The text.
*/
public CharSequence getText() {
if (hasSpans()) {
List<Integer> starts = extrasIntList(SPANS_START_KEY);
List<Integer> ends = extrasIntList(SPANS_END_KEY);
List<Integer> flags = extrasIntList(SPANS_FLAGS_KEY);
List<Integer> ids = extrasIntList(SPANS_ID_KEY);
Spannable spannable = new SpannableString(TextUtils.substring(mInfo.getText(),
0, mInfo.getText().length()));
for (int i = 0; i < starts.size(); i++) {
spannable.setSpan(new AccessibilityClickableSpanCompat(ids.get(i), this,
getExtras().getInt(SPANS_ACTION_ID_KEY)),
starts.get(i), ends.get(i), flags.get(i));
}
return spannable;
} else {
return mInfo.getText();
}
}
/**
* Sets the text of this node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param text The text.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setText(CharSequence text) {
mInfo.setText(text);
}
/**
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public void addSpansToExtras(CharSequence text, View view) {
if (Build.VERSION.SDK_INT < 26) {
clearExtrasSpans();
removeCollectedSpans(view);
ClickableSpan[] spans = getClickableSpans(text);
if (spans != null && spans.length > 0) {
getExtras().putInt(SPANS_ACTION_ID_KEY, R.id.accessibility_action_clickable_span);
SparseArray<WeakReference<ClickableSpan>> tagSpans =
getOrCreateSpansFromViewTags(view);
for (int i = 0; spans != null && i < spans.length; i++) {
int id = idForClickableSpan(spans[i], tagSpans);
tagSpans.put(id, new WeakReference<>(spans[i]));
addSpanLocationToExtras(spans[i], (Spanned) text, id);
}
}
}
}
private SparseArray<WeakReference<ClickableSpan>> getOrCreateSpansFromViewTags(View host) {
SparseArray<WeakReference<ClickableSpan>> spans = getSpansFromViewTags(host);
if (spans == null) {
spans = new SparseArray<>();
host.setTag(R.id.tag_accessibility_clickable_spans, spans);
}
return spans;
}
@SuppressWarnings("unchecked")
private SparseArray<WeakReference<ClickableSpan>> getSpansFromViewTags(View host) {
return (SparseArray<WeakReference<ClickableSpan>>) host.getTag(
R.id.tag_accessibility_clickable_spans);
}
/**
*/
@RestrictTo(LIBRARY_GROUP_PREFIX)
public static ClickableSpan[] getClickableSpans(CharSequence text) {
if (text instanceof Spanned) {
Spanned spanned = (Spanned) text;
return spanned.getSpans(0, text.length(), ClickableSpan.class);
}
return null;
}
private int idForClickableSpan(ClickableSpan span,
SparseArray<WeakReference<ClickableSpan>> spans) {
if (spans != null) {
for (int i = 0; i < spans.size(); i++) {
ClickableSpan aSpan = spans.valueAt(i).get();
if (span.equals(aSpan)) {
return spans.keyAt(i);
}
}
}
return sClickableSpanId++;
}
private boolean hasSpans() {
return !extrasIntList(SPANS_START_KEY).isEmpty();
}
private void clearExtrasSpans() {
mInfo.getExtras().remove(SPANS_START_KEY);
mInfo.getExtras().remove(SPANS_END_KEY);
mInfo.getExtras().remove(SPANS_FLAGS_KEY);
mInfo.getExtras().remove(SPANS_ID_KEY);
}
private void addSpanLocationToExtras(ClickableSpan span, Spanned spanned, int id) {
extrasIntList(SPANS_START_KEY).add(spanned.getSpanStart(span));
extrasIntList(SPANS_END_KEY).add(spanned.getSpanEnd(span));
extrasIntList(SPANS_FLAGS_KEY).add(spanned.getSpanFlags(span));
extrasIntList(SPANS_ID_KEY).add(id);
}
private void removeCollectedSpans(View view) {
SparseArray<WeakReference<ClickableSpan>> spans = getSpansFromViewTags(view);
if (spans != null) {
List<Integer> toBeRemovedIndices = new ArrayList<>();
for (int i = 0; i < spans.size(); i++) {
if (spans.valueAt(i).get() == null) {
toBeRemovedIndices.add(i);
}
}
for (int i = 0; i < toBeRemovedIndices.size(); i++) {
spans.remove(toBeRemovedIndices.get(i));
}
}
}
/**
* Gets the content description of this node.
*
* @return The content description.
*/
public CharSequence getContentDescription() {
return mInfo.getContentDescription();
}
/**
* Gets the state description of this node.
*
* @return the state description or null if android version smaller
* than 19.
*/
public @Nullable CharSequence getStateDescription() {
if (Build.VERSION.SDK_INT >= 30) {
return Api30Impl.getStateDescription(mInfo);
} else {
return mInfo.getExtras().getCharSequence(STATE_DESCRIPTION_KEY);
}
}
/**
* Sets the content description of this node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param contentDescription The content description.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setContentDescription(CharSequence contentDescription) {
mInfo.setContentDescription(contentDescription);
}
/**
* Sets the state description of this node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param stateDescription the state description of this node.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setStateDescription(@Nullable CharSequence stateDescription) {
if (Build.VERSION.SDK_INT >= 30) {
Api30Impl.setStateDescription(mInfo, stateDescription);
} else {
mInfo.getExtras().putCharSequence(STATE_DESCRIPTION_KEY, stateDescription);
}
}
/**
* Gets the unique id of this node.
*
* @return the unique id or null if android version smaller
* than 19.
*/
public @Nullable String getUniqueId() {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.getUniqueId(mInfo);
} else {
return mInfo.getExtras().getString(UNIQUE_ID_KEY);
}
}
/**
* Sets the unique id of this node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param uniqueId the unique id of this node.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setUniqueId(@Nullable String uniqueId) {
if (Build.VERSION.SDK_INT >= 33) {
Api33Impl.setUniqueId(mInfo, uniqueId);
} else {
mInfo.getExtras().putString(UNIQUE_ID_KEY, uniqueId);
}
}
/**
* Sets the container title for app-developer-defined container which can be any type of
* ViewGroup or layout.
* Container title will be used to group together related controls, similar to HTML fieldset.
* Or container title may identify a large piece of the UI that is visibly grouped together,
* such as a toolbar or a card, etc.
* <p>
* Container title helps to assist in navigation across containers and other groups.
* For example, a screen reader may use this to determine where to put accessibility focus.
* </p>
* <p>
* Container title is different from pane title{@link #setPaneTitle} which indicates that the
* node represents a window or activity.
* </p>
*
* <p>
* Example: An app can set container titles on several non-modal menus, containing TextViews
* or ImageButtons that have content descriptions, text, etc. Screen readers can quickly
* switch accessibility focus among menus instead of child views. Other accessibility-services
* can easily find the menu.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>API < 19: No-op</li>
* </ul>
* @param containerTitle The container title that is associated with a ViewGroup/Layout on the
* screen.
*/
public void setContainerTitle(@Nullable CharSequence containerTitle) {
if (Build.VERSION.SDK_INT >= 34) {
Api34Impl.setContainerTitle(mInfo, containerTitle);
} else {
mInfo.getExtras().putCharSequence(CONTAINER_TITLE_KEY, containerTitle);
}
}
/**
* Returns the container title.
* <p>
* Compatibility:
* <ul>
* <li>API < 19: Returns null</li>
* </ul>
* @see #setContainerTitle for details.
*/
@Nullable
public CharSequence getContainerTitle() {
if (Build.VERSION.SDK_INT >= 34) {
return Api34Impl.getContainerTitle(mInfo);
} else {
return mInfo.getExtras().getCharSequence(CONTAINER_TITLE_KEY);
}
}
/**
* Return an instance back to be reused.
* <p>
* <strong>Note:</strong> You must not touch the object after calling this function.
*
* @throws IllegalStateException If the info is already recycled.
* @deprecated Accessibility Object recycling is no longer necessary or functional.
*/
@Deprecated
public void recycle() { }
/**
* Sets the fully qualified resource name of the source view's id.
*
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param viewId The id resource name.
*/
public void setViewIdResourceName(String viewId) {
mInfo.setViewIdResourceName(viewId);
}
/**
* Gets the fully qualified resource name of the source view's id.
*
* <p>
* <strong>Note:</strong> The primary usage of this API is for UI test automation
* and in order to report the source view id of an {@link AccessibilityNodeInfoCompat}
* the client has to set the {@link AccessibilityServiceInfoCompat#FLAG_REPORT_VIEW_IDS}
* flag when configuring their {@link android.accessibilityservice.AccessibilityService}.
* </p>
*
* @return The id resource name.
*/
public String getViewIdResourceName() {
return mInfo.getViewIdResourceName();
}
/**
* Gets the node's live region mode.
* <p>
* A live region is a node that contains information that is important for
* the user and when it changes the user should be notified. For example,
* in a login screen with a TextView that displays an "incorrect password"
* notification, that view should be marked as a live region with mode
* {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_POLITE}.
* <p>
* It is the responsibility of the accessibility service to monitor
* {@link AccessibilityEventCompat#TYPE_WINDOW_CONTENT_CHANGED} events
* indicating changes to live region nodes and their children.
*
* @return The live region mode, or
* {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_NONE} if the view is
* not a live region.
* @see ViewCompat#getAccessibilityLiveRegion(View)
*/
public int getLiveRegion() {
return mInfo.getLiveRegion();
}
/**
* Sets the node's live region mode.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is
* made immutable before being delivered to an AccessibilityService.
*
* @param mode The live region mode, or
* {@link ViewCompat#ACCESSIBILITY_LIVE_REGION_NONE} if the view is
* not a live region.
* @see ViewCompat#setAccessibilityLiveRegion(View, int)
*/
public void setLiveRegion(int mode) {
mInfo.setLiveRegion(mode);
}
/**
* Get the drawing order of the view corresponding it this node.
* <p>
* Drawing order is determined only within the node's parent, so this index is only relative
* to its siblings.
* <p>
* In some cases, the drawing order is essentially simultaneous, so it is possible for two
* siblings to return the same value. It is also possible that values will be skipped.
*
* @return The drawing position of the view corresponding to this node relative to its siblings.
*/
public int getDrawingOrder() {
if (Build.VERSION.SDK_INT >= 24) {
return mInfo.getDrawingOrder();
} else {
return 0;
}
}
/**
* Set the drawing order of the view corresponding it this node.
*
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
* @param drawingOrderInParent
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setDrawingOrder(int drawingOrderInParent) {
if (Build.VERSION.SDK_INT >= 24) {
mInfo.setDrawingOrder(drawingOrderInParent);
}
}
/**
* Gets the collection info if the node is a collection. A collection
* child is always a collection item.
*
* @return The collection info.
*/
public CollectionInfoCompat getCollectionInfo() {
AccessibilityNodeInfo.CollectionInfo info = mInfo.getCollectionInfo();
if (info != null) {
return new CollectionInfoCompat(info);
}
return null;
}
public void setCollectionInfo(Object collectionInfo) {
mInfo.setCollectionInfo((collectionInfo == null) ? null
: (AccessibilityNodeInfo.CollectionInfo) ((CollectionInfoCompat)
collectionInfo).mInfo);
}
public void setCollectionItemInfo(Object collectionItemInfo) {
mInfo.setCollectionItemInfo((collectionItemInfo == null) ? null
: (AccessibilityNodeInfo.CollectionItemInfo) ((CollectionItemInfoCompat)
collectionItemInfo).mInfo);
}
/**
* Gets the collection item info if the node is a collection item. A collection
* item is always a child of a collection.
*
* @return The collection item info.
*/
public CollectionItemInfoCompat getCollectionItemInfo() {
AccessibilityNodeInfo.CollectionItemInfo info = mInfo.getCollectionItemInfo();
if (info != null) {
return new CollectionItemInfoCompat(info);
}
return null;
}
/**
* Gets the range info if this node is a range.
*
* @return The range.
*/
public RangeInfoCompat getRangeInfo() {
AccessibilityNodeInfo.RangeInfo info = mInfo.getRangeInfo();
if (info != null) {
return new RangeInfoCompat(info);
}
return null;
}
/**
* Sets the range info if this node is a range.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param rangeInfo The range info.
*/
public void setRangeInfo(RangeInfoCompat rangeInfo) {
mInfo.setRangeInfo((AccessibilityNodeInfo.RangeInfo) rangeInfo.mInfo);
}
/**
* Gets the {@link android.view.accessibility.AccessibilityNodeInfo.ExtraRenderingInfo
* extra rendering info} if the node is meant to be refreshed with extra data
* to examine rendering related accessibility issues.
*
* @return The {@link android.view.accessibility.AccessibilityNodeInfo.ExtraRenderingInfo
* extra rendering info}.
*/
@Nullable
public AccessibilityNodeInfo.ExtraRenderingInfo getExtraRenderingInfo() {
if (Build.VERSION.SDK_INT >= 33) {
return Api33Impl.getExtraRenderingInfo(mInfo);
} else {
return null;
}
}
/**
* Gets the actions that can be performed on the node.
*
* @return A list of AccessibilityActions.
* <p>
* Compatibility:
* <ul>
* <li>API < 21: Always returns {@code null}</li>
* </ul>
*/
@SuppressWarnings({"unchecked", "MixedMutabilityReturnType"})
public List<AccessibilityActionCompat> getActionList() {
List<Object> actions = null;
if (Build.VERSION.SDK_INT >= 21) {
actions = (List<Object>) (List<?>) mInfo.getActionList();
}
if (actions != null) {
List<AccessibilityActionCompat> result = new ArrayList<AccessibilityActionCompat>();
final int actionCount = actions.size();
for (int i = 0; i < actionCount; i++) {
Object action = actions.get(i);
result.add(new AccessibilityActionCompat(action));
}
return result;
} else {
return Collections.<AccessibilityActionCompat>emptyList();
}
}
/**
* Sets if the content of this node is invalid. For example,
* a date is not well-formed.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param contentInvalid If the node content is invalid.
*/
public void setContentInvalid(boolean contentInvalid) {
mInfo.setContentInvalid(contentInvalid);
}
/**
* Gets if the content of this node is invalid. For example,
* a date is not well-formed.
*
* @return If the node content is invalid.
*/
public boolean isContentInvalid() {
return mInfo.isContentInvalid();
}
/**
* Gets whether this node is context clickable.
*
* @return True if the node is context clickable.
*/
public boolean isContextClickable() {
if (Build.VERSION.SDK_INT >= 23) {
return mInfo.isContextClickable();
} else {
return false;
}
}
/**
* Sets whether this node is context clickable.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}. This class is made immutable
* before being delivered to an AccessibilityService.
* </p>
*
* @param contextClickable True if the node is context clickable.
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setContextClickable(boolean contextClickable) {
if (Build.VERSION.SDK_INT >= 23) {
mInfo.setContextClickable(contextClickable);
}
}
/**
* Gets the hint text of this node. Only applies to nodes where text can be entered.
*
* @return The hint text.
*/
public @Nullable CharSequence getHintText() {
if (Build.VERSION.SDK_INT >= 26) {
return mInfo.getHintText();
} else {
return mInfo.getExtras().getCharSequence(HINT_TEXT_KEY);
}
}
/**
* Sets the hint text of this node. Only applies to nodes where text can be entered.
* <p>This method has no effect below API 19</p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param hintText The hint text for this mode.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setHintText(@Nullable CharSequence hintText) {
if (Build.VERSION.SDK_INT >= 26) {
mInfo.setHintText(hintText);
} else {
mInfo.getExtras().putCharSequence(HINT_TEXT_KEY, hintText);
}
}
/**
* Sets the error text of this node.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param error The error text.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setError(CharSequence error) {
if (Build.VERSION.SDK_INT >= 21) {
mInfo.setError(error);
}
}
/**
* Gets the error text of this node.
*
* @return The error text.
*/
public CharSequence getError() {
if (Build.VERSION.SDK_INT >= 21) {
return mInfo.getError();
} else {
return null;
}
}
/**
* Sets the view for which the view represented by this info serves as a
* label for accessibility purposes.
*
* @param labeled The view for which this info serves as a label.
*/
public void setLabelFor(View labeled) {
mInfo.setLabelFor(labeled);
}
/**
* Sets the view for which the view represented by this info serves as a
* label for accessibility purposes. If <code>virtualDescendantId</code>
* is {@link View#NO_ID} the root is set as the labeled.
* <p>
* A virtual descendant is an imaginary View that is reported as a part of the view
* hierarchy for accessibility purposes. This enables custom views that draw complex
* content to report themselves as a tree of virtual views, thus conveying their
* logical structure.
* </p>
*
* @param root The root whose virtual descendant serves as a label.
* @param virtualDescendantId The id of the virtual descendant.
*/
public void setLabelFor(View root, int virtualDescendantId) {
mInfo.setLabelFor(root, virtualDescendantId);
}
/**
* Gets the node info for which the view represented by this info serves as
* a label for accessibility purposes.
*
* @return The labeled info.
*/
public AccessibilityNodeInfoCompat getLabelFor() {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabelFor());
}
/**
* Sets the view which serves as the label of the view represented by
* this info for accessibility purposes.
*
* @param label The view that labels this node's source.
*/
public void setLabeledBy(View label) {
mInfo.setLabeledBy(label);
}
/**
* Sets the view which serves as the label of the view represented by
* this info for accessibility purposes. If <code>virtualDescendantId</code>
* is {@link View#NO_ID} the root is set as the label.
* <p>
* A virtual descendant is an imaginary View that is reported as a part of the view
* hierarchy for accessibility purposes. This enables custom views that draw complex
* content to report themselves as a tree of virtual views, thus conveying their
* logical structure.
* </p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param root The root whose virtual descendant labels this node's source.
* @param virtualDescendantId The id of the virtual descendant.
*/
public void setLabeledBy(View root, int virtualDescendantId) {
mInfo.setLabeledBy(root, virtualDescendantId);
}
/**
* Gets the node info which serves as the label of the view represented by
* this info for accessibility purposes.
*
* @return The label.
*/
public AccessibilityNodeInfoCompat getLabeledBy() {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getLabeledBy());
}
/**
* Gets if this node opens a popup or a dialog.
*
* @return If the the node opens a popup.
*/
public boolean canOpenPopup() {
return mInfo.canOpenPopup();
}
/**
* Sets if this node opens a popup or a dialog.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param opensPopup If the the node opens a popup.
*/
public void setCanOpenPopup(boolean opensPopup) {
mInfo.setCanOpenPopup(opensPopup);
}
/**
* Finds {@link AccessibilityNodeInfoCompat}s by the fully qualified view id's resource
* name where a fully qualified id is of the from "package:id/id_resource_name".
* For example, if the target application's package is "foo.bar" and the id
* resource name is "baz", the fully qualified resource id is "foo.bar:id/baz".
*
* <p>
* <strong>Note:</strong> The primary usage of this API is for UI test automation
* and in order to report the fully qualified view id if an
* {@link AccessibilityNodeInfoCompat} the client has to set the
* {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}
* flag when configuring their {@link android.accessibilityservice.AccessibilityService}.
* </p>
*
* @param viewId The fully qualified resource name of the view id to find.
* @return A list of node info.
*/
@SuppressWarnings("MixedMutabilityReturnType")
public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByViewId(String viewId) {
List<AccessibilityNodeInfo> nodes = mInfo.findAccessibilityNodeInfosByViewId(viewId);
List<AccessibilityNodeInfoCompat> result = new ArrayList<>();
for (AccessibilityNodeInfo node : nodes) {
result.add(AccessibilityNodeInfoCompat.wrap(node));
}
return result;
}
/**
* Gets an optional bundle with extra data. The bundle
* is lazily created and never <code>null</code>.
* <p>
* <strong>Note:</strong> It is recommended to use the package
* name of your application as a prefix for the keys to avoid
* collisions which may confuse an accessibility service if the
* same key has different meaning when emitted from different
* applications.
* </p>
*
* @return The bundle.
*/
public Bundle getExtras() {
return mInfo.getExtras();
}
/**
* Gets the input type of the source as defined by {@link InputType}.
*
* @return The input type.
*/
public int getInputType() {
return mInfo.getInputType();
}
/**
* Sets the input type of the source as defined by {@link InputType}.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an
* AccessibilityService.
* </p>
*
* @param inputType The input type.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setInputType(int inputType) {
mInfo.setInputType(inputType);
}
/**
* Get the extra data available for this node.
* <p>
* Some data that is useful for some accessibility services is expensive to compute, and would
* place undue overhead on apps to compute all the time. That data can be requested with
* {@link #refreshWithExtraData(String, Bundle)}.
*
* @return An unmodifiable list of keys corresponding to extra data that can be requested.
* @see #EXTRA_DATA_RENDERING_INFO_KEY
* @see #EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY
*/
@NonNull
public List<String> getAvailableExtraData() {
if (Build.VERSION.SDK_INT >= 26) {
return mInfo.getAvailableExtraData();
} else {
return emptyList();
}
}
/**
* Set the extra data available for this node.
* <p>
* <strong>Note:</strong> When a {@code View} passes in a non-empty list, it promises that
* it will populate the node's extras with corresponding pieces of information in
* {@link View#addExtraDataToAccessibilityNodeInfo(AccessibilityNodeInfo, String, Bundle)}.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
*
* @param extraDataKeys A list of types of extra data that are available.
* @see #getAvailableExtraData()
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setAvailableExtraData(@NonNull List<String> extraDataKeys) {
if (Build.VERSION.SDK_INT >= 26) {
mInfo.setAvailableExtraData(extraDataKeys);
}
}
/**
* Sets the maximum text length, or -1 for no limit.
* <p>
* Typically used to indicate that an editable text field has a limit on
* the number of characters entered.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
*
* @param max The maximum text length.
* @see #getMaxTextLength()
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setMaxTextLength(int max) {
if (Build.VERSION.SDK_INT >= 21) {
mInfo.setMaxTextLength(max);
}
}
/**
* Returns the maximum text length for this node.
*
* @return The maximum text length, or -1 for no limit.
* @see #setMaxTextLength(int)
*/
public int getMaxTextLength() {
if (Build.VERSION.SDK_INT >= 21) {
return mInfo.getMaxTextLength();
} else {
return -1;
}
}
/**
* Sets the text selection start and end.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param start The text selection start.
* @param end The text selection end.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setTextSelection(int start, int end) {
mInfo.setTextSelection(start, end);
}
/**
* Gets the text selection start.
*
* @return The text selection start if there is selection or -1.
*/
public int getTextSelectionStart() {
return mInfo.getTextSelectionStart();
}
/**
* Gets the text selection end.
*
* @return The text selection end if there is selection or -1.
*/
public int getTextSelectionEnd() {
return mInfo.getTextSelectionEnd();
}
/**
* Gets the node before which this one is visited during traversal. A screen-reader
* must visit the content of this node before the content of the one it precedes.
*
* @return The succeeding node if such or <code>null</code>.
*
* @see #setTraversalBefore(android.view.View)
* @see #setTraversalBefore(android.view.View, int)
*/
public AccessibilityNodeInfoCompat getTraversalBefore() {
if (Build.VERSION.SDK_INT >= 22) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getTraversalBefore());
} else {
return null;
}
}
/**
* Sets the view before whose node this one should be visited during traversal. A
* screen-reader must visit the content of this node before the content of the one
* it precedes.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param view The view providing the preceding node.
*
* @see #getTraversalBefore()
*/
public void setTraversalBefore(View view) {
if (Build.VERSION.SDK_INT >= 22) {
mInfo.setTraversalBefore(view);
}
}
/**
* Sets the node before which this one is visited during traversal. A screen-reader
* must visit the content of this node before the content of the one it precedes.
* The successor is a virtual descendant of the given <code>root</code>. If
* <code>virtualDescendantId</code> equals to {@link View#NO_ID} the root is set
* as the successor.
* <p>
* A virtual descendant is an imaginary View that is reported as a part of the view
* hierarchy for accessibility purposes. This enables custom views that draw complex
* content to report them selves as a tree of virtual views, thus conveying their
* logical structure.
* </p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param root The root of the virtual subtree.
* @param virtualDescendantId The id of the virtual descendant.
*/
public void setTraversalBefore(View root, int virtualDescendantId) {
if (Build.VERSION.SDK_INT >= 22) {
mInfo.setTraversalBefore(root, virtualDescendantId);
}
}
/**
* Gets the node after which this one is visited in accessibility traversal.
* A screen-reader must visit the content of the other node before the content
* of this one.
*
* @return The succeeding node if such or <code>null</code>.
*
* @see #setTraversalAfter(android.view.View)
* @see #setTraversalAfter(android.view.View, int)
*/
public AccessibilityNodeInfoCompat getTraversalAfter() {
if (Build.VERSION.SDK_INT >= 22) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(mInfo.getTraversalAfter());
} else {
return null;
}
}
/**
* Sets the view whose node is visited after this one in accessibility traversal.
* A screen-reader must visit the content of the other node before the content
* of this one.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param view The previous view.
*
* @see #getTraversalAfter()
*/
public void setTraversalAfter(View view) {
if (Build.VERSION.SDK_INT >= 22) {
mInfo.setTraversalAfter(view);
}
}
/**
* Sets the node after which this one is visited in accessibility traversal.
* A screen-reader must visit the content of the other node before the content
* of this one. If <code>virtualDescendantId</code> equals to {@link View#NO_ID}
* the root is set as the predecessor.
* <p>
* A virtual descendant is an imaginary View that is reported as a part of the view
* hierarchy for accessibility purposes. This enables custom views that draw complex
* content to report them selves as a tree of virtual views, thus conveying their
* logical structure.
* </p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param root The root of the virtual subtree.
* @param virtualDescendantId The id of the virtual descendant.
*/
public void setTraversalAfter(View root, int virtualDescendantId) {
if (Build.VERSION.SDK_INT >= 22) {
mInfo.setTraversalAfter(root, virtualDescendantId);
}
}
/**
* Gets the window to which this node belongs.
*
* @return The window.
*
* @see android.accessibilityservice.AccessibilityService#getWindows()
*/
public AccessibilityWindowInfoCompat getWindow() {
if (Build.VERSION.SDK_INT >= 21) {
return AccessibilityWindowInfoCompat.wrapNonNullInstance(mInfo.getWindow());
} else {
return null;
}
}
/**
* Gets if the node can be dismissed.
*
* @return If the node can be dismissed.
*/
public boolean isDismissable() {
return mInfo.isDismissable();
}
/**
* Sets if the node can be dismissed.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param dismissable If the node can be dismissed.
*/
public void setDismissable(boolean dismissable) {
mInfo.setDismissable(dismissable);
}
/**
* Gets if the node is editable.
*
* @return True if the node is editable, false otherwise.
*/
public boolean isEditable() {
return mInfo.isEditable();
}
/**
* Sets whether this node is editable.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param editable True if the node is editable.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setEditable(boolean editable) {
mInfo.setEditable(editable);
}
/**
* Gets if the node is a multi line editable text.
*
* @return True if the node is multi line.
*/
public boolean isMultiLine() {
return mInfo.isMultiLine();
}
/**
* Sets if the node is a multi line editable text.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param multiLine True if the node is multi line.
*/
public void setMultiLine(boolean multiLine) {
mInfo.setMultiLine(multiLine);
}
/**
* Gets the tooltip text of this node.
*
* @return The tooltip text.
*/
@Nullable
public CharSequence getTooltipText() {
if (Build.VERSION.SDK_INT >= 28) {
return mInfo.getTooltipText();
} else {
return mInfo.getExtras().getCharSequence(TOOLTIP_TEXT_KEY);
}
}
/**
* Sets the tooltip text of this node.
* <p>This method has no effect below API 19</p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param tooltipText The tooltip text.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setTooltipText(@Nullable CharSequence tooltipText) {
if (Build.VERSION.SDK_INT >= 28) {
mInfo.setTooltipText(tooltipText);
} else {
mInfo.getExtras().putCharSequence(TOOLTIP_TEXT_KEY, tooltipText);
}
}
/**
* If this node represents a visually distinct region of the screen that may update separately
* from the rest of the window, it is considered a pane. Set the pane title to indicate that
* the node is a pane, and to provide a title for it.
* <p>This method has no effect below API 19</p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
* @param paneTitle The title of the window represented by this node.
*/
public void setPaneTitle(@Nullable CharSequence paneTitle) {
if (Build.VERSION.SDK_INT >= 28) {
mInfo.setPaneTitle(paneTitle);
} else {
mInfo.getExtras().putCharSequence(PANE_TITLE_KEY, paneTitle);
}
}
/**
* Get the title of the pane represented by this node.
*
* @return The title of the pane represented by this node, or {@code null} if this node does
* not represent a pane.
*/
public @Nullable CharSequence getPaneTitle() {
if (Build.VERSION.SDK_INT >= 28) {
return mInfo.getPaneTitle();
} else {
return mInfo.getExtras().getCharSequence(PANE_TITLE_KEY);
}
}
/**
* Returns whether the node is explicitly marked as a focusable unit by a screen reader. Note
* that {@code false} indicates that it is not explicitly marked, not that the node is not
* a focusable unit. Screen readers should generally use other signals, such as
* {@link #isFocusable()}, or the presence of text in a node, to determine what should receive
* focus.
*
* @return {@code true} if the node is specifically marked as a focusable unit for screen
* readers, {@code false} otherwise.
*/
public boolean isScreenReaderFocusable() {
if (Build.VERSION.SDK_INT >= 28) {
return mInfo.isScreenReaderFocusable();
}
return getBooleanProperty(BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE);
}
/**
* Sets whether the node should be considered a focusable unit by a screen reader.
* <p>This method has no effect below API 19</p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param screenReaderFocusable {@code true} if the node is a focusable unit for screen readers,
* {@code false} otherwise.
*/
public void setScreenReaderFocusable(boolean screenReaderFocusable) {
if (Build.VERSION.SDK_INT >= 28) {
mInfo.setScreenReaderFocusable(screenReaderFocusable);
} else {
setBooleanProperty(BOOLEAN_PROPERTY_SCREEN_READER_FOCUSABLE, screenReaderFocusable);
}
}
/**
* Returns whether the node's text represents a hint for the user to enter text. It should only
* be {@code true} if the node has editable text.
*
* @return {@code true} if the text in the node represents a hint to the user, {@code false}
* otherwise.
*/
public boolean isShowingHintText() {
if (Build.VERSION.SDK_INT >= 26) {
return mInfo.isShowingHintText();
}
return getBooleanProperty(BOOLEAN_PROPERTY_IS_SHOWING_HINT);
}
/**
* Sets whether the node's text represents a hint for the user to enter text. It should only
* be {@code true} if the node has editable text.
* <p>This method has no effect below API 19</p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param showingHintText {@code true} if the text in the node represents a hint to the user,
* {@code false} otherwise.
*/
public void setShowingHintText(boolean showingHintText) {
if (Build.VERSION.SDK_INT >= 26) {
mInfo.setShowingHintText(showingHintText);
} else {
setBooleanProperty(BOOLEAN_PROPERTY_IS_SHOWING_HINT, showingHintText);
}
}
/**
* Returns whether node represents a heading.
* <p><strong>Note:</strong> Returns {@code true} if either {@link #setHeading(boolean)}
* marks this node as a heading or if the node has a {@link CollectionItemInfoCompat} that marks
* it as such, to accommodate apps that use the now-deprecated API.</p>
*
* @return {@code true} if the node is a heading, {@code false} otherwise.
*/
@SuppressWarnings("deprecation")
public boolean isHeading() {
if (Build.VERSION.SDK_INT >= 28) {
return mInfo.isHeading();
}
if (getBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING)) return true;
CollectionItemInfoCompat collectionItemInfo = getCollectionItemInfo();
return (collectionItemInfo != null) && collectionItemInfo.isHeading();
}
/**
* Sets whether the node represents a heading.
* <p>This method has no effect below API 19</p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param isHeading {@code true} if the node is a heading, {@code false} otherwise.
*/
public void setHeading(boolean isHeading) {
if (Build.VERSION.SDK_INT >= 28) {
mInfo.setHeading(isHeading);
} else {
setBooleanProperty(BOOLEAN_PROPERTY_IS_HEADING, isHeading);
}
}
/**
* Returns whether node represents a text entry key that is part of a keyboard or keypad.
*
* @return {@code true} if the node is a text entry key, {@code false} otherwise.
*/
public boolean isTextEntryKey() {
if (Build.VERSION.SDK_INT >= 29) {
return mInfo.isTextEntryKey();
}
return getBooleanProperty(BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY);
}
/**
* Sets whether the node represents a text entry key that is part of a keyboard or keypad.
* <p>This method has no effect below API 19</p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param isTextEntryKey {@code true} if the node is a text entry key, {@code false} otherwise.
*/
public void setTextEntryKey(boolean isTextEntryKey) {
if (Build.VERSION.SDK_INT >= 29) {
mInfo.setTextEntryKey(isTextEntryKey);
} else {
setBooleanProperty(BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY, isTextEntryKey);
}
}
/**
* Gets whether the node has {@link #setRequestInitialAccessibilityFocus}.
*
* @return True if the node has requested initial accessibility focus.
*/
@SuppressLint("KotlinPropertyAccess")
public boolean hasRequestInitialAccessibilityFocus() {
if (Build.VERSION.SDK_INT >= 34) {
return Api34Impl.hasRequestInitialAccessibilityFocus(mInfo);
} else {
return getBooleanProperty(BOOLEAN_PROPERTY_HAS_REQUEST_INITIAL_ACCESSIBILITY_FOCUS);
}
}
/**
* Sets whether the node has requested initial accessibility focus.
*
* <p>
* If the node {@link #hasRequestInitialAccessibilityFocus}, this node would be one of
* candidates to be accessibility focused when the window appears.
* </p>
*
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param requestInitialAccessibilityFocus True if the node requests to receive initial
* accessibility focus.
* @throws IllegalStateException If called from an AccessibilityService.
*/
@SuppressLint("GetterSetterNames")
public void setRequestInitialAccessibilityFocus(boolean requestInitialAccessibilityFocus) {
if (Build.VERSION.SDK_INT >= 34) {
Api34Impl.setRequestInitialAccessibilityFocus(mInfo, requestInitialAccessibilityFocus);
} else {
setBooleanProperty(BOOLEAN_PROPERTY_HAS_REQUEST_INITIAL_ACCESSIBILITY_FOCUS,
requestInitialAccessibilityFocus);
}
}
/**
* Refreshes this info with the latest state of the view it represents.
* <p>
* <strong>Note:</strong> If this method returns false this info is obsolete
* since it represents a view that is no longer in the view tree.
* </p>
* @return Whether the refresh succeeded.
*/
public boolean refresh() {
return mInfo.refresh();
}
/**
* Gets the custom role description.
* @return The role description.
*/
public @Nullable CharSequence getRoleDescription() {
return mInfo.getExtras().getCharSequence(ROLE_DESCRIPTION_KEY);
}
/**
* Sets the custom role description.
*
* <p>
* The role description allows you to customize the name for the view's semantic
* role. For example, if you create a custom subclass of {@link android.view.View}
* to display a menu bar, you could assign it the role description of "menu bar".
* </p>
* <p>
* <strong>Warning:</strong> For consistency with other applications, you should
* not use the role description to force accessibility services to describe
* standard views (such as buttons or checkboxes) using specific wording. For
* example, you should not set a role description of "check box" or "tick box" for
* a standard {@link android.widget.CheckBox}. Instead let accessibility services
* decide what feedback to provide.
* </p>
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an AccessibilityService.
* </p>
*
* @param roleDescription The role description.
*/
public void setRoleDescription(@Nullable CharSequence roleDescription) {
mInfo.getExtras().putCharSequence(ROLE_DESCRIPTION_KEY, roleDescription);
}
/**
* Get the {@link TouchDelegateInfoCompat} for touch delegate behavior with the represented
* view. It is possible for the same node to be pointed to by several regions. Use
* {@link TouchDelegateInfoCompat#getRegionAt(int)} to get touch delegate target
* {@link Region}, and {@link TouchDelegateInfoCompat#getTargetForRegion(Region)}
* for {@link AccessibilityNodeInfoCompat} from the given region.
* <p>
* Compatibility:
* <ul>
* <li>API < 29: Always returns {@code null}</li>
* </ul>
*
* @return {@link TouchDelegateInfoCompat} or {@code null} if there are no touch delegates
* in this node.
*/
@Nullable
public TouchDelegateInfoCompat getTouchDelegateInfo() {
if (Build.VERSION.SDK_INT >= 29) {
TouchDelegateInfo delegateInfo = mInfo.getTouchDelegateInfo();
if (delegateInfo != null) {
return new TouchDelegateInfoCompat(delegateInfo);
}
}
return null;
}
/**
* Set touch delegate info if the represented view has a {@link android.view.TouchDelegate}.
* <p>
* <strong>Note:</strong> Cannot be called from an
* {@link android.accessibilityservice.AccessibilityService}.
* This class is made immutable before being delivered to an
* AccessibilityService.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>API < 29: No-op</li>
* </ul>
*
* @param delegatedInfo {@link TouchDelegateInfoCompat}
* @throws IllegalStateException If called from an AccessibilityService.
*/
public void setTouchDelegateInfo(@NonNull TouchDelegateInfoCompat delegatedInfo) {
if (Build.VERSION.SDK_INT >= 29) {
mInfo.setTouchDelegateInfo(delegatedInfo.mInfo);
}
}
/**
* Connects this node to the View's root so that operations on this node can query the entire
* {@link AccessibilityNodeInfoCompat} tree and perform accessibility actions on nodes.
*
* <p>
* Testing or debugging tools should create this {@link AccessibilityNodeInfoCompat} node using
* {@link ViewCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)}
* or {@link AccessibilityNodeProviderCompat} and call this
* method, then navigate and interact with the node tree by calling methods on the node.
* Calling this method more than once on the same node is a no-op. After calling this method,
* all nodes linked to this node (children, ancestors, etc.) are also queryable.
* </p>
*
* <p>
* Here "query" refers to the following node operations:
* <ul>
* <li>check properties of this node (example: {@link #isScrollable()})</li>
* <li>find and query children (example: {@link #getChild(int)})</li>
* <li>find and query the parent (example: {@link #getParent()})</li>
* <li>find focus (examples: {@link #findFocus(int)}, {@link #focusSearch(int)})</li>
* <li>find and query other nodes (example:
* {@link #findAccessibilityNodeInfosByText(String)},
* {@link #findAccessibilityNodeInfosByViewId(String)})</li>
* <li>perform actions (example: {@link #performAction(int)})</li>
* </ul>
* </p>
*
* <p>
* This is intended for short-lived inspections from testing or debugging tools in the app
* process, as operations on this node tree will only succeed as long as the associated
* view hierarchy remains attached to a window. {@link AccessibilityNodeInfoCompat} objects can
* quickly become out of sync with their corresponding {@link View} objects; if you wish to
* inspect a changed or different view hierarchy then create a new node from any view in that
* hierarchy and call this method on that new node, instead of disabling & re-enabling the
* connection on the previous node.
* </p>
* <p>
* Compatibility:
* <ul>
* <li>API < 34: No-op</li>
* </ul>
*
* @param view The view that generated this node, or any view in the same view-root hierarchy.
* @param enabled Whether to enable (true) or disable (false) querying from the app process.
* @throws IllegalStateException If called from an {@link AccessibilityService}, or if provided
* a {@link View} that is not attached to a window.
*/
public void setQueryFromAppProcessEnabled(@NonNull View view, boolean enabled) {
if (Build.VERSION.SDK_INT >= 34) {
Api34Impl.setQueryFromAppProcessEnabled(mInfo, view, enabled);
}
}
@Override
public int hashCode() {
return (mInfo == null) ? 0 : mInfo.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof AccessibilityNodeInfoCompat)) {
return false;
}
AccessibilityNodeInfoCompat other = (AccessibilityNodeInfoCompat) obj;
if (mInfo == null) {
if (other.mInfo != null) {
return false;
}
} else if (!mInfo.equals(other.mInfo)) {
return false;
}
if (mVirtualDescendantId != other.mVirtualDescendantId) {
return false;
}
if (mParentVirtualDescendantId != other.mParentVirtualDescendantId) {
return false;
}
return true;
}
@SuppressWarnings("deprecation")
@NonNull
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(super.toString());
Rect bounds = new Rect();
getBoundsInParent(bounds);
builder.append("; boundsInParent: " + bounds);
getBoundsInScreen(bounds);
builder.append("; boundsInScreen: " + bounds);
getBoundsInWindow(bounds);
builder.append("; boundsInWindow: " + bounds);
builder.append("; packageName: ").append(getPackageName());
builder.append("; className: ").append(getClassName());
builder.append("; text: ").append(getText());
builder.append("; error: ").append(getError());
builder.append("; maxTextLength: ").append(getMaxTextLength());
builder.append("; stateDescription: ").append(getStateDescription());
builder.append("; contentDescription: ").append(getContentDescription());
builder.append("; tooltipText: ").append(getTooltipText());
builder.append("; viewIdResName: ").append(getViewIdResourceName());
builder.append("; uniqueId: ").append(getUniqueId());
builder.append("; checkable: ").append(isCheckable());
builder.append("; checked: ").append(isChecked());
builder.append("; focusable: ").append(isFocusable());
builder.append("; focused: ").append(isFocused());
builder.append("; selected: ").append(isSelected());
builder.append("; clickable: ").append(isClickable());
builder.append("; longClickable: ").append(isLongClickable());
builder.append("; contextClickable: ").append(isContextClickable());
builder.append("; enabled: ").append(isEnabled());
builder.append("; password: ").append(isPassword());
builder.append("; scrollable: " + isScrollable());
builder.append("; containerTitle: ").append(getContainerTitle());
builder.append("; granularScrollingSupported: ").append(isGranularScrollingSupported());
builder.append("; importantForAccessibility: ").append(isImportantForAccessibility());
builder.append("; visible: ").append(isVisibleToUser());
builder.append("; isTextSelectable: ").append(isTextSelectable());
builder.append("; accessibilityDataSensitive: ").append(isAccessibilityDataSensitive());
builder.append("; [");
if (Build.VERSION.SDK_INT >= 21) {
List<AccessibilityActionCompat> actions = getActionList();
for (int i = 0; i < actions.size(); i++) {
AccessibilityActionCompat action = actions.get(i);
String actionName = getActionSymbolicName(action.getId());
if (actionName.equals("ACTION_UNKNOWN") && action.getLabel() != null) {
actionName = action.getLabel().toString();
}
builder.append(actionName);
if (i != actions.size() - 1) {
builder.append(", ");
}
}
} else {
for (int actionBits = getActions(); actionBits != 0;) {
final int action = 1 << Integer.numberOfTrailingZeros(actionBits);
actionBits &= ~action;
builder.append(getActionSymbolicName(action));
if (actionBits != 0) {
builder.append(", ");
}
}
}
builder.append("]");
return builder.toString();
}
private void setBooleanProperty(int property, boolean value) {
Bundle extras = getExtras();
if (extras != null) {
int booleanProperties = extras.getInt(BOOLEAN_PROPERTY_KEY, 0);
booleanProperties &= ~property;
booleanProperties |= value ? property : 0;
extras.putInt(BOOLEAN_PROPERTY_KEY, booleanProperties);
}
}
private boolean getBooleanProperty(int property) {
Bundle extras = getExtras();
if (extras == null) return false;
return (extras.getInt(BOOLEAN_PROPERTY_KEY, 0) & property) == property;
}
static String getActionSymbolicName(int action) {
switch (action) {
case ACTION_FOCUS:
return "ACTION_FOCUS";
case ACTION_CLEAR_FOCUS:
return "ACTION_CLEAR_FOCUS";
case ACTION_SELECT:
return "ACTION_SELECT";
case ACTION_CLEAR_SELECTION:
return "ACTION_CLEAR_SELECTION";
case ACTION_CLICK:
return "ACTION_CLICK";
case ACTION_LONG_CLICK:
return "ACTION_LONG_CLICK";
case ACTION_ACCESSIBILITY_FOCUS:
return "ACTION_ACCESSIBILITY_FOCUS";
case ACTION_CLEAR_ACCESSIBILITY_FOCUS:
return "ACTION_CLEAR_ACCESSIBILITY_FOCUS";
case ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
return "ACTION_NEXT_AT_MOVEMENT_GRANULARITY";
case ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
return "ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY";
case ACTION_NEXT_HTML_ELEMENT:
return "ACTION_NEXT_HTML_ELEMENT";
case ACTION_PREVIOUS_HTML_ELEMENT:
return "ACTION_PREVIOUS_HTML_ELEMENT";
case ACTION_SCROLL_FORWARD:
return "ACTION_SCROLL_FORWARD";
case ACTION_SCROLL_BACKWARD:
return "ACTION_SCROLL_BACKWARD";
case ACTION_CUT:
return "ACTION_CUT";
case ACTION_COPY:
return "ACTION_COPY";
case ACTION_PASTE:
return "ACTION_PASTE";
case ACTION_SET_SELECTION:
return "ACTION_SET_SELECTION";
case ACTION_EXPAND:
return "ACTION_EXPAND";
case ACTION_COLLAPSE:
return "ACTION_COLLAPSE";
case ACTION_SET_TEXT:
return "ACTION_SET_TEXT";
case android.R.id.accessibilityActionScrollUp:
return "ACTION_SCROLL_UP";
case android.R.id.accessibilityActionScrollLeft:
return "ACTION_SCROLL_LEFT";
case android.R.id.accessibilityActionScrollDown:
return "ACTION_SCROLL_DOWN";
case android.R.id.accessibilityActionScrollRight:
return "ACTION_SCROLL_RIGHT";
case android.R.id.accessibilityActionPageDown:
return "ACTION_PAGE_DOWN";
case android.R.id.accessibilityActionPageUp:
return "ACTION_PAGE_UP";
case android.R.id.accessibilityActionPageLeft:
return "ACTION_PAGE_LEFT";
case android.R.id.accessibilityActionPageRight:
return "ACTION_PAGE_RIGHT";
case android.R.id.accessibilityActionShowOnScreen:
return "ACTION_SHOW_ON_SCREEN";
case android.R.id.accessibilityActionScrollToPosition:
return "ACTION_SCROLL_TO_POSITION";
case android.R.id.accessibilityActionContextClick:
return "ACTION_CONTEXT_CLICK";
case android.R.id.accessibilityActionSetProgress:
return "ACTION_SET_PROGRESS";
case android.R.id.accessibilityActionMoveWindow:
return "ACTION_MOVE_WINDOW";
case android.R.id.accessibilityActionShowTooltip:
return "ACTION_SHOW_TOOLTIP";
case android.R.id.accessibilityActionHideTooltip:
return "ACTION_HIDE_TOOLTIP";
case android.R.id.accessibilityActionPressAndHold:
return "ACTION_PRESS_AND_HOLD";
case android.R.id.accessibilityActionImeEnter:
return "ACTION_IME_ENTER";
case android.R.id.accessibilityActionDragStart:
return "ACTION_DRAG_START";
case android.R.id.accessibilityActionDragDrop:
return "ACTION_DRAG_DROP";
case android.R.id.accessibilityActionDragCancel:
return "ACTION_DRAG_CANCEL";
case android.R.id.accessibilityActionScrollInDirection:
return "ACTION_SCROLL_IN_DIRECTION";
default:
return "ACTION_UNKNOWN";
}
}
@RequiresApi(21)
private static class Api21Impl {
private Api21Impl() {
// This class is non instantiable.
}
public static CollectionItemInfoCompat createCollectionItemInfo(int rowIndex, int rowSpan,
int columnIndex, int columnSpan, boolean heading, boolean selected) {
return new CollectionItemInfoCompat(
AccessibilityNodeInfo.CollectionItemInfo.obtain(rowIndex, rowSpan, columnIndex,
columnSpan, heading, selected));
}
}
@RequiresApi(30)
private static class Api30Impl {
private Api30Impl() {
// This class is non instantiable.
}
public static void setStateDescription(AccessibilityNodeInfo info,
CharSequence stateDescription) {
info.setStateDescription(stateDescription);
}
public static CharSequence getStateDescription(AccessibilityNodeInfo info) {
return info.getStateDescription();
}
public static Object createRangeInfo(int type, float min, float max, float current) {
return new AccessibilityNodeInfo.RangeInfo(type, min, max, current);
}
}
@RequiresApi(33)
private static class Api33Impl {
private Api33Impl() {
// This class is non instantiable.
}
public static AccessibilityNodeInfo.ExtraRenderingInfo getExtraRenderingInfo(
AccessibilityNodeInfo info) {
return info.getExtraRenderingInfo();
}
public static boolean isTextSelectable(AccessibilityNodeInfo info) {
return info.isTextSelectable();
}
public static void setTextSelectable(AccessibilityNodeInfo info, boolean selectable) {
info.setTextSelectable(selectable);
}
public static CollectionItemInfoCompat buildCollectionItemInfoCompat(
boolean heading, int columnIndex, int rowIndex, int columnSpan,
int rowSpan, boolean selected, String rowTitle, String columnTitle) {
return new CollectionItemInfoCompat(
new AccessibilityNodeInfo.CollectionItemInfo.Builder()
.setHeading(heading).setColumnIndex(columnIndex)
.setRowIndex(rowIndex)
.setColumnSpan(columnSpan)
.setRowSpan(rowSpan)
.setSelected(selected)
.setRowTitle(rowTitle)
.setColumnTitle(columnTitle)
.build());
}
public static AccessibilityNodeInfoCompat getChild(AccessibilityNodeInfo info, int index,
int prefetchingStrategy) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(info.getChild(index,
prefetchingStrategy));
}
public static AccessibilityNodeInfoCompat getParent(AccessibilityNodeInfo info,
int prefetchingStrategy) {
return AccessibilityNodeInfoCompat.wrapNonNullInstance(info.getParent(
prefetchingStrategy));
}
public static String getUniqueId(AccessibilityNodeInfo info) {
return info.getUniqueId();
}
public static void setUniqueId(AccessibilityNodeInfo info, String uniqueId) {
info.setUniqueId(uniqueId);
}
public static String getCollectionItemRowTitle(Object info) {
return ((AccessibilityNodeInfo.CollectionItemInfo) info).getRowTitle();
}
public static String getCollectionItemColumnTitle(Object info) {
return ((AccessibilityNodeInfo.CollectionItemInfo) info).getColumnTitle();
}
}
@RequiresApi(34)
private static class Api34Impl {
private Api34Impl() {
// This class is non instantiable.
}
public static boolean isAccessibilityDataSensitive(AccessibilityNodeInfo info) {
return info.isAccessibilityDataSensitive();
}
public static void setAccessibilityDataSensitive(AccessibilityNodeInfo info,
boolean accessibilityDataSensitive) {
info.setAccessibilityDataSensitive(accessibilityDataSensitive);
}
public static CharSequence getContainerTitle(AccessibilityNodeInfo info) {
return info.getContainerTitle();
}
public static void setContainerTitle(AccessibilityNodeInfo info,
CharSequence containerTitle) {
info.setContainerTitle(containerTitle);
}
public static void getBoundsInWindow(AccessibilityNodeInfo info, Rect bounds) {
info.getBoundsInWindow(bounds);
}
public static void setBoundsInWindow(AccessibilityNodeInfo info, Rect bounds) {
info.setBoundsInWindow(bounds);
}
public static boolean hasRequestInitialAccessibilityFocus(AccessibilityNodeInfo info) {
return info.hasRequestInitialAccessibilityFocus();
}
public static void setRequestInitialAccessibilityFocus(AccessibilityNodeInfo info,
boolean requestInitialAccessibilityFocus) {
info.setRequestInitialAccessibilityFocus(requestInitialAccessibilityFocus);
}
public static long getMinDurationBetweenContentChangeMillis(AccessibilityNodeInfo info) {
return info.getMinDurationBetweenContentChanges().toMillis();
}
public static void setMinDurationBetweenContentChangeMillis(AccessibilityNodeInfo info,
long duration) {
info.setMinDurationBetweenContentChanges(Duration.ofMillis(duration));
}
public static void setQueryFromAppProcessEnabled(AccessibilityNodeInfo info, View view,
boolean enabled) {
info.setQueryFromAppProcessEnabled(view, enabled);
}
public static AccessibilityNodeInfo.AccessibilityAction getActionScrollInDirection() {
return AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_IN_DIRECTION;
}
}
}