Java Code Examples for android.view.accessibility.AccessibilityNodeInfo#getChildCount()

The following examples show how to use android.view.accessibility.AccessibilityNodeInfo#getChildCount() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: LaunchApp.java    From PUMA with Apache License 2.0 6 votes vote down vote up
private List<AccessibilityNodeInfo> get_leaf_nodes(AccessibilityNodeInfo root) {
	List<AccessibilityNodeInfo> ret = new ArrayList<AccessibilityNodeInfo>();
	Queue<AccessibilityNodeInfo> Q = new LinkedList<AccessibilityNodeInfo>();
	Q.add(root);

	while (!Q.isEmpty()) {
		AccessibilityNodeInfo node = Q.poll();

		if (node == null) {
			Util.log("Processing NULL");
			continue;
		}

		int childCnt = node.getChildCount();
		if (childCnt > 0) {
			for (int i = 0; i < childCnt; i++) {
				AccessibilityNodeInfo child = node.getChild(i);
				Q.add(child); // no need to check NULL, checked above
			}
		} else {
			ret.add(node);
		}
	}
	return ret;
}
 
Example 2
Source File: LaunchApp.java    From PUMA with Apache License 2.0 6 votes vote down vote up
private void traverse_node_recursive(AccessibilityNodeInfo node, int level) {
	if (node == null) {
		return;
	}

	int child_cnt = node.getChildCount();
	StringBuilder sb = new StringBuilder();

	if (child_cnt > 0) {
		for (int i = 0; i < child_cnt; i++) {
			traverse_node_recursive(node.getChild(i), level + 1);
		}
	} else {
		Rect bounds = new Rect();
		node.getBoundsInScreen(bounds);

		for (int i = 0; i < level; i++) {
			sb.append(" ");
		}

		sb.append(node.getText());
		sb.append(bounds.toShortString());

		Util.log(sb);
	}
}
 
Example 3
Source File: LaunchApp.java    From PUMA with Apache License 2.0 6 votes vote down vote up
private List<AccessibilityNodeInfo> flattenTree(AccessibilityNodeInfo rootNode) {
	List<AccessibilityNodeInfo> allNodes = new ArrayList<AccessibilityNodeInfo>();
	Queue<AccessibilityNodeInfo> Q = new LinkedList<AccessibilityNodeInfo>();

	Q.add(rootNode);

	// BFS, level-order traversal
	while (!Q.isEmpty()) {
		AccessibilityNodeInfo node = Q.poll();
		allNodes.add(node);

		for (int i = 0; i < node.getChildCount(); i++) {
			AccessibilityNodeInfo child = node.getChild(i);
			Q.add(child);
		}
	}

	return allNodes;
}
 
Example 4
Source File: UiAutomationElement.java    From appium-uiautomator2-server with Apache License 2.0 6 votes vote down vote up
private List<UiAutomationElement> buildChildren(AccessibilityNodeInfo node) {
    final int childCount = node.getChildCount();
    if (childCount == 0 || getDepth() >= MAX_DEPTH) {
        if (getDepth() >= MAX_DEPTH) {
            Logger.warn(String.format("Skipping building children of '%s' because the maximum " +
                    "recursion depth (%s) has been reached", node, MAX_DEPTH));
        }
        return Collections.emptyList();
    }

    List<UiAutomationElement> children = new ArrayList<>(childCount);
    boolean areInvisibleElementsAllowed = AppiumUIA2Driver
            .getInstance()
            .getSessionOrThrow()
            .getCapability(ALLOW_INVISIBLE_ELEMENTS.toString(), false);
    for (int i = 0; i < childCount; i++) {
        AccessibilityNodeInfo child = node.getChild(i);
        //Ignore if element is not visible on the screen
        if (child != null && (child.isVisibleToUser() || areInvisibleElementsAllowed)) {
            children.add(getOrCreateElement(child, i, getDepth() + 1));
        }
    }
    return children;
}
 
Example 5
Source File: MyAccessibilityNodeInfoSuite.java    From PUMA with Apache License 2.0 6 votes vote down vote up
public static void dumpTree(AccessibilityNodeInfo root, int level) {
	AccessibilityNodeInfo content = root;

	String s = "";
	for (int i = 0; i < level; i++) {
		s += " ";
	}

	Rect bound = new Rect();
	root.getBoundsInParent(bound);
	Util.log(s + content.getClassName() + "," + content.getText() + "," + content.isVisibleToUser() + "," + bound);

	for (int i = 0; i < root.getChildCount(); i++) {
		MyAccessibilityNodeInfoSuite.dumpTree(root.getChild(i), level + 1);
	}
}
 
Example 6
Source File: MouseAccessibilityService.java    From android-mouse-cursor with MIT License 6 votes vote down vote up
private static void logNodeHierachy(AccessibilityNodeInfo nodeInfo, int depth) {
    Rect bounds = new Rect();
    nodeInfo.getBoundsInScreen(bounds);

    StringBuilder sb = new StringBuilder();
    if (depth > 0) {
        for (int i=0; i<depth; i++) {
            sb.append("  ");
        }
        sb.append("\u2514 ");
    }
    sb.append(nodeInfo.getClassName());
    sb.append(" (" + nodeInfo.getChildCount() +  ")");
    sb.append(" " + bounds.toString());
    if (nodeInfo.getText() != null) {
        sb.append(" - \"" + nodeInfo.getText() + "\"");
    }
    Log.v(TAG, sb.toString());

    for (int i=0; i<nodeInfo.getChildCount(); i++) {
        AccessibilityNodeInfo childNode = nodeInfo.getChild(i);
        if (childNode != null) {
            logNodeHierachy(childNode, depth + 1);
        }
    }
}
 
Example 7
Source File: AccessUtil.java    From pc-android-controller-android with Apache License 2.0 5 votes vote down vote up
private void findChildView2(AccessibilityNodeInfo info, String parentText) {
        parentText = parentText + " |-- " + info.getText();
        L.d("得到控件 " + parentText);
        for (int i = 0; i < info.getChildCount(); i++) {
            AccessibilityNodeInfo child = info.getChild(i);
            if (child != null) {
//                L.d("得到子控件 " + child.getText());
                findChildView2(child, parentText + "");
            } else {
//                L.d("得到所有控件" + info.getText());
            }
        }
    }
 
Example 8
Source File: AccessibilityNodeInfoRef.java    From oversec with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Traverses to the next sibling of this node within its parent, returning
 * {@code true} on success.
 */
public boolean nextSibling() {
    if (mNode == null) {
        return false;
    }
    AccessibilityNodeInfo parent = mNode.getParent();
    if (parent == null) {
        return false;
    }
    try {
        int childCount = parent.getChildCount();
        int childNumber = getChildNumber(parent);
        if (childNumber < 0) {
            return false;
        }
        for (int i = childNumber + 1; i < childCount; ++i) {
            AccessibilityNodeInfo newNode =
                    parent.getChild(i);
            if (newNode == null) {
                return false;
            }
            if (AccessibilityNodeInfoUtils.isVisibleOrLegacy(newNode)) {
                reset(newNode);
                return true;
            }
            newNode.recycle();
        }
    } finally {
        parent.recycle();
    }
    return false;
}
 
Example 9
Source File: AccessibilityNodeInfoDumper.java    From android-uiautomator-server with MIT License 5 votes vote down vote up
/**
 * This should be used when it's already determined that the node is NAF and a further check of
 * its children is in order. A node maybe a container such as LinerLayout and may be set to be
 * clickable but have no text or content description but it is counting on one of its children
 * to fulfill the requirement for being accessibility friendly by having one or more of its
 * children fill the text or content-description. Such a combination is considered by this
 * dumper as acceptable for accessibility.
 *
 * @return false if node fails the check.
 */
private static boolean childNafCheck(AccessibilityNodeInfo node) {
    int childCount = node.getChildCount();
    for (int x = 0; x < childCount; x++) {
        AccessibilityNodeInfo childNode = node.getChild(x);
        if (childNode == null) {
            Log.i(String.format("Null child %d/%d, parent: %s", x, childCount, node.toString()));
            continue;
        }
        if (!safeCharSeqToString(childNode.getContentDescription()).isEmpty() || !safeCharSeqToString(childNode.getText()).isEmpty())
            return true;
        if (childNafCheck(childNode)) return true;
    }
    return false;
}
 
Example 10
Source File: OversecAccessibilityService.java    From oversec with GNU General Public License v3.0 5 votes vote down vote up
private void scrapeCompleteSubtree_MAIN(Tree.TreeNode treeNode, AccessibilityNodeInfo node, PerformNodeAction nodeAction) {
    checkHandlerThread();

    node.refresh();

    checkFocusedNode_PreLollipop(node);

    if (!node.isVisibleToUser()) {
        return;
    }

    int cc = node.getChildCount();

    for (int i = 0; i < cc; i++) {
        AccessibilityNodeInfo child = node.getChild(i);


        if (child != null) {
            Tree.TreeNode childTreeNode = mTree.put(child);
            treeNode.addChild(childTreeNode);
            if (nodeAction != null) {
                nodeAction.onNodeScanned(child);
            }
            scrapeCompleteSubtree_MAIN(childTreeNode, child, nodeAction);
            child.recycle();
        } else {
            Ln.d("SKRAPE: warning, couldn't get a child!");
            //TODO: one reason for this might be a too large binder transaction -> maybe at least give some feedback to the user
        }
    }

}
 
Example 11
Source File: RedPacketService.java    From styT with Apache License 2.0 5 votes vote down vote up
/**
 * 遍历查找红包
 */
private void findRedPacket(AccessibilityNodeInfo rootNode) {
    if (rootNode != null) {
        //从最后一行开始找起
        for (int i = rootNode.getChildCount() - 1; i >= 0; i--) {
            AccessibilityNodeInfo node = rootNode.getChild(i);
            //如果node为空则跳过该节点
            if (node == null) {
                continue;
            }
            CharSequence text = node.getText();
            if (text != null && text.toString().equals("领取红包")) {
                AccessibilityNodeInfo parent = node.getParent();
                //while循环,遍历"领取红包"的各个父布局,直至找到可点击的为止
                while (parent != null) {
                    if (parent.isClickable()) {
                        //模拟点击
                        Log.e("spire发现了列表页的红包 执行点击", text.toString());
                        parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                        //isOpenRP用于判断该红包是否点击过
                        isOpenRP = true;

                        break;
                    }
                    parent = parent.getParent();
                }
            }
            //判断是否已经打开过那个最新的红包了,是的话就跳出for循环,不是的话继续遍历
            if (isOpenRP) {
                break;
            } else {
                findRedPacket(node);
            }

        }
    }
}
 
Example 12
Source File: USSDService.java    From VoIpUSSD with Apache License 2.0 5 votes vote down vote up
private static void getLeaves(List<AccessibilityNodeInfo> leaves, AccessibilityNodeInfo node) {
    if (node.getChildCount() == 0) {
        leaves.add(node);
        return;
    }

    for (int i = 0; i < node.getChildCount(); i++) {
        getLeaves(leaves, node.getChild(i));
    }
}
 
Example 13
Source File: AccessibilityInteractionController.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
private void prefetchSiblingsOfVirtualNode(AccessibilityNodeInfo current, View providerHost,
        AccessibilityNodeProvider provider, List<AccessibilityNodeInfo> outInfos) {
    final long parentNodeId = current.getParentNodeId();
    final int parentAccessibilityViewId =
        AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
    final int parentVirtualDescendantId =
        AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
    if (parentVirtualDescendantId != AccessibilityNodeProvider.HOST_VIEW_ID
            || parentAccessibilityViewId == providerHost.getAccessibilityViewId()) {
        final AccessibilityNodeInfo parent =
                provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
        if (parent != null) {
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                    return;
                }
                final long childNodeId = parent.getChildId(i);
                if (childNodeId != current.getSourceNodeId()) {
                    final int childVirtualDescendantId =
                        AccessibilityNodeInfo.getVirtualDescendantId(childNodeId);
                    AccessibilityNodeInfo child = provider.createAccessibilityNodeInfo(
                            childVirtualDescendantId);
                    if (child != null) {
                        outInfos.add(child);
                    }
                }
            }
        }
    } else {
        prefetchSiblingsOfRealNode(providerHost, outInfos);
    }
}
 
Example 14
Source File: AccessibilityUtils.java    From PrivacyStreams with Apache License 2.0 5 votes vote down vote up
public static SerializedAccessibilityNodeInfo serialize(AccessibilityNodeInfo node){
    SerializedAccessibilityNodeInfo serializedNode = new SerializedAccessibilityNodeInfo();
    Rect boundsInScreen = new Rect(), boundsInParent = new Rect();
    if(node == null){
        return null;
    }
    if(node.getClassName() != null)
        serializedNode.className = node.getClassName().toString();
    node.getBoundsInScreen(boundsInScreen);
    node.getBoundsInParent(boundsInParent);

    serializedNode.boundsInScreen = boundsInScreen.flattenToString();
    serializedNode.boundsInParent = boundsInParent.flattenToString();

    if(node.getContentDescription() != null)
        serializedNode.contentDescription = node.getContentDescription().toString();

    if(node.getText() != null){
        serializedNode.text = node.getText().toString();
    }

    if(node.getViewIdResourceName() != null)
        serializedNode.viewId = node.getViewIdResourceName();

    int childCount = node.getChildCount();
    for(int i = 0; i < childCount; i ++){
        if(node.getChild(i) != null){
            serializedNode.children.add(serialize(node.getChild(i)));
        }
    }

    return serializedNode;
}
 
Example 15
Source File: TimClient.java    From Anti-recall with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
     * 好友:
     * 姓名       1    android.widget.TextView
     * 消息       5-[]-last android.widget.TextView   focusable
     * 文本框     7-0  android.widget.EditText
     * 发送按钮   7-1  android.widget.Button
     * <p>
     * 群:
     * 群名       1
     * 消息       4/5-
     * <p>
     * 群里的临时会话:
     * 姓名       1-0
     * 消息       6-[]-last
     * 文本框     8-0
     * 发送按钮   8-1
     */
    protected boolean init(AccessibilityNodeInfo root) {
        //16 是其他界面
        //14 是没有聊过天
        //12 是发送完消息
        if (root.getChildCount() < 12) {
            Log.v(TAG, "init: root.childCount: " + root.getChildCount());
            return false;
        }

//        List<AccessibilityNodeInfo> inputList;
//        List<AccessibilityNodeInfo> sendList;

//        inputList = root.findAccessibilityNodeInfosByViewId(IdInput);
//        sendList = root.findAccessibilityNodeInfosByViewId(IdSend);

//        if (inputList.size() == 0) {
//            Log.d(TAG, "init: input is null, return");
//            return false;
//        }
//        if (sendList.size() == 0) {
//            Log.d(TAG, "init: send button is null, return");
//            return false;
//        }
//        inputNode = inputList.get(0);
//        sendBtnNode = sendList.get(0);

        List<AccessibilityNodeInfo> titleList;
        titleList = root.findAccessibilityNodeInfosByViewId(IdTitle);
        if (titleList.size() == 0) {
            Log.d(TAG, "init: title is null, return");
            return false;
        }
        titleNode = titleList.get(0);
        if (titleNode.getText() == null) {
            Log.d(TAG, "init: name is null,return");
            return false;
        }
        title = titleNode.getText() + "";
        isOtherMsg = false;

        for (int i = 4; i < 7; i++) {
            AccessibilityNodeInfo child = root.getChild(i);
            String name = child.getViewIdResourceName();
            if (name == null)
                continue;
            switch (name) {
                case IdChatGroupView:
                    chatGroupViewNode = child;
                    break;
                case IdOtherMsg:
                    otherMsgNode = child;
                    isOtherMsg = true;
                    break;
            }
        }

        if (chatGroupViewNode == null) {
            Log.i(TAG, "init: chatGroupViewNode is null, return");
            return false;
        }

        return true;
    }
 
Example 16
Source File: QueryController.java    From JsDroidCmd with Mozilla Public License 2.0 4 votes vote down vote up
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;
}
 
Example 17
Source File: AccessibilityInteractionController.java    From android_9.0.0_r45 with Apache License 2.0 4 votes vote down vote up
private void enforceNodeTreeConsistent(List<AccessibilityNodeInfo> nodes) {
    LongSparseArray<AccessibilityNodeInfo> nodeMap =
            new LongSparseArray<AccessibilityNodeInfo>();
    final int nodeCount = nodes.size();
    for (int i = 0; i < nodeCount; i++) {
        AccessibilityNodeInfo node = nodes.get(i);
        nodeMap.put(node.getSourceNodeId(), node);
    }

    // If the nodes are a tree it does not matter from
    // which node we start to search for the root.
    AccessibilityNodeInfo root = nodeMap.valueAt(0);
    AccessibilityNodeInfo parent = root;
    while (parent != null) {
        root = parent;
        parent = nodeMap.get(parent.getParentNodeId());
    }

    // Traverse the tree and do some checks.
    AccessibilityNodeInfo accessFocus = null;
    AccessibilityNodeInfo inputFocus = null;
    HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>();
    Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
    fringe.add(root);

    while (!fringe.isEmpty()) {
        AccessibilityNodeInfo current = fringe.poll();

        // Check for duplicates
        if (!seen.add(current)) {
            throw new IllegalStateException("Duplicate node: "
                    + current + " in window:"
                    + mViewRootImpl.mAttachInfo.mAccessibilityWindowId);
        }

        // Check for one accessibility focus.
        if (current.isAccessibilityFocused()) {
            if (accessFocus != null) {
                throw new IllegalStateException("Duplicate accessibility focus:"
                        + current
                        + " in window:" + mViewRootImpl.mAttachInfo.mAccessibilityWindowId);
            } else {
                accessFocus = current;
            }
        }

        // Check for one input focus.
        if (current.isFocused()) {
            if (inputFocus != null) {
                throw new IllegalStateException("Duplicate input focus: "
                    + current + " in window:"
                    + mViewRootImpl.mAttachInfo.mAccessibilityWindowId);
            } else {
                inputFocus = current;
            }
        }

        final int childCount = current.getChildCount();
        for (int j = 0; j < childCount; j++) {
            final long childId = current.getChildId(j);
            final AccessibilityNodeInfo child = nodeMap.get(childId);
            if (child != null) {
                fringe.add(child);
            }
        }
    }

    // Check for disconnected nodes.
    for (int j = nodeMap.size() - 1; j >= 0; j--) {
        AccessibilityNodeInfo info = nodeMap.valueAt(j);
        if (!seen.contains(info)) {
            throw new IllegalStateException("Disconnected node: " + info);
        }
    }
}
 
Example 18
Source File: AccessibilityNodeInfoUtils.java    From oversec with GNU General Public License v3.0 4 votes vote down vote up
/**
     * Gets the text of a <code>node</code> by returning the content description
     * (if available) or by returning the text.
     *
     * @param node The node.
     * @return The node text.
     */
    public static CharSequence getNodeText(AccessibilityNodeInfo node) {
        if (node == null) {
            return null;
        }


        CharSequence text = node.getText();
        if (!TextUtils.isEmpty(text)
                && (TextUtils.getTrimmedLength(text) > 0)) {
            return text;
        }

        //Use contentDescription only if there are no child nodes -

        if (node.getChildCount() == 0) {
            final CharSequence contentDescription = node.getContentDescription();
            if (!TextUtils.isEmpty(contentDescription)
                    && (TextUtils.getTrimmedLength(contentDescription) > 0)) {
                return contentDescription;
            }


        }
        return null;

//        // Prefer content description over text.
//        // TODO: Why are we checking the trimmed length?
//        final CharSequence contentDescription = node.getContentDescription();
//        if (!TextUtils.isEmpty(contentDescription)
//                && (TextUtils.getTrimmedLength(contentDescription) > 0)) {
//            return contentDescription;
//        }
//
//        CharSequence text = node.getText();
//        if (!TextUtils.isEmpty(text)
//                && (TextUtils.getTrimmedLength(text) > 0)) {
//            return text;
//        }
//
//        return null;
    }
 
Example 19
Source File: QueryController.java    From za-Farmer with MIT License 4 votes vote down vote up
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;
}
 
Example 20
Source File: QueryController.java    From za-Farmer with MIT License 4 votes vote down vote up
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;
}