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

Commit 197230a3 authored by Candice Lo's avatar Candice Lo Committed by Android (Google) Code Review
Browse files

Merge changes from topic "update_window_magnifier_bottom_boundary" into main

* changes:
  fix(window magnification): Update the boundary for window magnifier at the bottom
  Create aconfig flag update_window_magnifier_bottom_boundary
parents 80fb40fa c2d58ee0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -119,6 +119,16 @@ flag {
    }
}

flag {
    name: "update_window_magnifier_bottom_boundary"
    namespace: "accessibility"
    description: "Update the window magnifier boundary at the bottom to the top of the system gesture inset."
    bug: "380320995"
    metadata {
      purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "hearing_devices_dialog_related_tools"
    namespace: "accessibility"
+2 −2
Original line number Diff line number Diff line
@@ -203,8 +203,8 @@ class WindowMagnificationAnimationController implements ValueAnimator.AnimatorUp
            return;
        }
        final float currentScale = mController.getScale();
        final float currentCenterX = mController.getCenterX();
        final float currentCenterY = mController.getCenterY();
        final float currentCenterX = mController.getMagnificationFrameCenterX();
        final float currentCenterY = mController.getMagnificationFrameCenterY();

        if (mState == STATE_DISABLED) {
            // We don't need to offset the center during the animation.
+43 −7
Original line number Diff line number Diff line
@@ -497,6 +497,9 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        if (configDiff == 0) {
            return;
        }
        if (Flags.updateWindowMagnifierBottomBoundary()) {
            updateSystemGestureInsetsTop();
        }
        if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
            onRotate();
        }
@@ -542,8 +545,11 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        }
        mWindowBounds.set(currentWindowBounds);
        final Size windowFrameSize = restoreMagnificationWindowFrameIndexAndSizeIfPossible();
        final float newCenterX = (getCenterX()) * mWindowBounds.width() / oldWindowBounds.width();
        final float newCenterY = (getCenterY()) * mWindowBounds.height() / oldWindowBounds.height();
        final float newCenterX =
                (getMagnificationFrameCenterX()) * mWindowBounds.width() / oldWindowBounds.width();
        final float newCenterY =
                (getMagnificationFrameCenterY()) * mWindowBounds.height()
                        / oldWindowBounds.height();

        setMagnificationFrame(windowFrameSize.getWidth(), windowFrameSize.getHeight(),
                (int) newCenterX, (int) newCenterY);
@@ -672,10 +678,14 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    }

    private void onWindowInsetChanged() {
        if (Flags.updateWindowMagnifierBottomBoundary()) {
            updateSystemGestureInsetsTop();
        } else {
            if (updateSystemGestureInsetsTop()) {
                updateSystemUIStateIfNeeded();
            }
        }
    }

    private void applyTouchableRegion() {
        // Sometimes this can get posted and run after deleteWindowMagnification() is called.
@@ -939,7 +949,9 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
        final int x = MathUtils.clamp(mMagnificationFrame.left - mMirrorSurfaceMargin, minX, maxX);

        final int minY = -mOuterBorderSize;
        final int maxY = mWindowBounds.bottom - height + mOuterBorderSize;
        final int maxY = Flags.updateWindowMagnifierBottomBoundary()
                ? mSystemGestureTop - height + mOuterBorderSize
                : mWindowBounds.bottom - height + mOuterBorderSize;
        final int y = MathUtils.clamp(mMagnificationFrame.top - mMirrorSurfaceMargin, minY, maxY);

        if (computeWindowSize) {
@@ -1098,6 +1110,10 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    }

    private void updateSysUIState(boolean force) {
        if (Flags.updateWindowMagnifierBottomBoundary()) {
            return;
        }

        final boolean overlap = isActivated() && mSystemGestureTop > 0
                && mMirrorViewBounds.bottom > mSystemGestureTop;
        if (force || overlap != mOverlapWithGestureInsets) {
@@ -1313,7 +1329,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
     *
     * @return the X coordinate. {@link Float#NaN} if the window is invisible.
     */
    float getCenterX() {
    float getMagnificationFrameCenterX() {
        return isActivated() ? mMagnificationFrame.exactCenterX() : Float.NaN;
    }

@@ -1322,10 +1338,30 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
     *
     * @return the Y coordinate. {@link Float#NaN} if the window is invisible.
     */
    float getCenterY() {
    float getMagnificationFrameCenterY() {
        return isActivated() ? mMagnificationFrame.exactCenterY() : Float.NaN;
    }

    /**
     * Returns the screen-relative X coordinate of the center of the magnifier window.
     * This could be different from the position of the magnification frame since the magnification
     * frame could overlap with the bottom inset, but the magnifier window would not.
     * @return the Y coordinate. {@link Float#NaN} if the window is invisible.
     */
    float getMagnifierWindowX() {
        return isActivated() ? (float) mMirrorViewBounds.left : Float.NaN;
    }

    /**
     * Returns the screen-relative Y coordinate of the center of the magnifier window.
     * This could be different from the position of the magnification frame since the magnification
     * frame could overlap with the bottom inset, but the magnifier window would not.
     * @return the Y coordinate. {@link Float#NaN} if the window is invisible.
     */
    float getMagnifierWindowY() {
        return isActivated() ? (float) mMirrorViewBounds.top : Float.NaN;
    }


    @VisibleForTesting
    boolean isDiagonalScrollingEnabled() {
+16 −16
Original line number Diff line number Diff line
@@ -242,8 +242,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
            mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                    targetCenterX, targetCenterY, mAnimationCallback2);
            mCurrentScale.set(mController.getScale());
            mCurrentCenterX.set(mController.getCenterX());
            mCurrentCenterY.set(mController.getCenterY());
            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
            advanceTimeBy(mWaitAnimationDuration);
        });

@@ -297,8 +297,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
            mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                    targetCenterX, targetCenterY, mAnimationCallback);
            mCurrentScale.set(mController.getScale());
            mCurrentCenterX.set(mController.getCenterX());
            mCurrentCenterY.set(mController.getCenterY());
            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
            advanceTimeBy(mWaitAnimationDuration);
        });

@@ -339,8 +339,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
            mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                    targetCenterX, targetCenterY, mAnimationCallback);
            mCurrentScale.set(mController.getScale());
            mCurrentCenterX.set(mController.getCenterX());
            mCurrentCenterY.set(mController.getCenterY());
            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
            advanceTimeBy(mWaitAnimationDuration);
        });

@@ -375,8 +375,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
            mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                    targetCenterX, targetCenterY, mAnimationCallback);
            mCurrentScale.set(mController.getScale());
            mCurrentCenterX.set(mController.getCenterX());
            mCurrentCenterY.set(mController.getCenterY());
            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
            advanceTimeBy(mWaitAnimationDuration);
        });

@@ -463,8 +463,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
            mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                    targetCenterX, targetCenterY, mAnimationCallback2);
            mCurrentScale.set(mController.getScale());
            mCurrentCenterX.set(mController.getCenterX());
            mCurrentCenterY.set(mController.getCenterY());
            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
        });

        // Current spec shouldn't match given spec.
@@ -548,8 +548,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
            mWindowMagnificationAnimationController.enableWindowMagnification(targetScale,
                    targetCenterX, targetCenterY, mAnimationCallback2);
            mCurrentScale.set(mController.getScale());
            mCurrentCenterX.set(mController.getCenterX());
            mCurrentCenterY.set(mController.getCenterY());
            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
            advanceTimeBy(mWaitAnimationDuration);
        });

@@ -777,8 +777,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
            mWindowMagnificationAnimationController.deleteWindowMagnification(
                    mAnimationCallback2);
            mCurrentScale.set(mController.getScale());
            mCurrentCenterX.set(mController.getCenterX());
            mCurrentCenterY.set(mController.getCenterY());
            mCurrentCenterX.set(mController.getMagnificationFrameCenterX());
            mCurrentCenterY.set(mController.getMagnificationFrameCenterY());
            // ValueAnimator.reverse() could not work correctly with the AnimatorTestRule since it
            // is using SystemClock in reverse() (b/305731398). Therefore, we call end() on the
            // animator directly to verify the result of animation is correct instead of querying
@@ -940,8 +940,8 @@ public class WindowMagnificationAnimationControllerTest extends SysuiTestCase {
    private void verifyFinalSpec(float expectedScale, float expectedCenterX,
            float expectedCenterY) {
        assertEquals(expectedScale, mController.getScale(), 0f);
        assertEquals(expectedCenterX, mController.getCenterX(), 0f);
        assertEquals(expectedCenterY, mController.getCenterY(), 0f);
        assertEquals(expectedCenterX, mController.getMagnificationFrameCenterX(), 0f);
        assertEquals(expectedCenterY, mController.getMagnificationFrameCenterY(), 0f);
    }

    private void enableWindowMagnificationWithoutAnimation() {
+58 −21
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.os.SystemClock;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
import android.testing.TestableLooper;
import android.testing.TestableResources;
@@ -88,6 +90,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;

import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.AnimatorTestRule;
import com.android.systemui.kosmos.KosmosJavaAdapter;
@@ -128,6 +131,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
    public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule(/* test= */ null);

    private static final int LAYOUT_CHANGE_TIMEOUT_MS = 5000;
    private static final int INSET_BOTTOM = 10;
    @Mock
    private MirrorWindowControl mMirrorWindowControl;
    @Mock
@@ -329,9 +333,9 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
        verify(mWindowMagnifierCallback, atLeast(2)).onSourceBoundsChanged(
                (eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
        assertThat(mWindowMagnificationController.getCenterX())
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
        assertThat(mWindowMagnificationController.getCenterY())
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
    }

@@ -382,6 +386,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_UPDATE_WINDOW_MAGNIFIER_BOTTOM_BOUNDARY)
    public void deleteWindowMagnification_enableAtTheBottom_overlapFlagIsFalse() {
        final WindowManager wm = mContext.getSystemService(WindowManager.class);
        final Rect bounds = wm.getCurrentWindowMetrics().getBounds();
@@ -457,12 +462,14 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        verify(mAnimationCallback, never()).onResult(eq(false));
        verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
                .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
        assertThat(mWindowMagnificationController.getCenterX())
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
        assertThat(mWindowMagnificationController.getCenterY())
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
        assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(targetCenterX);
        assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(targetCenterY);
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                .isEqualTo(targetCenterX);
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                .isEqualTo(targetCenterY);
    }

    @Test
@@ -498,12 +505,14 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        verify(mAnimationCallback, times(3)).onResult(eq(false));
        verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
                .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
        assertThat(mWindowMagnificationController.getCenterX())
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                .isEqualTo(sourceBoundsCaptor.getValue().exactCenterX());
        assertThat(mWindowMagnificationController.getCenterY())
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                .isEqualTo(sourceBoundsCaptor.getValue().exactCenterY());
        assertThat(mWindowMagnificationController.getCenterX()).isEqualTo(centerX + 40);
        assertThat(mWindowMagnificationController.getCenterY()).isEqualTo(centerY + 40);
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX())
                .isEqualTo(centerX + 40);
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY())
                .isEqualTo(centerY + 40);
    }

    @Test
@@ -545,8 +554,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
            mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
                    magnifiedCenter.x, magnifiedCenter.y);
            // Get the center again in case the center we set is out of screen.
            magnifiedCenter.set(mWindowMagnificationController.getCenterX(),
                    mWindowMagnificationController.getCenterY());
            magnifiedCenter.set(mWindowMagnificationController.getMagnificationFrameCenterX(),
                    mWindowMagnificationController.getMagnificationFrameCenterY());
        });
        // Rotate the window clockwise 90 degree.
        windowBounds.set(windowBounds.top, windowBounds.left, windowBounds.bottom,
@@ -559,8 +568,9 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        assertThat(mWindowMagnificationController.mRotation).isEqualTo(newRotation);
        final PointF expectedCenter = new PointF(magnifiedCenter.y,
                displayWidth - magnifiedCenter.x);
        final PointF actualCenter = new PointF(mWindowMagnificationController.getCenterX(),
                mWindowMagnificationController.getCenterY());
        final PointF actualCenter =
                new PointF(mWindowMagnificationController.getMagnificationFrameCenterX(),
                        mWindowMagnificationController.getMagnificationFrameCenterY());
        assertThat(actualCenter).isEqualTo(expectedCenter);
    }

@@ -603,10 +613,10 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        });

        // The ratio of center to window size should be the same.
        assertThat(mWindowMagnificationController.getCenterX() / testWindowBounds.width())
                .isEqualTo(expectedRatio);
        assertThat(mWindowMagnificationController.getCenterY() / testWindowBounds.height())
                .isEqualTo(expectedRatio);
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterX()
                / testWindowBounds.width()).isEqualTo(expectedRatio);
        assertThat(mWindowMagnificationController.getMagnificationFrameCenterY()
                / testWindowBounds.height()).isEqualTo(expectedRatio);
    }

    @Test
@@ -1175,6 +1185,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_UPDATE_WINDOW_MAGNIFIER_BOTTOM_BOUNDARY)
    public void moveWindowMagnificationToTheBottom_enabledWithGestureInset_overlapFlagIsTrue() {
        final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
        setSystemGestureInsets();
@@ -1190,6 +1201,30 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        ReferenceTestUtils.waitForCondition(() -> hasMagnificationOverlapFlag());
    }

    @Test
    @EnableFlags(Flags.FLAG_UPDATE_WINDOW_MAGNIFIER_BOTTOM_BOUNDARY)
    public void moveWindowMagnificationToTheBottom_stopsAtSystemGestureTop() {
        final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
        setSystemGestureInsets();
        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
                    Float.NaN);
        });

        ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
        final int mOuterBorderSize = mResources.getDimensionPixelSize(
                R.dimen.magnification_outer_border_margin);

        final float expectedY =
                (float) (bounds.bottom - INSET_BOTTOM - params.height + mOuterBorderSize);

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.moveWindowMagnifier(0, bounds.height());
        });

        assertThat(mWindowMagnificationController.getMagnifierWindowY()).isEqualTo(expectedY);
    }

    @Test
    public void moveWindowMagnificationToRightEdge_dragHandleMovesToLeftAndUpdatesTapExcludeRegion()
            throws RemoteException {
@@ -1445,8 +1480,10 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.setWindowSizeAndCenter(minimumWindowSize,
                    minimumWindowSize, bounds.right, bounds.bottom);
            magnificationCenterX.set((int) mWindowMagnificationController.getCenterX());
            magnificationCenterY.set((int) mWindowMagnificationController.getCenterY());
            magnificationCenterX.set(
                    (int) mWindowMagnificationController.getMagnificationFrameCenterX());
            magnificationCenterY.set(
                    (int) mWindowMagnificationController.getMagnificationFrameCenterY());
        });

        assertThat(magnificationCenterX.get()).isLessThan(bounds.right);
@@ -1501,7 +1538,7 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {

    private void setSystemGestureInsets() {
        final WindowInsets testInsets = new WindowInsets.Builder()
                .setInsets(systemGestures(), Insets.of(0, 0, 0, 10))
                .setInsets(systemGestures(), Insets.of(0, 0, 0, INSET_BOTTOM))
                .build();
        mWindowManager.setWindowInsets(testInsets);
    }