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

Commit 882145e7 authored by Rhed Jao's avatar Rhed Jao
Browse files

Improve A11yNodeInfo visibility for magnification

Returns visible if device enables magnification and node is visible
but outside of magnified area.

Bug: 79162853
Bug: 79531479
Test: atest AccessibilityMagnificationTest
Change-Id: I481bd5c3d73d01c0cd8b3e0ebd7a1584c9ae7064
parent 036426c7
Loading
Loading
Loading
Loading
+6 −35
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import android.text.style.AccessibilityClickableSpan;
import android.text.style.ClickableSpan;
import android.util.LongSparseArray;
import android.util.Slog;
import android.view.View.AttachInfo;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeIdManager;
@@ -903,38 +902,6 @@ public final class AccessibilityInteractionController {
                }
            }
        }

        if (spec != null) {
            AttachInfo attachInfo = mViewRootImpl.mAttachInfo;
            if (attachInfo.mDisplay == null) {
                return;
            }

            final float scale = attachInfo.mApplicationScale * spec.scale;

            Rect visibleWinFrame = mTempRect1;
            visibleWinFrame.left = (int) (attachInfo.mWindowLeft * scale + spec.offsetX);
            visibleWinFrame.top = (int) (attachInfo.mWindowTop * scale + spec.offsetY);
            visibleWinFrame.right = (int) (visibleWinFrame.left + mViewRootImpl.mWidth * scale);
            visibleWinFrame.bottom = (int) (visibleWinFrame.top + mViewRootImpl.mHeight * scale);

            attachInfo.mDisplay.getRealSize(mTempPoint);
            final int displayWidth = mTempPoint.x;
            final int displayHeight = mTempPoint.y;

            Rect visibleDisplayFrame = mTempRect2;
            visibleDisplayFrame.set(0, 0, displayWidth, displayHeight);

            if (!visibleWinFrame.intersect(visibleDisplayFrame)) {
                // If there's no intersection with display, set visibleWinFrame empty.
                visibleDisplayFrame.setEmpty();
            }

            if (!visibleWinFrame.intersects(boundsInScreen.left, boundsInScreen.top,
                    boundsInScreen.right, boundsInScreen.bottom)) {
                info.setVisibleToUser(false);
            }
        }
    }

    private boolean shouldApplyAppScaleAndMagnificationSpec(float appScale,
@@ -948,8 +915,10 @@ public final class AccessibilityInteractionController {
        try {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            adjustBoundsInScreenIfNeeded(infos);
            applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
            // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
            // then impact the visibility result, we need to adjust visibility before apply scale.
            adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
            applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
            callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
            if (infos != null) {
                infos.clear();
@@ -967,8 +936,10 @@ public final class AccessibilityInteractionController {
        try {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            adjustBoundsInScreenIfNeeded(info);
            applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
            // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
            // then impact the visibility result, we need to adjust visibility before apply scale.
            adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
            applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
            callback.setFindAccessibilityNodeInfoResult(info, interactionId);
        } catch (RemoteException re) {
                /* ignore - the other side will time out */
+17 −0
Original line number Diff line number Diff line
@@ -1688,6 +1688,11 @@ public class AccessibilityNodeInfo implements Parcelable {
     * Instead it represents the result of {@link View#getParentForAccessibility()},
     * which returns the closest ancestor where {@link View#isImportantForAccessibility()} is true.
     * So this method is not reliable.
     * <p>
     * When magnification is enabled, the bounds in parent are also scaled up by magnification
     * scale. For example, it returns Rect(20, 20, 200, 200) for original bounds
     * Rect(10, 10, 100, 100), when the magnification scale is 2.
     * <p/>
     *
     * @param outBounds The output node bounds.
     * @deprecated Use {@link #getBoundsInScreen(Rect)} instead.
@@ -1725,6 +1730,12 @@ public class AccessibilityNodeInfo implements Parcelable {

    /**
     * Gets the node bounds in screen coordinates.
     * <p>
     * When magnification is enabled, the bounds in screen are scaled up by magnification scale
     * and the positions are also adjusted according to the offset of magnification viewport.
     * For example, it returns Rect(-180, -180, 0, 0) for original bounds Rect(10, 10, 100, 100),
     * when the magnification scale is 2 and offsets for X and Y are both 200.
     * <p/>
     *
     * @param outBounds The output node bounds.
     */
@@ -1861,6 +1872,12 @@ public class AccessibilityNodeInfo implements Parcelable {

    /**
     * Gets whether this node is visible to the user.
     * <p>
     * Between {@link Build.VERSION_CODES#JELLY_BEAN API 16} and
     * {@link Build.VERSION_CODES#Q API 29}, this method may incorrectly return false when
     * magnification is enabled. On other versions, a node is considered visible even if it is not
     * on the screen because magnification is active.
     * </p>
     *
     * @return Whether the node is visible to the user.
     */