1. The user can touch the screen at an arbitrary location potentially crossing the root namespace
bounday which will send an accessibility event to accessibility services and they should be able
to obtain the event source. Also accessibility ids are guaranteed to be unique in the window.
Added a package scoped findViewByAccessibilityId method that dives into nested root namespaces.
2. Added accessibility support to the AnalogClock.
bug:
5405934
Change-Id: I84edcb554bae41aafcbbc2723c5e62c1ef8a6ddf
}
/**
+ * Finds a view by its unuque and stable accessibility id.
+ *
+ * @param accessibilityId The searched accessibility id.
+ * @return The found view.
+ */
+ final View findViewByAccessibilityId(int accessibilityId) {
+ if (accessibilityId < 0) {
+ return null;
+ }
+ return findViewByAccessibilityIdTraversal(accessibilityId);
+ }
+
+ /**
+ * Performs the traversal to find a view by its unuque and stable accessibility id.
+ *
+ * <strong>Note:</strong>This method does not stop at the root namespace
+ * boundary since the user can touch the screen at an arbitrary location
+ * potentially crossing the root namespace bounday which will send an
+ * accessibility event to accessibility services and they should be able
+ * to obtain the event source. Also accessibility ids are guaranteed to be
+ * unique in the window.
+ *
+ * @param accessibilityId The accessibility id.
+ * @return The found view.
+ */
+ View findViewByAccessibilityIdTraversal(int accessibilityId) {
+ if (getAccessibilityViewId() == accessibilityId) {
+ return this;
+ }
+ return null;
+ }
+
+ /**
* Look for a child view with the given tag. If this view has the given
* tag, return this view.
*
}
}
+ @Override
+ View findViewByAccessibilityIdTraversal(int accessibilityId) {
+ View foundView = super.findViewByAccessibilityIdTraversal(accessibilityId);
+ if (foundView != null) {
+ return foundView;
+ }
+ final int childrenCount = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i = 0; i < childrenCount; i++) {
+ View child = children[i];
+ foundView = child.findViewByAccessibilityIdTraversal(accessibilityId);
+ if (foundView != null) {
+ return foundView;
+ }
+ }
+ return null;
+ }
+
/**
* {@inheritDoc}
*/
import android.widget.Scroller;
import com.android.internal.policy.PolicyManager;
-import com.android.internal.util.Predicate;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
final class AccessibilityInteractionController {
private static final int POOL_SIZE = 5;
- private FindByAccessibilitytIdPredicate mFindByAccessibilityIdPredicate =
- new FindByAccessibilitytIdPredicate();
-
private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
new ArrayList<AccessibilityNodeInfo>();
AccessibilityNodeInfo info = null;
try {
- FindByAccessibilitytIdPredicate predicate = mFindByAccessibilityIdPredicate;
- predicate.init(accessibilityId);
- View root = ViewRootImpl.this.mView;
- View target = root.findViewByPredicate(predicate);
- if (target != null && target.getVisibility() == View.VISIBLE) {
+ View target = findViewByAccessibilityId(accessibilityId);
+ if (target != null) {
info = target.createAccessibilityNodeInfo();
}
} finally {
if (root == null) {
return null;
}
- mFindByAccessibilityIdPredicate.init(accessibilityId);
- View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate);
- if (foundView == null || foundView.getVisibility() != View.VISIBLE) {
+ View foundView = root.findViewByAccessibilityId(accessibilityId);
+ if (foundView != null && foundView.getVisibility() != View.VISIBLE) {
return null;
}
return foundView;
}
-
- private final class FindByAccessibilitytIdPredicate implements Predicate<View> {
- public int mSearchedId;
-
- public void init(int searchedId) {
- mSearchedId = searchedId;
- }
-
- public boolean apply(View view) {
- return (view.getAccessibilityViewId() == mSearchedId);
- }
- }
}
private class SendWindowContentChangedAccessibilityEvent implements Runnable {
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.View;
mMinutes = minute + second / 60.0f;
mHour = hour + mMinutes / 60.0f;
mChanged = true;
+
+ updateContentDescription(mCalendar);
}
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
invalidate();
}
};
+
+ private void updateContentDescription(Time time) {
+ final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
+ String contentDescription = DateUtils.formatDateTime(mContext,
+ time.toMillis(false), flags);
+ setContentDescription(contentDescription);
+ }
}
}
// set the content descriptions
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- setContentDescriptions();
- }
+ setContentDescriptions();
}
@Override