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
This commit is contained in:
mincheli
2021-04-01 11:12:00 +08:00
parent 732aed15d7
commit 778e94a7ca
2 changed files with 50 additions and 9 deletions

View File

@@ -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() {

View File

@@ -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<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
final ArgumentCaptor<Runnable> 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();