Skip to content

Commit 6704c23

Browse files
sganovAndroid (Google) Code Review
authored andcommitted
Merge "AccessibilityNodeInfo for visible views should reported." into jb-dev
2 parents cdbbecf + 0a1bb6d commit 6704c23

File tree

4 files changed

+104
-17
lines changed

4 files changed

+104
-17
lines changed

api/current.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25180,6 +25180,7 @@ package android.view.accessibility {
2518025180
method public boolean isPassword();
2518125181
method public boolean isScrollable();
2518225182
method public boolean isSelected();
25183+
method public boolean isVisibleToUser();
2518325184
method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View);
2518425185
method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View, int);
2518525186
method public static android.view.accessibility.AccessibilityNodeInfo obtain();
@@ -25209,6 +25210,7 @@ package android.view.accessibility {
2520925210
method public void setSource(android.view.View);
2521025211
method public void setSource(android.view.View, int);
2521125212
method public void setText(java.lang.CharSequence);
25213+
method public void setVisibleToUser(boolean);
2521225214
method public void writeToParcel(android.os.Parcel, int);
2521325215
field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
2521425216
field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";

core/java/android/view/AccessibilityInteractionController.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ private void clear() {
126126
}
127127
}
128128

129+
private boolean isShown(View view) {
130+
// The first two checks are made also made by isShown() which
131+
// however traverses the tree up to the parent to catch that.
132+
// Therefore, we do some fail fast check to minimize the up
133+
// tree traversal.
134+
return (view.mAttachInfo != null
135+
&& view.mAttachInfo.mWindowVisibility == View.VISIBLE
136+
&& view.isShown());
137+
}
138+
129139
public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
130140
long accessibilityNodeId, int interactionId,
131141
IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
@@ -174,7 +184,7 @@ private void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message)
174184
} else {
175185
root = findViewByAccessibilityId(accessibilityViewId);
176186
}
177-
if (root != null && root.isDisplayedOnScreen()) {
187+
if (root != null && isShown(root)) {
178188
mPrefetcher.prefetchAccessibilityNodeInfos(root, virtualDescendantId, flags, infos);
179189
}
180190
} finally {
@@ -236,7 +246,7 @@ private void findAccessibilityNodeInfoByViewIdUiThread(Message message) {
236246
}
237247
if (root != null) {
238248
View target = root.findViewById(viewId);
239-
if (target != null && target.isDisplayedOnScreen()) {
249+
if (target != null && isShown(target)) {
240250
info = target.createAccessibilityNodeInfo();
241251
}
242252
}
@@ -298,7 +308,7 @@ private void findAccessibilityNodeInfosByTextUiThread(Message message) {
298308
} else {
299309
root = mViewRootImpl.mView;
300310
}
301-
if (root != null && root.isDisplayedOnScreen()) {
311+
if (root != null && isShown(root)) {
302312
AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
303313
if (provider != null) {
304314
infos = provider.findAccessibilityNodeInfosByText(text,
@@ -315,7 +325,7 @@ private void findAccessibilityNodeInfosByTextUiThread(Message message) {
315325
final int viewCount = foundViews.size();
316326
for (int i = 0; i < viewCount; i++) {
317327
View foundView = foundViews.get(i);
318-
if (foundView.isDisplayedOnScreen()) {
328+
if (isShown(foundView)) {
319329
provider = foundView.getAccessibilityNodeProvider();
320330
if (provider != null) {
321331
List<AccessibilityNodeInfo> infosFromProvider =
@@ -390,7 +400,7 @@ private void findFocusUiThread(Message message) {
390400
} else {
391401
root = mViewRootImpl.mView;
392402
}
393-
if (root != null && root.isDisplayedOnScreen()) {
403+
if (root != null && isShown(root)) {
394404
switch (focusType) {
395405
case AccessibilityNodeInfo.FOCUS_ACCESSIBILITY: {
396406
View host = mViewRootImpl.mAccessibilityFocusedHost;
@@ -411,7 +421,7 @@ private void findFocusUiThread(Message message) {
411421
case AccessibilityNodeInfo.FOCUS_INPUT: {
412422
// Input focus cannot go to virtual views.
413423
View target = root.findFocus();
414-
if (target != null && target.isDisplayedOnScreen()) {
424+
if (target != null && isShown(target)) {
415425
focused = target.createAccessibilityNodeInfo();
416426
}
417427
} break;
@@ -477,7 +487,7 @@ private void focusSearchUiThread(Message message) {
477487
} else {
478488
root = mViewRootImpl.mView;
479489
}
480-
if (root != null && root.isDisplayedOnScreen()) {
490+
if (root != null && isShown(root)) {
481491
if ((direction & View.FOCUS_ACCESSIBILITY) == View.FOCUS_ACCESSIBILITY) {
482492
AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
483493
if (provider != null) {
@@ -565,7 +575,7 @@ private void perfromAccessibilityActionUiThread(Message message) {
565575
} else {
566576
target = mViewRootImpl.mView;
567577
}
568-
if (target != null && target.isDisplayedOnScreen()) {
578+
if (target != null && isShown(target)) {
569579
AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
570580
if (provider != null) {
571581
succeeded = provider.performAction(virtualDescendantId, action,
@@ -590,7 +600,7 @@ private View findViewByAccessibilityId(int accessibilityId) {
590600
return null;
591601
}
592602
View foundView = root.findViewByAccessibilityId(accessibilityId);
593-
if (foundView != null && !foundView.isDisplayedOnScreen()) {
603+
if (foundView != null && !isShown(foundView)) {
594604
return null;
595605
}
596606
return foundView;
@@ -670,7 +680,7 @@ private void prefetchSiblingsOfRealNode(View current,
670680
}
671681
View child = children.getChildAt(i);
672682
if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
673-
&& child.isDisplayedOnScreen()) {
683+
&& isShown(child)) {
674684
AccessibilityNodeInfo info = null;
675685
AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
676686
if (provider == null) {
@@ -706,7 +716,7 @@ private void prefetchDescendantsOfRealNode(View root,
706716
return;
707717
}
708718
View child = children.getChildAt(i);
709-
if (child.isDisplayedOnScreen()) {
719+
if (isShown(child)) {
710720
AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
711721
if (provider == null) {
712722
AccessibilityNodeInfo info = child.createAccessibilityNodeInfo();

core/java/android/view/View.java

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4665,6 +4665,51 @@ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
46654665
}
46664666
}
46674667

4668+
/**
4669+
* Gets the location of this view in screen coordintates.
4670+
*
4671+
* @param outRect The output location
4672+
*/
4673+
private void getBoundsOnScreen(Rect outRect) {
4674+
if (mAttachInfo == null) {
4675+
return;
4676+
}
4677+
4678+
RectF position = mAttachInfo.mTmpTransformRect;
4679+
position.setEmpty();
4680+
4681+
if (!hasIdentityMatrix()) {
4682+
getMatrix().mapRect(position);
4683+
}
4684+
4685+
position.offset(mLeft, mRight);
4686+
4687+
ViewParent parent = mParent;
4688+
while (parent instanceof View) {
4689+
View parentView = (View) parent;
4690+
4691+
position.offset(-parentView.mScrollX, -parentView.mScrollY);
4692+
4693+
if (!parentView.hasIdentityMatrix()) {
4694+
parentView.getMatrix().mapRect(position);
4695+
}
4696+
4697+
position.offset(parentView.mLeft, parentView.mTop);
4698+
4699+
parent = parentView.mParent;
4700+
}
4701+
4702+
if (parent instanceof ViewRootImpl) {
4703+
ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
4704+
position.offset(0, -viewRootImpl.mCurScrollY);
4705+
}
4706+
4707+
position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
4708+
4709+
outRect.set((int) (position.left + 0.5f), (int) (position.top + 0.5f),
4710+
(int) (position.right + 0.5f), (int) (position.bottom + 0.5f));
4711+
}
4712+
46684713
/**
46694714
* @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
46704715
*
@@ -4675,8 +4720,7 @@ void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
46754720
getDrawingRect(bounds);
46764721
info.setBoundsInParent(bounds);
46774722

4678-
getGlobalVisibleRect(bounds);
4679-
bounds.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
4723+
getBoundsOnScreen(bounds);
46804724
info.setBoundsInScreen(bounds);
46814725

46824726
if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
@@ -4686,6 +4730,8 @@ void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
46864730
}
46874731
}
46884732

4733+
info.setVisibleToUser(isVisibleToUser());
4734+
46894735
info.setPackageName(mContext.getPackageName());
46904736
info.setClassName(View.class.getName());
46914737
info.setContentDescription(getContentDescription());
@@ -4736,11 +4782,13 @@ void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
47364782
}
47374783

47384784
/**
4739-
* Computes whether this view is visible on the screen.
4785+
* Computes whether this view is visible to the user. Such a view is
4786+
* attached, visible, all its predecessors are visible, it is not clipped
4787+
* entirely by its predecessors, and has an alpha greater than zero.
47404788
*
47414789
* @return Whether the view is visible on the screen.
47424790
*/
4743-
boolean isDisplayedOnScreen() {
4791+
private boolean isVisibleToUser() {
47444792
// The first two checks are made also made by isShown() which
47454793
// however traverses the tree up to the parent to catch that.
47464794
// Therefore, we do some fail fast check to minimize the up
@@ -6395,9 +6443,9 @@ public void addChildrenForAccessibility(ArrayList<View> children) {
63956443
boolean includeForAccessibility() {
63966444
if (mAttachInfo != null) {
63976445
if (!mAttachInfo.mIncludeNotImportantViews) {
6398-
return isImportantForAccessibility() && isDisplayedOnScreen();
6446+
return isImportantForAccessibility();
63996447
} else {
6400-
return isDisplayedOnScreen();
6448+
return true;
64016449
}
64026450
}
64036451
return false;

core/java/android/view/accessibility/AccessibilityNodeInfo.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ public class AccessibilityNodeInfo implements Parcelable {
287287

288288
private static final int PROPERTY_ACCESSIBILITY_FOCUSED = 0x00000400;
289289

290+
private static final int PROPERTY_VISIBLE_TO_USER = 0x00000800;
291+
290292
/**
291293
* Bits that provide the id of a virtual descendant of a view.
292294
*/
@@ -909,6 +911,31 @@ public void setFocused(boolean focused) {
909911
setBooleanProperty(PROPERTY_FOCUSED, focused);
910912
}
911913

914+
/**
915+
* Sets whether this node is visible to the user.
916+
*
917+
* @return Whether the node is visible to the user.
918+
*/
919+
public boolean isVisibleToUser() {
920+
return getBooleanProperty(PROPERTY_VISIBLE_TO_USER);
921+
}
922+
923+
/**
924+
* Sets whether this node is visible to the user.
925+
* <p>
926+
* <strong>Note:</strong> Cannot be called from an
927+
* {@link android.accessibilityservice.AccessibilityService}.
928+
* This class is made immutable before being delivered to an AccessibilityService.
929+
* </p>
930+
*
931+
* @param visibleToUser Whether the node is visible to the user.
932+
*
933+
* @throws IllegalStateException If called from an AccessibilityService.
934+
*/
935+
public void setVisibleToUser(boolean visibleToUser) {
936+
setBooleanProperty(PROPERTY_VISIBLE_TO_USER, visibleToUser);
937+
}
938+
912939
/**
913940
* Gets whether this node is accessibility focused.
914941
*

0 commit comments

Comments
 (0)