summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2012-05-08 11:32:20 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-05-08 11:32:20 -0700
commit6704c233390743890d23338a2329dcda5709b810 (patch)
tree0eb8ef2f3ce8baf27f326ba8fac0e2d317ffdf45 /core/java/android
parentcdbbecf357bf47e6eee6ba54caee5791834b5deb (diff)
parent0a1bb6dffc358c01e10555c5c833edb7dba69659 (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.java32
-rw-r--r--core/java/android/view/View.java60
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java27
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.