From cdea71792595c4f74b8ad46ebeed534289a2363e Mon Sep 17 00:00:00 2001 From: Roy Chou Date: Thu, 2 Feb 2023 16:21:54 +0000 Subject: [PATCH 1/2] feat(#AlwaysOnMagnifier)!: Support always on feature in FullScreenMagnificationController Add variable mAlwaysOnMagnificationEnabled in FullScreenMagnificationController. If enabled is true, when onUserContextChanged method is triggered, the magnifier will zoom to 100% and keep in activated state. If enabled is false, the magnifier will be disabled. It's the original behavior. Bug: 146504200 Test: manual atest FullScreenMagnificationControllerTest Change-Id: Id7be1fe2cb66ce079f413103ea4e134b4542571c --- .../FullScreenMagnificationController.java | 42 +++++++++++++++---- ...FullScreenMagnificationControllerTest.java | 21 ++++++++++ 2 files changed, 55 insertions(+), 8 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 595cdec23b600..d7c5b5d92d7f3 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java @@ -57,6 +57,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; +import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.AccessibilityTraceManager; import com.android.server.wm.WindowManagerInternal; @@ -99,7 +100,8 @@ public class FullScreenMagnificationController implements private final Rect mTempRect = new Rect(); // Whether the following typing focus feature for magnification is enabled. private boolean mMagnificationFollowTypingEnabled = true; - + // Whether the always on magnification feature is enabled. + private boolean mAlwaysOnMagnificationEnabled = false; private final DisplayManagerInternal mDisplayManagerInternal; /** @@ -291,18 +293,15 @@ public class FullScreenMagnificationController implements @Override public void onDisplaySizeChanged() { - // Treat as context change and reset - final Message m = PooledLambda.obtainMessage( - FullScreenMagnificationController::resetIfNeeded, - FullScreenMagnificationController.this, mDisplayId, true); - mControllerCtx.getHandler().sendMessage(m); + // Treat as context change + onUserContextChanged(); } @Override public void onUserContextChanged() { final Message m = PooledLambda.obtainMessage( - FullScreenMagnificationController::resetIfNeeded, - FullScreenMagnificationController.this, mDisplayId, true); + FullScreenMagnificationController::onUserContextChanged, + FullScreenMagnificationController.this, mDisplayId); mControllerCtx.getHandler().sendMessage(m); } @@ -795,6 +794,33 @@ public class FullScreenMagnificationController implements return mMagnificationFollowTypingEnabled; } + void setAlwaysOnMagnificationEnabled(boolean enabled) { + mAlwaysOnMagnificationEnabled = enabled; + } + + boolean isAlwaysOnMagnificationEnabled() { + return mAlwaysOnMagnificationEnabled; + } + + /** + * if the magnifier with given displayId is activated: + * 1. if {@link #isAlwaysOnMagnificationEnabled()}, zoom the magnifier to 100%, + * 2. otherwise, reset the magnification. + * + * @param displayId The logical display id. + */ + void onUserContextChanged(int displayId) { + synchronized (mLock) { + if (isAlwaysOnMagnificationEnabled()) { + setScaleAndCenter(displayId, 1.0f, Float.NaN, Float.NaN, + true, + AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID); + } else { + reset(displayId, true); + } + } + } + /** * Remove the display magnification with given id. * diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java index bf23d9dcbe96e..2d036fec11640 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java @@ -1196,6 +1196,27 @@ public class FullScreenMagnificationControllerTest { persistedScale); } + @Test + public void testOnContextChanged_alwaysOnFeatureDisabled_resetMagnification() { + setScaleToMagnifying(); + + mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(false); + mFullScreenMagnificationController.onUserContextChanged(DISPLAY_0); + + verify(mRequestObserver).onFullScreenMagnificationActivationState(eq(DISPLAY_0), eq(false)); + } + + @Test + public void testOnContextChanged_alwaysOnFeatureEnabled_setScaleTo1xAndStayActivated() { + setScaleToMagnifying(); + + mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(true); + mFullScreenMagnificationController.onUserContextChanged(DISPLAY_0); + + assertEquals(1.0f, mFullScreenMagnificationController.getScale(DISPLAY_0), 0); + assertTrue(mFullScreenMagnificationController.isActivated(DISPLAY_0)); + } + private void setScaleToMagnifying() { register(DISPLAY_0); float scale = 2.0f; From 1286fd24e5b44c91d4c13729ee716d991372ef55 Mon Sep 17 00:00:00 2001 From: Roy Chou Date: Thu, 2 Feb 2023 16:40:33 +0000 Subject: [PATCH 2/2] feat(#AlwaysOnMagnifier): Adjust FullScreenMagnificationGestureHandler to support always on feature For b/267210808, we adjust the gesture handler to disable the magnification after user zoomInTemporary by shortcut and release. It's the original behavior. After the feature AlwaysOnMagnification is supported in FullScreenMagnificationController, if the feature is enabled, the gesture handler will make magnifier zoom to 100% and keep activated instead. Besides, in FullScreenMagnificationGestureHandlerTest, we rename STATE_ZOOMED to STATE_ACTIVATED. It is becasue user can activate the magnifier and zoom to 100%. Bug: 267210808 Test: manually atest FullScreenMagnificationGestureHandlerTest Change-Id: I44e6c54fbdec02562f7f6bfca3ab054db4ed5db5 --- ...FullScreenMagnificationGestureHandler.java | 70 ++++--- ...ScreenMagnificationGestureHandlerTest.java | 172 ++++++++++++------ 2 files changed, 160 insertions(+), 82 deletions(-) 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 9fc9d57159bbd..9c84c048003d4 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java @@ -445,12 +445,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH */ final class ViewportDraggingState implements State { - /** Whether to disable zoom after dragging ends */ - @VisibleForTesting boolean mActivatedBeforeDrag; - /** Whether to restore scale after dragging ends */ - private boolean mZoomedInTemporary; - /** The cached scale for recovering after dragging ends */ - private float mScaleBeforeZoomedInTemporary; + /** + * The cached scale for recovering after dragging ends. + * If the scale >= 1.0, the magnifier needs to recover to scale. + * Otherwise, the magnifier should be disabled. + */ + @VisibleForTesting float mScaleToRecoverAfterDraggingEnd = Float.NaN; private boolean mLastMoveOutsideMagnifiedRegion; @@ -460,8 +460,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH final int action = event.getActionMasked(); switch (action) { case ACTION_POINTER_DOWN: { - clear(); - transitionTo(mPanningScalingState); + clearAndTransitToPanningScalingState(); } break; case ACTION_MOVE: { @@ -484,14 +483,18 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH case ACTION_UP: case ACTION_CANCEL: { - if (mActivatedBeforeDrag) { - if (mZoomedInTemporary) { - zoomToScale(mScaleBeforeZoomedInTemporary, event.getX(), event.getY()); - } + // If mScaleToRecoverAfterDraggingEnd >= 1.0, the dragging state is triggered + // by zoom in temporary, and the magnifier needs to recover to original scale + // after exiting dragging state. + // Otherwise, the magnifier should be disabled. + if (mScaleToRecoverAfterDraggingEnd >= 1.0f) { + zoomToScale(mScaleToRecoverAfterDraggingEnd, event.getX(), + event.getY()); } else { zoomOff(); } clear(); + mScaleToRecoverAfterDraggingEnd = Float.NaN; transitionTo(mDetectingState); } break; @@ -504,27 +507,49 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } } - public void prepareForZoomInTemporary() { - mViewportDraggingState.mActivatedBeforeDrag = - mFullScreenMagnificationController.isActivated(mDisplayId); + private boolean isAlwaysOnMagnificationEnabled() { + return mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled(); + } - mViewportDraggingState.mZoomedInTemporary = true; - mViewportDraggingState.mScaleBeforeZoomedInTemporary = - mFullScreenMagnificationController.getScale(mDisplayId); + public void prepareForZoomInTemporary(boolean shortcutTriggered) { + boolean shouldRecoverAfterDraggingEnd; + if (mFullScreenMagnificationController.isActivated(mDisplayId)) { + // For b/267210808, if always-on feature is not enabled, we keep the expected + // behavior. If users tap shortcut and then tap-and-hold to zoom in temporary, + // the magnifier should be disabled after release. + // If always-on feature is enabled, in the same scenario the magnifier would + // zoom to 1.0 and keep activated. + if (shortcutTriggered) { + shouldRecoverAfterDraggingEnd = isAlwaysOnMagnificationEnabled(); + } else { + shouldRecoverAfterDraggingEnd = true; + } + } else { + shouldRecoverAfterDraggingEnd = false; + } + + mScaleToRecoverAfterDraggingEnd = shouldRecoverAfterDraggingEnd + ? mFullScreenMagnificationController.getScale(mDisplayId) : Float.NaN; + } + + private void clearAndTransitToPanningScalingState() { + final float scaleToRecovery = mScaleToRecoverAfterDraggingEnd; + clear(); + mScaleToRecoverAfterDraggingEnd = scaleToRecovery; + transitionTo(mPanningScalingState); } @Override public void clear() { mLastMoveOutsideMagnifiedRegion = false; - mZoomedInTemporary = false; - mScaleBeforeZoomedInTemporary = 1.0f; + mScaleToRecoverAfterDraggingEnd = Float.NaN; } @Override public String toString() { return "ViewportDraggingState{" - + "mActivatedBeforeDrag=" + mActivatedBeforeDrag + + "mScaleToRecoverAfterDraggingEnd=" + mScaleToRecoverAfterDraggingEnd + ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion + '}'; } @@ -921,13 +946,14 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH void transitionToViewportDraggingStateAndClear(MotionEvent down) { if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()"); + final boolean shortcutTriggered = mShortcutTriggered; clear(); // Triple tap and hold also belongs to triple tap event. final boolean enabled = !isActivated(); logMagnificationTripleTap(enabled); - mViewportDraggingState.prepareForZoomInTemporary(); + mViewportDraggingState.prepareForZoomInTemporary(shortcutTriggered); zoomInTemporary(down.getX(), down.getY()); 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 5334e4cd04b8c..a095760dff92f 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 @@ -81,23 +81,27 @@ import java.util.function.IntConsumer; * IDLE -> SHORTCUT_TRIGGERED [label="a11y\nbtn"] * IDLE -> DOUBLE_TAP [label="2tap"] * DOUBLE_TAP -> IDLE [label="timeout"] - * DOUBLE_TAP -> ZOOMED [label="tap"] + * DOUBLE_TAP -> ACTIVATED [label="tap"] * DOUBLE_TAP -> NON_ACTIVATED_ZOOMED_TMP [label="hold"] * NON_ACTIVATED_ZOOMED_TMP -> IDLE [label="release"] * SHORTCUT_TRIGGERED -> IDLE [label="a11y\nbtn"] - * SHORTCUT_TRIGGERED -> ZOOMED[label="tap"] - * SHORTCUT_TRIGGERED -> ACTIVATED_ZOOMED_TMP [label="hold"] + * SHORTCUT_TRIGGERED -> ACTIVATED [label="tap"] + * SHORTCUT_TRIGGERED -> SHORTCUT_TRIGGERED_ZOOMED_TMP [label="hold"] * SHORTCUT_TRIGGERED -> PANNING [label="2hold] - * ZOOMED -> ZOOMED_DOUBLE_TAP [label="2tap"] - * ZOOMED -> IDLE [label="a11y\nbtn"] - * ZOOMED -> PANNING [label="2hold"] - * ZOOMED_DOUBLE_TAP -> ZOOMED [label="timeout"] - * ZOOMED_DOUBLE_TAP -> ACTIVATED_ZOOMED_TMP [label="hold"] - * ZOOMED_DOUBLE_TAP -> IDLE [label="tap"] - * ACTIVATED_ZOOMED_TMP -> ZOOMED [label="release"] - * PANNING -> ZOOMED [label="release"] + * if always-on enabled: + * SHORTCUT_TRIGGERED_ZOOMED_TMP -> ACTIVATED [label="release"] + * else: + * SHORTCUT_TRIGGERED_ZOOMED_TMP -> IDLE [label="release"] + * ACTIVATED -> ACTIVATED_DOUBLE_TAP [label="2tap"] + * ACTIVATED -> IDLE [label="a11y\nbtn"] + * ACTIVATED -> PANNING [label="2hold"] + * ACTIVATED_DOUBLE_TAP -> ACTIVATED [label="timeout"] + * ACTIVATED_DOUBLE_TAP -> ACTIVATED_ZOOMED_TMP [label="hold"] + * ACTIVATED_DOUBLE_TAP -> IDLE [label="tap"] + * ACTIVATED_ZOOMED_TMP -> ACTIVATED [label="release"] + * PANNING -> ACTIVATED [label="release"] * PANNING -> PANNING_SCALING [label="pinch"] - * PANNING_SCALING -> ZOOMED [label="release"] + * PANNING_SCALING -> ACTIVATED [label="release"] * } * } */ @@ -105,14 +109,15 @@ import java.util.function.IntConsumer; public class FullScreenMagnificationGestureHandlerTest { public static final int STATE_IDLE = 1; - public static final int STATE_ZOOMED = 2; + public static final int STATE_ACTIVATED = 2; public static final int STATE_2TAPS = 3; - public static final int STATE_ZOOMED_2TAPS = 4; + public static final int STATE_ACTIVATED_2TAPS = 4; public static final int STATE_SHORTCUT_TRIGGERED = 5; public static final int STATE_NON_ACTIVATED_ZOOMED_TMP = 6; public static final int STATE_ACTIVATED_ZOOMED_TMP = 7; - public static final int STATE_PANNING = 8; - public static final int STATE_SCALING_AND_PANNING = 9; + 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 FIRST_STATE = STATE_IDLE; public static final int LAST_STATE = STATE_SCALING_AND_PANNING; @@ -167,6 +172,7 @@ public class FullScreenMagnificationGestureHandlerTest { } }; mFullScreenMagnificationController.register(DISPLAY_0); + mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(true); mClock = new OffsettableClock.Stopped(); boolean detectTripleTap = true; @@ -267,22 +273,22 @@ public class FullScreenMagnificationGestureHandlerTest { assertTransition(STATE_SHORTCUT_TRIGGERED, () -> { send(downEvent()); fastForward1sec(); - }, STATE_ACTIVATED_ZOOMED_TMP); + }, STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP); - // A11y button followed by a tap turns zoom on - assertTransition(STATE_SHORTCUT_TRIGGERED, () -> tap(), STATE_ZOOMED); + // A11y button followed by a tap turns magnifier on + assertTransition(STATE_SHORTCUT_TRIGGERED, () -> tap(), STATE_ACTIVATED); // A11y button pressed second time negates the 1st press assertTransition(STATE_SHORTCUT_TRIGGERED, () -> triggerShortcut(), STATE_IDLE); - // A11y button turns zoom off - assertTransition(STATE_ZOOMED, () -> triggerShortcut(), STATE_IDLE); + // A11y button turns magnifier off + assertTransition(STATE_ACTIVATED, () -> triggerShortcut(), STATE_IDLE); - // Double tap times out while zoomed - assertTransition(STATE_ZOOMED_2TAPS, () -> { + // Double tap times out while activated + assertTransition(STATE_ACTIVATED_2TAPS, () -> { allowEventDelegation(); fastForward1sec(); - }, STATE_ZOOMED); + }, STATE_ACTIVATED); // tap+tap+swipe doesn't get delegated assertTransition(STATE_2TAPS, () -> swipe(), STATE_IDLE); @@ -290,8 +296,29 @@ public class FullScreenMagnificationGestureHandlerTest { // tap+tap+swipe&hold initiates temporary viewport dragging zoom in immediately assertTransition(STATE_2TAPS, () -> swipeAndHold(), STATE_NON_ACTIVATED_ZOOMED_TMP); - // release when activated temporary zoom in back to zoomed - assertTransition(STATE_ACTIVATED_ZOOMED_TMP, () -> upEvent(), STATE_ZOOMED); + // release when activated temporary zoom in back to activated + assertTransition(STATE_ACTIVATED_ZOOMED_TMP, () -> send(upEvent()), STATE_ACTIVATED); + } + + @Test + public void testRelease_shortcutTriggeredZoomedTmp_alwaysOnNotEnabled_shouldInIdle() { + mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(false); + goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP); + send(upEvent()); + + assertIn(STATE_IDLE); + } + + @Test + public void testRelease_shortcutTriggeredZoomedTmp_alwaysOnEnabled_shouldInActivated() { + mFullScreenMagnificationController.setAlwaysOnMagnificationEnabled(true); + goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP); + send(upEvent()); + + assertIn(STATE_ACTIVATED); + assertTrue(!isZoomed()); + + returnToNormalFrom(STATE_ACTIVATED); } @Test @@ -310,7 +337,7 @@ public class FullScreenMagnificationGestureHandlerTest { longTap(); }; assertStaysIn(STATE_IDLE, tapAndLongTap); - assertStaysIn(STATE_ZOOMED, tapAndLongTap); + assertStaysIn(STATE_ACTIVATED, tapAndLongTap); // Triple tap with delays in between doesn't count Runnable slow3tap = () -> { @@ -321,7 +348,7 @@ public class FullScreenMagnificationGestureHandlerTest { tap(); }; assertStaysIn(STATE_IDLE, slow3tap); - assertStaysIn(STATE_ZOOMED, slow3tap); + assertStaysIn(STATE_ACTIVATED, slow3tap); } @Test @@ -337,9 +364,9 @@ public class FullScreenMagnificationGestureHandlerTest { @Test public void testTripleTapAndHold_zoomsImmediately() { assertZoomsImmediatelyOnSwipeFrom(STATE_2TAPS, STATE_NON_ACTIVATED_ZOOMED_TMP); - assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED, STATE_ACTIVATED_ZOOMED_TMP); - assertZoomsImmediatelyOnSwipeFrom(STATE_ZOOMED_2TAPS, STATE_ACTIVATED_ZOOMED_TMP); - + assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED, + STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP); + assertZoomsImmediatelyOnSwipeFrom(STATE_ACTIVATED_2TAPS, STATE_ACTIVATED_ZOOMED_TMP); } @Test @@ -361,8 +388,8 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test - public void testTwoFingersOneTap_zoomedState_dispatchMotionEvents() { - goFromStateIdleTo(STATE_ZOOMED); + public void testTwoFingersOneTap_activatedState_dispatchMotionEvents() { + goFromStateIdleTo(STATE_ACTIVATED); final EventCaptor eventCaptor = new EventCaptor(); mMgh.setNext(eventCaptor); @@ -371,7 +398,7 @@ public class FullScreenMagnificationGestureHandlerTest { send(pointerEvent(ACTION_POINTER_UP, DEFAULT_X * 2, DEFAULT_Y)); send(upEvent()); - assertIn(STATE_ZOOMED); + assertIn(STATE_ACTIVATED); final List expectedActions = new ArrayList(); expectedActions.add(Integer.valueOf(ACTION_DOWN)); expectedActions.add(Integer.valueOf(ACTION_POINTER_DOWN)); @@ -379,12 +406,12 @@ public class FullScreenMagnificationGestureHandlerTest { expectedActions.add(Integer.valueOf(ACTION_UP)); assertActionsInOrder(eventCaptor.mEvents, expectedActions); - returnToNormalFrom(STATE_ZOOMED); + returnToNormalFrom(STATE_ACTIVATED); } @Test - public void testThreeFingersOneTap_zoomedState_dispatchMotionEvents() { - goFromStateIdleTo(STATE_ZOOMED); + public void testThreeFingersOneTap_activatedState_dispatchMotionEvents() { + goFromStateIdleTo(STATE_ACTIVATED); final EventCaptor eventCaptor = new EventCaptor(); mMgh.setNext(eventCaptor); PointF pointer1 = DEFAULT_POINT; @@ -398,7 +425,7 @@ public class FullScreenMagnificationGestureHandlerTest { send(pointerEvent(ACTION_POINTER_UP, new PointF[] {pointer1, pointer2, pointer3}, 2)); send(upEvent()); - assertIn(STATE_ZOOMED); + assertIn(STATE_ACTIVATED); final List expectedActions = new ArrayList(); expectedActions.add(Integer.valueOf(ACTION_DOWN)); expectedActions.add(Integer.valueOf(ACTION_POINTER_DOWN)); @@ -408,12 +435,12 @@ public class FullScreenMagnificationGestureHandlerTest { expectedActions.add(Integer.valueOf(ACTION_UP)); assertActionsInOrder(eventCaptor.mEvents, expectedActions); - returnToNormalFrom(STATE_ZOOMED); + returnToNormalFrom(STATE_ACTIVATED); } @Test - public void testFirstFingerSwipe_twoPointerDownAndZoomedState_panningState() { - goFromStateIdleTo(STATE_ZOOMED); + public void testFirstFingerSwipe_twoPointerDownAndActivatedState_panningState() { + goFromStateIdleTo(STATE_ACTIVATED); PointF pointer1 = DEFAULT_POINT; PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y); @@ -429,8 +456,8 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test - public void testSecondFingerSwipe_twoPointerDownAndZoomedState_panningState() { - goFromStateIdleTo(STATE_ZOOMED); + public void testSecondFingerSwipe_twoPointerDownAndActivatedState_panningState() { + goFromStateIdleTo(STATE_ACTIVATED); PointF pointer1 = DEFAULT_POINT; PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y); @@ -463,8 +490,8 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test - public void testZoomedWithTripleTap_invokeShowWindowPromptAction() { - goFromStateIdleTo(STATE_ZOOMED); + public void testActivatedWithTripleTap_invokeShowWindowPromptAction() { + goFromStateIdleTo(STATE_ACTIVATED); verify(mWindowMagnificationPromptController).showNotificationIfNeeded(); } @@ -541,9 +568,8 @@ public class FullScreenMagnificationGestureHandlerTest { check(!isActivated(), state); check(!isZoomed(), state); } break; - case STATE_ZOOMED: { + case STATE_ACTIVATED: { check(isActivated(), state); - check(isZoomed(), state); check(tapCount() < 2, state); } break; case STATE_2TAPS: { @@ -551,7 +577,7 @@ public class FullScreenMagnificationGestureHandlerTest { check(!isZoomed(), state); check(tapCount() == 2, state); } break; - case STATE_ZOOMED_2TAPS: { + case STATE_ACTIVATED_2TAPS: { check(isActivated(), state); check(isZoomed(), state); check(tapCount() == 2, state); @@ -561,14 +587,29 @@ public class FullScreenMagnificationGestureHandlerTest { check(isZoomed(), state); check(mMgh.mCurrentState == mMgh.mViewportDraggingState, state); - check(!mMgh.mViewportDraggingState.mActivatedBeforeDrag, state); + check(Float.isNaN(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd), + state); } break; case STATE_ACTIVATED_ZOOMED_TMP: { check(isActivated(), state); check(isZoomed(), state); check(mMgh.mCurrentState == mMgh.mViewportDraggingState, state); - check(mMgh.mViewportDraggingState.mActivatedBeforeDrag, state); + check(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd >= 1.0f, + state); + } break; + case STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP: { + check(isActivated(), state); + check(isZoomed(), state); + check(mMgh.mCurrentState == mMgh.mViewportDraggingState, + state); + if (mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled()) { + check(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd >= 1.0f, + state); + } else { + check(Float.isNaN(mMgh.mViewportDraggingState.mScaleToRecoverAfterDraggingEnd), + state); + } } break; case STATE_SHORTCUT_TRIGGERED: { check(mMgh.mDetectingState.mShortcutTriggered, state); @@ -605,7 +646,7 @@ public class FullScreenMagnificationGestureHandlerTest { tap(); tap(); } break; - case STATE_ZOOMED: { + case STATE_ACTIVATED: { if (mMgh.mDetectTripleTap) { goFromStateIdleTo(STATE_2TAPS); tap(); @@ -614,8 +655,8 @@ public class FullScreenMagnificationGestureHandlerTest { tap(); } } break; - case STATE_ZOOMED_2TAPS: { - goFromStateIdleTo(STATE_ZOOMED); + case STATE_ACTIVATED_2TAPS: { + goFromStateIdleTo(STATE_ACTIVATED); tap(); tap(); } break; @@ -625,7 +666,12 @@ public class FullScreenMagnificationGestureHandlerTest { fastForward1sec(); } break; case STATE_ACTIVATED_ZOOMED_TMP: { - goFromStateIdleTo(STATE_ZOOMED_2TAPS); + goFromStateIdleTo(STATE_ACTIVATED_2TAPS); + send(downEvent()); + fastForward1sec(); + } break; + case STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP: { + goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED); send(downEvent()); fastForward1sec(); } break; @@ -634,7 +680,7 @@ public class FullScreenMagnificationGestureHandlerTest { triggerShortcut(); } break; case STATE_PANNING: { - goFromStateIdleTo(STATE_ZOOMED); + goFromStateIdleTo(STATE_ACTIVATED); send(downEvent()); send(pointerEvent(ACTION_POINTER_DOWN, DEFAULT_X * 2, DEFAULT_Y)); fastForward(ViewConfiguration.getTapTimeout()); @@ -665,16 +711,16 @@ public class FullScreenMagnificationGestureHandlerTest { allowEventDelegation(); fastForward1sec(); } break; - case STATE_ZOOMED: { + case STATE_ACTIVATED: { if (mMgh.mDetectTripleTap) { tap(); tap(); - returnToNormalFrom(STATE_ZOOMED_2TAPS); + returnToNormalFrom(STATE_ACTIVATED_2TAPS); } else { triggerShortcut(); } } break; - case STATE_ZOOMED_2TAPS: { + case STATE_ACTIVATED_2TAPS: { tap(); } break; case STATE_NON_ACTIVATED_ZOOMED_TMP: { @@ -682,7 +728,13 @@ public class FullScreenMagnificationGestureHandlerTest { } break; case STATE_ACTIVATED_ZOOMED_TMP: { send(upEvent()); - returnToNormalFrom(STATE_ZOOMED); + returnToNormalFrom(STATE_ACTIVATED); + } break; + case STATE_SHORTCUT_TRIGGERED_ZOOMED_TMP: { + send(upEvent()); + if (mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled()) { + returnToNormalFrom(STATE_ACTIVATED); + } } break; case STATE_SHORTCUT_TRIGGERED: { triggerShortcut(); @@ -690,7 +742,7 @@ public class FullScreenMagnificationGestureHandlerTest { case STATE_PANNING: { send(pointerEvent(ACTION_POINTER_UP, DEFAULT_X * 2, DEFAULT_Y)); send(upEvent()); - returnToNormalFrom(STATE_ZOOMED); + returnToNormalFrom(STATE_ACTIVATED); } break; case STATE_SCALING_AND_PANNING: { returnToNormalFrom(STATE_PANNING);