Example usage for android.support.v4.view.accessibility AccessibilityNodeInfoCompat getContentDescription

List of usage examples for android.support.v4.view.accessibility AccessibilityNodeInfoCompat getContentDescription

Introduction

In this page you can find the example usage for android.support.v4.view.accessibility AccessibilityNodeInfoCompat getContentDescription.

Prototype

public CharSequence getContentDescription() 

Source Link

Document

Gets the content description of this node.

Usage

From source file:Main.java

/**
 * Returns whether the specified node has text.
 *
 * @param node The node to check.//from   w w w.  j a v  a 2s  .c  o m
 * @return {@code true} if the node has text.
 */
private static boolean hasText(AccessibilityNodeInfoCompat node) {
    if (node == null) {
        return false;
    }

    return (!TextUtils.isEmpty(node.getText()) || !TextUtils.isEmpty(node.getContentDescription()));
}

From source file:com.android.talkback.menurules.RuleSpannables.java

/**
 * Retrieves SpannableString in the accessibility node. The content description and text of the
 * node is checked in order.//from   w  ww.  j  a  va  2s.  c  om
 * @param node
 * @return SpannableString with at least 1 UrlSpan. null if no UrlSpan found in the node.
 */
private static SpannableString getStringWithUrlSpan(AccessibilityNodeInfoCompat node) {
    CharSequence text = node.getContentDescription();
    if (!TextUtils.isEmpty(text)) {
        if (!(text instanceof SpannableString)) {
            return null;
        }
    } else {
        text = node.getText();
        if (TextUtils.isEmpty(text) || !(text instanceof SpannableString)) {
            return null;
        }
    }

    SpannableString spannable = (SpannableString) text;
    final URLSpan[] urlSpans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    if (urlSpans == null || urlSpans.length == 0) {
        return null;
    }

    return spannable;
}

From source file:Main.java

/**
 * Gets the text of a <code>node</code> by returning the content description
 * (if available) or by returning the text.
 *
 * @param node The node./*from  w  w  w  . j av  a 2s .co m*/
 * @return The node text.
 */
public static CharSequence getNodeText(AccessibilityNodeInfoCompat node) {
    if (node == null) {
        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;
    }

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

    return null;
}

From source file:Main.java

/**
 * Returns whether the specified node has text or a content description.
 *
 * @param node The node to check.//from  w w  w  .  j a v  a  2s  .c o  m
 * @return {@code true} if the node has text.
 */
public static boolean hasText(@Nullable AccessibilityNodeInfoCompat node) {
    if (node == null) {
        return false;
    }

    return !TextUtils.isEmpty(node.getText()) || !TextUtils.isEmpty(node.getContentDescription());
}

From source file:com.facebook.stetho.inspector.elements.android.AccessibilityNodeInfoWrapper.java

@Nullable
public static CharSequence getDescription(AccessibilityNodeInfoCompat node, View view) {
    CharSequence contentDescription = node.getContentDescription();
    CharSequence nodeText = node.getText();

    boolean hasNodeText = !TextUtils.isEmpty(nodeText);
    boolean isEditText = view instanceof EditText;

    // EditText's prioritize their own text content over a contentDescription
    if (!TextUtils.isEmpty(contentDescription) && (!isEditText || !hasNodeText)) {
        return contentDescription;
    }//from w ww .  j  av  a  2 s .  c  o m

    if (hasNodeText) {
        return nodeText;
    }

    // If there are child views and no contentDescription the text of all non-focusable children,
    // comma separated, becomes the description.
    if (view instanceof ViewGroup) {
        final StringBuilder concatChildDescription = new StringBuilder();
        final String separator = ", ";
        ViewGroup viewGroup = (ViewGroup) view;

        for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
            final View child = viewGroup.getChildAt(i);

            AccessibilityNodeInfoCompat childNodeInfo = AccessibilityNodeInfoCompat.obtain();
            ViewCompat.onInitializeAccessibilityNodeInfo(child, childNodeInfo);

            CharSequence childNodeDescription = null;
            if (AccessibilityUtil.isSpeakingNode(childNodeInfo, child)
                    && !AccessibilityUtil.isAccessibilityFocusable(childNodeInfo, child)) {
                childNodeDescription = getDescription(childNodeInfo, child);
            }

            if (!TextUtils.isEmpty(childNodeDescription)) {
                if (concatChildDescription.length() > 0) {
                    concatChildDescription.append(separator);
                }
                concatChildDescription.append(childNodeDescription);
            }
            childNodeInfo.recycle();
        }

        return concatChildDescription.length() > 0 ? concatChildDescription.toString() : null;
    }

    return null;
}

From source file:com.android.utils.AutomationUtils.java

/**
 * Returns whether a node matches the class specified by
 * {@code className} and exactly match the text or content description
 * specified by {@code text}.//ww  w. ja v  a 2 s  .co  m
 */
private static boolean nodeMatchesFilter(AccessibilityNodeInfoCompat node, CharSequence referenceClassName,
        String findText) {

    return ClassLoadingCache.checkInstanceOf(node.getClassName(), referenceClassName)
            && (TextUtils.equals(findText, node.getText())
                    || TextUtils.equals(findText, node.getContentDescription()));

}

From source file:com.android.talkback.speechrules.NodeSpeechRuleProcessor.java

/**
 * Determines whether the node has a contentDescription that should cause its subtree's
 * description to be ignored.// w w  w  .  j  a  v a  2  s  .  co m
 * The traditional behavior in TalkBack has been to return {@code true} for any node with a
 * non-empty contentDescription. In this function, we thus whitelist certain roles where it
 * doesn't make sense for the contentDescription to override the entire subtree.
 */
private static boolean hasOverridingContentDescription(AccessibilityNodeInfoCompat node) {
    switch (Role.getRole(node)) {
    case Role.ROLE_PAGER:
    case Role.ROLE_GRID:
    case Role.ROLE_LIST:
        return false;
    default:
        return node != null && !TextUtils.isEmpty(node.getContentDescription());
    }
}

From source file:com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckUtils.java

/**
 * Retrieve text for a node, which may include text from children of the node. This text is an
 * approximation of, but not always identical to, what TalkBack would speak for the node. One
 * difference is that there are no separators between the speakable text from different nodes.
 *
 * @param info The info whose text should be returned.
 *
 * @return Speakable text derived from the info and its children. Returns an empty string if there
 *         is no such text, and {@code null} if {@code info == null}.
 *//*  w  w w .  j a v a2s.c  o m*/
static CharSequence getSpeakableTextForInfo(AccessibilityNodeInfo info) {
    if (info == null) {
        return null;
    }

    /* getLabeledBy for API 17+ */
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {

        AccessibilityNodeInfo labeledBy = info.getLabeledBy();
        if (labeledBy != null) {
            /* There could be a chain of labeledBy. Make sure it isn't a loop */
            Set<AccessibilityNodeInfo> infosVisited = new HashSet<>();
            infosVisited.add(info);
            infosVisited.add(labeledBy);
            AccessibilityNodeInfo endOfLabeledByChain = labeledBy.getLabeledBy();
            while (endOfLabeledByChain != null) {
                if (infosVisited.contains(endOfLabeledByChain)) {
                    infosVisited.remove(info);
                    for (AccessibilityNodeInfo infoVisited : infosVisited) {
                        infoVisited.recycle();
                    }
                    return null;
                }
                infosVisited.add(endOfLabeledByChain);
                labeledBy = endOfLabeledByChain;
                endOfLabeledByChain = labeledBy.getLabeledBy();
            }
            CharSequence labelText = getSpeakableTextForInfo(labeledBy);
            infosVisited.remove(info);
            for (AccessibilityNodeInfo infoVisited : infosVisited) {
                infoVisited.recycle();
            }
            return labelText;
        }
    }

    AccessibilityNodeInfoCompat compat = new AccessibilityNodeInfoCompat(info);

    // TODO(caseburkhardt) Pull in TalkBack's actual logic
    CharSequence nodeText = AccessibilityNodeInfoUtils.getNodeText(compat);
    StringBuilder returnStringBuilder = new StringBuilder((nodeText == null) ? "" : nodeText);
    /* If this node has a contentDescription, it overrides anything in children */
    if (TextUtils.isEmpty(compat.getContentDescription())) {
        for (int i = 0; i < compat.getChildCount(); ++i) {
            AccessibilityNodeInfoCompat child = compat.getChild(i);
            if (AccessibilityNodeInfoUtils.isVisibleOrLegacy(child)
                    && !AccessibilityNodeInfoUtils.isActionableForAccessibility(child)) {
                returnStringBuilder.append(getSpeakableTextForInfo((AccessibilityNodeInfo) child.getInfo()));
            }
        }
    }
    return returnStringBuilder;
}

From source file:com.googlecode.eyesfree.utils.TreeDebug.java

/**
 * Gets a description of the properties of a node.
 *///from w w  w . j a  v a 2  s .  co m
public static CharSequence nodeDebugDescription(AccessibilityNodeInfoCompat node) {
    StringBuilder sb = new StringBuilder();
    sb.append(node.getWindowId());

    if (node.getClassName() != null) {
        appendSimpleName(sb, node.getClassName());
    } else {
        sb.append("??");
    }

    if (!node.isVisibleToUser()) {
        sb.append(":invisible");
    }

    if (node.getText() != null) {
        sb.append(":");
        sb.append(node.getText().toString().trim());
    }

    if (node.getContentDescription() != null) {
        sb.append(":");
        sb.append(node.getContentDescription().toString().trim());
    }

    int actions = node.getActions();
    if (actions != 0) {
        sb.append(":");
        if ((actions & AccessibilityNodeInfoCompat.ACTION_FOCUS) != 0) {
            sb.append("F");
        }
        if ((actions & AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS) != 0) {
            sb.append("A");
        }
        if ((actions & AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS) != 0) {
            sb.append("a");
        }
        if ((actions & AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD) != 0) {
            sb.append("-");
        }
        if ((actions & AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD) != 0) {
            sb.append("+");
        }
    }

    if (node.isCheckable()) {
        sb.append(":");
        if (node.isChecked()) {
            sb.append("(X)");
        } else {
            sb.append("( )");
        }
    }

    if (node.isFocusable()) {
        sb.append(":focusable");
    }

    if (node.isFocused()) {
        sb.append(":focused");
    }

    if (node.isSelected()) {
        sb.append(":selected");
    }

    if (node.isClickable()) {
        sb.append(":clickable");
    }

    if (node.isLongClickable()) {
        sb.append(":longClickable");
    }

    if (node.isAccessibilityFocused()) {
        sb.append(":accessibilityFocused");
    }

    if (!node.isEnabled()) {
        sb.append(":disabled");
    }

    return sb.toString();
}

From source file:com.google.android.marvin.utils.AutomationUtils.java

/**
 * Returns whether a node matches the class specified by
 * {@code className} and exactly match the text or content description
 * specified by {@code text}.//w  w w  .j av  a2  s .  c  om
 */
private static boolean nodeMatchesFilter(Context context, AccessibilityNodeInfoCompat node,
        CharSequence referenceClassName, String findText) {
    final ClassLoadingManager loader = ClassLoadingManager.getInstance();
    final CharSequence nodeClass = node.getClassName();
    final CharSequence nodePackage = node.getPackageName();

    if (!loader.checkInstanceOf(context, nodeClass, nodePackage, referenceClassName)) {
        return false;
    }

    final CharSequence nodeText = node.getText();
    if (TextUtils.equals(findText, nodeText)) {
        return true;
    }

    final CharSequence nodeDesc = node.getContentDescription();
    if (TextUtils.equals(findText, nodeDesc)) {
        return true;
    }

    return false;
}