Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11b5c309 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by The Android Automerger
Browse files

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
parent 7420a7cd
Loading
Loading
Loading
Loading
+2 −4
Original line number Original line Diff line number Diff line
@@ -4483,10 +4483,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        getDrawingRect(bounds);
        getDrawingRect(bounds);
        info.setBoundsInParent(bounds);
        info.setBoundsInParent(bounds);
        int[] locationOnScreen = mAttachInfo.mInvalidateChildLocation;
        getGlobalVisibleRect(bounds);
        getLocationOnScreen(locationOnScreen);
        bounds.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
        bounds.offsetTo(0, 0);
        bounds.offset(locationOnScreen[0], locationOnScreen[1]);
        info.setBoundsInScreen(bounds);
        info.setBoundsInScreen(bounds);
        if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
        if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
+20 −7
Original line number Original line Diff line number Diff line
@@ -5064,6 +5064,19 @@ public final class ViewRootImpl implements ViewParent,
        }
        }
    }
    }


    /**
     * Computes whether a view is visible on the screen.
     *
     * @param view The view to check.
     * @return Whether the view is visible on the screen.
     */
    private boolean isDisplayedOnScreen(View view) {
        return (view.mAttachInfo != null
                && view.mAttachInfo.mWindowVisibility == View.VISIBLE
                && view.getVisibility() == View.VISIBLE
                && view.getGlobalVisibleRect(mTempRect));
    }

    /**
    /**
     * Class for managing accessibility interactions initiated from the system
     * Class for managing accessibility interactions initiated from the system
     * and targeting the view hierarchy. A *ClientThread method is to be
     * and targeting the view hierarchy. A *ClientThread method is to be
@@ -5175,7 +5188,7 @@ public final class ViewRootImpl implements ViewParent,
                } else {
                } else {
                    target = findViewByAccessibilityId(accessibilityViewId);
                    target = findViewByAccessibilityId(accessibilityViewId);
                }
                }
                if (target != null && target.getVisibility() == View.VISIBLE) {
                if (target != null && isDisplayedOnScreen(target)) {
                    getAccessibilityNodePrefetcher().prefetchAccessibilityNodeInfos(target,
                    getAccessibilityNodePrefetcher().prefetchAccessibilityNodeInfos(target,
                            virtualDescendantId, prefetchFlags, infos);
                            virtualDescendantId, prefetchFlags, infos);
                }
                }
@@ -5231,7 +5244,7 @@ public final class ViewRootImpl implements ViewParent,
                }
                }
                if (root != null) {
                if (root != null) {
                    View target = root.findViewById(viewId);
                    View target = root.findViewById(viewId);
                    if (target != null && target.getVisibility() == View.VISIBLE) {
                    if (target != null && isDisplayedOnScreen(target)) {
                        info = target.createAccessibilityNodeInfo();
                        info = target.createAccessibilityNodeInfo();
                    }
                    }
                }
                }
@@ -5287,7 +5300,7 @@ public final class ViewRootImpl implements ViewParent,
                } else {
                } else {
                    target = ViewRootImpl.this.mView;
                    target = ViewRootImpl.this.mView;
                }
                }
                if (target != null && target.getVisibility() == View.VISIBLE) {
                if (target != null && isDisplayedOnScreen(target)) {
                    AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                    AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                    if (provider != null) {
                    if (provider != null) {
                        infos = provider.findAccessibilityNodeInfosByText(text,
                        infos = provider.findAccessibilityNodeInfosByText(text,
@@ -5304,7 +5317,7 @@ public final class ViewRootImpl implements ViewParent,
                            final int viewCount = foundViews.size();
                            final int viewCount = foundViews.size();
                            for (int i = 0; i < viewCount; i++) {
                            for (int i = 0; i < viewCount; i++) {
                                View foundView = foundViews.get(i);
                                View foundView = foundViews.get(i);
                                if (foundView.getVisibility() == View.VISIBLE) {
                                if (isDisplayedOnScreen(foundView)) {
                                    provider = foundView.getAccessibilityNodeProvider();
                                    provider = foundView.getAccessibilityNodeProvider();
                                    if (provider != null) {
                                    if (provider != null) {
                                        List<AccessibilityNodeInfo> infosFromProvider =
                                        List<AccessibilityNodeInfo> infosFromProvider =
@@ -5367,7 +5380,7 @@ public final class ViewRootImpl implements ViewParent,
            boolean succeeded = false;
            boolean succeeded = false;
            try {
            try {
                View target = findViewByAccessibilityId(accessibilityViewId);
                View target = findViewByAccessibilityId(accessibilityViewId);
                if (target != null && target.getVisibility() == View.VISIBLE) {
                if (target != null && isDisplayedOnScreen(target)) {
                    AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                    AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                    if (provider != null) {
                    if (provider != null) {
                        succeeded = provider.performAccessibilityAction(action,
                        succeeded = provider.performAccessibilityAction(action,
@@ -5505,7 +5518,7 @@ public final class ViewRootImpl implements ViewParent,
                    View child = parentGroup.getChildAt(i);
                    View child = parentGroup.getChildAt(i);
                    if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE
                    if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE
                            && child.getAccessibilityViewId() != current.getAccessibilityViewId()
                            && child.getAccessibilityViewId() != current.getAccessibilityViewId()
                            && child.getVisibility() == View.VISIBLE) {
                            && isDisplayedOnScreen(child)) {
                        final long childNodeId = AccessibilityNodeInfo.makeNodeId(
                        final long childNodeId = AccessibilityNodeInfo.makeNodeId(
                                child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
                                child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
                        AccessibilityNodeInfo info = null;
                        AccessibilityNodeInfo info = null;
@@ -5533,7 +5546,7 @@ public final class ViewRootImpl implements ViewParent,
                final int childCount = rootGroup.getChildCount();
                final int childCount = rootGroup.getChildCount();
                for (int i = 0; i < childCount; i++) {
                for (int i = 0; i < childCount; i++) {
                    View child = rootGroup.getChildAt(i);
                    View child = rootGroup.getChildAt(i);
                    if (child.getVisibility() == View.VISIBLE
                    if (isDisplayedOnScreen(child)
                            && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                            && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                        final long childNodeId = AccessibilityNodeInfo.makeNodeId(
                        final long childNodeId = AccessibilityNodeInfo.makeNodeId(
                                child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
                                child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);