OSDN Git Service

Accessibility services cannot obtain the source of an event coming from a root namesp...
authorSvetoslav Ganov <svetoslavganov@google.com>
Mon, 3 Oct 2011 21:18:42 +0000 (14:18 -0700)
committerSvetoslav Ganov <svetoslavganov@google.com>
Mon, 3 Oct 2011 22:07:44 +0000 (15:07 -0700)
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

core/java/android/view/View.java
core/java/android/view/ViewGroup.java
core/java/android/view/ViewRootImpl.java
core/java/android/widget/AnalogClock.java
core/java/android/widget/TimePicker.java

index d193d6e..31740ef 100644 (file)
@@ -12093,6 +12093,39 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
     }
 
     /**
+     * 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.
      *
index fb0d80a..5b4a6f8 100644 (file)
@@ -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}
      */
index 9cb4e5e..a9a0347 100644 (file)
@@ -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<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
             new ArrayList<AccessibilityNodeInfo>();
 
@@ -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<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 {
index 84ebec3..63a0870 100644 (file)
@@ -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);
+    }
 }
index 7444d46..f52e773 100644 (file)
@@ -237,9 +237,7 @@ public class TimePicker extends FrameLayout {
         }
 
         // set the content descriptions
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            setContentDescriptions();
-        }
+        setContentDescriptions();
     }
 
     @Override