Skip to content

Commit aa6f3de

Browse files
committed
Some view not shown on the screen are reported for accessibility.
1. Some applications are keeping around visible views off screen to improve responsiveness by drawing them in layers, etc. While such a view is not visible on the screen the accessibility layer was reporting it since it was visible. Now the check is improved to verify whether the view is attached, is in visible window, is visible, and has a rectangle that is not clipped by its predecessors. 2. AccessibilityNodeInfo bounds in screen were not properly set since only the top left point was offset appropriately to take into account any predecessor's transformation matrix and the not transformed width and height were used. Now the bounds are properly offset. bug:6291855 Change-Id: I244d1d9af81391676c1c9e0fe86cf4574ff37225
1 parent a379eec commit aa6f3de

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

core/java/android/view/View.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4483,10 +4483,8 @@ void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
44834483
getDrawingRect(bounds);
44844484
info.setBoundsInParent(bounds);
44854485

4486-
int[] locationOnScreen = mAttachInfo.mInvalidateChildLocation;
4487-
getLocationOnScreen(locationOnScreen);
4488-
bounds.offsetTo(0, 0);
4489-
bounds.offset(locationOnScreen[0], locationOnScreen[1]);
4486+
getGlobalVisibleRect(bounds);
4487+
bounds.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
44904488
info.setBoundsInScreen(bounds);
44914489

44924490
if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {

core/java/android/view/ViewRootImpl.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5064,6 +5064,19 @@ public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String te
50645064
}
50655065
}
50665066

5067+
/**
5068+
* Computes whether a view is visible on the screen.
5069+
*
5070+
* @param view The view to check.
5071+
* @return Whether the view is visible on the screen.
5072+
*/
5073+
private boolean isDisplayedOnScreen(View view) {
5074+
return (view.mAttachInfo != null
5075+
&& view.mAttachInfo.mWindowVisibility == View.VISIBLE
5076+
&& view.getVisibility() == View.VISIBLE
5077+
&& view.getGlobalVisibleRect(mTempRect));
5078+
}
5079+
50675080
/**
50685081
* Class for managing accessibility interactions initiated from the system
50695082
* and targeting the view hierarchy. A *ClientThread method is to be
@@ -5175,7 +5188,7 @@ public void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message)
51755188
} else {
51765189
target = findViewByAccessibilityId(accessibilityViewId);
51775190
}
5178-
if (target != null && target.getVisibility() == View.VISIBLE) {
5191+
if (target != null && isDisplayedOnScreen(target)) {
51795192
getAccessibilityNodePrefetcher().prefetchAccessibilityNodeInfos(target,
51805193
virtualDescendantId, prefetchFlags, infos);
51815194
}
@@ -5231,7 +5244,7 @@ public void findAccessibilityNodeInfoByViewIdUiThread(Message message) {
52315244
}
52325245
if (root != null) {
52335246
View target = root.findViewById(viewId);
5234-
if (target != null && target.getVisibility() == View.VISIBLE) {
5247+
if (target != null && isDisplayedOnScreen(target)) {
52355248
info = target.createAccessibilityNodeInfo();
52365249
}
52375250
}
@@ -5287,7 +5300,7 @@ public void findAccessibilityNodeInfosByTextUiThread(Message message) {
52875300
} else {
52885301
target = ViewRootImpl.this.mView;
52895302
}
5290-
if (target != null && target.getVisibility() == View.VISIBLE) {
5303+
if (target != null && isDisplayedOnScreen(target)) {
52915304
AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
52925305
if (provider != null) {
52935306
infos = provider.findAccessibilityNodeInfosByText(text,
@@ -5304,7 +5317,7 @@ public void findAccessibilityNodeInfosByTextUiThread(Message message) {
53045317
final int viewCount = foundViews.size();
53055318
for (int i = 0; i < viewCount; i++) {
53065319
View foundView = foundViews.get(i);
5307-
if (foundView.getVisibility() == View.VISIBLE) {
5320+
if (isDisplayedOnScreen(foundView)) {
53085321
provider = foundView.getAccessibilityNodeProvider();
53095322
if (provider != null) {
53105323
List<AccessibilityNodeInfo> infosFromProvider =
@@ -5367,7 +5380,7 @@ public void perfromAccessibilityActionUiThread(Message message) {
53675380
boolean succeeded = false;
53685381
try {
53695382
View target = findViewByAccessibilityId(accessibilityViewId);
5370-
if (target != null && target.getVisibility() == View.VISIBLE) {
5383+
if (target != null && isDisplayedOnScreen(target)) {
53715384
AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
53725385
if (provider != null) {
53735386
succeeded = provider.performAccessibilityAction(action,
@@ -5505,7 +5518,7 @@ private void prefetchSiblingsOfRealNode(View current,
55055518
View child = parentGroup.getChildAt(i);
55065519
if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE
55075520
&& child.getAccessibilityViewId() != current.getAccessibilityViewId()
5508-
&& child.getVisibility() == View.VISIBLE) {
5521+
&& isDisplayedOnScreen(child)) {
55095522
final long childNodeId = AccessibilityNodeInfo.makeNodeId(
55105523
child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
55115524
AccessibilityNodeInfo info = null;
@@ -5533,7 +5546,7 @@ private void prefetchDescendantsOfRealNode(View root,
55335546
final int childCount = rootGroup.getChildCount();
55345547
for (int i = 0; i < childCount; i++) {
55355548
View child = rootGroup.getChildAt(i);
5536-
if (child.getVisibility() == View.VISIBLE
5549+
if (isDisplayedOnScreen(child)
55375550
&& outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
55385551
final long childNodeId = AccessibilityNodeInfo.makeNodeId(
55395552
child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);

0 commit comments

Comments
 (0)