android.view.accessibility.AccessibilityNodeInfo#isVisibleToUser ( )源码实例Demo

下面列出了android.view.accessibility.AccessibilityNodeInfo#isVisibleToUser ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: RedEnvelopeAssistant   文件: RedEnvelopeHelper.java
/**获得红包详情页面打开节点*/
@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;
}
 
源代码2 项目: PUMA   文件: LaunchApp.java
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;
}
 
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;
}
 
源代码4 项目: SoloPi   文件: AccessibilityNodeTree.java
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();
}
 
源代码5 项目: za-Farmer   文件: AccessibilityNodeInfoDumper.java
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");
}
 
源代码6 项目: talkback   文件: FocusFinder.java
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;
}
 
源代码7 项目: JsDroidCmd   文件: AccessibilityNodeInfoDumper.java
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();
			}
		}
	}
}
 
源代码8 项目: UIAutomatorWD   文件: UiAutomationElement.java
/**
 * 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);
}
 
源代码9 项目: brailleback   文件: FocusFinder.java
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;
}
 
源代码10 项目: za-Farmer   文件: QueryController.java
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;
}
 
源代码11 项目: za-Farmer   文件: QueryController.java
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;
}
 
源代码12 项目: za-Farmer   文件: ByMatcher.java
/**
     * 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;
    }
 
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();
}
 
源代码14 项目: JsDroidCmd   文件: QueryController.java
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;
}
 
源代码15 项目: JsDroidCmd   文件: QueryController.java
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;
}
 
源代码16 项目: JsDroidCmd   文件: AccessibilityNodeInfoDumper.java
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");
}
 
源代码17 项目: JsDroidCmd   文件: ByMatcher.java
/**
 * 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;
}
 
源代码18 项目: PUMA   文件: LaunchApp.java
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);
	}
}
 
public static boolean isVisible(@Nullable AccessibilityNodeInfo nodeInfo) {
    return nodeInfo != null && nodeInfo.isVisibleToUser();
}
 
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");
}