From 778e94a7ca22a7bff73bdddaebf63b1eef448edb Mon Sep 17 00:00:00 2001 From: mincheli Date: Thu, 1 Apr 2021 11:12:00 +0800 Subject: [PATCH] Makes the movable region of magnification button sticking to the edges When dragging magnification button, the button should stick to the closer edge of the screen edges automatically after the dragging gesture is finished. And not to reset the position after the button is removed. So the but tton position can be recovered after calling showButton() again. Demo video: b/162706034#comment3 Bug: 162706034 Test: atest MagnificationModeSwitchTest Change-Id: I78127f3e3f479e797426e0f451424f6ed090cd78 --- .../MagnificationModeSwitch.java | 23 +++++++++--- .../MagnificationModeSwitchTest.java | 36 ++++++++++++++++--- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java index 1ffccb78102af..ee7eb4b50bcb8 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java @@ -77,6 +77,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL private boolean mIsVisible = false; private final MagnificationGestureDetector mGestureDetector; private boolean mSingleTapDetected = false; + private boolean mToLeftScreenEdge = false; MagnificationModeSwitch(@UiContext Context context) { this(context, createView(context), new SfVsyncFrameCallbackProvider()); @@ -156,9 +157,10 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL mParams.height = size; mParams.width = size; if (mIsVisible) { - mWindowManager.updateViewLayout(mImageView, mParams); - // Exclude magnification switch button from system gesture area. - setSystemGestureExclusion(); + stickToScreenEdge(mToLeftScreenEdge); + // Reset button to make its window layer always above the mirror window. + removeButton(); + showButton(mMagnificationMode, /* resetPosition= */false); } } @@ -190,6 +192,12 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL @Override public boolean onFinish(float xOffset, float yOffset) { + if (mIsVisible) { + final int windowWidth = mWindowManager.getCurrentWindowMetrics().getBounds().width(); + final int halfWindowWidth = windowWidth / 2; + mToLeftScreenEdge = (mParams.x < halfWindowWidth); + stickToScreenEdge(mToLeftScreenEdge); + } if (!mSingleTapDetected) { showButton(mMagnificationMode); } @@ -197,6 +205,12 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL return true; } + private void stickToScreenEdge(boolean toLeftScreenEdge) { + mParams.x = toLeftScreenEdge + ? mDraggableWindowBounds.left : mDraggableWindowBounds.right; + updateButtonViewLayoutIfNeeded(); + } + private void moveButton(float offsetX, float offsetY) { mSfVsyncFrameProvider.postFrameCallback(l -> { mParams.x += offsetX; @@ -241,6 +255,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL mDraggableWindowBounds.set(getDraggableWindowBounds()); mParams.x = mDraggableWindowBounds.right; mParams.y = mDraggableWindowBounds.bottom; + mToLeftScreenEdge = false; } mWindowManager.addView(mImageView, mParams); // Exclude magnification switch button from system gesture area. @@ -283,7 +298,7 @@ class MagnificationModeSwitch implements MagnificationGestureDetector.OnGestureL return; } mDraggableWindowBounds.set(newBounds); - updateButtonViewLayoutIfNeeded(); + stickToScreenEdge(mToLeftScreenEdge); } private void updateButtonViewLayoutIfNeeded() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java index 1d475cdd4ac6c..d9a240f4273e5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java @@ -80,6 +80,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @@ -204,7 +205,10 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { mMagnificationModeSwitch.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY); - verify(mWindowManager).updateViewLayout(eq(mSpyImageView), any()); + InOrder inOrder = Mockito.inOrder(mWindowManager); + inOrder.verify(mWindowManager).updateViewLayout(eq(mSpyImageView), any()); + inOrder.verify(mWindowManager).removeView(eq(mSpyImageView)); + inOrder.verify(mWindowManager).addView(eq(mSpyImageView), any()); verify(mSpyImageView).setSystemGestureExclusionRects(any(List.class)); } @@ -217,7 +221,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { verify(mWindowManager).updateViewLayout(eq(mSpyImageView), any(WindowManager.LayoutParams.class)); - assertLayoutPosition(); + assertLayoutPosition(/* toLeftScreenEdge= */ false); } @Test @@ -233,6 +237,26 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { assertNotEquals(oldDraggableBounds, mMagnificationModeSwitch.mDraggableWindowBounds); } + @Test + public void onDraggingGestureFinish_buttonIsShowing_stickToRightEdge() { + final int windowHalfWidth = + mWindowManager.getCurrentWindowMetrics().getBounds().width() / 2; + mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); + + // Drag button to right side on screen + final int offset = ViewConfiguration.get(mContext).getScaledTouchSlop() + 10; + final long downTime = SystemClock.uptimeMillis(); + mTouchListener.onTouch(mSpyImageView, obtainMotionEvent( + downTime, 0, ACTION_DOWN, 100, 100)); + mTouchListener.onTouch(mSpyImageView, + obtainMotionEvent(downTime, downTime, ACTION_MOVE, windowHalfWidth - offset, 100)); + + mTouchListener.onTouch(mSpyImageView, obtainMotionEvent( + downTime, downTime, ACTION_UP, windowHalfWidth - offset, 100)); + + assertLayoutPosition(/* toLeftScreenEdge= */false); + } + @Test public void performSingleTap_fullscreenMode_removeViewAndChangeSettingsValue() { mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN); @@ -416,7 +440,7 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { } private void assertShowFadingAnimation(float alpha) { - ArgumentCaptor runnableCaptor = ArgumentCaptor.forClass(Runnable.class); + final ArgumentCaptor runnableCaptor = ArgumentCaptor.forClass(Runnable.class); if (alpha == FADE_IN_ALPHA) { // Fade-in verify(mSpyImageView).postOnAnimation(runnableCaptor.capture()); } else { // Fade-out @@ -490,8 +514,10 @@ public class MagnificationModeSwitchTest extends SysuiTestCase { mFadeOutAnimation = null; } - private void assertLayoutPosition() { - final int expectedX = mMagnificationModeSwitch.mDraggableWindowBounds.right; + private void assertLayoutPosition(boolean toLeftScreenEdge) { + final int expectedX = + toLeftScreenEdge ? mMagnificationModeSwitch.mDraggableWindowBounds.left + : mMagnificationModeSwitch.mDraggableWindowBounds.right; final int expectedY = mMagnificationModeSwitch.mDraggableWindowBounds.bottom; final WindowManager.LayoutParams layoutParams = mWindowManager.getLayoutParamsFromAttachedView();