summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java106
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java121
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java116
3 files changed, 324 insertions, 19 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index 1482d078fa8c..3f3fa3419117 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -246,6 +246,31 @@ public class FullScreenMagnificationController implements
}
@GuardedBy("mLock")
+ boolean isAtEdge() {
+ return isAtLeftEdge() || isAtRightEdge() || isAtTopEdge() || isAtBottomEdge();
+ }
+
+ @GuardedBy("mLock")
+ boolean isAtLeftEdge() {
+ return getOffsetX() == getMaxOffsetXLocked();
+ }
+
+ @GuardedBy("mLock")
+ boolean isAtRightEdge() {
+ return getOffsetX() == getMinOffsetXLocked();
+ }
+
+ @GuardedBy("mLock")
+ boolean isAtTopEdge() {
+ return getOffsetY() == getMaxOffsetYLocked();
+ }
+
+ @GuardedBy("mLock")
+ boolean isAtBottomEdge() {
+ return getOffsetY() == getMinOffsetYLocked();
+ }
+
+ @GuardedBy("mLock")
float getCenterX() {
return (mMagnificationBounds.width() / 2.0f
+ mMagnificationBounds.left - getOffsetX()) / getScale();
@@ -1086,6 +1111,87 @@ public class FullScreenMagnificationController implements
}
/**
+ * Returns whether the user is at one of the edges (left, right, top, bottom)
+ * of the magnification viewport
+ *
+ * @param displayId
+ * @return if user is at the edge of the view
+ */
+ public boolean isAtEdge(int displayId) {
+ synchronized (mLock) {
+ final DisplayMagnification display = mDisplays.get(displayId);
+ if (display == null) {
+ return false;
+ }
+ return display.isAtEdge();
+ }
+ }
+
+ /**
+ * Returns whether the user is at the left edge of the viewport
+ *
+ * @param displayId
+ * @return if user is at left edge of view
+ */
+ public boolean isAtLeftEdge(int displayId) {
+ synchronized (mLock) {
+ final DisplayMagnification display = mDisplays.get(displayId);
+ if (display == null) {
+ return false;
+ }
+ return display.isAtLeftEdge();
+ }
+ }
+
+ /**
+ * Returns whether the user is at the right edge of the viewport
+ *
+ * @param displayId
+ * @return if user is at right edge of view
+ */
+ public boolean isAtRightEdge(int displayId) {
+ synchronized (mLock) {
+ final DisplayMagnification display = mDisplays.get(displayId);
+ if (display == null) {
+ return false;
+ }
+ return display.isAtRightEdge();
+ }
+ }
+
+ /**
+ * Returns whether the user is at the top edge of the viewport
+ *
+ * @param displayId
+ * @return if user is at top edge of view
+ */
+ public boolean isAtTopEdge(int displayId) {
+ synchronized (mLock) {
+ final DisplayMagnification display = mDisplays.get(displayId);
+ if (display == null) {
+ return false;
+ }
+ return display.isAtTopEdge();
+ }
+ }
+
+ /**
+ * Returns whether the user is at the bottom edge of the viewport
+ *
+ * @param displayId
+ * @return if user is at bottom edge of view
+ */
+ public boolean isAtBottomEdge(int displayId) {
+ synchronized (mLock) {
+ final DisplayMagnification display = mDisplays.get(displayId);
+ if (display == null) {
+ return false;
+ }
+ return display.isAtBottomEdge();
+ }
+ }
+
+ /**
* Returns the Y offset of the magnification viewport. If an animation
* is in progress, this reflects the end state of the animation.
*
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index 038847e2a759..4aebbf11c7af 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -137,6 +137,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@VisibleForTesting final DetectingState mDetectingState;
@VisibleForTesting final PanningScalingState mPanningScalingState;
@VisibleForTesting final ViewportDraggingState mViewportDraggingState;
+ @VisibleForTesting final SinglePanningState mSinglePanningState;
private final ScreenStateReceiver mScreenStateReceiver;
private final WindowMagnificationPromptController mPromptController;
@@ -146,7 +147,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private PointerCoords[] mTempPointerCoords;
private PointerProperties[] mTempPointerProperties;
-
+ @VisibleForTesting boolean mIsSinglePanningEnabled;
public FullScreenMagnificationGestureHandler(@UiContext Context context,
FullScreenMagnificationController fullScreenMagnificationController,
AccessibilityTraceManager trace,
@@ -202,6 +203,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
mDetectingState = new DetectingState(context);
mViewportDraggingState = new ViewportDraggingState();
mPanningScalingState = new PanningScalingState(context);
+ mSinglePanningState = new SinglePanningState(context);
+ setSinglePanningEnabled(false);
if (mDetectShortcutTrigger) {
mScreenStateReceiver = new ScreenStateReceiver(context, this);
@@ -213,6 +216,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
transitionTo(mDetectingState);
}
+ @VisibleForTesting
+ void setSinglePanningEnabled(boolean isEnabled) {
+ mIsSinglePanningEnabled = isEnabled;
+ }
+
@Override
void onMotionEventInternal(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
handleEventWith(mCurrentState, event, rawEvent, policyFlags);
@@ -223,6 +231,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
// To keep InputEventConsistencyVerifiers within GestureDetectors happy
mPanningScalingState.mScrollGestureDetector.onTouchEvent(event);
mPanningScalingState.mScaleGestureDetector.onTouchEvent(event);
+ mSinglePanningState.mScrollGestureDetector.onTouchEvent(event);
try {
stateHandler.onMotionEvent(event, rawEvent, policyFlags);
@@ -669,7 +678,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@Override
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
-
// Ensures that the state at the end of delegation is consistent with the last delegated
// UP/DOWN event in queue: still delegating if pointer is down, detecting otherwise
switch (event.getActionMasked()) {
@@ -726,6 +734,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@VisibleForTesting Handler mHandler = new Handler(Looper.getMainLooper(), this);
+ private PointF mFirstPointerDownLocation = new PointF(Float.NaN, Float.NaN);
+
DetectingState(Context context) {
mLongTapMinDelay = ViewConfiguration.getLongPressTimeout();
mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout()
@@ -765,10 +775,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
cacheDelayedMotionEvent(event, rawEvent, policyFlags);
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
-
mLastDetectingDownEventTime = event.getDownTime();
mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
+ mFirstPointerDownLocation.set(event.getX(), event.getY());
+
if (!mFullScreenMagnificationController.magnificationRegionContains(
mDisplayId, event.getX(), event.getY())) {
@@ -800,7 +811,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
break;
case ACTION_POINTER_DOWN: {
if (isActivated() && event.getPointerCount() == 2) {
- storeSecondPointerDownLocation(event);
+ storePointerDownLocation(mSecondPointerDownLocation, event);
mHandler.sendEmptyMessageDelayed(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
ViewConfiguration.getTapTimeout());
} else {
@@ -815,7 +826,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
case ACTION_MOVE: {
if (isFingerDown()
&& distance(mLastDown, /* move */ event) > mSwipeMinDistance) {
-
// Swipe detected - transition immediately
// For convenience, viewport dragging takes precedence
@@ -826,10 +836,15 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
} else if (isActivated() && event.getPointerCount() == 2) {
//Primary pointer is swiping, so transit to PanningScalingState
transitToPanningScalingStateAndClear();
+ } else if (mIsSinglePanningEnabled
+ && isActivated()
+ && event.getPointerCount() == 1
+ && !isOverscroll(event)) {
+ transitToSinglePanningStateAndClear();
} else {
transitionToDelegatingStateAndClear();
}
- } else if (isActivated() && secondPointerDownValid()
+ } else if (isActivated() && pointerDownValid(mSecondPointerDownLocation)
&& distanceClosestPointerToPoint(
mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) {
//Second pointer is swiping, so transit to PanningScalingState
@@ -843,11 +858,9 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
if (!mFullScreenMagnificationController.magnificationRegionContains(
mDisplayId, event.getX(), event.getY())) {
-
transitionToDelegatingStateAndClear();
} else if (isMultiTapTriggered(3 /* taps */)) {
-
onTripleTap(/* up */ event);
} else if (
@@ -856,7 +869,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
//TODO long tap should never happen here
&& ((timeBetween(mLastDown, mLastUp) >= mLongTapMinDelay)
|| (distance(mLastDown, mLastUp) >= mSwipeMinDistance))) {
-
transitionToDelegatingStateAndClear();
}
@@ -865,14 +877,28 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
}
- private void storeSecondPointerDownLocation(MotionEvent event) {
+ private boolean isOverscroll(MotionEvent event) {
+ if (!pointerDownValid(mFirstPointerDownLocation)) {
+ return false;
+ }
+ float dX = event.getX() - mFirstPointerDownLocation.x;
+ float dY = event.getY() - mFirstPointerDownLocation.y;
+ boolean didOverscroll =
+ mFullScreenMagnificationController.isAtLeftEdge(mDisplayId) && dX > 0
+ || mFullScreenMagnificationController.isAtRightEdge(mDisplayId) && dX < 0
+ || mFullScreenMagnificationController.isAtTopEdge(mDisplayId) && dY > 0
+ || mFullScreenMagnificationController.isAtBottomEdge(mDisplayId) && dY < 0;
+ return didOverscroll;
+ }
+
+ private void storePointerDownLocation(PointF pointerDownLocation, MotionEvent event) {
final int index = event.getActionIndex();
- mSecondPointerDownLocation.set(event.getX(index), event.getY(index));
+ pointerDownLocation.set(event.getX(index), event.getY(index));
}
- private boolean secondPointerDownValid() {
- return !(Float.isNaN(mSecondPointerDownLocation.x) && Float.isNaN(
- mSecondPointerDownLocation.y));
+ private boolean pointerDownValid(PointF pointerDownLocation) {
+ return !(Float.isNaN(pointerDownLocation.x) && Float.isNaN(
+ pointerDownLocation.y));
}
private void transitToPanningScalingStateAndClear() {
@@ -880,6 +906,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
clear();
}
+ private void transitToSinglePanningStateAndClear() {
+ transitionTo(mSinglePanningState);
+ clear();
+ }
+
public boolean isMultiTapTriggered(int numTaps) {
// Shortcut acts as the 2 initial taps
@@ -947,6 +978,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
setShortcutTriggered(false);
removePendingDelayedMessages();
clearDelayedMotionEvents();
+ mFirstPointerDownLocation.set(Float.NaN, Float.NaN);
mSecondPointerDownLocation.set(Float.NaN, Float.NaN);
}
@@ -1165,12 +1197,14 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
+ ", mDelegatingState=" + mDelegatingState
+ ", mMagnifiedInteractionState=" + mPanningScalingState
+ ", mViewportDraggingState=" + mViewportDraggingState
+ + ", mSinglePanningState=" + mSinglePanningState
+ ", mDetectTripleTap=" + mDetectTripleTap
+ ", mDetectShortcutTrigger=" + mDetectShortcutTrigger
+ ", mCurrentState=" + State.nameOf(mCurrentState)
+ ", mPreviousState=" + State.nameOf(mPreviousState)
+ ", mMagnificationController=" + mFullScreenMagnificationController
+ ", mDisplayId=" + mDisplayId
+ + ", mIsSinglePanningEnabled=" + mIsSinglePanningEnabled
+ '}';
}
@@ -1285,8 +1319,67 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
* Indicates an error with a gesture handler or state.
*/
private static class GestureException extends Exception {
+
GestureException(String message) {
super(message);
}
}
+
+ final class SinglePanningState extends SimpleOnGestureListener implements State {
+ private final GestureDetector mScrollGestureDetector;
+ private MotionEventInfo mEvent;
+
+ SinglePanningState(Context context) {
+ mScrollGestureDetector = new GestureDetector(context, this, Handler.getMain());
+ }
+
+ @Override
+ public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ int action = event.getActionMasked();
+ switch (action) {
+ case ACTION_UP:
+ case ACTION_CANCEL:
+ clear();
+ transitionTo(mDetectingState);
+ break;
+ }
+ }
+
+ @Override
+ public boolean onScroll(
+ MotionEvent first, MotionEvent second, float distanceX, float distanceY) {
+ if (mCurrentState != mSinglePanningState) {
+ return true;
+ }
+ mFullScreenMagnificationController.offsetMagnifiedRegion(
+ mDisplayId,
+ distanceX,
+ distanceY,
+ AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
+ if (DEBUG_PANNING_SCALING) {
+ Slog.i(
+ mLogTag,
+ "SinglePanningState Panned content by scrollX: "
+ + distanceX
+ + " scrollY: "
+ + distanceY
+ + " isAtEdge: "
+ + mFullScreenMagnificationController.isAtEdge(mDisplayId));
+ }
+ // TODO: b/280812104 Dispatch events before Delegation
+ if (mFullScreenMagnificationController.isAtEdge(mDisplayId)) {
+ clear();
+ transitionTo(mDelegatingState);
+ }
+ return /* event consumed: */ true;
+ }
+
+ @Override
+ public String toString() {
+ return "SinglePanningState{"
+ + "isEdgeOfView="
+ + mFullScreenMagnificationController.isAtEdge(mDisplayId)
+ + "}";
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 32d0c98d4481..989aee06a1df 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -33,6 +33,7 @@ import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -42,6 +43,8 @@ import static org.mockito.Mockito.when;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.Region;
import android.os.Handler;
import android.os.Message;
import android.os.UserHandle;
@@ -67,11 +70,13 @@ import com.android.server.wm.WindowManagerInternal;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
import java.util.ArrayList;
import java.util.List;
@@ -123,9 +128,10 @@ public class FullScreenMagnificationGestureHandlerTest {
public static final int STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP = 8;
public static final int STATE_PANNING = 9;
public static final int STATE_SCALING_AND_PANNING = 10;
+ public static final int STATE_SINGLE_PANNING = 11;
public static final int FIRST_STATE = STATE_IDLE;
- public static final int LAST_STATE = STATE_SCALING_AND_PANNING;
+ public static final int LAST_STATE = STATE_SINGLE_PANNING;
// Co-prime x and y, to potentially catch x-y-swapped errors
public static final float DEFAULT_X = 301;
@@ -155,6 +161,10 @@ public class FullScreenMagnificationGestureHandlerTest {
private float mOriginalMagnificationPersistedScale;
+ static final Rect INITIAL_MAGNIFICATION_BOUNDS = new Rect(0, 0, 800, 800);
+
+ static final Region INITIAL_MAGNIFICATION_REGION = new Region(INITIAL_MAGNIFICATION_BOUNDS);
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -182,11 +192,19 @@ public class FullScreenMagnificationGestureHandlerTest {
new MagnificationScaleProvider(mContext),
() -> null,
ConcurrentUtils.DIRECT_EXECUTOR) {
- @Override
- public boolean magnificationRegionContains(int displayId, float x, float y) {
- return true;
- }
+ @Override
+ public boolean magnificationRegionContains(int displayId, float x, float y) {
+ return true;
+ }
};
+
+ doAnswer((Answer<Void>) invocationOnMock -> {
+ Object[] args = invocationOnMock.getArguments();
+ Region regionArg = (Region) args[1];
+ regionArg.set(new Rect(INITIAL_MAGNIFICATION_BOUNDS));
+ return null;
+ }).when(mockWindowManager).getMagnificationRegion(anyInt(), any(Region.class));
+
mFullScreenMagnificationController.register(DISPLAY_0);
mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(true);
mClock = new OffsettableClock.Stopped();
@@ -214,6 +232,7 @@ public class FullScreenMagnificationGestureHandlerTest {
mContext, mFullScreenMagnificationController, mMockTraceManager, mMockCallback,
detectTripleTap, detectShortcutTrigger,
mWindowMagnificationPromptController, DISPLAY_0);
+ h.setSinglePanningEnabled(true);
mHandler = new TestHandler(h.mDetectingState, mClock) {
@Override
protected String messageToString(Message m) {
@@ -239,6 +258,7 @@ public class FullScreenMagnificationGestureHandlerTest {
* {@link #returnToNormalFrom} (for navigating back to {@link #STATE_IDLE})
*/
@Test
+ @Ignore("b/291925580")
public void testEachState_isReachableAndRecoverable() {
forEachState(state -> {
goFromStateIdleTo(state);
@@ -526,6 +546,75 @@ public class FullScreenMagnificationGestureHandlerTest {
}
@Test
+ public void testActionUpNotAtEdge_singlePanningState_detectingState() {
+ goFromStateIdleTo(STATE_SINGLE_PANNING);
+
+ send(upEvent());
+
+ check(mMgh.mCurrentState == mMgh.mDetectingState, STATE_IDLE);
+ assertTrue(isZoomed());
+ }
+
+ @Test
+ public void testScroll_SinglePanningDisabled_delegatingState() {
+ mMgh.setSinglePanningEnabled(false);
+
+ goFromStateIdleTo(STATE_ACTIVATED);
+ allowEventDelegation();
+ swipeAndHold();
+
+ assertTrue(mMgh.mCurrentState == mMgh.mDelegatingState);
+ }
+
+ @Test
+ public void testScroll_zoomedStateAndAtEdge_delegatingState() {
+ goFromStateIdleTo(STATE_ACTIVATED);
+ mFullScreenMagnificationController.setCenter(
+ DISPLAY_0,
+ INITIAL_MAGNIFICATION_BOUNDS.left,
+ INITIAL_MAGNIFICATION_BOUNDS.top / 2,
+ false,
+ 1);
+ final float swipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop() + 1;
+ PointF initCoords =
+ new PointF(
+ mFullScreenMagnificationController.getCenterX(DISPLAY_0),
+ mFullScreenMagnificationController.getCenterY(DISPLAY_0));
+ PointF endCoords = new PointF(initCoords.x, initCoords.y);
+ endCoords.offset(swipeMinDistance, 0);
+ allowEventDelegation();
+
+ swipeAndHold(initCoords, endCoords);
+
+ assertTrue(mMgh.mCurrentState == mMgh.mDelegatingState);
+ assertTrue(isZoomed());
+ }
+
+ @Test
+ public void testScroll_singlePanningAndAtEdge_delegatingState() {
+ goFromStateIdleTo(STATE_SINGLE_PANNING);
+ mFullScreenMagnificationController.setCenter(
+ DISPLAY_0,
+ INITIAL_MAGNIFICATION_BOUNDS.left,
+ INITIAL_MAGNIFICATION_BOUNDS.top / 2,
+ false,
+ 1);
+ final float swipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop() + 1;
+ PointF initCoords =
+ new PointF(
+ mFullScreenMagnificationController.getCenterX(DISPLAY_0),
+ mFullScreenMagnificationController.getCenterY(DISPLAY_0));
+ PointF endCoords = new PointF(initCoords.x, initCoords.y);
+ endCoords.offset(swipeMinDistance, 0);
+ allowEventDelegation();
+
+ swipeAndHold(initCoords, endCoords);
+
+ assertTrue(mMgh.mCurrentState == mMgh.mDelegatingState);
+ assertTrue(isZoomed());
+ }
+
+ @Test
public void testShortcutTriggered_invokeShowWindowPromptAction() {
goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED);
@@ -740,6 +829,10 @@ public class FullScreenMagnificationGestureHandlerTest {
state);
check(mMgh.mPanningScalingState.mScaling, state);
} break;
+ case STATE_SINGLE_PANNING: {
+ check(isZoomed(), state);
+ check(mMgh.mCurrentState == mMgh.mSinglePanningState, state);
+ } break;
default: throw new IllegalArgumentException("Illegal state: " + state);
}
}
@@ -803,6 +896,10 @@ public class FullScreenMagnificationGestureHandlerTest {
send(pointerEvent(ACTION_MOVE, DEFAULT_X * 2, DEFAULT_Y * 4));
send(pointerEvent(ACTION_MOVE, DEFAULT_X * 2, DEFAULT_Y * 5));
} break;
+ case STATE_SINGLE_PANNING: {
+ goFromStateIdleTo(STATE_ACTIVATED);
+ swipeAndHold();
+ } break;
default:
throw new IllegalArgumentException("Illegal state: " + state);
}
@@ -859,6 +956,10 @@ public class FullScreenMagnificationGestureHandlerTest {
case STATE_SCALING_AND_PANNING: {
returnToNormalFrom(STATE_PANNING);
} break;
+ case STATE_SINGLE_PANNING: {
+ send(upEvent());
+ returnToNormalFrom(STATE_ACTIVATED);
+ } break;
default: throw new IllegalArgumentException("Illegal state: " + state);
}
}
@@ -906,6 +1007,11 @@ public class FullScreenMagnificationGestureHandlerTest {
send(moveEvent(DEFAULT_X * 2, DEFAULT_Y * 2));
}
+ private void swipeAndHold(PointF start, PointF end) {
+ send(downEvent(start.x, start.y));
+ send(moveEvent(end.x, end.y));
+ }
+
private void longTap() {
send(downEvent());
fastForward(2000);