@Test public void testScrollWithParent_shouldScrollAndClearFocus() { AccessibilityNodeInfoCompat parent = AccessibilityNodeInfoCompat.obtain(); ((ShadowAccessibilityNodeInfoCompat) ShadowExtractor.extract(parent)).addChild(mCompat1); ShadowAccessibilityNodeInfo shadowParent = (ShadowAccessibilityNodeInfo) ShadowExtractor.extract(parent.getInfo()); parent.setScrollable(true); mActionNode1.recycle(); mActionNode1 = new AccessibilityNodeActionNode( mCompat1, new AccessibilityNodeInfoCompat.AccessibilityActionCompat( AccessibilityNodeInfoCompat.ACTION_CLICK, "label1")); mSelectionNode = new OptionScanSelectionNode(mActionNode1, mActionNode2); mOptionManager.clearFocusIfNewTree(mSelectionNode); mOptionManager.selectOption(0); mOptionManager.performScrollAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD); assertEquals(0, mShadowInfo1.getPerformedActions().size()); List<Integer> parentActions = shadowParent.getPerformedActions(); assertEquals(1, parentActions.size()); assertEquals( new Integer(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD), parentActions.get(0)); verify(mOverlayController, times(3)).clearOverlay(); parent.recycle(); }
public void testDeleteKey() throws Exception { // Set initial focus. AccessibilityNodeInfoCompat initial = getNodeForId(R.id.button1); initial.performAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS); mSearchNavMode.setInitialNodeToCurrent(); mSearchNavMode.onActivate(); AccessibilityNodeInfoCompat root = getNodeForId(R.id.top); assertNotNull(root); // Search and focus a result. mSearchNavMode.setQueryTextForTest("xy"); sendInputEvent(BrailleInputEvent.CMD_NAV_ITEM_NEXT); assertFocusedNodeText("xyy", root); // Test delete. sendInputEvent(BrailleInputEvent.CMD_KEY_DEL); assertEquals("x", mSearchNavMode.getQueryTextForTest()); assertFocusedNodeText("xyy", root); // Test a second delete. sendInputEvent(BrailleInputEvent.CMD_KEY_DEL); assertEquals("", mSearchNavMode.getQueryTextForTest()); assertFocusedNodeText("xyy", root); // Test a third delete. Since the query is empty now, this should escape // and bring focus back to the initial node. sendInputEvent(BrailleInputEvent.CMD_KEY_DEL); assertFalse(mSearchActive); AccessibilityNodeInfoCompat focused = getFocusedNode(root); assertEquals(initial, focused); }
private static void logNodeTree( AccessibilityNodeInfoCompat node, String indent, HashSet<AccessibilityNodeInfoCompat> seen) { if (!seen.add(node)) { LogUtils.log(TreeDebug.class, Log.VERBOSE, "Cycle: %d", node.hashCode()); return; } // Include the hash code as a "poor man's" id, knowing that it // might not always be unique. LogUtils.log( TreeDebug.class, Log.VERBOSE, "%s(%d)%s", indent, node.hashCode(), nodeDebugDescription(node)); indent += " "; int childCount = node.getChildCount(); for (int i = 0; i < childCount; ++i) { AccessibilityNodeInfoCompat child = node.getChild(i); if (child == null) { LogUtils.log(TreeDebug.class, Log.VERBOSE, "%sCouldn't get child %d", indent, i); continue; } logNodeTree(child, indent, seen); } }
/** Logs the tree using the input node as the root. */ public static void logNodeTree(AccessibilityNodeInfoCompat node) { if (node == null) { return; } HashSet<AccessibilityNodeInfoCompat> seen = new HashSet<AccessibilityNodeInfoCompat>(); logNodeTree(AccessibilityNodeInfoCompat.obtain(node), "", seen); for (AccessibilityNodeInfoCompat n : seen) { n.recycle(); } }
/** Returns the focused node or the specified root if none found. */ private AccessibilityNodeInfoCompat getFocusedNode(AccessibilityNodeInfoCompat root) { AccessibilityNodeInfoCompat focused = null; if (root != null) { focused = root.findFocus(AccessibilityNodeInfoCompat.FOCUS_ACCESSIBILITY); if (focused != null && focused.isVisibleToUser()) { return focused; } return root; } return null; }
@Override protected void onPopulateNodeForVirtualView( int virtualViewId, AccessibilityNodeInfoCompat node) { getItemBounds(virtualViewId, mTempRect); node.setContentDescription(getItemDescription(virtualViewId)); node.setBoundsInParent(mTempRect); node.addAction(AccessibilityNodeInfo.ACTION_CLICK); if (virtualViewId == mSelectedDay) { node.setSelected(true); } }
/** * Obtain a list of nodes in the order TalkBack would traverse them * * @param root The root of the tree to traverse * @return The nodes in {@code root}'s subtree (including root) in the order TalkBack would * traverse them. */ public static LinkedList<SwitchAccessNodeCompat> getNodesInTalkBackOrder( SwitchAccessNodeCompat root) { LinkedList<SwitchAccessNodeCompat> outList = new LinkedList<>(); OrderedTraversalController traversalController = new OrderedTraversalController(); traversalController.initOrder(root); AccessibilityNodeInfoCompat node = traversalController.findFirst(); while (node != null) { outList.add(new SwitchAccessNodeCompat(node.getInfo(), root.getWindowsAbove())); node = traversalController.findNext(node); } traversalController.recycle(); return outList; }
private AccessibilityNodeInfoCompat getNodeForParent() { final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain(mParentView); ViewCompat.onInitializeAccessibilityNodeInfo(mParentView, info); final LinkedList<T> items = new LinkedList<T>(); getVisibleItems(items); for (T item : items) { final int virtualDescendantId = getIdForItem(item); info.addChild(mParentView, virtualDescendantId); } return info; }
private AccessibilityNodeInfoCompat createNodeForHost() { AccessibilityNodeInfoCompat accessibilitynodeinfocompat = AccessibilityNodeInfoCompat.obtain(mView); ViewCompat.onInitializeAccessibilityNodeInfo(mView, accessibilitynodeinfocompat); Object obj = new LinkedList(); getVisibleVirtualViews(((List) (obj))); Integer integer; for (obj = ((LinkedList) (obj)).iterator(); ((Iterator) (obj)).hasNext(); accessibilitynodeinfocompat.addChild(mView, integer.intValue())) { integer = (Integer) ((Iterator) (obj)).next(); } return accessibilitynodeinfocompat; }
public void onInitializeAccessibilityNodeInfo( Object paramObject, View paramView, AccessibilityNodeInfoCompat paramAccessibilityNodeInfoCompat) { AccessibilityDelegateCompatIcs.onInitializeAccessibilityNodeInfo( paramObject, paramView, paramAccessibilityNodeInfoCompat.getInfo()); }
public void onInitializeAccessibilityNodeInfo(View var1, AccessibilityNodeInfoCompat var2) { super.onInitializeAccessibilityNodeInfo(var1, var2); NestedScrollView var4 = (NestedScrollView) var1; var2.setClassName(ScrollView.class.getName()); if (var4.isEnabled()) { int var3 = var4.getScrollRange(); if (var3 > 0) { var2.setScrollable(true); if (var4.getScrollY() > 0) { var2.addAction(8192); } if (var4.getScrollY() < var3) { var2.addAction(4096); } } } }
public void testToggleOff() throws Exception { // Set initial focus. AccessibilityNodeInfoCompat initial = getNodeForId(R.id.button1); assertTrue(initial.performAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS)); mSearchNavMode.setInitialNodeToCurrent(); mSearchNavMode.onActivate(); AccessibilityNodeInfoCompat root = getNodeForId(R.id.top); assertNotNull(root); // Search for a node. mSearchNavMode.setQueryTextForTest("xy"); sendInputEvent(BrailleInputEvent.CMD_NAV_ITEM_NEXT); assertFocusedNodeText("xyy", root); // Test toggling off. Should reset focus back to the initial. sendInputEvent(BrailleInputEvent.CMD_TOGGLE_INCREMENTAL_SEARCH); assertFalse(mSearchActive); AccessibilityNodeInfoCompat focused = getFocusedNode(root); assertEquals(initial, focused); }
@Override public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { if (virtualViewId == View.NO_ID) { return getNodeForParent(); } final T item = getItemForId(virtualViewId); if (item == null) { return null; } final AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain(); populateNodeForItemInternal(item, node); return node; }
@Override public void onInitializeAccessibilityNodeInfo(View object, AccessibilityNodeInfoCompat accessibilityNodeInfoCompat) { AccessibilityNodeInfoCompat accessibilityNodeInfoCompat2 = AccessibilityNodeInfoCompat.obtain(accessibilityNodeInfoCompat); super.onInitializeAccessibilityNodeInfo((View)object, accessibilityNodeInfoCompat2); this.copyNodeInfoNoChildren(accessibilityNodeInfoCompat, accessibilityNodeInfoCompat2); accessibilityNodeInfoCompat2.recycle(); accessibilityNodeInfoCompat.setClassName((CharSequence)SlidingPaneLayout.class.getName()); accessibilityNodeInfoCompat.setSource((View)object); object = ViewCompat.getParentForAccessibility((View)object); if (object instanceof View) { accessibilityNodeInfoCompat.setParent((View)object); } int n = SlidingPaneLayout.this.getChildCount(); for (int i = 0; i < n; ++i) { object = SlidingPaneLayout.this.getChildAt(i); if (this.filter((View)object) || object.getVisibility() != 0) continue; ViewCompat.setImportantForAccessibility((View)object, 1); accessibilityNodeInfoCompat.addChild((View)object); } }
@Override protected void onPopulateNodeForVirtualView( int virtualViewId, AccessibilityNodeInfoCompat node) { if (mVirtualViews == null || mVirtualViews.size() <= virtualViewId) { // TODO(clholgat): Remove this work around when the Android bug is fixed. // crbug.com/420177 node.setBoundsInParent(mPlaceHolderRect); node.setContentDescription(PLACE_HOLDER_STRING); return; } VirtualView view = mVirtualViews.get(virtualViewId); view.getTouchTarget(mTouchTarget); node.setBoundsInParent(rectToPx(mTouchTarget)); node.setContentDescription(view.getAccessibilityDescription()); node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK); node.addAction(AccessibilityNodeInfoCompat.ACTION_FOCUS); node.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK); }
private AccessibilityNodeInfoCompat populateNodeForItemInternal( T item, AccessibilityNodeInfoCompat node) { final int virtualDescendantId = getIdForItem(item); // Ensure the client has good defaults. node.setEnabled(true); // Allow the client to populate the node. populateNodeForItem(item, node); if (TextUtils.isEmpty(node.getText()) && TextUtils.isEmpty(node.getContentDescription())) { throw new RuntimeException( "You must add text or a content description in populateNodeForItem()"); } // Don't allow the client to override these properties. node.setPackageName(mParentView.getContext().getPackageName()); node.setClassName(item.getClass().getName()); node.setParent(mParentView); node.setSource(mParentView, virtualDescendantId); if (mFocusedItemId == virtualDescendantId) { node.addAction(AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS); } else { node.addAction(AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS); } node.getBoundsInParent(mTempParentRect); if (mTempParentRect.isEmpty()) { throw new RuntimeException("You must set parent bounds in populateNodeForItem()"); } // Set the visibility based on the parent bound. if (intersectVisibleToUser(mTempParentRect)) { node.setVisibleToUser(true); node.setBoundsInParent(mTempParentRect); } // Calculate screen-relative bound. mParentView.getLocationOnScreen(mTempGlobalRect); final int offsetX = mTempGlobalRect[0]; final int offsetY = mTempGlobalRect[1]; mTempScreenRect.set(mTempParentRect); mTempScreenRect.offset(offsetX, offsetY); node.setBoundsInScreen(mTempScreenRect); return node; }
public void onInitializeAccessibilityNodeInfo( View view, AccessibilityNodeInfoCompat accessibilitynodeinfocompat) { ViewCompatICS.onInitializeAccessibilityNodeInfo(view, accessibilitynodeinfocompat.getInfo()); }
private void copyNodeInfoNoChildren(AccessibilityNodeInfoCompat accessibilityNodeInfoCompat, AccessibilityNodeInfoCompat accessibilityNodeInfoCompat2) { Rect rect = this.mTmpRect; accessibilityNodeInfoCompat2.getBoundsInParent(rect); accessibilityNodeInfoCompat.setBoundsInParent(rect); accessibilityNodeInfoCompat2.getBoundsInScreen(rect); accessibilityNodeInfoCompat.setBoundsInScreen(rect); accessibilityNodeInfoCompat.setVisibleToUser(accessibilityNodeInfoCompat2.isVisibleToUser()); accessibilityNodeInfoCompat.setPackageName(accessibilityNodeInfoCompat2.getPackageName()); accessibilityNodeInfoCompat.setClassName(accessibilityNodeInfoCompat2.getClassName()); accessibilityNodeInfoCompat.setContentDescription(accessibilityNodeInfoCompat2.getContentDescription()); accessibilityNodeInfoCompat.setEnabled(accessibilityNodeInfoCompat2.isEnabled()); accessibilityNodeInfoCompat.setClickable(accessibilityNodeInfoCompat2.isClickable()); accessibilityNodeInfoCompat.setFocusable(accessibilityNodeInfoCompat2.isFocusable()); accessibilityNodeInfoCompat.setFocused(accessibilityNodeInfoCompat2.isFocused()); accessibilityNodeInfoCompat.setAccessibilityFocused(accessibilityNodeInfoCompat2.isAccessibilityFocused()); accessibilityNodeInfoCompat.setSelected(accessibilityNodeInfoCompat2.isSelected()); accessibilityNodeInfoCompat.setLongClickable(accessibilityNodeInfoCompat2.isLongClickable()); accessibilityNodeInfoCompat.addAction(accessibilityNodeInfoCompat2.getActions()); accessibilityNodeInfoCompat.setMovementGranularities(accessibilityNodeInfoCompat2.getMovementGranularities()); }
private void assertFocusedNodeText(String text, AccessibilityNodeInfoCompat root) { AccessibilityNodeInfoCompat focused = getFocusedNode(root); assertNotNull(focused); assertEquals(text, focused.getText()); }
/** Gets a description of the properties of a node. */ 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(); }
public final void onInitializeAccessibilityNodeInfo( View view, AccessibilityNodeInfoCompat accessibilitynodeinfocompat) { AccessibilityNodeInfoCompat accessibilitynodeinfocompat1 = AccessibilityNodeInfoCompat.obtain(accessibilitynodeinfocompat); super.onInitializeAccessibilityNodeInfo(view, accessibilitynodeinfocompat1); accessibilitynodeinfocompat.setClassName( com / roidapp / baselib / view / FixedDrawerLayout.getName()); accessibilitynodeinfocompat.setSource(view); Object obj = ViewCompat.getParentForAccessibility(view); if (obj instanceof View) { accessibilitynodeinfocompat.setParent((View) obj); } obj = b; accessibilitynodeinfocompat1.getBoundsInParent(((Rect) (obj))); accessibilitynodeinfocompat.setBoundsInParent(((Rect) (obj))); accessibilitynodeinfocompat1.getBoundsInScreen(((Rect) (obj))); accessibilitynodeinfocompat.setBoundsInScreen(((Rect) (obj))); accessibilitynodeinfocompat.setVisibleToUser(accessibilitynodeinfocompat1.isVisibleToUser()); accessibilitynodeinfocompat.setPackageName(accessibilitynodeinfocompat1.getPackageName()); accessibilitynodeinfocompat.setClassName(accessibilitynodeinfocompat1.getClassName()); accessibilitynodeinfocompat.setContentDescription( accessibilitynodeinfocompat1.getContentDescription()); accessibilitynodeinfocompat.setEnabled(accessibilitynodeinfocompat1.isEnabled()); accessibilitynodeinfocompat.setClickable(accessibilitynodeinfocompat1.isClickable()); accessibilitynodeinfocompat.setFocusable(accessibilitynodeinfocompat1.isFocusable()); accessibilitynodeinfocompat.setFocused(accessibilitynodeinfocompat1.isFocused()); accessibilitynodeinfocompat.setAccessibilityFocused( accessibilitynodeinfocompat1.isAccessibilityFocused()); accessibilitynodeinfocompat.setSelected(accessibilitynodeinfocompat1.isSelected()); accessibilitynodeinfocompat.setLongClickable(accessibilitynodeinfocompat1.isLongClickable()); accessibilitynodeinfocompat.addAction(accessibilitynodeinfocompat1.getActions()); accessibilitynodeinfocompat1.recycle(); view = (ViewGroup) view; int j = view.getChildCount(); for (int i = 0; i < j; i++) { View view1 = view.getChildAt(i); if (FixedDrawerLayout.h(view1)) { accessibilitynodeinfocompat.addChild(view1); } } }
@Override public void onInitializeAccessibilityNodeInfo(View view, AccessibilityNodeInfoCompat info) { super.onInitializeAccessibilityNodeInfo(view, info); info.setClassName(view.getClass().getName()); }
private AccessibilityNodeInfoCompat createNodeForChild(int i) { AccessibilityNodeInfoCompat accessibilitynodeinfocompat = AccessibilityNodeInfoCompat.obtain(); accessibilitynodeinfocompat.setEnabled(true); accessibilitynodeinfocompat.setClassName(DEFAULT_CLASS_NAME); onPopulateNodeForVirtualView(i, accessibilitynodeinfocompat); if (accessibilitynodeinfocompat.getText() == null && accessibilitynodeinfocompat.getContentDescription() == null) { throw new RuntimeException( "Callbacks must add text or a content description in populateNodeForVirtualViewId()"); } accessibilitynodeinfocompat.getBoundsInParent(mTempParentRect); if (mTempParentRect.isEmpty()) { throw new RuntimeException( "Callbacks must set parent bounds in populateNodeForVirtualViewId()"); } int j = accessibilitynodeinfocompat.getActions(); if ((j & 0x40) != 0) { throw new RuntimeException( "Callbacks must not add ACTION_ACCESSIBILITY_FOCUS in populateNodeForVirtualViewId()"); } if ((j & 0x80) != 0) { throw new RuntimeException( "Callbacks must not add ACTION_CLEAR_ACCESSIBILITY_FOCUS in populateNodeForVirtualViewId()"); } accessibilitynodeinfocompat.setPackageName(mView.getContext().getPackageName()); accessibilitynodeinfocompat.setSource(mView, i); accessibilitynodeinfocompat.setParent(mView); if (mFocusedVirtualViewId == i) { accessibilitynodeinfocompat.setAccessibilityFocused(true); accessibilitynodeinfocompat.addAction(128); } else { accessibilitynodeinfocompat.setAccessibilityFocused(false); accessibilitynodeinfocompat.addAction(64); } if (intersectVisibleToUser(mTempParentRect)) { accessibilitynodeinfocompat.setVisibleToUser(true); accessibilitynodeinfocompat.setBoundsInParent(mTempParentRect); } mView.getLocationOnScreen(mTempGlobalRect); i = mTempGlobalRect[0]; j = mTempGlobalRect[1]; mTempScreenRect.set(mTempParentRect); mTempScreenRect.offset(i, j); accessibilitynodeinfocompat.setBoundsInScreen(mTempScreenRect); return accessibilitynodeinfocompat; }