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

Commit 957deabf authored by Jackal Guo's avatar Jackal Guo
Browse files

Apply the screen matrix to the boundsInScreen

View could be embedded within a SurfaceView via SurfaceControlViewHost
now. We need to apply the screen matrix to the bound after that since
the host SurfaceView may scale or offset the embedded view. Otherwise,
the boundsInScreen would be incorrect.

Bug: 148821260
Test: a11y CTS & unit tests
Change-Id: Ia590cfd20b26a9d9c58b8499098d25ad9d67f261
parent 34cbb221
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import java.lang.ref.WeakReference;
 */
final class AccessibilityEmbeddedConnection extends IAccessibilityEmbeddedConnection.Stub {
    private final WeakReference<ViewRootImpl> mViewRootImpl;
    private final Matrix mTmpScreenMatrix = new Matrix();

    AccessibilityEmbeddedConnection(ViewRootImpl viewRootImpl) {
        mViewRootImpl = new WeakReference<>(viewRootImpl);
@@ -73,9 +74,11 @@ final class AccessibilityEmbeddedConnection extends IAccessibilityEmbeddedConnec
    public void setScreenMatrix(float[] matrixValues) {
        final ViewRootImpl viewRootImpl = mViewRootImpl.get();
        if (viewRootImpl != null) {
            // TODO(b/148821260): Implement the rest of matrix values.
            viewRootImpl.mAttachInfo.mLocationInParentDisplay.set(
                    (int) matrixValues[Matrix.MTRANS_X], (int) matrixValues[Matrix.MTRANS_Y]);
            mTmpScreenMatrix.setValues(matrixValues);
            if (viewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy == null) {
                viewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy = new Matrix();
            }
            viewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy.set(mTmpScreenMatrix);
        }
    }
}
+36 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_A
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_REQUESTED_KEY;
import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY;

import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -109,6 +110,7 @@ public final class AccessibilityInteractionController {
    private final Rect mTempRect = new Rect();
    private final Rect mTempRect1 = new Rect();
    private final Rect mTempRect2 = new Rect();
    private final RectF mTempRectF = new RectF();

    private AddNodeInfosForViewId mAddNodeInfosForViewId;

@@ -855,6 +857,38 @@ public final class AccessibilityInteractionController {
        return mViewRootImpl.mAttachInfo.mLocationInParentDisplay.equals(0, 0);
    }

    private void applyScreenMatrixIfNeeded(List<AccessibilityNodeInfo> infos) {
        if (infos == null || shouldBypassApplyScreenMatrix()) {
            return;
        }
        final int infoCount = infos.size();
        for (int i = 0; i < infoCount; i++) {
            final AccessibilityNodeInfo info = infos.get(i);
            applyScreenMatrixIfNeeded(info);
        }
    }

    private void applyScreenMatrixIfNeeded(AccessibilityNodeInfo info) {
        if (info == null || shouldBypassApplyScreenMatrix()) {
            return;
        }
        final Rect boundsInScreen = mTempRect;
        final RectF transformedBounds = mTempRectF;
        final Matrix screenMatrix = mViewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy;

        info.getBoundsInScreen(boundsInScreen);
        transformedBounds.set(boundsInScreen);
        screenMatrix.mapRect(transformedBounds);
        boundsInScreen.set((int) transformedBounds.left, (int) transformedBounds.top,
                (int) transformedBounds.right, (int) transformedBounds.bottom);
        info.setBoundsInScreen(boundsInScreen);
    }

    private boolean shouldBypassApplyScreenMatrix() {
        final Matrix screenMatrix = mViewRootImpl.mAttachInfo.mScreenMatrixInEmbeddedHierarchy;
        return screenMatrix == null || screenMatrix.isIdentity();
    }

    private void associateLeashedParentIfNeeded(List<AccessibilityNodeInfo> infos) {
        if (infos == null || shouldBypassAssociateLeashedParent()) {
            return;
@@ -945,6 +979,7 @@ public final class AccessibilityInteractionController {
        try {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            associateLeashedParentIfNeeded(infos);
            applyScreenMatrixIfNeeded(infos);
            adjustBoundsInScreenIfNeeded(infos);
            // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
            // then impact the visibility result, we need to adjust visibility before apply scale.
@@ -967,6 +1002,7 @@ public final class AccessibilityInteractionController {
        try {
            mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
            associateLeashedParentIfNeeded(info);
            applyScreenMatrixIfNeeded(info);
            adjustBoundsInScreenIfNeeded(info);
            // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
            // then impact the visibility result, we need to adjust visibility before apply scale.
+6 −0
Original line number Diff line number Diff line
@@ -28820,6 +28820,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         */
        final Point mLocationInParentDisplay = new Point();
        /**
         * The screen matrix of this view when it's on a {@link SurfaceControlViewHost} that is
         * embedded within a SurfaceView.
         */
        Matrix mScreenMatrixInEmbeddedHierarchy;
        /**
         * Global to the view hierarchy used as a temporary for dealing with
         * x/y points in the transparent region computations.