private AccessibilityNodeInfo findNodeRegularRecursive( UiSelector subSelector, AccessibilityNodeInfo fromNode, int index) { if (subSelector.isMatchFor(fromNode, index)) { if (DEBUG) { Log.d(LOG_TAG, formatLog(String.format("%s", subSelector.dumpToString(false)))); } if (subSelector.isLeaf()) { return fromNode; } if (subSelector.hasChildSelector()) { mLogIndent++; // next selector subSelector = subSelector.getChildSelector(); if (subSelector == null) { Log.e(LOG_TAG, "Error: A child selector without content"); return null; // there is an implementation fault } } else if (subSelector.hasParentSelector()) { mLogIndent++; // next selector subSelector = subSelector.getParentSelector(); if (subSelector == null) { Log.e(LOG_TAG, "Error: A parent selector without content"); return null; // there is an implementation fault } // the selector requested we start at this level from // the parent node from the one we just matched fromNode = fromNode.getParent(); if (fromNode == null) return null; } } int childCount = fromNode.getChildCount(); boolean hasNullChild = false; for (int i = 0; i < childCount; i++) { AccessibilityNodeInfo childNode = fromNode.getChild(i); if (childNode == null) { Log.w( LOG_TAG, String.format("AccessibilityNodeInfo returned a null child (%d of %d)", i, childCount)); if (!hasNullChild) { Log.w(LOG_TAG, String.format("parent = %s", fromNode.toString())); } hasNullChild = true; continue; } if (!childNode.isVisibleToUser()) { if (VERBOSE) Log.v(LOG_TAG, String.format("Skipping invisible child: %s", childNode.toString())); continue; } AccessibilityNodeInfo retNode = findNodeRegularRecursive(subSelector, childNode, i); if (retNode != null) { return retNode; } } return null; }
private AccessibilityNodeInfo findNodePatternRecursive( UiSelector subSelector, AccessibilityNodeInfo fromNode, int index, UiSelector originalPattern) { if (subSelector.isMatchFor(fromNode, index)) { if (subSelector.isLeaf()) { if (mPatternIndexer == 0) { if (DEBUG) Log.d(LOG_TAG, formatLog(String.format("%s", subSelector.dumpToString(false)))); return fromNode; } else { if (DEBUG) Log.d(LOG_TAG, formatLog(String.format("%s", subSelector.dumpToString(false)))); mPatternCounter++; // count the pattern matched mPatternIndexer--; // decrement until zero for the instance requested // At a leaf selector within a group and still not instance matched // then reset the selector to continue search from current position // in the accessibility tree for the next pattern match up until the // pattern index hits 0. subSelector = originalPattern; // starting over with next pattern search so reset to parent level mLogIndent = mLogParentIndent; } } else { if (DEBUG) Log.d(LOG_TAG, formatLog(String.format("%s", subSelector.dumpToString(false)))); if (subSelector.hasChildSelector()) { mLogIndent++; // next selector subSelector = subSelector.getChildSelector(); if (subSelector == null) { Log.e(LOG_TAG, "Error: A child selector without content"); return null; } } else if (subSelector.hasParentSelector()) { mLogIndent++; // next selector subSelector = subSelector.getParentSelector(); if (subSelector == null) { Log.e(LOG_TAG, "Error: A parent selector without content"); return null; } fromNode = fromNode.getParent(); if (fromNode == null) return null; } } } int childCount = fromNode.getChildCount(); boolean hasNullChild = false; for (int i = 0; i < childCount; i++) { AccessibilityNodeInfo childNode = fromNode.getChild(i); if (childNode == null) { Log.w( LOG_TAG, String.format("AccessibilityNodeInfo returned a null child (%d of %d)", i, childCount)); if (!hasNullChild) { Log.w(LOG_TAG, String.format("parent = %s", fromNode.toString())); } hasNullChild = true; continue; } if (!childNode.isVisibleToUser()) { if (DEBUG) Log.d(LOG_TAG, String.format("Skipping invisible child: %s", childNode.toString())); continue; } AccessibilityNodeInfo retNode = findNodePatternRecursive(subSelector, childNode, i, originalPattern); if (retNode != null) { return retNode; } } return null; }