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();