Example usage for android.view.accessibility AccessibilityNodeInfo getViewIdResourceName

List of usage examples for android.view.accessibility AccessibilityNodeInfo getViewIdResourceName

Introduction

In this page you can find the example usage for android.view.accessibility AccessibilityNodeInfo getViewIdResourceName.

Prototype

public String getViewIdResourceName() 

Source Link

Document

Gets the fully qualified resource name of the source view's id.

Usage

From source file:Main.java

public static String getViewIdResourceName(AccessibilityNodeInfo nodeInfo) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        return nodeInfo.getViewIdResourceName();
    }//from  ww  w. j  a va 2s . com
    return null;
}

From source file:com.googlecode.eyesfree.brailleback.utils.LabelingUtils.java

/**
 * Gets the text of a <code>node</code> by returning the content description
 * (if available) or by returning the text. Will use the specified
 * <code>CustomLabelManager</code> as a fall back if both are null.
 * If the label manager is null, does the same funciton as
 * {@code getNodeText} in {@code AccessibilityNodeInfoUtils}
 *
 * @param node The node./*  w  ww.  j  ava2 s. c  o m*/
 * @param labelManager The label manager.
 * @return The node text.
 */
public static CharSequence getNodeText(AccessibilityNodeInfoCompat node, CustomLabelManager labelManager) {
    CharSequence text = AccessibilityNodeInfoUtils.getNodeText(node);
    if (!TextUtils.isEmpty(text)) {
        return text;
    }

    if (labelManager != null && labelManager.isInitialized()) {
        // TODO: Don't need to do this when support libs fixed.
        final AccessibilityNodeInfo unwrappedNode = (AccessibilityNodeInfo) node.getInfo();
        Label label = labelManager.getLabelForViewIdFromCache(unwrappedNode.getViewIdResourceName());
        if (label != null) {
            return label.getText();
        }
    }
    return null;
}

From source file:com.google.android.marvin.talkback.speechrules.RuleNonTextViews.java

@Override
public CharSequence format(Context context, AccessibilityNodeInfoCompat node, AccessibilityEvent event) {
    final CharSequence text = super.format(context, node, event);
    final boolean isClickable = AccessibilityNodeInfoUtils.isClickable(node);
    final boolean hasLabel = !TextUtils.isEmpty(text);

    if (hasLabel) {
        // We speak labeled images as buttons if acitonable, or simply speak
        // their text if non-actionable.
        if (isClickable) {
            return context.getString(R.string.template_button, text);
        } else {/*from w w  w.j ava2 s  .c o m*/
            return text;
        }
    } else {
        if (mLabelManager != null) {
            // TODO(caseyburkhardt): Eliminate this dance when support library is fixed.
            final AccessibilityNodeInfo unwrappedNode = (AccessibilityNodeInfo) node.getInfo();

            // Check to see if a custom label exists for the unlabeled control.
            final Label label = mLabelManager.getLabelForViewIdFromCache(unwrappedNode.getViewIdResourceName());
            if (label != null) {
                final CharSequence labelText = label.getText();
                if (isClickable) {
                    return context.getString(R.string.template_button, labelText);
                } else {
                    return labelText;
                }
            }
        }

        // We provide as much information about the control as possible in
        // the case it is unlabeled.
        final int nodeInt = (node.hashCode() % 100);
        if (isClickable) {
            return context.getString(R.string.template_unlabeled_button, nodeInt);
        } else {
            return context.getString(R.string.template_unlabeled_image_view, nodeInt);
        }
    }
}

From source file:com.google.android.marvin.talkback.menurules.RuleUnlabeledImage.java

@Override
public List<RadialMenuItem> getMenuItemsForNode(TalkBackService service, AccessibilityNodeInfoCompat node) {
    final AccessibilityNodeInfoCompat nodeCopy = AccessibilityNodeInfoCompat.obtain(node);
    // TODO(caseyburkhardt): Undo when the support library is fixed.
    final AccessibilityNodeInfo unwrappedCopy = (AccessibilityNodeInfo) nodeCopy.getInfo();
    final CustomLabelManager labelManager = service.getLabelManager();
    final List<RadialMenuItem> items = new LinkedList<RadialMenuItem>();

    final Label viewLabel = labelManager.getLabelForViewIdFromCache(unwrappedCopy.getViewIdResourceName());
    if (viewLabel == null) {
        final RadialMenuItem addLabel = new RadialMenuItem(service, RadialMenu.NONE,
                R.id.labeling_breakout_add_label, RadialMenu.NONE,
                service.getString(R.string.label_dialog_title_add));
        items.add(addLabel);//from w w  w  .  j  a  v a2  s. c om
    } else {
        final RadialMenuItem editLabel = new RadialMenuItem(service, RadialMenu.NONE,
                R.id.labeling_breakout_edit_label, RadialMenu.NONE,
                service.getString(R.string.label_dialog_title_edit));
        final RadialMenuItem removeLabel = new RadialMenuItem(service, RadialMenu.NONE,
                R.id.labeling_breakout_remove_label, RadialMenu.NONE,
                service.getString(R.string.label_dialog_title_remove));
        items.add(editLabel);
        items.add(removeLabel);
    }

    for (MenuItem item : items) {
        item.setOnMenuItemClickListener(
                new UnlabeledImageMenuItemClickListener(service, unwrappedCopy, viewLabel));
    }

    return items;
}

From source file:com.googlecode.eyesfree.brailleback.BrailleMenuNavigationMode.java

/**
 * Activates the currently selected menu item.
 *//*w w  w  .jav  a  2 s .  co  m*/
public boolean activateCurrentMenuItem() {
    // Grab the state we need before closing the menu, since that
    // clears out all state.
    final int itemId = mMenuItems.get(mCurrentIndex).getId();
    AccessibilityNodeInfoCompat node = mInitialNode.release();
    try {
        closeMenu();

        if (node == null) {
            return false;
        }

        // This must be checked before we try to grab a label.
        if (itemId == R.string.menu_item_update_talkback) {
            return launchIntentToPlayStoreTalkBack();
        }

        AccessibilityNodeInfo unwrapped = (AccessibilityNodeInfo) node.getInfo();
        final Label existingLabel = mLabelManager.getLabelForViewIdFromCache(unwrapped.getViewIdResourceName());

        if (itemId == R.string.menu_item_label_add) {
            return LabelOperationUtils.startActivityAddLabelForNode(mAccessibilityService, unwrapped);
        } else if (itemId == R.string.menu_item_label_edit) {
            return LabelOperationUtils.startActivityEditLabel(mAccessibilityService, existingLabel);
        } else if (itemId == R.string.menu_item_label_remove) {
            return LabelOperationUtils.startActivityRemoveLabel(mAccessibilityService, existingLabel);
        }
    } finally {
        AccessibilityNodeInfoUtils.recycleNodes(node);
    }
    return false;
}

From source file:com.google.android.marvin.talkback.menurules.RuleUnlabeledImage.java

@Override
public boolean accept(Context context, AccessibilityNodeInfoCompat node) {
    final AccessibilityNodeInfo unwrapped = (AccessibilityNodeInfo) node.getInfo();
    final boolean isImage = AccessibilityNodeInfoUtils.nodeMatchesClassByType(context, node,
            android.widget.ImageView.class);
    final boolean hasDescription = !TextUtils.isEmpty(AccessibilityNodeInfoUtils.getNodeText(node));
    final Pair<String, String> parsedId = CustomLabelManager
            .splitResourceName(unwrapped.getViewIdResourceName());
    final boolean hasParseableId = (parsedId != null);

    // TODO(caseyburkhardt): There are a number of views that have a
    // different resource namespace than their parent application. It's
    // likely we'll need to refine the database structure to accommodate
    // these while also allowing the user to modify them through TalkBack
    // settings. For now, we'll simply not allow labeling of such views.
    boolean isFromKnownApp = false;
    if (hasParseableId) {
        try {//from ww w.  ja  v a 2  s .c  om
            context.getPackageManager().getPackageInfo(parsedId.first, 0);
            isFromKnownApp = true;
        } catch (NameNotFoundException e) {
            // Do nothing.
        }
    }

    return (isImage && !hasDescription && hasParseableId && isFromKnownApp);
}

From source file:com.googlecode.eyesfree.brailleback.BrailleMenuNavigationMode.java

/**
 * Returns a list of menu item strings to be shown for the specified node.
 * May be empty if no items needed (already labeled by developer).
 *///from   ww  w  .j a  v  a2s.c o m
private List<MenuItem> getItemsForNode(AccessibilityNodeInfoCompat node) {
    List<MenuItem> items = new ArrayList<MenuItem>();
    AccessibilityNodeInfo unwrapped = (AccessibilityNodeInfo) node.getInfo();
    boolean hasDescription = !TextUtils.isEmpty(AccessibilityNodeInfoUtils.getNodeText(node));
    final Pair<String, String> parsedId = CustomLabelManager
            .splitResourceName(unwrapped.getViewIdResourceName());
    boolean hasParseableId = (parsedId != null);

    // TODO(caseyburkhardt): There are a number of views that have a
    // different resource namespace than their parent application. It's
    // likely we'll need to refine the database structure to accommodate
    // these while also allowing the user to modify them through TalkBack
    // settings. For now, we'll simply not allow labeling of such views.
    boolean isFromKnownApp = false;
    if (hasParseableId) {
        try {
            mAccessibilityService.getPackageManager().getPackageInfo(parsedId.first, 0);
            isFromKnownApp = true;
        } catch (NameNotFoundException e) {
            // Do nothing.
        }
    }

    // Return empty list if it has a description, has no parseable id since
    // we don't support those in the label manager right now, or if it's id
    // is in a different namespace than a known package.
    if (hasDescription || !hasParseableId || !isFromKnownApp) {
        return items;
    }

    // If label manager is not initialized, it is because user has a
    // version of TalkBack that doesn't support labeling.
    // Tell the user to update.
    if (!mLabelManager.isInitialized()) {
        items.add(new MenuItem(R.string.menu_item_update_talkback, mAccessibilityService));
        return items;
    }

    final Label viewLabel = mLabelManager.getLabelForViewIdFromCache(unwrapped.getViewIdResourceName());
    // If no custom label, only have "add" option. If there is already a
    // label we have the "edit" and "remove" options.
    if (viewLabel == null) {
        items.add(new MenuItem(R.string.menu_item_label_add, mAccessibilityService));
    } else {
        items.add(new MenuItem(R.string.menu_item_label_edit, mAccessibilityService));
        items.add(new MenuItem(R.string.menu_item_label_remove, mAccessibilityService));
    }
    return items;
}

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

@Override
public List<AccessibilityInfoCheckResult> runCheckOnInfoHierarchy(AccessibilityNodeInfo root, Context context,
        Bundle metadata) {/* w w w . j a v  a 2  s . co  m*/
    List<AccessibilityInfoCheckResult> results = new ArrayList<AccessibilityInfoCheckResult>();
    Bitmap screenCapture = null;
    if (metadata != null) {
        screenCapture = metadata.getParcelable(AccessibilityCheckMetadata.METADATA_KEY_SCREEN_CAPTURE_BITMAP);
    }

    if (screenCapture == null) {
        results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.NOT_RUN,
                "This check did not execute because it was unable to obtain screen capture data.", null));
        return results;
    }

    AccessibilityNodeInfoCompat rootCompat = new AccessibilityNodeInfoCompat(root);
    List<AccessibilityNodeInfoCompat> candidates = AccessibilityNodeInfoUtils.searchAllFromBfs(context,
            rootCompat, FILTER_CONTRAST_EVAL_ELIGIBLE);
    List<AccessibilityNodeInfoCompat> nonCandidates = AccessibilityNodeInfoUtils.searchAllFromBfs(context,
            rootCompat, FILTER_CONTRAST_EVAL_INELIGIBLE);

    // Ineligible nodes all receive NOT_RUN results
    for (AccessibilityNodeInfoCompat nonCandidate : nonCandidates) {
        AccessibilityNodeInfo unwrappedNonCandidate = (AccessibilityNodeInfo) nonCandidate.getInfo();
        results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.NOT_RUN,
                "This view's contrast was not evaluated because it contains neither text nor an image.",
                unwrappedNonCandidate));
    }

    Rect screenCaptureBounds = new Rect(0, 0, screenCapture.getWidth() - 1, screenCapture.getHeight() - 1);
    for (AccessibilityNodeInfoCompat candidate : candidates) {
        AccessibilityNodeInfo unwrappedCandidate = (AccessibilityNodeInfo) candidate.getInfo();
        Rect viewBounds = new Rect();
        unwrappedCandidate.getBoundsInScreen(viewBounds);
        if (!screenCaptureBounds.contains(viewBounds)) {
            // If an off-screen view reports itself as visible, we shouldn't evaluate it.
            String message = String.format("View bounds %1$s were not within the screen capture bounds %2$s.",
                    viewBounds, screenCaptureBounds);
            results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.NOT_RUN,
                    message, unwrappedCandidate));
            continue;
        }
        ContrastSwatch candidateSwatch = new ContrastSwatch(
                ScreenshotUtils.cropBitmap(screenCapture, viewBounds), viewBounds,
                unwrappedCandidate.getViewIdResourceName());
        double contrastRatio = candidateSwatch.getContrastRatio();
        if (AccessibilityNodeInfoUtils.nodeMatchesAnyClassByType(context, candidate, TextView.class)) {
            if (contrastRatio < ContrastUtils.CONTRAST_RATIO_WCAG_LARGE_TEXT) {
                String message = String.format(
                        "This view's foreground to background contrast ratio " + "(%1$.2f) is not sufficient.",
                        contrastRatio);
                results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.ERROR,
                        message, unwrappedCandidate));
            } else if (contrastRatio < ContrastUtils.CONTRAST_RATIO_WCAG_NORMAL_TEXT) {
                String message = String.format(
                        "This view's foreground to background contrast ratio "
                                + "(%1$.2f) may not be sufficient unless it contains large text.",
                        contrastRatio);
                results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.WARNING,
                        message, unwrappedCandidate));
            }
        } else if (AccessibilityNodeInfoUtils.nodeMatchesAnyClassByType(context, candidate, ImageView.class)) {
            // Lower confidence in heuristics for ImageViews, so we'll report only warnings and use
            // the more permissive threshold ratio since images are generally large.
            if (contrastRatio < ContrastUtils.CONTRAST_RATIO_WCAG_LARGE_TEXT) {
                String message = String.format("This image's foreground to background contrast ratio "
                        + "(%1$.2f) is not sufficient.  NOTE: This test is experimental and may be less "
                        + "accurate for some images.", contrastRatio);
                results.add(new AccessibilityInfoCheckResult(getClass(), AccessibilityCheckResultType.WARNING,
                        message, unwrappedCandidate));
            }
        }
        candidateSwatch.recycle();
    }

    AccessibilityNodeInfoUtils.recycleNodes(candidates);
    AccessibilityNodeInfoUtils.recycleNodes(nonCandidates);
    return results;
}

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

ViewHierarchyElement(int id, @Nullable ViewHierarchyElement 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;

    // Base properties
    this.className = fromInfo.getClassName();
    this.packageName = fromInfo.getPackageName();
    this.accessibilityClassName = fromInfo.getClassName();
    this.contentDescription = SpannableString.valueOf(fromInfo.getContentDescription());
    this.text = SpannableString.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.hasTouchDelegate = false; /* Touch delegates are not considered by AccessibilityServices */
    android.graphics.Rect tempRect = new android.graphics.Rect();
    fromInfo.getBoundsInScreen(tempRect);
    this.boundsInScreen = new Rect(tempRect);
    this.nonclippedHeight = null; /* AccessibilityServices cannot discover nonclipped dimensions */
    this.nonclippedWidth = null; /* AccessibilityServices cannot discover nonclipped dimensions */
    this.textSize = null;
    this.textColor = null;
    this.backgroundDrawableColor = null;
    this.typefaceStyle = null;
    this.enabled = fromInfo.isEnabled();
}