diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index d193d6e41504d..31740ef01ad07 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12092,6 +12092,39 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return findViewTraversal(id); } + /** + * 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. + * + * Note: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. diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index fb0d80a688e4b..5b4a6f8a78e62 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -821,6 +821,24 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + @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} */ diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9cb4e5e7b0a8c..a9a0347d10f61 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -74,7 +74,6 @@ import android.view.inputmethod.InputMethodManager; 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; @@ -4462,9 +4461,6 @@ public final class ViewRootImpl extends Handler implements ViewParent, final class AccessibilityInteractionController { private static final int POOL_SIZE = 5; - private FindByAccessibilitytIdPredicate mFindByAccessibilityIdPredicate = - new FindByAccessibilitytIdPredicate(); - private ArrayList mTempAccessibilityNodeInfoList = new ArrayList(); @@ -4551,11 +4547,8 @@ public final class ViewRootImpl extends Handler implements ViewParent, 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 { @@ -4794,25 +4787,12 @@ public final class ViewRootImpl extends Handler implements ViewParent, 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 { - public int mSearchedId; - - public void init(int searchedId) { - mSearchedId = searchedId; - } - - public boolean apply(View view) { - return (view.getAccessibilityViewId() == mSearchedId); - } - } } private class SendWindowContentChangedAccessibilityEvent implements Runnable { diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java index 84ebec34e3d1f..63a0870307f79 100644 --- a/core/java/android/widget/AnalogClock.java +++ b/core/java/android/widget/AnalogClock.java @@ -25,6 +25,7 @@ import android.content.res.TypedArray; 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; @@ -228,6 +229,8 @@ public class AnalogClock extends View { mMinutes = minute + second / 60.0f; mHour = hour + mMinutes / 60.0f; mChanged = true; + + updateContentDescription(mCalendar); } private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @@ -243,4 +246,11 @@ public class AnalogClock extends View { 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); + } } diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 7444d46178a6d..f52e7739e9a37 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -237,9 +237,7 @@ public class TimePicker extends FrameLayout { } // set the content descriptions - if (AccessibilityManager.getInstance(mContext).isEnabled()) { - setContentDescriptions(); - } + setContentDescriptions(); } @Override