Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added limit to avoid stackoverflows when calculating visible bounds #288

Merged
merged 2 commits into from Jul 11, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -36,6 +36,8 @@
* This class contains static helper methods to work with {@link AccessibilityNodeInfo}
*/
public class AccessibilityNodeInfoHelpers {

tri-fraga marked this conversation as resolved.
Show resolved Hide resolved
private final static int MAX_DEPTH = 70;
tri-fraga marked this conversation as resolved.
Show resolved Hide resolved

@Nullable
public static Range<Integer> getSelectionRange(@Nullable AccessibilityNodeInfo nodeInfo) {
Expand Down Expand Up @@ -75,14 +77,24 @@ public static String getText(@Nullable AccessibilityNodeInfo nodeInfo, boolean r
}
return charSequenceToString(nodeInfo.getText(), replaceNull);
}

/**
/**
* Returns the node's bounds clipped to the size of the display
*
* @return null if node is null, else a Rect containing visible bounds
*/
@SuppressLint("CheckResult")
public static Rect getVisibleBounds(@Nullable AccessibilityNodeInfo node) {
return getVisibleBounds(node, 0);
}

/**
* Returns the node's bounds clipped to the size of the display, limited by the MAX_DEPTH
*
* @return null if node is null, else a Rect containing visible bounds
*/
@SuppressLint("CheckResult")
private static Rect getVisibleBounds(@Nullable AccessibilityNodeInfo node, int depth) {
if (node == null) {
return null;
}
Expand All @@ -96,16 +108,18 @@ public static Rect getVisibleBounds(@Nullable AccessibilityNodeInfo node) {
Rect screen = new Rect(0, 0, uiDevice.getDisplayWidth(), uiDevice.getDisplayHeight());
ret.intersect(screen);

// Find the visible bounds of our first scrollable ancestor
for (AccessibilityNodeInfo ancestor = node.getParent(); ancestor != null; ancestor = ancestor.getParent()) {
// Find the visible bounds of our first scrollable ancestor
for (AccessibilityNodeInfo ancestor = node.getParent(); ancestor != null && depth < MAX_DEPTH; ancestor = ancestor.getParent()) {
// If this ancestor is scrollable
if (ancestor.isScrollable()) {
// Trim any portion of the bounds that are hidden by the non-visible portion of our
// ancestor
Rect ancestorRect = getVisibleBounds(ancestor);
Rect ancestorRect = getVisibleBounds(ancestor, depth);
ret.intersect(ancestorRect);
break;
}

depth++;
tri-fraga marked this conversation as resolved.
Show resolved Hide resolved
}

return ret;
Expand Down