Use views not components for Litho nodes in AX tree + more sidebar props

Summary: Switches the tree to use the view hierarchy for Litho nodes rather than Litho component hierarchy since Accessibility services interact with the views rendered. Includes a few more properties in the accessibility sidebar and updates to the segmented sidebar based on derived/non-derived properties for all views. Also adds functions to the AccessibilityUtil to be able to work on the accessibility sidebar while still leaving the non-accessibility sidebar unchanged. Eventually the accessibility panel will be removed from 'normal' mode and the original functions will no longer be necessary.

Reviewed By: blavalla

Differential Revision: D8881739

fbshipit-source-id: 9ce37e8f18025538cba2c86c0895ee38d13d024b
This commit is contained in:
Sara Valderrama
2018-07-18 17:01:17 -07:00
committed by Facebook Github Bot
parent b28e96624d
commit 0244f15dab
4 changed files with 200 additions and 44 deletions

View File

@@ -336,6 +336,90 @@ public final class AccessibilityUtil {
return nodeInfoProps.build();
}
/**
* Creates a {@link SonarObject} of useful properties of AccessibilityNodeInfo, to be shown in the
* Sonar Layout Inspector extension. All properties are immutable since they are all derived from
* various {@link View} properties. This is a more complete list than
* getAccessibilityNodeInfoProperties returns.
*
* @param view The {@link View} to derive the AccessibilityNodeInfo properties from.
* @return {@link SonarObject} containing the properties.
*/
@Nullable
public static SonarObject getAXNodeInfoProperties(View view) {
final AccessibilityNodeInfoCompat nodeInfo =
ViewAccessibilityHelper.createNodeInfoFromView(view);
if (nodeInfo == null) {
return null;
}
final SonarObject.Builder nodeInfoProps = new SonarObject.Builder();
final Rect bounds = new Rect();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
final SonarArray.Builder actionsArrayBuilder = new SonarArray.Builder();
for (AccessibilityNodeInfoCompat.AccessibilityActionCompat action :
nodeInfo.getActionList()) {
final String actionLabel = (String) action.getLabel();
if (actionLabel != null) {
actionsArrayBuilder.put(actionLabel);
} else {
actionsArrayBuilder.put(
AccessibilityUtil.sAccessibilityActionMapping.get(action.getId(), false));
}
}
nodeInfoProps.put("actions", actionsArrayBuilder.build());
}
nodeInfoProps
.put("checkable", nodeInfo.isCheckable())
.put("checked", nodeInfo.isChecked())
.put("clickable", nodeInfo.isClickable())
.put("content-description", nodeInfo.getContentDescription())
.put("content-invalid", nodeInfo.isContentInvalid())
.put("context-clickable", nodeInfo.isContextClickable())
.put("dismissable", nodeInfo.isDismissable())
.put("drawing-order", nodeInfo.getDrawingOrder())
.put("editable", nodeInfo.isEditable())
.put("enabled", nodeInfo.isEnabled())
.put("focusable", nodeInfo.isFocusable())
.put("focused", nodeInfo.isAccessibilityFocused())
.put("important-for-accessibility", nodeInfo.isImportantForAccessibility())
.put("long-clickable", nodeInfo.isLongClickable())
.put("multiline", nodeInfo.isMultiLine())
.put("password", nodeInfo.isPassword())
.put("scrollable", nodeInfo.isScrollable())
.put("selected", nodeInfo.isSelected())
.put("text", nodeInfo.getText())
.put("visible-to-user", nodeInfo.isVisibleToUser());
nodeInfo.getBoundsInParent(bounds);
nodeInfoProps.put(
"parent-bounds",
new SonarObject.Builder()
.put("width", bounds.width())
.put("height", bounds.height())
.put("top", bounds.top)
.put("left", bounds.left)
.put("bottom", bounds.bottom)
.put("right", bounds.right));
nodeInfo.getBoundsInScreen(bounds);
nodeInfoProps.put(
"screen-bounds",
new SonarObject.Builder()
.put("width", bounds.width())
.put("height", bounds.height())
.put("top", bounds.top)
.put("left", bounds.left)
.put("bottom", bounds.bottom)
.put("right", bounds.right));
nodeInfo.recycle();
return nodeInfoProps.build();
}
/**
* Modifies a {@link SonarObject.Builder} to add Talkback-specific Accessibiltiy properties to be
* shown in the Sonar Layout Inspector.
@@ -392,8 +476,10 @@ public final class AccessibilityUtil {
.put("talkback-description", description == null ? "" : description);
}
SonarObject axProps = getAccessibilityNodeInfoProperties(view);
props.put("node-info", axProps == null ? "null" : axProps);
SonarObject axNodeInfo = getAXNodeInfoProperties(view);
if (axNodeInfo != null) {
props.put("node-info", axNodeInfo);
}
return props.build();
}