public static boolean isTalkbackFocusable()

in core/src/main/java/com/facebook/testing/screenshot/layouthierarchy/AccessibilityUtil.java [505:578]


  public static boolean isTalkbackFocusable(View view) {
    if (view == null) {
      return false;
    }

    final int important = ViewCompat.getImportantForAccessibility(view);
    if (important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO
        || important == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
      return false;
    }

    // Go all the way up the tree to make sure no parent has hidden its descendants
    ViewParent parent = view.getParent();
    while (parent instanceof View) {
      if (ViewCompat.getImportantForAccessibility((View) parent)
          == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
        return false;
      }
      parent = parent.getParent();
    }

    // Trying to evaluate the focusability of certain element types (mainly list views) can cause
    // problems when trying to determine the offset of the elements Rect relative to its parent in
    // ViewGroup.offsetRectBetweenParentAndChild. If this happens, simply return false, as this view
    // will not be focusable.
    AccessibilityNodeInfoCompat node;
    try {
      node = createNodeInfoFromView(view);
    } catch (IllegalArgumentException e) {
      return false;
    }

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

    // Non-leaf nodes identical in size to their Window should not be focusable.
    if (areBoundsIdenticalToWindow(node, view) && node.getChildCount() > 0) {
      return false;
    }

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

      if (isAccessibilityFocusable(node, view)) {
        if (!hasVisibleChildren(view)) {
          // Leaves that are accessibility focusable are never ignored, even if they don't have a
          // speakable description
          return true;
        } else if (isSpeakingNode(node, view)) {
          // Node is focusable and has something to speak
          return true;
        }

        // Node is focusable and has nothing to speak
        return false;
      }

      // if view is not accessibility focusable, it needs to have text and no focusable ancestors.
      if (!hasText(node)) {
        return false;
      }

      if (!hasFocusableAncestor(node, view)) {
        return true;
      }

      return false;
    } finally {
      node.recycle();
    }
  }