@Test public void lastDescentWithChildren_shouldReturnTrueAndSetItselfForLastChildren() { AccessibilityNodeInfo parentNode = AccessibilityNodeInfo.obtain(); parentNode.setVisibleToUser(true); parentNode.setContentDescription("Parent"); AccessibilityNodeInfo child1Node = AccessibilityNodeInfo.obtain(); child1Node.setVisibleToUser(true); child1Node.setContentDescription("Child1"); AccessibilityNodeInfo child2Node = AccessibilityNodeInfo.obtain(); child2Node.setVisibleToUser(true); child2Node.setContentDescription("Child2"); ((ShadowAccessibilityNodeInfo) ShadowExtractor.extract(parentNode)).addChild(child1Node); ((ShadowAccessibilityNodeInfo) ShadowExtractor.extract(parentNode)).addChild(child2Node); AccessibilityNodeInfoCompat parentCompat = new AccessibilityNodeInfoCompat(parentNode); AccessibilityNodeInfoRef ref = AccessibilityNodeInfoRef.obtain(parentCompat); System.out.println("lastDescentWithChildren_shouldReturnTrueAndSetItselfForLastChildren"); assertTrue(ref.lastDescendant()); assertEquals(child2Node, ref.get().getInfo()); parentNode.recycle(); child1Node.recycle(); child2Node.recycle(); ref.recycle(); }
@Override protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfo node) { final boolean hasBounds = getBoundsForDay(virtualViewId, mTempRect); if (!hasBounds) { // The day is invalid, kill the node. mTempRect.setEmpty(); node.setContentDescription(""); node.setBoundsInParent(mTempRect); node.setVisibleToUser(false); return; } node.setText(getDayText(virtualViewId)); node.setContentDescription(getDayDescription(virtualViewId)); node.setBoundsInParent(mTempRect); final boolean isDayEnabled = isDayEnabled(virtualViewId); if (isDayEnabled) { node.addAction(AccessibilityAction.ACTION_CLICK); } node.setEnabled(isDayEnabled); if (virtualViewId == mActivatedDay) { // TODO: This should use activated once that's supported. node.setChecked(true); } }
@Test public void parentWithSelfReferencedParent_shouldReturnFalse() { AccessibilityNodeInfo curNode = AccessibilityNodeInfo.obtain(); curNode.setVisibleToUser(true); AccessibilityNodeInfo parentNode = AccessibilityNodeInfo.obtain(); parentNode.setVisibleToUser(true); curNode.setContentDescription("Current"); ((ShadowAccessibilityNodeInfo) ShadowExtractor.extract(curNode)).addChild(curNode); ((ShadowAccessibilityNodeInfo) ShadowExtractor.extract(curNode)).setVisibleToUser(true); AccessibilityNodeInfoCompat currentCompat = new AccessibilityNodeInfoCompat(curNode); AccessibilityNodeInfoRef ref = AccessibilityNodeInfoRef.obtain(currentCompat); assertFalse(ref.parent()); parentNode.recycle(); curNode.recycle(); ref.recycle(); }
public void b(Object paramObject, CharSequence paramCharSequence) { ((AccessibilityNodeInfo) paramObject).setContentDescription(paramCharSequence); }
public static void sendAccessibilityEvent(final JSONObject message) { if (!sEnabled) return; final int eventType = message.optInt("eventType", -1); if (eventType < 0) { Log.e(LOGTAG, "No accessibility event type provided"); return; } if (Versions.preJB) { // Before Jelly Bean we send events directly from here while spoofing the source by setting // the package and class name manually. ThreadUtils.postToBackgroundThread( new Runnable() { @Override public void run() { sendDirectAccessibilityEvent(eventType, message); } }); } else { // In Jelly Bean we populate an AccessibilityNodeInfo with the minimal amount of data to have // it work with TalkBack. final LayerView view = GeckoAppShell.getLayerView(); if (view == null) return; if (sVirtualCursorNode == null) sVirtualCursorNode = AccessibilityNodeInfo.obtain(view, VIRTUAL_CURSOR_POSITION); sVirtualCursorNode.setEnabled(message.optBoolean("enabled", true)); sVirtualCursorNode.setClickable(message.optBoolean("clickable")); sVirtualCursorNode.setCheckable(message.optBoolean("checkable")); sVirtualCursorNode.setChecked(message.optBoolean("checked")); sVirtualCursorNode.setPassword(message.optBoolean("password")); final JSONArray textArray = message.optJSONArray("text"); StringBuilder sb = new StringBuilder(); if (textArray != null && textArray.length() > 0) { sb.append(textArray.optString(0)); for (int i = 1; i < textArray.length(); i++) { sb.append(" ").append(textArray.optString(i)); } } sVirtualCursorNode.setText(sb.toString()); sVirtualCursorNode.setContentDescription(message.optString("description")); JSONObject bounds = message.optJSONObject("bounds"); if (bounds != null) { Rect relativeBounds = new Rect( bounds.optInt("left"), bounds.optInt("top"), bounds.optInt("right"), bounds.optInt("bottom")); sVirtualCursorNode.setBoundsInParent(relativeBounds); int[] locationOnScreen = new int[2]; view.getLocationOnScreen(locationOnScreen); Rect screenBounds = new Rect(relativeBounds); screenBounds.offset(locationOnScreen[0], locationOnScreen[1]); sVirtualCursorNode.setBoundsInScreen(screenBounds); } final JSONObject braille = message.optJSONObject("brailleOutput"); if (braille != null) { sendBrailleText( view, braille.optString("text"), braille.optInt("selectionStart"), braille.optInt("selectionEnd")); } ThreadUtils.postToUiThread( new Runnable() { @Override public void run() { // If this is an accessibility focus, a lot of internal voodoo happens so we perform // an // accessibility focus action on the view, and it in turn sends the right events. switch (eventType) { case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: sEventMessage = message; view.performAccessibilityAction( AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); break; case AccessibilityEvent.TYPE_ANNOUNCEMENT: case AccessibilityEvent.TYPE_VIEW_SCROLLED: sEventMessage = null; final AccessibilityEvent accEvent = AccessibilityEvent.obtain(eventType); view.onInitializeAccessibilityEvent(accEvent); populateEventFromJSON(accEvent, message); view.getParent().requestSendAccessibilityEvent(view, accEvent); break; default: sEventMessage = message; view.sendAccessibilityEvent(eventType); break; } } }); } }