diff options
| author | Svetoslav Ganov <svetoslavganov@google.com> | 2012-05-08 11:32:20 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-05-08 11:32:20 -0700 |
| commit | 6704c233390743890d23338a2329dcda5709b810 (patch) | |
| tree | 0eb8ef2f3ce8baf27f326ba8fac0e2d317ffdf45 /core/java/android | |
| parent | cdbbecf357bf47e6eee6ba54caee5791834b5deb (diff) | |
| parent | 0a1bb6dffc358c01e10555c5c833edb7dba69659 (diff) | |
Merge "AccessibilityNodeInfo for visible views should reported." into jb-dev
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/view/AccessibilityInteractionController.java | 32 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 60 | ||||
| -rw-r--r-- | core/java/android/view/accessibility/AccessibilityNodeInfo.java | 27 |
3 files changed, 102 insertions, 17 deletions
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index 63871486ade6..881594da0a1a 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -126,6 +126,16 @@ final class AccessibilityInteractionController { } } + private boolean isShown(View view) { + // The first two checks are made also made by isShown() which + // however traverses the tree up to the parent to catch that. + // Therefore, we do some fail fast check to minimize the up + // tree traversal. + return (view.mAttachInfo != null + && view.mAttachInfo.mWindowVisibility == View.VISIBLE + && view.isShown()); + } + public void findAccessibilityNodeInfoByAccessibilityIdClientThread( long accessibilityNodeId, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, @@ -174,7 +184,7 @@ final class AccessibilityInteractionController { } else { root = findViewByAccessibilityId(accessibilityViewId); } - if (root != null && root.isDisplayedOnScreen()) { + if (root != null && isShown(root)) { mPrefetcher.prefetchAccessibilityNodeInfos(root, virtualDescendantId, flags, infos); } } finally { @@ -236,7 +246,7 @@ final class AccessibilityInteractionController { } if (root != null) { View target = root.findViewById(viewId); - if (target != null && target.isDisplayedOnScreen()) { + if (target != null && isShown(target)) { info = target.createAccessibilityNodeInfo(); } } @@ -298,7 +308,7 @@ final class AccessibilityInteractionController { } else { root = mViewRootImpl.mView; } - if (root != null && root.isDisplayedOnScreen()) { + if (root != null && isShown(root)) { AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider(); if (provider != null) { infos = provider.findAccessibilityNodeInfosByText(text, @@ -315,7 +325,7 @@ final class AccessibilityInteractionController { final int viewCount = foundViews.size(); for (int i = 0; i < viewCount; i++) { View foundView = foundViews.get(i); - if (foundView.isDisplayedOnScreen()) { + if (isShown(foundView)) { provider = foundView.getAccessibilityNodeProvider(); if (provider != null) { List<AccessibilityNodeInfo> infosFromProvider = @@ -390,7 +400,7 @@ final class AccessibilityInteractionController { } else { root = mViewRootImpl.mView; } - if (root != null && root.isDisplayedOnScreen()) { + if (root != null && isShown(root)) { switch (focusType) { case AccessibilityNodeInfo.FOCUS_ACCESSIBILITY: { View host = mViewRootImpl.mAccessibilityFocusedHost; @@ -411,7 +421,7 @@ final class AccessibilityInteractionController { case AccessibilityNodeInfo.FOCUS_INPUT: { // Input focus cannot go to virtual views. View target = root.findFocus(); - if (target != null && target.isDisplayedOnScreen()) { + if (target != null && isShown(target)) { focused = target.createAccessibilityNodeInfo(); } } break; @@ -477,7 +487,7 @@ final class AccessibilityInteractionController { } else { root = mViewRootImpl.mView; } - if (root != null && root.isDisplayedOnScreen()) { + if (root != null && isShown(root)) { if ((direction & View.FOCUS_ACCESSIBILITY) == View.FOCUS_ACCESSIBILITY) { AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider(); if (provider != null) { @@ -565,7 +575,7 @@ final class AccessibilityInteractionController { } else { target = mViewRootImpl.mView; } - if (target != null && target.isDisplayedOnScreen()) { + if (target != null && isShown(target)) { AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider(); if (provider != null) { succeeded = provider.performAction(virtualDescendantId, action, @@ -590,7 +600,7 @@ final class AccessibilityInteractionController { return null; } View foundView = root.findViewByAccessibilityId(accessibilityId); - if (foundView != null && !foundView.isDisplayedOnScreen()) { + if (foundView != null && !isShown(foundView)) { return null; } return foundView; @@ -670,7 +680,7 @@ final class AccessibilityInteractionController { } View child = children.getChildAt(i); if (child.getAccessibilityViewId() != current.getAccessibilityViewId() - && child.isDisplayedOnScreen()) { + && isShown(child)) { AccessibilityNodeInfo info = null; AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); if (provider == null) { @@ -706,7 +716,7 @@ final class AccessibilityInteractionController { return; } View child = children.getChildAt(i); - if (child.isDisplayedOnScreen()) { + if (isShown(child)) { AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider(); if (provider == null) { AccessibilityNodeInfo info = child.createAccessibilityNodeInfo(); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 4d2bc42a141d..8053238e567e 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -4666,6 +4666,51 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } /** + * Gets the location of this view in screen coordintates. + * + * @param outRect The output location + */ + private void getBoundsOnScreen(Rect outRect) { + if (mAttachInfo == null) { + return; + } + + RectF position = mAttachInfo.mTmpTransformRect; + position.setEmpty(); + + if (!hasIdentityMatrix()) { + getMatrix().mapRect(position); + } + + position.offset(mLeft, mRight); + + ViewParent parent = mParent; + while (parent instanceof View) { + View parentView = (View) parent; + + position.offset(-parentView.mScrollX, -parentView.mScrollY); + + if (!parentView.hasIdentityMatrix()) { + parentView.getMatrix().mapRect(position); + } + + position.offset(parentView.mLeft, parentView.mTop); + + parent = parentView.mParent; + } + + if (parent instanceof ViewRootImpl) { + ViewRootImpl viewRootImpl = (ViewRootImpl) parent; + position.offset(0, -viewRootImpl.mCurScrollY); + } + + position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop); + + outRect.set((int) (position.left + 0.5f), (int) (position.top + 0.5f), + (int) (position.right + 0.5f), (int) (position.bottom + 0.5f)); + } + + /** * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo) * * Note: Called from the default {@link AccessibilityDelegate}. @@ -4675,8 +4720,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal getDrawingRect(bounds); info.setBoundsInParent(bounds); - getGlobalVisibleRect(bounds); - bounds.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop); + getBoundsOnScreen(bounds); info.setBoundsInScreen(bounds); if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) { @@ -4686,6 +4730,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } } + info.setVisibleToUser(isVisibleToUser()); + info.setPackageName(mContext.getPackageName()); info.setClassName(View.class.getName()); info.setContentDescription(getContentDescription()); @@ -4736,11 +4782,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } /** - * Computes whether this view is visible on the screen. + * Computes whether this view is visible to the user. Such a view is + * attached, visible, all its predecessors are visible, it is not clipped + * entirely by its predecessors, and has an alpha greater than zero. * * @return Whether the view is visible on the screen. */ - boolean isDisplayedOnScreen() { + private boolean isVisibleToUser() { // The first two checks are made also made by isShown() which // however traverses the tree up to the parent to catch that. // Therefore, we do some fail fast check to minimize the up @@ -6395,9 +6443,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal boolean includeForAccessibility() { if (mAttachInfo != null) { if (!mAttachInfo.mIncludeNotImportantViews) { - return isImportantForAccessibility() && isDisplayedOnScreen(); + return isImportantForAccessibility(); } else { - return isDisplayedOnScreen(); + return true; } } return false; diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index fef24e265062..6b14ba5e3723 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -287,6 +287,8 @@ public class AccessibilityNodeInfo implements Parcelable { private static final int PROPERTY_ACCESSIBILITY_FOCUSED = 0x00000400; + private static final int PROPERTY_VISIBLE_TO_USER = 0x00000800; + /** * Bits that provide the id of a virtual descendant of a view. */ @@ -910,6 +912,31 @@ public class AccessibilityNodeInfo implements Parcelable { } /** + * Sets whether this node is visible to the user. + * + * @return Whether the node is visible to the user. + */ + public boolean isVisibleToUser() { + return getBooleanProperty(PROPERTY_VISIBLE_TO_USER); + } + + /** + * Sets whether this node is visible to the user. + * <p> + * <strong>Note:</strong> Cannot be called from an + * {@link android.accessibilityservice.AccessibilityService}. + * This class is made immutable before being delivered to an AccessibilityService. + * </p> + * + * @param visibleToUser Whether the node is visible to the user. + * + * @throws IllegalStateException If called from an AccessibilityService. + */ + public void setVisibleToUser(boolean visibleToUser) { + setBooleanProperty(PROPERTY_VISIBLE_TO_USER, visibleToUser); + } + + /** * Gets whether this node is accessibility focused. * * @return True if the node is accessibility focused. |
