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

The following examples show how to use android.view.accessibility.AccessibilityNodeInfo#isVisibleToUser() . 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: RedEnvelopeHelper.java    From RedEnvelopeAssistant with MIT License 8 votes vote down vote up
/**获得红包详情页面打开节点*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public static AccessibilityNodeInfo getWechatRedEnvelopeOpenNode(AccessibilityNodeInfo info) {
	if (info == null)
		return null;
	List<AccessibilityNodeInfo> list = info.findAccessibilityNodeInfosByViewId("com.tencent.mm:id/b2c");
	AccessibilityNodeInfo tempNode=null;
	for(int i=0;i<list.size();i++){
		tempNode=list.get(i);
		LogUtil.d("e2ee"+tempNode.isVisibleToUser()+"-"+tempNode.isEnabled());
		if ("android.widget.Button".equals(tempNode.getClassName())&&tempNode.isVisibleToUser()){
			return tempNode;
		}
	}
	return null;
}
 
Example 2
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 3
Source File: LaunchApp.java    From PUMA with Apache License 2.0 6 votes vote down vote up
private boolean matchNode(AccessibilityNodeInfo node) {
	String clsName = node.getClassName().toString();
	Class EDITTEXT, B, WEBVIEW;
	boolean matchedEditText = false;
	boolean matchedWebView = false;

	try {
		B = Class.forName(clsName, false, this.getClass().getClassLoader());

		EDITTEXT = Class.forName(EditText.class.getCanonicalName(), false, this.getClass().getClassLoader());
		matchedEditText = EDITTEXT.isAssignableFrom(B);

		WEBVIEW = Class.forName(WebView.class.getCanonicalName(), false, this.getClass().getClassLoader());
		matchedWebView = WEBVIEW.isAssignableFrom(B);
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}

	return node.isClickable() && node.isEnabled() && node.isVisibleToUser() && !node.isCheckable() && !matchedEditText && !matchedWebView;
}
 
Example 4
Source File: AccessibilityNodeInfoDumper.java    From za-Farmer with MIT License 5 votes vote down vote up
private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer,int index,
        int width, int height) throws IOException {
    serializer.startTag("", "node");
    if (!nafExcludedClass(node) && !nafCheck(node))
        serializer.attribute("", "NAF", Boolean.toString(true));
    serializer.attribute("", "index", Integer.toString(index));
    serializer.attribute("", "text", safeCharSeqToString(node.getText()));
    serializer.attribute("", "resource-id", safeCharSeqToString(node.getViewIdResourceName()));
    serializer.attribute("", "class", safeCharSeqToString(node.getClassName()));
    serializer.attribute("", "package", safeCharSeqToString(node.getPackageName()));
    serializer.attribute("", "content-desc", safeCharSeqToString(node.getContentDescription()));
    serializer.attribute("", "checkable", Boolean.toString(node.isCheckable()));
    serializer.attribute("", "checked", Boolean.toString(node.isChecked()));
    serializer.attribute("", "clickable", Boolean.toString(node.isClickable()));
    serializer.attribute("", "enabled", Boolean.toString(node.isEnabled()));
    serializer.attribute("", "focusable", Boolean.toString(node.isFocusable()));
    serializer.attribute("", "focused", Boolean.toString(node.isFocused()));
    serializer.attribute("", "scrollable", Boolean.toString(node.isScrollable()));
    serializer.attribute("", "long-clickable", Boolean.toString(node.isLongClickable()));
    serializer.attribute("", "password", Boolean.toString(node.isPassword()));
    serializer.attribute("", "selected", Boolean.toString(node.isSelected()));
    serializer.attribute("", "bounds", AccessibilityNodeInfoHelper.getVisibleBoundsInScreen(
            node, width, height).toShortString());
    int count = node.getChildCount();
    for (int i = 0; i < count; i++) {
        AccessibilityNodeInfo child = node.getChild(i);
        if (child != null) {
            if (child.isVisibleToUser()) {
                dumpNodeRec(child, serializer, i, width, height);
                child.recycle();
            } else {
                Log.i(LOGTAG, String.format("Skipping invisible child: %s", child.toString()));
            }
        } else {
            Log.i(LOGTAG, String.format("Null child %d/%d, parent: %s",
                    i, count, node.toString()));
        }
    }
    serializer.endTag("", "node");
}
 
Example 5
Source File: FocusFinder.java    From brailleback with Apache License 2.0 5 votes vote down vote up
public static AccessibilityNodeInfoCompat getFocusedNode(
    AccessibilityService service, boolean fallbackOnRoot) {
    AccessibilityNodeInfo root =
            service.getRootInActiveWindow();
    AccessibilityNodeInfo focused = null;
    try {
        AccessibilityNodeInfo ret = null;
        if (root != null) {
            focused = root.findFocus(
                AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
            if (focused != null && focused.isVisibleToUser()) {
                ret = focused;
                focused = null;
            } else if (fallbackOnRoot) {
                ret = root;
                root = null;
            }
        } else {
            LogUtils.log(service, Log.ERROR, "No current window root");
        }
        if (ret != null) {
            return new AccessibilityNodeInfoCompat(ret);
        }
    } finally {
        if (root != null) {
            root.recycle();
        }
        if (focused != null) {
            focused.recycle();
        }
    }
    return null;
}
 
Example 6
Source File: FocusFinder.java    From talkback with Apache License 2.0 5 votes vote down vote up
public static @Nullable AccessibilityNodeInfoCompat getFocusedNode(
    AccessibilityService service, boolean fallbackOnRoot) {
  AccessibilityNodeInfo root = service.getRootInActiveWindow();
  AccessibilityNodeInfo focused = null;

  try {
    AccessibilityNodeInfo ret = null;
    if (root != null) {
      focused = root.findFocus(AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
      if (focused != null && focused.isVisibleToUser()) {
        ret = focused;
        focused = null;
      } else if (fallbackOnRoot) {
        ret = root;
        root = null;
      }
    } else {
      LogUtils.e(TAG, "No current window root");
    }

    if (ret != null) {
      return AccessibilityNodeInfoUtils.toCompat(ret);
    }
  } finally {
    if (root != null) {
      root.recycle();
    }

    if (focused != null) {
      focused.recycle();
    }
  }

  return null;
}
 
Example 7
Source File: AccessibilityNodeTree.java    From SoloPi with Apache License 2.0 5 votes vote down vote up
private void initAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    this.className = StringUtil.nonNullString(info.getClassName());
    this.packageName = StringUtil.nonNullString(info.getPackageName());
    this.resourceId = info.getViewIdResourceName();
    this.text = StringUtil.nonNullString(info.getText());
    this.description = StringUtil.nonNullString(info.getContentDescription());
    Rect rect = new Rect();
    info.getBoundsInScreen(rect);
    this.nodeBound = rect;
    this.isScrollable = info.isScrollable();
    this.visible = info.isVisibleToUser();
    this.isClickable = info.isClickable();
    this.isFocusable = info.isFocusable();
    this.isEditable = info.isEditable();
}
 
Example 8
Source File: AccessibilityNodeInfoDumper.java    From JsDroidCmd with Mozilla Public License 2.0 5 votes vote down vote up
public static void dumpNode(AccessibilityNodeInfo info, Node root,
		int index, int width, int height) {
	root.sourceId = info.getSourceNodeId();
	root.index = index;
	root.text = safeCharSeqToString(info.getText());
	root.res = safeCharSeqToString(info.getViewIdResourceName());
	root.clazz = safeCharSeqToString(info.getClassName());
	root.pkg = safeCharSeqToString(info.getPackageName());
	root.desc = safeCharSeqToString(info.getContentDescription());
	root.checkable = info.isCheckable();
	root.checked = info.isChecked();
	root.clickable = info.isClickable();
	root.enabled = info.isEnabled();
	root.focusable = info.isFocusable();
	root.focused = info.isFocused();
	root.scrollable = info.isScrollable();
	root.longClickable = info.isLongClickable();
	root.password = info.isPassword();
	root.selected = info.isSelected();
	android.graphics.Rect r = AccessibilityNodeInfoHelper
			.getVisibleBoundsInScreen(info, width, height);
	root.rect = new Rect(r.left, r.top, r.right, r.bottom);
	root.children = new ArrayList<Node>();
	int count = info.getChildCount();
	for (int i = 0; i < count; i++) {
		AccessibilityNodeInfo child = info.getChild(i);
		if (child != null) {
			if (child.isVisibleToUser()) {
				Node childNode = new Node();
				dumpNode(child, childNode, i, width, height);
				root.children.add(childNode);
				child.recycle();
			}
		}
	}
}
 
Example 9
Source File: UiAutomationElement.java    From UIAutomatorWD with MIT License 5 votes vote down vote up
/**
 * A snapshot of all attributes is taken at construction. The attributes of a
 * {@code UiAutomationElement} instance are immutable. If the underlying
 * {@link AccessibilityNodeInfo} is updated, a new {@code UiAutomationElement}
 * instance will be created in
 */
protected UiAutomationElement( AccessibilityNodeInfo node,
                               UiAutomationElement parent, int index) {
    this.node = node;
    this.parent = parent;

    Map<Attribute, Object> attribs = new EnumMap<Attribute, Object>(Attribute.class);

    put(attribs, Attribute.INDEX, index);
    put(attribs, Attribute.PACKAGE, charSequenceToString(node.getPackageName()));
    put(attribs, Attribute.CLASS, charSequenceToString(node.getClassName()));
    put(attribs, Attribute.TEXT, charSequenceToString(node.getText()));
    put(attribs, Attribute.CONTENT_DESC, charSequenceToString(node.getContentDescription()));
    put(attribs, Attribute.RESOURCE_ID, charSequenceToString(node.getViewIdResourceName()));
    put(attribs, Attribute.CHECKABLE, node.isCheckable());
    put(attribs, Attribute.CHECKED, node.isChecked());
    put(attribs, Attribute.CLICKABLE, node.isClickable());
    put(attribs, Attribute.ENABLED, node.isEnabled());
    put(attribs, Attribute.FOCUSABLE, node.isFocusable());
    put(attribs, Attribute.FOCUSED, node.isFocused());
    put(attribs, Attribute.LONG_CLICKABLE, node.isLongClickable());
    put(attribs, Attribute.PASSWORD, node.isPassword());
    put(attribs, Attribute.SCROLLABLE, node.isScrollable());
    if (node.getTextSelectionStart() >= 0
            && node.getTextSelectionStart() != node.getTextSelectionEnd()) {
        attribs.put(Attribute.SELECTION_START, node.getTextSelectionStart());
        attribs.put(Attribute.SELECTION_END, node.getTextSelectionEnd());
    }
    put(attribs, Attribute.SELECTED, node.isSelected());
    put(attribs, Attribute.BOUNDS, getBounds(node));
    attributes = Collections.unmodifiableMap(attribs);

    // Order matters as getVisibleBounds depends on visible
    visible = node.isVisibleToUser();
    visibleBounds = getVisibleBounds(node);
    List<UiAutomationElement> mutableChildren = buildChildren(node);
    this.children = mutableChildren == null ? null : Collections.unmodifiableList(mutableChildren);
}
 
Example 10
Source File: QueryController.java    From JsDroidCmd with Mozilla Public License 2.0 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 11
Source File: AccessibilityNodeInfoDumper.java    From android-uiautomator-server with MIT License 4 votes vote down vote up
private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer, int index, int width, int height) throws IOException {
    serializer.startTag("", "node");
    if (!nafExcludedClass(node) && !nafCheck(node))
        serializer.attribute("", "NAF", Boolean.toString(true));
    serializer.attribute("", "index", Integer.toString(index));
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        serializer.attribute("", "resource-id", safeCharSeqToString(node.getViewIdResourceName()));
    }
    serializer.attribute("", "text", safeCharSeqToString(node.getText()));
    serializer.attribute("", "class", safeCharSeqToString(node.getClassName()));
    serializer.attribute("", "package", safeCharSeqToString(node.getPackageName()));
    serializer.attribute("", "content-desc", safeCharSeqToString(node.getContentDescription()));
    serializer.attribute("", "checkable", Boolean.toString(node.isCheckable()));
    serializer.attribute("", "checked", Boolean.toString(node.isChecked()));
    serializer.attribute("", "clickable", Boolean.toString(node.isClickable()));
    serializer.attribute("", "enabled", Boolean.toString(node.isEnabled()));
    serializer.attribute("", "focusable", Boolean.toString(node.isFocusable()));
    serializer.attribute("", "focused", Boolean.toString(node.isFocused()));
    serializer.attribute("", "scrollable", Boolean.toString(node.isScrollable()));
    serializer.attribute("", "long-clickable", Boolean.toString(node.isLongClickable()));
    serializer.attribute("", "password", Boolean.toString(node.isPassword()));
    serializer.attribute("", "selected", Boolean.toString(node.isSelected()));
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        serializer.attribute("", "bounds", getVisibleBoundsInScreen(node, width, height).toShortString());
    }
    int count = node.getChildCount();
    for (int i = 0; i < count; i++) {
        AccessibilityNodeInfo child = node.getChild(i);
        if (child != null) {
            if (child.isVisibleToUser()) {
                dumpNodeRec(child, serializer, i, width, height);
                child.recycle();
            } else {
                Log.i(String.format("Skipping invisible child: %s", child.toString()));
            }
        } else {
            Log.i(String.format("Null child %d/%d, parent: %s", i, count, node.toString()));
        }
    }
    serializer.endTag("", "node");
}
 
Example 12
Source File: AccessibilityNodeInfoHelpers.java    From appium-uiautomator2-server with Apache License 2.0 4 votes vote down vote up
public static boolean isVisible(@Nullable AccessibilityNodeInfo nodeInfo) {
    return nodeInfo != null && nodeInfo.isVisibleToUser();
}
 
Example 13
Source File: LaunchApp.java    From PUMA with Apache License 2.0 4 votes vote down vote up
private AccessibilityNodeInfo getScrollableNode(AccessibilityNodeInfo treeRoot) {
	List<AccessibilityNodeInfo> ret = new ArrayList<AccessibilityNodeInfo>();
	Queue<AccessibilityNodeInfo> Q = new LinkedList<AccessibilityNodeInfo>();
	Q.add(treeRoot);

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

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

		// check current node
		if (node.isVisibleToUser() && node.isEnabled() && node.isScrollable()) {
			ret.add(node);
		}

		// add its children to queue
		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
			}
		}
	}

	if (ret.isEmpty()) {
		Util.log("No scrollable node found");
		return null;
	} else {
		if (ret.size() > 1) {
			Util.log("NOTE: Found  " + ret.size() + " scrollable nodes.");
		}

		Util.log("Selected " + ret.get(0).getClassName());

		return ret.get(0);
	}
}
 
Example 14
Source File: ByMatcher.java    From JsDroidCmd with Mozilla Public License 2.0 4 votes vote down vote up
/**
 * Traverses the {@link AccessibilityNodeInfo} hierarchy starting at {@code node}, and returns
 * a list of nodes which match the {@code selector} criteria. <br />
 * <strong>Note:</strong> The caller must release each {@link AccessibilityNodeInfo} instance
 * by calling {@link AccessibilityNodeInfo#recycle()} to avoid leaking resources.
 *
 * @param node The root of the {@link AccessibilityNodeInfo} subtree we are currently searching.
 * @param index The index of this node underneath its parent.
 * @param depth The distance between {@code node} and the root node.
 * @param partialMatches The current list of {@link PartialMatch}es that need to be updated.
 * @return A {@link List} of {@link AccessibilityNodeInfo}s that meet the search criteria.
 */
private List<AccessibilityNodeInfo> findMatches(AccessibilityNodeInfo node,
        int index, int depth, SinglyLinkedList<PartialMatch> partialMatches) {

    List<AccessibilityNodeInfo> ret = new ArrayList<AccessibilityNodeInfo>();

    // Don't bother searching the subtree if it is not visible
    if (!node.isVisibleToUser()) {
        return ret;
    }

    // Update partial matches
    for (PartialMatch partialMatch : partialMatches) {
        partialMatches = partialMatch.update(node, index, depth, partialMatches);
    }

    // Create a new match, if necessary
    PartialMatch currentMatch = PartialMatch.accept(node, mSelector, index, depth);
    if (currentMatch != null) {
        partialMatches = SinglyLinkedList.prepend(currentMatch, partialMatches);
    }

    // For each child
    int numChildren = node.getChildCount();
    boolean hasNullChild = false;
    for (int i = 0; i < numChildren; i++) {
        AccessibilityNodeInfo child = node.getChild(i);
        if (child == null) {
            if (!hasNullChild) {
                Log.w(TAG, String.format("Node returned null child: %s", node.toString()));
            }
            hasNullChild = true;
            Log.w(TAG, String.format("Skipping null child (%s of %s)", i, numChildren));
            continue;
        }

        // Add any matches found under the child subtree
        ret.addAll(findMatches(child, i, depth + 1, partialMatches));

        // We're done with the child
        child.recycle();

        // Return early if we sound a match and shortCircuit is true
        if (!ret.isEmpty() && mShortCircuit) {
            return ret;
        }
    }

    // Finalize match, if necessary
    if (currentMatch != null && currentMatch.finalizeMatch()) {
        ret.add(AccessibilityNodeInfo.obtain(node));
    }

    return ret;
}
 
Example 15
Source File: AccessibilityNodeInfoDumper.java    From JsDroidCmd with Mozilla Public License 2.0 4 votes vote down vote up
private static void dumpNodeRec(AccessibilityNodeInfo node,
		XmlSerializer serializer, int index, int width, int height)
		throws IOException {
	serializer.startTag("", "node");
	if (!nafExcludedClass(node) && !nafCheck(node))
		serializer.attribute("", "NAF", Boolean.toString(true));
	serializer.attribute("", "index", Integer.toString(index));
	serializer.attribute("", "text", safeCharSeqToString(node.getText()));
	serializer.attribute("", "resource-id",
			safeCharSeqToString(node.getViewIdResourceName()));
	serializer.attribute("", "class",
			safeCharSeqToString(node.getClassName()));
	serializer.attribute("", "package",
			safeCharSeqToString(node.getPackageName()));
	serializer.attribute("", "content-desc",
			safeCharSeqToString(node.getContentDescription()));
	serializer.attribute("", "checkable",
			Boolean.toString(node.isCheckable()));
	serializer.attribute("", "checked", Boolean.toString(node.isChecked()));
	serializer.attribute("", "clickable",
			Boolean.toString(node.isClickable()));
	serializer.attribute("", "enabled", Boolean.toString(node.isEnabled()));
	serializer.attribute("", "focusable",
			Boolean.toString(node.isFocusable()));
	serializer.attribute("", "focused", Boolean.toString(node.isFocused()));
	serializer.attribute("", "scrollable",
			Boolean.toString(node.isScrollable()));
	serializer.attribute("", "long-clickable",
			Boolean.toString(node.isLongClickable()));
	serializer.attribute("", "password",
			Boolean.toString(node.isPassword()));
	serializer.attribute("", "selected",
			Boolean.toString(node.isSelected()));
	serializer.attribute("", "bounds", AccessibilityNodeInfoHelper
			.getVisibleBoundsInScreen(node, width, height).toShortString());
	int count = node.getChildCount();
	for (int i = 0; i < count; i++) {
		AccessibilityNodeInfo child = node.getChild(i);
		if (child != null) {
			if (child.isVisibleToUser()) {
				dumpNodeRec(child, serializer, i, width, height);
				child.recycle();
			} else {
				Log.i(LOGTAG,
						String.format("Skipping invisible child: %s",
								child.toString()));
			}
		} else {
			Log.i(LOGTAG, String.format("Null child %d/%d, parent: %s", i,
					count, node.toString()));
		}
	}
	serializer.endTag("", "node");
}
 
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: ViewHierarchyElementAndroid.java    From Accessibility-Test-Framework-for-Android with Apache License 2.0 4 votes vote down vote up
Builder(int id, @Nullable ViewHierarchyElementAndroid parent, AccessibilityNodeInfo fromInfo) {
  // Bookkeeping
  this.id = id;
  this.parentId = (parent != null) ? parent.getId() : null;

  // API 18+ properties
  this.resourceName = AT_18 ? fromInfo.getViewIdResourceName() : null;
  this.editable = AT_18 ? fromInfo.isEditable() : null;

  // API 16+ properties
  this.visibleToUser = AT_16 ? fromInfo.isVisibleToUser() : null;

  // API 21+ properties
  if (AT_21) {
    ImmutableList.Builder<ViewHierarchyActionAndroid> actionBuilder =
        new ImmutableList.Builder<>();
    actionBuilder.addAll(
        Lists.transform(
            fromInfo.getActionList(),
            action -> ViewHierarchyActionAndroid.newBuilder(action).build()));
    this.actionList = actionBuilder.build();
  }

  // API 24+ properties
  this.drawingOrder = AT_24 ? fromInfo.getDrawingOrder() : null;

  // API 29+ properties
  this.hasTouchDelegate = AT_29 ? (fromInfo.getTouchDelegateInfo() != null) : null;

  // Base properties
  this.className = fromInfo.getClassName();
  this.packageName = fromInfo.getPackageName();
  this.accessibilityClassName = fromInfo.getClassName();
  this.contentDescription = SpannableStringAndroid.valueOf(fromInfo.getContentDescription());
  this.text = SpannableStringAndroid.valueOf(fromInfo.getText());

  this.importantForAccessibility = true;
  this.clickable = fromInfo.isClickable();
  this.longClickable = fromInfo.isLongClickable();
  this.focusable = fromInfo.isFocusable();
  this.scrollable = fromInfo.isScrollable();
  this.canScrollForward =
      ((fromInfo.getActions() & AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) != 0);
  this.canScrollBackward =
      ((fromInfo.getActions() & AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) != 0);
  this.checkable = fromInfo.isCheckable();
  this.checked = fromInfo.isChecked();
  this.touchDelegateBounds = new ArrayList<>(); // Populated after construction
  android.graphics.Rect tempRect = new android.graphics.Rect();
  fromInfo.getBoundsInScreen(tempRect);
  this.boundsInScreen = new Rect(tempRect.left, tempRect.top, tempRect.right, tempRect.bottom);
  this.nonclippedHeight = null;
  this.nonclippedWidth = null;
  this.textSize = null;
  this.textColor = null;
  this.backgroundDrawableColor = null;
  this.typefaceStyle = null;
  this.enabled = fromInfo.isEnabled();
}
 
Example 18
Source File: ByMatcher.java    From za-Farmer with MIT License 4 votes vote down vote up
/**
     * Traverses the {@link AccessibilityNodeInfo} hierarchy starting at {@code node}, and returns
     * a list of nodes which match the {@code selector} criteria. <br />
     * <strong>Note:</strong> The caller must release each {@link AccessibilityNodeInfo} instance
     * by calling {@link AccessibilityNodeInfo#recycle()} to avoid leaking resources.
     *
     * @param node The root of the {@link AccessibilityNodeInfo} subtree we are currently searching.
     * @param index The index of this node underneath its parent.
     * @param depth The distance between {@code node} and the root node.
     * @param partialMatches The current list of {@link PartialMatch}es that need to be updated.
     * @return A {@link List} of {@link AccessibilityNodeInfo}s that meet the search criteria.
     */
    private List<AccessibilityNodeInfo> findMatches(AccessibilityNodeInfo node,
            int index, int depth, SinglyLinkedList<PartialMatch> partialMatches) {

        List<AccessibilityNodeInfo> ret = new ArrayList<AccessibilityNodeInfo>();

        // Don't bother searching the subtree if it is not visible
//        if (!node.isVisibleToUser()) {
//            return ret;
//        }

        // Update partial matches
        for (PartialMatch partialMatch : partialMatches) {
            partialMatches = partialMatch.update(node, index, depth, partialMatches);
        }

        // Create a new match, if necessary
        PartialMatch currentMatch = PartialMatch.accept(node, mSelector, index, depth);
        if (currentMatch != null) {
            partialMatches = SinglyLinkedList.prepend(currentMatch, partialMatches);
        }

        // For each child
        int numChildren = node.getChildCount();
        boolean hasNullChild = false;
        for (int i = 0; i < numChildren; i++) {
            AccessibilityNodeInfo child = node.getChild(i);
            if (child == null) {
                if (!hasNullChild) {
                    Log.w(TAG, String.format("Node returned null child: %s", node.toString()));
                }
                hasNullChild = true;
                Log.w(TAG, String.format("Skipping null child (%s of %s)", i, numChildren));
                continue;
            }

            // Add any matches found under the child subtree
            ret.addAll(findMatches(child, i, depth + 1, partialMatches));

            // We're done with the child
            child.recycle();

            // Return early if we sound a match and shortCircuit is true
            if (!ret.isEmpty() && mShortCircuit) {
                return ret;
            }
        }

        // Finalize match, if necessary
        if (currentMatch != null && currentMatch.finalizeMatch() && node.isVisibleToUser()) {
            ret.add(AccessibilityNodeInfo.obtain(node));
        }

        return ret;
    }
 
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;
}