diff --git a/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/ViewDescriptor.java b/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/ViewDescriptor.java index 9c3b24379..3acf19eb3 100644 --- a/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/ViewDescriptor.java +++ b/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/ViewDescriptor.java @@ -196,8 +196,7 @@ public class ViewDescriptor extends NodeDescriptor { } return Arrays.asList( - new Named<>("View", viewProps.build()), - new Named<>("Accessibility", getAccessibilityData(node))); + new Named<>("View", viewProps.build())); } @Override @@ -205,36 +204,13 @@ public class ViewDescriptor extends NodeDescriptor { return Arrays.asList( new Named<>(axNodeInfoPropsTitle, AccessibilityUtil.getAccessibilityNodeInfoData(node)), new Named<>(axTalkbackPropsTitle, AccessibilityUtil.getTalkbackData(node)), - new Named<>(axViewPropsTitle, AccessibilityUtil.getViewAXData(node))); - } - - private static SonarObject getAccessibilityData(View view) { - final SonarObject.Builder accessibilityProps = new SonarObject.Builder(); - - // This needs to be an empty string to be mutable. See t20470623. - CharSequence contentDescription = - view.getContentDescription() != null ? view.getContentDescription() : ""; - accessibilityProps.put("content-description", InspectorValue.mutable(contentDescription)); - accessibilityProps.put("focusable", InspectorValue.mutable(view.isFocusable())); - accessibilityProps.put("node-info", AccessibilityUtil.getAccessibilityNodeInfoProperties(view)); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - accessibilityProps.put( - "important-for-accessibility", - AccessibilityUtil.sImportantForAccessibilityMapping.get( - view.getImportantForAccessibility())); - } - - AccessibilityUtil.addTalkbackProperties(accessibilityProps, view); - - return accessibilityProps.build(); + new Named<>(axViewPropsTitle, AccessibilityUtil.getViewData(node))); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @Override public void setValue(View node, String[] path, SonarDynamic value) { - if (path[0].equals("Accessibility") - || path[0].equals(axViewPropsTitle) + if (path[0].equals(axViewPropsTitle) || path[0].equals(axNodeInfoPropsTitle) || path[0].equals(axTalkbackPropsTitle)) { setAccessibilityValue(node, path, value); diff --git a/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/utils/AccessibilityUtil.java b/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/utils/AccessibilityUtil.java index d0dae9271..3fc03f3ee 100644 --- a/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/utils/AccessibilityUtil.java +++ b/android/src/main/java/com/facebook/sonar/plugins/inspector/descriptors/utils/AccessibilityUtil.java @@ -510,75 +510,6 @@ public final class AccessibilityUtil { } } - /** - * Creates a {@link SonarObject} of useful properties of AccessibilityNodeInfo, to be shown in the - * Sonar Layout Inspector. All properties are immutable since they are all derived from various - * {@link View} properties. - * - * @param view The {@link View} to derive the AccessibilityNodeInfo properties from. - * @return {@link SonarObject} containing the properties. - */ - @Nullable - public static SonarObject getAccessibilityNodeInfoProperties(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("clickable", nodeInfo.isClickable()) - .put("content-description", nodeInfo.getContentDescription()) - .put("text", nodeInfo.getText()) - .put("accessibility-focused", nodeInfo.isAccessibilityFocused()) - .put("long-clickable", nodeInfo.isLongClickable()) - .put("focusable", nodeInfo.isFocusable()); - - 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(); - } - /** * Creates a {@link SonarObject} of useful properties of AccessibilityNodeInfo, to be shown in the * Sonar Layout Inspector accessibility extension. All properties are immutable since they are all derived from @@ -697,7 +628,7 @@ public final class AccessibilityUtil { } } - public static SonarObject getViewAXData(View view) { + public static SonarObject getViewData(View view) { final SonarObject.Builder props = new SonarObject.Builder(); // This needs to be an empty string to be mutable. See t20470623. diff --git a/android/src/main/java/com/facebook/sonar/plugins/litho/DebugComponentDescriptor.java b/android/src/main/java/com/facebook/sonar/plugins/litho/DebugComponentDescriptor.java index fb6220c6b..611972e64 100644 --- a/android/src/main/java/com/facebook/sonar/plugins/litho/DebugComponentDescriptor.java +++ b/android/src/main/java/com/facebook/sonar/plugins/litho/DebugComponentDescriptor.java @@ -2,8 +2,6 @@ package com.facebook.sonar.plugins.litho; -import static com.facebook.litho.annotations.ImportantForAccessibility.IMPORTANT_FOR_ACCESSIBILITY_NO; -import static com.facebook.litho.annotations.ImportantForAccessibility.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS; import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Color; import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Enum; import static com.facebook.sonar.plugins.inspector.InspectorValue.Type.Number; @@ -30,8 +28,6 @@ import com.facebook.sonar.plugins.inspector.Named; import com.facebook.sonar.plugins.inspector.NodeDescriptor; import com.facebook.sonar.plugins.inspector.Touch; import com.facebook.sonar.plugins.inspector.descriptors.ObjectDescriptor; -import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityRoleUtil; -import com.facebook.sonar.plugins.inspector.descriptors.utils.AccessibilityUtil; import com.facebook.yoga.YogaAlign; import com.facebook.yoga.YogaDirection; import com.facebook.yoga.YogaEdge; @@ -49,9 +45,6 @@ import javax.annotation.Nullable; public class DebugComponentDescriptor extends NodeDescriptor { - private static final String axViewPropsTitle = "DebugLayoutNode"; - private static final String axNodeInfoPropsTitle = "NodeInfo & TalkBack"; - private Map>> mOverrides = new HashMap<>(); private DebugComponent.Overrider mOverrider = new DebugComponent.Overrider() { @@ -100,10 +93,6 @@ public class DebugComponentDescriptor extends NodeDescriptor { override.second); } catch (Exception ignored) { } - } else if (override.first[0].equals("Accessibility") - || override.first[0].equals(axViewPropsTitle) - || override.first[0].equals(axNodeInfoPropsTitle)) { - applyAccessibilityOverride(node, override.first[1], override.second); } } } @@ -175,98 +164,9 @@ public class DebugComponentDescriptor extends NodeDescriptor { data.add(new Named<>("State", stateData)); } - final SonarObject accessibilityData = getAccessibilityData(node); - if (accessibilityData != null) { - data.add(new Named<>("Accessibility", accessibilityData)); - } - return data; } - @Override - public List> getAXData(DebugComponent node) throws Exception { - NodeDescriptor componentDescriptor = descriptorForClass(node.getComponent().getClass()); - if (componentDescriptor.getClass() != ObjectDescriptor.class) { - return componentDescriptor.getAXData(node.getComponent()); - } - final List> sections = new ArrayList<>(); - - final SonarObject derivedData = getDerivedAXData(node); - if (derivedData != null) { - sections.add(new Named<>(axNodeInfoPropsTitle, derivedData)); - } - - final SonarObject viewData = getViewAXData(node); - if (viewData != null) { - sections.add(new Named<>(axViewPropsTitle, viewData)); - } - - return sections; - } - - @Nullable - private static SonarObject getViewAXData(DebugComponent node) { - final DebugLayoutNode layout = node.getLayoutNode(); - if (layout == null) { - return null; - } - - final SonarObject.Builder props = new SonarObject.Builder(); - - // This needs to be an empty string to be mutable. See t20470623. - final CharSequence contentDescription = - layout.getContentDescription() != null ? layout.getContentDescription() : ""; - props.put("content-description", InspectorValue.mutable(contentDescription)); - props.put("focusable", InspectorValue.mutable(layout.getFocusable())); - props.put( - "important-for-accessibility", - AccessibilityUtil.sImportantForAccessibilityMapping.get( - layout.getImportantForAccessibility())); - - return props.build(); - } - - @Nullable - private static SonarObject getDerivedAXData(DebugComponent node) { - final DebugLayoutNode layout = node.getLayoutNode(); - if (layout == null) { - return null; - } - - final View hostView = node.getComponentHost(); - final SonarObject.Builder props = new SonarObject.Builder(); - - // No host view exists, so this component is inherently not accessible. Add the reason why this - // is the case and then return. - if (hostView == node.getLithoView() || hostView == null) { - final int importantForAccessibility = layout.getImportantForAccessibility(); - final boolean isAccessibilityEnabled = - AccessibilityUtil.isAccessibilityEnabled(node.getContext()); - String ignoredReason; - - if (!isAccessibilityEnabled) { - ignoredReason = "No accessibility service is running."; - } else if (importantForAccessibility == IMPORTANT_FOR_ACCESSIBILITY_NO) { - ignoredReason = "Component has importantForAccessibility set to NO."; - } else if (importantForAccessibility == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { - ignoredReason = "Component has importantForAccessibility set to NO_HIDE_DESCENDANTS."; - } else { - ignoredReason = "Component does not have content, or accessibility handlers."; - } - - props.put("talkback-ignored", true); - props.put("talkback-ignored-reasons", ignoredReason); - - return props.build(); - } - - // host view exists so add node info and TalkBack properties - props.put("node-info", AccessibilityUtil.getAccessibilityNodeInfoData(hostView)); - AccessibilityUtil.addTalkbackProperties(props, hostView); - - return props.build(); - } - @Nullable private static SonarObject getLayoutData(DebugComponent node) { final DebugLayoutNode layout = node.getLayoutNode(); @@ -466,57 +366,6 @@ public class DebugComponentDescriptor extends NodeDescriptor { return false; } - @Nullable - private static SonarObject getAccessibilityData(DebugComponent node) { - final DebugLayoutNode layout = node.getLayoutNode(); - if (layout == null) { - return null; - } - - final View hostView = node.getComponentHost(); - final SonarObject.Builder accessibilityProps = new SonarObject.Builder(); - - // This needs to be an empty string to be mutable. See t20470623. - final CharSequence contentDescription = - layout.getContentDescription() != null ? layout.getContentDescription() : ""; - accessibilityProps.put("content-description", InspectorValue.mutable(contentDescription)); - accessibilityProps.put("focusable", InspectorValue.mutable(layout.getFocusable())); - accessibilityProps.put( - "important-for-accessibility", - AccessibilityUtil.sImportantForAccessibilityMapping.get( - layout.getImportantForAccessibility())); - - // No host view exists, so this component is inherently not accessible. Add the reason why this - // is the case and then return. - if (hostView == node.getLithoView() || hostView == null) { - final int importantForAccessibility = layout.getImportantForAccessibility(); - final boolean isAccessibilityEnabled = - AccessibilityUtil.isAccessibilityEnabled(node.getContext()); - String ignoredReason; - - if (!isAccessibilityEnabled) { - ignoredReason = "No accessibility service is running."; - } else if (importantForAccessibility == IMPORTANT_FOR_ACCESSIBILITY_NO) { - ignoredReason = "Component has importantForAccessibility set to NO."; - } else if (importantForAccessibility == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) { - ignoredReason = "Component has importantForAccessibility set to NO_HIDE_DESCENDANTS."; - } else { - ignoredReason = "Component does not have content, or accessibility handlers."; - } - - accessibilityProps.put("talkback-ignored", true); - accessibilityProps.put("talkback-ignored-reasons", ignoredReason); - - return accessibilityProps.build(); - } - - accessibilityProps.put( - "node-info", AccessibilityUtil.getAccessibilityNodeInfoProperties(hostView)); - AccessibilityUtil.addTalkbackProperties(accessibilityProps, hostView); - - return accessibilityProps.build(); - } - @Override public void setValue(DebugComponent node, String[] path, SonarDynamic value) { List> overrides = mOverrides.get(node.getGlobalKey()); @@ -547,17 +396,6 @@ public class DebugComponentDescriptor extends NodeDescriptor { return attributes; } - @Override - public List> getAXAttributes(DebugComponent node) { - final View hostView = node.getComponentHost(); - List> attributes = new ArrayList<>(); - String role = AccessibilityRoleUtil.getRole(hostView).toString(); - if (!role.equals("NONE")) { - attributes.add(new Named<>("role", role)); - } - return attributes; - } - @Override public SonarObject getExtraInfo(DebugComponent node) { SonarObject.Builder extraInfo = new SonarObject.Builder(); @@ -659,22 +497,6 @@ public class DebugComponentDescriptor extends NodeDescriptor { return descriptor.matches(query, node); } - private static void applyAccessibilityOverride( - DebugLayoutNode node, String key, SonarDynamic value) { - switch (key) { - case "focusable": - node.setFocusable(value.asBoolean()); - break; - case "important-for-accessibility": - node.setImportantForAccessibility( - AccessibilityUtil.sImportantForAccessibilityMapping.get(value.asString())); - break; - case "content-description": - node.setContentDescription(value.asString()); - break; - } - } - private static void applyLayoutOverride(DebugLayoutNode node, String[] path, SonarDynamic value) { switch (path[0]) { case "background":