feat(#AlwaysOnMagnifier)!: Supports magnification zooming to 100% [1/2]
There are 2 parts in this feature.
1. support fullscreen magnifier zooming to 100%.
2. support window magnifier zooming to 100%.
This CL is for the 1st part.
We change the minimum magnifiable scale to 100% in fullscreen magnifier, and prevent persistedScale from being 100%.
We adjust the flag mMagnificationActivated's usage and add new function isActivated(). Originally, The services check isMagnifying() to identify the fullscreen magnifier is activated. If the magnifier zooms to 100%, the magnifier state would become activated but not magnifying. Accordingly, the services cannot identify whether the magnifier is activated when zooming to 100%. Therefore, instead of isMagnifying(), the services change to check fullscreen magnifier is activated by isActivated().
We support pinching to zoom gesture after tapping on a11y shortcut to activate fullscreen magnifier. Originally, we can use pinching gesture only when we additionally perform one more tap in advance.
Besides, when magnifier is already activated, we support further zoom in temporary by triple tap and hold gesture. Originally, the gesture only changes the state to the viewport dragging mode.
Constrain the scale range in persisted scale getter/setter to >= 2.0 to prevent the presisted scale from being 100%. It results in zooming in with persisted scale would make context no changes.
Bug: 146504199, 242739712
Test: manually
atest FullScreenMagnificationControllerTest
atest magnification/FullScreenMagnificationGestureHandlerTest
atest cts/FullScreenMagnificationGestureHandlerTest
atest MagnificationControllerTest
atest AccessibilityManagerServiceTest
atest AccessibilityMagnificationTest
Change-Id: I3b0b119e9833eddb9a13681e4631b3ff47c6ce1e
This commit is contained in:
@@ -3228,7 +3228,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
|
||||
if (targetName.equals(MAGNIFICATION_CONTROLLER_NAME)) {
|
||||
final boolean enabled =
|
||||
!getMagnificationController().getFullScreenMagnificationController()
|
||||
.isMagnifying(displayId);
|
||||
.isActivated(displayId);
|
||||
logAccessibilityShortcutActivated(mContext, MAGNIFICATION_COMPONENT_NAME, shortcutType,
|
||||
enabled);
|
||||
sendAccessibilityButtonToInputFilter(displayId);
|
||||
|
||||
@@ -126,8 +126,6 @@ public class FullScreenMagnificationController implements
|
||||
private boolean mUnregisterPending;
|
||||
private boolean mDeleteAfterUnregister;
|
||||
|
||||
private boolean mForceShowMagnifiableBounds;
|
||||
|
||||
private final int mDisplayId;
|
||||
|
||||
private int mIdOfLastServiceToMagnify = INVALID_SERVICE_ID;
|
||||
@@ -213,8 +211,8 @@ public class FullScreenMagnificationController implements
|
||||
return mRegistered;
|
||||
}
|
||||
|
||||
boolean isMagnifying() {
|
||||
return mCurrentMagnificationSpec.scale > 1.0f;
|
||||
boolean isActivated() {
|
||||
return mMagnificationActivated;
|
||||
}
|
||||
|
||||
float getScale() {
|
||||
@@ -370,12 +368,6 @@ public class FullScreenMagnificationController implements
|
||||
@GuardedBy("mLock")
|
||||
void onMagnificationChangedLocked() {
|
||||
final float scale = getScale();
|
||||
final boolean lastMagnificationActivated = mMagnificationActivated;
|
||||
mMagnificationActivated = scale > 1.0f;
|
||||
if (mMagnificationActivated != lastMagnificationActivated) {
|
||||
mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
|
||||
mDisplayId, mMagnificationActivated);
|
||||
}
|
||||
|
||||
final MagnificationConfig config = new MagnificationConfig.Builder()
|
||||
.setMode(MAGNIFICATION_MODE_FULLSCREEN)
|
||||
@@ -384,7 +376,7 @@ public class FullScreenMagnificationController implements
|
||||
.setCenterY(getCenterY()).build();
|
||||
mMagnificationInfoChangedCallback.onFullScreenMagnificationChanged(mDisplayId,
|
||||
mMagnificationRegion, config);
|
||||
if (mUnregisterPending && !isMagnifying()) {
|
||||
if (mUnregisterPending && !isActivated()) {
|
||||
unregister(mDeleteAfterUnregister);
|
||||
}
|
||||
}
|
||||
@@ -476,21 +468,22 @@ public class FullScreenMagnificationController implements
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
void setForceShowMagnifiableBounds(boolean show) {
|
||||
if (mRegistered) {
|
||||
mForceShowMagnifiableBounds = show;
|
||||
if (traceEnabled()) {
|
||||
logTrace("setForceShowMagnifiableBounds",
|
||||
"displayID=" + mDisplayId + ";show=" + show);
|
||||
}
|
||||
mControllerCtx.getWindowManager().setForceShowMagnifiableBounds(
|
||||
mDisplayId, show);
|
||||
private boolean setActivated(boolean activated) {
|
||||
if (DEBUG) {
|
||||
Slog.i(LOG_TAG, "setActivated(activated = " + activated + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
boolean isForceShowMagnifiableBounds() {
|
||||
return mRegistered && mForceShowMagnifiableBounds;
|
||||
final boolean changed = (mMagnificationActivated != activated);
|
||||
|
||||
if (changed) {
|
||||
mMagnificationActivated = activated;
|
||||
mMagnificationInfoChangedCallback.onFullScreenMagnificationActivationState(
|
||||
mDisplayId, mMagnificationActivated);
|
||||
mControllerCtx.getWindowManager().setForceShowMagnifiableBounds(
|
||||
mDisplayId, activated);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@@ -504,13 +497,13 @@ public class FullScreenMagnificationController implements
|
||||
return false;
|
||||
}
|
||||
final MagnificationSpec spec = mCurrentMagnificationSpec;
|
||||
final boolean changed = !spec.isNop();
|
||||
final boolean changed = isActivated();
|
||||
setActivated(false);
|
||||
if (changed) {
|
||||
spec.clear();
|
||||
onMagnificationChangedLocked();
|
||||
}
|
||||
mIdOfLastServiceToMagnify = INVALID_SERVICE_ID;
|
||||
mForceShowMagnifiableBounds = false;
|
||||
sendSpecToAnimation(spec, animationCallback);
|
||||
return changed;
|
||||
}
|
||||
@@ -554,9 +547,10 @@ public class FullScreenMagnificationController implements
|
||||
+ ", centerY = " + centerY + ", endCallback = "
|
||||
+ animationCallback + ", id = " + id + ")");
|
||||
}
|
||||
final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
|
||||
boolean changed = setActivated(true);
|
||||
changed |= updateMagnificationSpecLocked(scale, centerX, centerY);
|
||||
sendSpecToAnimation(mCurrentMagnificationSpec, animationCallback);
|
||||
if (isMagnifying() && (id != INVALID_SERVICE_ID)) {
|
||||
if (isActivated() && (id != INVALID_SERVICE_ID)) {
|
||||
mIdOfLastServiceToMagnify = id;
|
||||
mMagnificationInfoChangedCallback.onRequestMagnificationSpec(mDisplayId,
|
||||
mIdOfLastServiceToMagnify);
|
||||
@@ -779,7 +773,7 @@ public class FullScreenMagnificationController implements
|
||||
if (display == null) {
|
||||
return;
|
||||
}
|
||||
if (!display.isMagnifying()) {
|
||||
if (!display.isActivated()) {
|
||||
return;
|
||||
}
|
||||
final Rect magnifiedRegionBounds = mTempRect;
|
||||
@@ -831,16 +825,16 @@ public class FullScreenMagnificationController implements
|
||||
|
||||
/**
|
||||
* @param displayId The logical display id.
|
||||
* @return {@code true} if magnification is active, e.g. the scale
|
||||
* is > 1, {@code false} otherwise
|
||||
* @return {@code true} if magnification is activated,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public boolean isMagnifying(int displayId) {
|
||||
public boolean isActivated(int displayId) {
|
||||
synchronized (mLock) {
|
||||
final DisplayMagnification display = mDisplays.get(displayId);
|
||||
if (display == null) {
|
||||
return false;
|
||||
}
|
||||
return display.isMagnifying();
|
||||
return display.isActivated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1166,6 +1160,9 @@ public class FullScreenMagnificationController implements
|
||||
*/
|
||||
public void persistScale(int displayId) {
|
||||
final float scale = getScale(Display.DEFAULT_DISPLAY);
|
||||
if (scale < 2.0f) {
|
||||
return;
|
||||
}
|
||||
mScaleProvider.putScale(scale, displayId);
|
||||
}
|
||||
|
||||
@@ -1177,7 +1174,8 @@ public class FullScreenMagnificationController implements
|
||||
* scale if none is available
|
||||
*/
|
||||
public float getPersistedScale(int displayId) {
|
||||
return mScaleProvider.getScale(displayId);
|
||||
return MathUtils.constrain(mScaleProvider.getScale(displayId),
|
||||
2.0f, MagnificationScaleProvider.MAX_SCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1198,12 +1196,12 @@ public class FullScreenMagnificationController implements
|
||||
*
|
||||
* @param displayId The logical display id.
|
||||
* @param animate whether the animate the transition
|
||||
* @return whether was {@link #isMagnifying(int) magnifying}
|
||||
* @return whether was {@link #isActivated(int)} activated}
|
||||
*/
|
||||
boolean resetIfNeeded(int displayId, boolean animate) {
|
||||
synchronized (mLock) {
|
||||
final DisplayMagnification display = mDisplays.get(displayId);
|
||||
if (display == null || !display.isMagnifying()) {
|
||||
if (display == null || !display.isActivated()) {
|
||||
return false;
|
||||
}
|
||||
display.reset(animate);
|
||||
@@ -1221,7 +1219,7 @@ public class FullScreenMagnificationController implements
|
||||
boolean resetIfNeeded(int displayId, int connectionId) {
|
||||
synchronized (mLock) {
|
||||
final DisplayMagnification display = mDisplays.get(displayId);
|
||||
if (display == null || !display.isMagnifying()
|
||||
if (display == null || !display.isActivated()
|
||||
|| connectionId != display.getIdOfLastServiceToMagnify()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1230,16 +1228,6 @@ public class FullScreenMagnificationController implements
|
||||
}
|
||||
}
|
||||
|
||||
void setForceShowMagnifiableBounds(int displayId, boolean show) {
|
||||
synchronized (mLock) {
|
||||
final DisplayMagnification display = mDisplays.get(displayId);
|
||||
if (display == null) {
|
||||
return;
|
||||
}
|
||||
display.setForceShowMagnifiableBounds(show);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that the IME window visibility changed.
|
||||
*
|
||||
@@ -1251,21 +1239,6 @@ public class FullScreenMagnificationController implements
|
||||
mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(displayId, shown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the magnifiable regions of the display is forced to be shown.
|
||||
*
|
||||
* @param displayId The logical display id.
|
||||
*/
|
||||
public boolean isForceShowMagnifiableBounds(int displayId) {
|
||||
synchronized (mLock) {
|
||||
final DisplayMagnification display = mDisplays.get(displayId);
|
||||
if (display == null) {
|
||||
return false;
|
||||
}
|
||||
return display.isForceShowMagnifiableBounds();
|
||||
}
|
||||
}
|
||||
|
||||
private void onScreenTurnedOff() {
|
||||
final Message m = PooledLambda.obtainMessage(
|
||||
FullScreenMagnificationController::resetAllIfNeeded, this, false);
|
||||
@@ -1295,7 +1268,7 @@ public class FullScreenMagnificationController implements
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!display.isMagnifying()) {
|
||||
if (!display.isActivated()) {
|
||||
display.unregister(delete);
|
||||
} else {
|
||||
display.unregisterPending(delete);
|
||||
|
||||
@@ -122,7 +122,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
// The MIN_SCALE is different from MagnificationScaleProvider.MIN_SCALE due
|
||||
// to AccessibilityService.MagnificationController#setScale() has
|
||||
// different scale range
|
||||
private static final float MIN_SCALE = 2.0f;
|
||||
private static final float MIN_SCALE = 1.0f;
|
||||
private static final float MAX_SCALE = MagnificationScaleProvider.MAX_SCALE;
|
||||
|
||||
@VisibleForTesting final FullScreenMagnificationController mFullScreenMagnificationController;
|
||||
@@ -220,14 +220,19 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
|
||||
@Override
|
||||
public void handleShortcutTriggered() {
|
||||
boolean wasMagnifying = mFullScreenMagnificationController.resetIfNeeded(mDisplayId,
|
||||
/* animate */ true);
|
||||
if (wasMagnifying) {
|
||||
final boolean isActivated = mFullScreenMagnificationController.isActivated(mDisplayId);
|
||||
|
||||
if (isActivated) {
|
||||
zoomOff();
|
||||
clearAndTransitionToStateDetecting();
|
||||
} else {
|
||||
mPromptController.showNotificationIfNeeded();
|
||||
mDetectingState.toggleShortcutTriggered();
|
||||
}
|
||||
|
||||
if (mDetectingState.isShortcutTriggered()) {
|
||||
mPromptController.showNotificationIfNeeded();
|
||||
zoomToScale(1.0f, Float.NaN, Float.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -441,7 +446,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
final class ViewportDraggingState implements State {
|
||||
|
||||
/** Whether to disable zoom after dragging ends */
|
||||
boolean mZoomedInBeforeDrag;
|
||||
@VisibleForTesting boolean mActivatedBeforeDrag;
|
||||
/** Whether to restore scale after dragging ends */
|
||||
private boolean mZoomedInTemporary;
|
||||
/** The cached scale for recovering after dragging ends */
|
||||
private float mScaleBeforeZoomedInTemporary;
|
||||
|
||||
private boolean mLastMoveOutsideMagnifiedRegion;
|
||||
|
||||
@Override
|
||||
@@ -474,7 +484,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
|
||||
case ACTION_UP:
|
||||
case ACTION_CANCEL: {
|
||||
if (!mZoomedInBeforeDrag) zoomOff();
|
||||
if (mActivatedBeforeDrag) {
|
||||
if (mZoomedInTemporary) {
|
||||
zoomToScale(mScaleBeforeZoomedInTemporary, event.getX(), event.getY());
|
||||
}
|
||||
} else {
|
||||
zoomOff();
|
||||
}
|
||||
clear();
|
||||
transitionTo(mDetectingState);
|
||||
}
|
||||
@@ -488,15 +504,27 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
}
|
||||
}
|
||||
|
||||
public void prepareForZoomInTemporary() {
|
||||
mViewportDraggingState.mActivatedBeforeDrag =
|
||||
mFullScreenMagnificationController.isActivated(mDisplayId);
|
||||
|
||||
mViewportDraggingState.mZoomedInTemporary = true;
|
||||
mViewportDraggingState.mScaleBeforeZoomedInTemporary =
|
||||
mFullScreenMagnificationController.getScale(mDisplayId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
mLastMoveOutsideMagnifiedRegion = false;
|
||||
|
||||
mZoomedInTemporary = false;
|
||||
mScaleBeforeZoomedInTemporary = 1.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ViewportDraggingState{"
|
||||
+ "mZoomedInBeforeDrag=" + mZoomedInBeforeDrag
|
||||
+ "mActivatedBeforeDrag=" + mActivatedBeforeDrag
|
||||
+ ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion
|
||||
+ '}';
|
||||
}
|
||||
@@ -625,10 +653,10 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
transitionToDelegatingStateAndClear();
|
||||
|
||||
} else if (mDetectTripleTap
|
||||
// If magnified, delay an ACTION_DOWN for mMultiTapMaxDelay
|
||||
// If activated, delay an ACTION_DOWN for mMultiTapMaxDelay
|
||||
// to ensure reachability of
|
||||
// STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN)
|
||||
|| mFullScreenMagnificationController.isMagnifying(mDisplayId)) {
|
||||
|| isActivated()) {
|
||||
|
||||
afterMultiTapTimeoutTransitionToDelegatingState();
|
||||
|
||||
@@ -640,8 +668,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
}
|
||||
break;
|
||||
case ACTION_POINTER_DOWN: {
|
||||
if (mFullScreenMagnificationController.isMagnifying(mDisplayId)
|
||||
&& event.getPointerCount() == 2) {
|
||||
if (isActivated() && event.getPointerCount() == 2) {
|
||||
storeSecondPointerDownLocation(event);
|
||||
mHandler.sendEmptyMessageDelayed(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
|
||||
ViewConfiguration.getTapTimeout());
|
||||
@@ -665,13 +692,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
// (which is a rare combo to be used aside from magnification)
|
||||
if (isMultiTapTriggered(2 /* taps */) && event.getPointerCount() == 1) {
|
||||
transitionToViewportDraggingStateAndClear(event);
|
||||
} else if (isMagnifying() && event.getPointerCount() == 2) {
|
||||
} else if (isActivated() && event.getPointerCount() == 2) {
|
||||
//Primary pointer is swiping, so transit to PanningScalingState
|
||||
transitToPanningScalingStateAndClear();
|
||||
} else {
|
||||
transitionToDelegatingStateAndClear();
|
||||
}
|
||||
} else if (isMagnifying() && secondPointerDownValid()
|
||||
} else if (isActivated() && secondPointerDownValid()
|
||||
&& distanceClosestPointerToPoint(
|
||||
mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) {
|
||||
//Second pointer is swiping, so transit to PanningScalingState
|
||||
@@ -734,7 +761,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
|
||||
// Only log the triple tap event, use numTaps to filter.
|
||||
if (multitapTriggered && numTaps > 2) {
|
||||
final boolean enabled = mFullScreenMagnificationController.isMagnifying(mDisplayId);
|
||||
final boolean enabled = isActivated();
|
||||
logMagnificationTripleTap(enabled);
|
||||
}
|
||||
return multitapTriggered;
|
||||
@@ -862,24 +889,33 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
mSecondPointerDownLocation.set(Float.NaN, Float.NaN);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could be triggered by both 2 cases.
|
||||
* 1. direct three tap gesture
|
||||
* 2. one tap while shortcut triggered (it counts as two taps).
|
||||
*/
|
||||
private void onTripleTap(MotionEvent up) {
|
||||
if (DEBUG_DETECTING) {
|
||||
Slog.i(mLogTag, "onTripleTap(); delayed: "
|
||||
+ MotionEventInfo.toString(mDelayedEventQueue));
|
||||
}
|
||||
clear();
|
||||
|
||||
// Toggle zoom
|
||||
if (mFullScreenMagnificationController.isMagnifying(mDisplayId)) {
|
||||
zoomOff();
|
||||
} else {
|
||||
// We put mShortcutTriggered into conditions.
|
||||
// The reason is when the shortcut is triggered,
|
||||
// the magnifier is activated and keeps in scale 1.0,
|
||||
// and in this case, we still want to zoom on the magnifier.
|
||||
if (!isActivated() || mShortcutTriggered) {
|
||||
mPromptController.showNotificationIfNeeded();
|
||||
zoomOn(up.getX(), up.getY());
|
||||
} else {
|
||||
zoomOff();
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
private boolean isMagnifying() {
|
||||
return mFullScreenMagnificationController.isMagnifying(mDisplayId);
|
||||
private boolean isActivated() {
|
||||
return mFullScreenMagnificationController.isActivated(mDisplayId);
|
||||
}
|
||||
|
||||
void transitionToViewportDraggingStateAndClear(MotionEvent down) {
|
||||
@@ -887,14 +923,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()");
|
||||
clear();
|
||||
|
||||
mViewportDraggingState.mZoomedInBeforeDrag =
|
||||
mFullScreenMagnificationController.isMagnifying(mDisplayId);
|
||||
|
||||
// Triple tap and hold also belongs to triple tap event.
|
||||
final boolean enabled = !mViewportDraggingState.mZoomedInBeforeDrag;
|
||||
final boolean enabled = !isActivated();
|
||||
logMagnificationTripleTap(enabled);
|
||||
|
||||
zoomOn(down.getX(), down.getY());
|
||||
mViewportDraggingState.prepareForZoomInTemporary();
|
||||
|
||||
zoomInTemporary(down.getX(), down.getY());
|
||||
|
||||
transitionTo(mViewportDraggingState);
|
||||
}
|
||||
@@ -919,7 +954,10 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
if (DEBUG_DETECTING) Slog.i(mLogTag, "setShortcutTriggered(" + state + ")");
|
||||
|
||||
mShortcutTriggered = state;
|
||||
mFullScreenMagnificationController.setForceShowMagnifiableBounds(mDisplayId, state);
|
||||
}
|
||||
|
||||
private boolean isShortcutTriggered() {
|
||||
return mShortcutTriggered;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -948,12 +986,29 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
|
||||
}
|
||||
}
|
||||
|
||||
private void zoomInTemporary(float centerX, float centerY) {
|
||||
final float currentScale = mFullScreenMagnificationController.getScale(mDisplayId);
|
||||
final float persistedScale = MathUtils.constrain(
|
||||
mFullScreenMagnificationController.getPersistedScale(mDisplayId),
|
||||
MIN_SCALE, MAX_SCALE);
|
||||
|
||||
final float scale = MathUtils.constrain(Math.max(currentScale + 1.0f, persistedScale),
|
||||
MIN_SCALE, MAX_SCALE);
|
||||
|
||||
zoomToScale(scale, centerX, centerY);
|
||||
}
|
||||
|
||||
private void zoomOn(float centerX, float centerY) {
|
||||
if (DEBUG_DETECTING) Slog.i(mLogTag, "zoomOn(" + centerX + ", " + centerY + ")");
|
||||
|
||||
final float scale = MathUtils.constrain(
|
||||
mFullScreenMagnificationController.getPersistedScale(mDisplayId),
|
||||
MIN_SCALE, MAX_SCALE);
|
||||
zoomToScale(scale, centerX, centerY);
|
||||
}
|
||||
|
||||
private void zoomToScale(float scale, float centerX, float centerY) {
|
||||
scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
|
||||
mFullScreenMagnificationController.setScaleAndCenter(mDisplayId,
|
||||
scale, centerX, centerY,
|
||||
/* animate */ true,
|
||||
|
||||
@@ -254,13 +254,15 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
final DisableMagnificationCallback animationEndCallback =
|
||||
new DisableMagnificationCallback(transitionCallBack, displayId, targetMode,
|
||||
scale, currentCenter, true);
|
||||
|
||||
setDisableMagnificationCallbackLocked(displayId, animationEndCallback);
|
||||
|
||||
if (targetMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
|
||||
screenMagnificationController.reset(displayId, animationEndCallback);
|
||||
} else {
|
||||
windowMagnificationMgr.disableWindowMagnification(displayId, false,
|
||||
animationEndCallback);
|
||||
}
|
||||
setDisableMagnificationCallbackLocked(displayId, animationEndCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,17 +483,17 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
*/
|
||||
private boolean shouldNotifyMagnificationChange(int displayId, int changeMode) {
|
||||
synchronized (mLock) {
|
||||
final boolean fullScreenMagnifying = mFullScreenMagnificationController != null
|
||||
&& mFullScreenMagnificationController.isMagnifying(displayId);
|
||||
final boolean fullScreenActivated = mFullScreenMagnificationController != null
|
||||
&& mFullScreenMagnificationController.isActivated(displayId);
|
||||
final boolean windowEnabled = mWindowMagnificationMgr != null
|
||||
&& mWindowMagnificationMgr.isWindowMagnifierEnabled(displayId);
|
||||
final Integer transitionMode = mTransitionModes.get(displayId);
|
||||
if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenMagnifying)
|
||||
if (((changeMode == MAGNIFICATION_MODE_FULLSCREEN && fullScreenActivated)
|
||||
|| (changeMode == MAGNIFICATION_MODE_WINDOW && windowEnabled))
|
||||
&& (transitionMode == null)) {
|
||||
return true;
|
||||
}
|
||||
if ((!fullScreenMagnifying && !windowEnabled)
|
||||
if ((!fullScreenActivated && !windowEnabled)
|
||||
&& (transitionMode == null)) {
|
||||
return true;
|
||||
}
|
||||
@@ -742,7 +744,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
mWindowMagnificationMgr.getCenterY(displayId));
|
||||
} else {
|
||||
if (mFullScreenMagnificationController == null
|
||||
|| !mFullScreenMagnificationController.isMagnifying(displayId)) {
|
||||
|| !mFullScreenMagnificationController.isActivated(displayId)) {
|
||||
return null;
|
||||
}
|
||||
mTempPoint.set(mFullScreenMagnificationController.getCenterX(displayId),
|
||||
@@ -766,9 +768,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
if (mFullScreenMagnificationController == null) {
|
||||
return false;
|
||||
}
|
||||
isActivated = mFullScreenMagnificationController.isMagnifying(displayId)
|
||||
|| mFullScreenMagnificationController.isForceShowMagnifiableBounds(
|
||||
displayId);
|
||||
isActivated = mFullScreenMagnificationController.isActivated(displayId);
|
||||
}
|
||||
} else if (mode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
|
||||
synchronized (mLock) {
|
||||
@@ -829,7 +829,7 @@ public class MagnificationController implements WindowMagnificationManager.Callb
|
||||
final FullScreenMagnificationController screenMagnificationController =
|
||||
getFullScreenMagnificationController();
|
||||
if (mCurrentMode == ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
|
||||
&& !screenMagnificationController.isMagnifying(mDisplayId)) {
|
||||
&& !screenMagnificationController.isActivated(mDisplayId)) {
|
||||
MagnificationConfig.Builder configBuilder =
|
||||
new MagnificationConfig.Builder();
|
||||
Region region = new Region();
|
||||
|
||||
@@ -313,13 +313,13 @@ public class MagnificationProcessor {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link FullScreenMagnificationController#isMagnifying(int)}
|
||||
* {@link FullScreenMagnificationController#isActivated(int)}
|
||||
* {@link WindowMagnificationManager#isWindowMagnifierEnabled(int)}
|
||||
*/
|
||||
public boolean isMagnifying(int displayId) {
|
||||
int mode = getControllingMode(displayId);
|
||||
if (mode == MAGNIFICATION_MODE_FULLSCREEN) {
|
||||
return mController.getFullScreenMagnificationController().isMagnifying(displayId);
|
||||
return mController.getFullScreenMagnificationController().isActivated(displayId);
|
||||
} else if (mode == MAGNIFICATION_MODE_WINDOW) {
|
||||
return mController.getWindowMagnificationMgr().isWindowMagnifierEnabled(displayId);
|
||||
}
|
||||
|
||||
@@ -891,8 +891,7 @@ final class AccessibilityController {
|
||||
// to show the border. We will do so when the pending message is handled.
|
||||
if (!mHandler.hasMessages(
|
||||
MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)) {
|
||||
setMagnifiedRegionBorderShown(
|
||||
isMagnifying() || isForceShowingMagnifiableBounds(), true);
|
||||
setMagnifiedRegionBorderShown(isForceShowingMagnifiableBounds(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1057,7 +1056,7 @@ final class AccessibilityController {
|
||||
// rotation or folding/unfolding the device. In the rotation case, the screenshot
|
||||
// used for rotation already has the border. After the rotation is complete
|
||||
// we will show the border.
|
||||
if (isMagnifying() || isForceShowingMagnifiableBounds()) {
|
||||
if (isForceShowingMagnifiableBounds()) {
|
||||
setMagnifiedRegionBorderShown(false, false);
|
||||
final long delay = (long) (mLongAnimationDuration
|
||||
* mService.getWindowAnimationScaleLocked());
|
||||
@@ -1398,8 +1397,7 @@ final class AccessibilityController {
|
||||
|
||||
case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : {
|
||||
synchronized (mService.mGlobalLock) {
|
||||
if (mMagnifedViewport.isMagnifying()
|
||||
|| isForceShowingMagnifiableBounds()) {
|
||||
if (isForceShowingMagnifiableBounds()) {
|
||||
mMagnifedViewport.setMagnifiedRegionBorderShown(true, true);
|
||||
mService.scheduleAnimationLocked();
|
||||
}
|
||||
|
||||
@@ -214,7 +214,8 @@ public class FullScreenMagnificationControllerTest {
|
||||
}
|
||||
|
||||
private void notRegistered_publicMethodsShouldBeBenign(int displayId) {
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, displayId);
|
||||
|
||||
assertFalse(
|
||||
mFullScreenMagnificationController.magnificationRegionContains(displayId, 100,
|
||||
100));
|
||||
@@ -646,9 +647,9 @@ public class FullScreenMagnificationControllerTest {
|
||||
.setScale(displayId, 1.5f, startCenter.x, startCenter.y, false,
|
||||
SERVICE_ID_2);
|
||||
assertFalse(mFullScreenMagnificationController.resetIfNeeded(displayId, SERVICE_ID_1));
|
||||
assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */true, /* magnifying= */true, displayId);
|
||||
assertTrue(mFullScreenMagnificationController.resetIfNeeded(displayId, SERVICE_ID_2));
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, displayId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -667,7 +668,7 @@ public class FullScreenMagnificationControllerTest {
|
||||
assertTrue(mFullScreenMagnificationController.resetIfNeeded(displayId, false));
|
||||
verify(mRequestObserver).onFullScreenMagnificationChanged(eq(displayId),
|
||||
eq(INITIAL_MAGNIFICATION_REGION), any(MagnificationConfig.class));
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, displayId);
|
||||
assertFalse(mFullScreenMagnificationController.resetIfNeeded(displayId, false));
|
||||
}
|
||||
|
||||
@@ -731,7 +732,7 @@ public class FullScreenMagnificationControllerTest {
|
||||
mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
|
||||
mStateListener.onAnimationEnd(mMockValueAnimator);
|
||||
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_0));
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, displayId);
|
||||
verify(lastAnimationCallback).onResult(true);
|
||||
}
|
||||
|
||||
@@ -749,8 +750,8 @@ public class FullScreenMagnificationControllerTest {
|
||||
mMessageCapturingHandler.sendAllMessages();
|
||||
br.onReceive(mMockContext, null);
|
||||
mMessageCapturingHandler.sendAllMessages();
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_0));
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_1));
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, DISPLAY_0);
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, DISPLAY_1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -768,7 +769,7 @@ public class FullScreenMagnificationControllerTest {
|
||||
mMessageCapturingHandler.sendAllMessages();
|
||||
callbacks.onUserContextChanged();
|
||||
mMessageCapturingHandler.sendAllMessages();
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, displayId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -784,10 +785,10 @@ public class FullScreenMagnificationControllerTest {
|
||||
MagnificationCallbacks callbacks = getMagnificationCallbacks(displayId);
|
||||
zoomIn2xToMiddle(displayId);
|
||||
mMessageCapturingHandler.sendAllMessages();
|
||||
assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */true, /* magnifying= */true, displayId);
|
||||
callbacks.onDisplaySizeChanged();
|
||||
mMessageCapturingHandler.sendAllMessages();
|
||||
assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */false, /* magnifying= */false, DISPLAY_0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1133,22 +1134,16 @@ public class FullScreenMagnificationControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetForceShowMagnifiableBounds() {
|
||||
public void testZoomTo1x_shouldActivatedAndForceShowMagnifiableBounds() {
|
||||
register(DISPLAY_0);
|
||||
final float scale = 1.0f;
|
||||
mFullScreenMagnificationController.setScaleAndCenter(
|
||||
DISPLAY_0, scale, Float.NaN, Float.NaN, true, SERVICE_ID_1);
|
||||
|
||||
mFullScreenMagnificationController.setForceShowMagnifiableBounds(DISPLAY_0, true);
|
||||
|
||||
checkActivatedAndMagnifyingState(/* activated= */true, /* magnifying= */false, DISPLAY_0);
|
||||
verify(mMockWindowManager).setForceShowMagnifiableBounds(DISPLAY_0, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsForceShowMagnifiableBounds() {
|
||||
register(DISPLAY_0);
|
||||
mFullScreenMagnificationController.setForceShowMagnifiableBounds(DISPLAY_0, true);
|
||||
|
||||
assertTrue(mFullScreenMagnificationController.isForceShowMagnifiableBounds(DISPLAY_0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetScale_toMagnifying_shouldNotifyActivatedState() {
|
||||
setScaleToMagnifying();
|
||||
@@ -1220,7 +1215,15 @@ public class FullScreenMagnificationControllerTest {
|
||||
float scale = 2.0f;
|
||||
mFullScreenMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y,
|
||||
false, SERVICE_ID_1);
|
||||
assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
|
||||
checkActivatedAndMagnifyingState(/* activated= */true, /* magnifying= */true, displayId);
|
||||
}
|
||||
|
||||
private void checkActivatedAndMagnifyingState(
|
||||
boolean activated, boolean magnifying, int displayId) {
|
||||
final boolean isActivated = mFullScreenMagnificationController.isActivated(displayId);
|
||||
final boolean isMagnifying = mFullScreenMagnificationController.getScale(displayId) > 1.0f;
|
||||
assertTrue(isActivated == activated);
|
||||
assertTrue(isMagnifying == magnifying);
|
||||
}
|
||||
|
||||
private MagnificationCallbacks getMagnificationCallbacks(int displayId) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.accessibility.magnification;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_MOVE;
|
||||
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
import static android.view.MotionEvent.ACTION_POINTER_UP;
|
||||
import static android.view.MotionEvent.ACTION_UP;
|
||||
|
||||
@@ -78,24 +79,25 @@ import java.util.function.IntConsumer;
|
||||
* {@code
|
||||
* digraph {
|
||||
* IDLE -> SHORTCUT_TRIGGERED [label="a11y\nbtn"]
|
||||
* SHORTCUT_TRIGGERED -> IDLE [label="a11y\nbtn"]
|
||||
* IDLE -> DOUBLE_TAP [label="2tap"]
|
||||
* DOUBLE_TAP -> IDLE [label="timeout"]
|
||||
* DOUBLE_TAP -> TRIPLE_TAP_AND_HOLD [label="down"]
|
||||
* SHORTCUT_TRIGGERED -> TRIPLE_TAP_AND_HOLD [label="down"]
|
||||
* TRIPLE_TAP_AND_HOLD -> ZOOMED [label="up"]
|
||||
* TRIPLE_TAP_AND_HOLD -> DRAGGING_TMP [label="hold/\nswipe"]
|
||||
* DRAGGING_TMP -> IDLE [label="release"]
|
||||
* DOUBLE_TAP -> ZOOMED [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 -> PANNING [label="2hold]
|
||||
* ZOOMED -> ZOOMED_DOUBLE_TAP [label="2tap"]
|
||||
* ZOOMED_DOUBLE_TAP -> ZOOMED [label="timeout"]
|
||||
* ZOOMED_DOUBLE_TAP -> DRAGGING [label="hold"]
|
||||
* ZOOMED_DOUBLE_TAP -> IDLE [label="tap"]
|
||||
* DRAGGING -> ZOOMED [label="release"]
|
||||
* 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"]
|
||||
* PANNING -> PANNING_SCALING [label="pinch"]
|
||||
* PANNING_SCALING -> ZOOMED [label="release"]
|
||||
* PANNING -> ZOOMED [label="release"]
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
@@ -107,12 +109,11 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
public static final int STATE_2TAPS = 3;
|
||||
public static final int STATE_ZOOMED_2TAPS = 4;
|
||||
public static final int STATE_SHORTCUT_TRIGGERED = 5;
|
||||
public static final int STATE_DRAGGING_TMP = 6;
|
||||
public static final int STATE_DRAGGING = 7;
|
||||
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 FIRST_STATE = STATE_IDLE;
|
||||
public static final int LAST_STATE = STATE_SCALING_AND_PANNING;
|
||||
|
||||
@@ -164,10 +165,6 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
public boolean magnificationRegionContains(int displayId, float x, float y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
void setForceShowMagnifiableBounds(int displayId, boolean show) {
|
||||
}
|
||||
};
|
||||
mFullScreenMagnificationController.register(DISPLAY_0);
|
||||
mClock = new OffsettableClock.Stopped();
|
||||
@@ -266,11 +263,11 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
@SuppressWarnings("Convert2MethodRef")
|
||||
@Test
|
||||
public void testAlternativeTransitions_areWorking() {
|
||||
// A11y button followed by a tap&hold turns temporary "viewport dragging" zoom on
|
||||
// A11y button followed by a tap&hold turns temporary "viewport dragging" zoom in
|
||||
assertTransition(STATE_SHORTCUT_TRIGGERED, () -> {
|
||||
send(downEvent());
|
||||
fastForward1sec();
|
||||
}, STATE_DRAGGING_TMP);
|
||||
}, STATE_ACTIVATED_ZOOMED_TMP);
|
||||
|
||||
// A11y button followed by a tap turns zoom on
|
||||
assertTransition(STATE_SHORTCUT_TRIGGERED, () -> tap(), STATE_ZOOMED);
|
||||
@@ -281,7 +278,6 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
// A11y button turns zoom off
|
||||
assertTransition(STATE_ZOOMED, () -> triggerShortcut(), STATE_IDLE);
|
||||
|
||||
|
||||
// Double tap times out while zoomed
|
||||
assertTransition(STATE_ZOOMED_2TAPS, () -> {
|
||||
allowEventDelegation();
|
||||
@@ -291,8 +287,11 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
// tap+tap+swipe doesn't get delegated
|
||||
assertTransition(STATE_2TAPS, () -> swipe(), STATE_IDLE);
|
||||
|
||||
// tap+tap+swipe initiates viewport dragging immediately
|
||||
assertTransition(STATE_2TAPS, () -> swipeAndHold(), STATE_DRAGGING_TMP);
|
||||
// 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);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -337,8 +336,10 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
|
||||
@Test
|
||||
public void testTripleTapAndHold_zoomsImmediately() {
|
||||
assertZoomsImmediatelyOnSwipeFrom(STATE_2TAPS);
|
||||
assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED);
|
||||
assertZoomsImmediatelyOnSwipeFrom(STATE_2TAPS, STATE_NON_ACTIVATED_ZOOMED_TMP);
|
||||
assertZoomsImmediatelyOnSwipeFrom(STATE_SHORTCUT_TRIGGERED, STATE_ACTIVATED_ZOOMED_TMP);
|
||||
assertZoomsImmediatelyOnSwipeFrom(STATE_ZOOMED_2TAPS, STATE_ACTIVATED_ZOOMED_TMP);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -391,10 +392,10 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
PointF pointer3 = new PointF(DEFAULT_X * 2, DEFAULT_Y);
|
||||
|
||||
send(downEvent());
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}));
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2, pointer3}));
|
||||
send(pointerEvent(ACTION_POINTER_UP, new PointF[] {pointer1, pointer2, pointer3}));
|
||||
send(pointerEvent(ACTION_POINTER_UP, new PointF[] {pointer1, pointer2, pointer3}));
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}, 1));
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2, pointer3}, 2));
|
||||
send(pointerEvent(ACTION_POINTER_UP, new PointF[] {pointer1, pointer2, pointer3}, 2));
|
||||
send(pointerEvent(ACTION_POINTER_UP, new PointF[] {pointer1, pointer2, pointer3}, 2));
|
||||
send(upEvent());
|
||||
|
||||
assertIn(STATE_ZOOMED);
|
||||
@@ -411,38 +412,53 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirstFingerSwipe_TwoPinterDownAndZoomedState_panningState() {
|
||||
public void testFirstFingerSwipe_twoPointerDownAndZoomedState_panningState() {
|
||||
goFromStateIdleTo(STATE_ZOOMED);
|
||||
PointF pointer1 = DEFAULT_POINT;
|
||||
PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y);
|
||||
|
||||
send(downEvent());
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}));
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}, 1));
|
||||
//The minimum movement to transit to panningState.
|
||||
final float sWipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop();
|
||||
pointer1.offset(sWipeMinDistance + 1, 0);
|
||||
send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}));
|
||||
send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}, 0));
|
||||
assertIn(STATE_PANNING);
|
||||
|
||||
assertIn(STATE_PANNING);
|
||||
returnToNormalFrom(STATE_PANNING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondFingerSwipe_TwoPinterDownAndZoomedState_panningState() {
|
||||
public void testSecondFingerSwipe_twoPointerDownAndZoomedState_panningState() {
|
||||
goFromStateIdleTo(STATE_ZOOMED);
|
||||
PointF pointer1 = DEFAULT_POINT;
|
||||
PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y);
|
||||
|
||||
send(downEvent());
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}));
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}, 1));
|
||||
//The minimum movement to transit to panningState.
|
||||
final float sWipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop();
|
||||
pointer2.offset(sWipeMinDistance + 1, 0);
|
||||
send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}));
|
||||
send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}, 1));
|
||||
assertIn(STATE_PANNING);
|
||||
|
||||
returnToNormalFrom(STATE_PANNING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecondFingerSwipe_twoPointerDownAndShortcutTriggeredState_panningState() {
|
||||
goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED);
|
||||
PointF pointer1 = DEFAULT_POINT;
|
||||
PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y);
|
||||
|
||||
send(downEvent());
|
||||
send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}, 1));
|
||||
//The minimum movement to transit to panningState.
|
||||
final float sWipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop();
|
||||
pointer2.offset(sWipeMinDistance + 1, 0);
|
||||
send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}, 1));
|
||||
assertIn(STATE_PANNING);
|
||||
|
||||
returnToNormalFrom(STATE_PANNING);
|
||||
}
|
||||
|
||||
@@ -474,11 +490,11 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void assertZoomsImmediatelyOnSwipeFrom(int state) {
|
||||
goFromStateIdleTo(state);
|
||||
private void assertZoomsImmediatelyOnSwipeFrom(int fromState, int toState) {
|
||||
goFromStateIdleTo(fromState);
|
||||
swipeAndHold();
|
||||
assertIn(STATE_DRAGGING_TMP);
|
||||
returnToNormalFrom(STATE_DRAGGING_TMP);
|
||||
assertIn(toState);
|
||||
returnToNormalFrom(toState);
|
||||
}
|
||||
|
||||
private void assertTransition(int fromState, Runnable transitionAction, int toState) {
|
||||
@@ -522,44 +538,51 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
case STATE_IDLE: {
|
||||
check(tapCount() < 2, state);
|
||||
check(!mMgh.mDetectingState.mShortcutTriggered, state);
|
||||
check(!isActivated(), state);
|
||||
check(!isZoomed(), state);
|
||||
} break;
|
||||
case STATE_ZOOMED: {
|
||||
check(isActivated(), state);
|
||||
check(isZoomed(), state);
|
||||
check(tapCount() < 2, state);
|
||||
} break;
|
||||
case STATE_2TAPS: {
|
||||
check(!isActivated(), state);
|
||||
check(!isZoomed(), state);
|
||||
check(tapCount() == 2, state);
|
||||
} break;
|
||||
case STATE_ZOOMED_2TAPS: {
|
||||
check(isActivated(), state);
|
||||
check(isZoomed(), state);
|
||||
check(tapCount() == 2, state);
|
||||
} break;
|
||||
case STATE_DRAGGING: {
|
||||
case STATE_NON_ACTIVATED_ZOOMED_TMP: {
|
||||
check(isActivated(), state);
|
||||
check(isZoomed(), state);
|
||||
check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
|
||||
state);
|
||||
check(mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
|
||||
check(!mMgh.mViewportDraggingState.mActivatedBeforeDrag, state);
|
||||
} break;
|
||||
case STATE_DRAGGING_TMP: {
|
||||
case STATE_ACTIVATED_ZOOMED_TMP: {
|
||||
check(isActivated(), state);
|
||||
check(isZoomed(), state);
|
||||
check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
|
||||
state);
|
||||
check(!mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
|
||||
check(mMgh.mViewportDraggingState.mActivatedBeforeDrag, state);
|
||||
} break;
|
||||
case STATE_SHORTCUT_TRIGGERED: {
|
||||
check(mMgh.mDetectingState.mShortcutTriggered, state);
|
||||
check(isActivated(), state);
|
||||
check(!isZoomed(), state);
|
||||
} break;
|
||||
case STATE_PANNING: {
|
||||
check(isZoomed(), state);
|
||||
check(isActivated(), state);
|
||||
check(mMgh.mCurrentState == mMgh.mPanningScalingState,
|
||||
state);
|
||||
check(!mMgh.mPanningScalingState.mScaling, state);
|
||||
} break;
|
||||
case STATE_SCALING_AND_PANNING: {
|
||||
check(isZoomed(), state);
|
||||
check(isActivated(), state);
|
||||
check(mMgh.mCurrentState == mMgh.mPanningScalingState,
|
||||
state);
|
||||
check(mMgh.mPanningScalingState.mScaling, state);
|
||||
@@ -596,13 +619,13 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
tap();
|
||||
tap();
|
||||
} break;
|
||||
case STATE_DRAGGING: {
|
||||
goFromStateIdleTo(STATE_ZOOMED_2TAPS);
|
||||
case STATE_NON_ACTIVATED_ZOOMED_TMP: {
|
||||
goFromStateIdleTo(STATE_2TAPS);
|
||||
send(downEvent());
|
||||
fastForward1sec();
|
||||
} break;
|
||||
case STATE_DRAGGING_TMP: {
|
||||
goFromStateIdleTo(STATE_2TAPS);
|
||||
case STATE_ACTIVATED_ZOOMED_TMP: {
|
||||
goFromStateIdleTo(STATE_ZOOMED_2TAPS);
|
||||
send(downEvent());
|
||||
fastForward1sec();
|
||||
} break;
|
||||
@@ -654,13 +677,13 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
case STATE_ZOOMED_2TAPS: {
|
||||
tap();
|
||||
} break;
|
||||
case STATE_DRAGGING: {
|
||||
case STATE_NON_ACTIVATED_ZOOMED_TMP: {
|
||||
send(upEvent());
|
||||
} break;
|
||||
case STATE_ACTIVATED_ZOOMED_TMP: {
|
||||
send(upEvent());
|
||||
returnToNormalFrom(STATE_ZOOMED);
|
||||
} break;
|
||||
case STATE_DRAGGING_TMP: {
|
||||
send(upEvent());
|
||||
} break;
|
||||
case STATE_SHORTCUT_TRIGGERED: {
|
||||
triggerShortcut();
|
||||
} break;
|
||||
@@ -682,8 +705,12 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isActivated() {
|
||||
return mMgh.mFullScreenMagnificationController.isActivated(DISPLAY_0);
|
||||
}
|
||||
|
||||
private boolean isZoomed() {
|
||||
return mMgh.mFullScreenMagnificationController.isMagnifying(DISPLAY_0);
|
||||
return mMgh.mFullScreenMagnificationController.getScale(DISPLAY_0) > 1.0f;
|
||||
}
|
||||
|
||||
private int tapCount() {
|
||||
@@ -770,10 +797,10 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
|
||||
|
||||
private MotionEvent pointerEvent(int action, float x, float y) {
|
||||
return pointerEvent(action, new PointF[] {DEFAULT_POINT, new PointF(x, y)});
|
||||
return pointerEvent(action, new PointF[] {DEFAULT_POINT, new PointF(x, y)}, 1);
|
||||
}
|
||||
|
||||
private MotionEvent pointerEvent(int action, PointF[] pointersPosition) {
|
||||
private MotionEvent pointerEvent(int action, PointF[] pointersPosition, int changedIndex) {
|
||||
final MotionEvent.PointerProperties[] PointerPropertiesArray =
|
||||
new MotionEvent.PointerProperties[pointersPosition.length];
|
||||
for (int i = 0; i < pointersPosition.length; i++) {
|
||||
@@ -792,6 +819,8 @@ public class FullScreenMagnificationGestureHandlerTest {
|
||||
pointerCoordsArray[i] = pointerCoords;
|
||||
}
|
||||
|
||||
action += (changedIndex << ACTION_POINTER_INDEX_SHIFT);
|
||||
|
||||
return MotionEvent.obtain(
|
||||
/* downTime */ mClock.now(),
|
||||
/* eventTime */ mClock.now(),
|
||||
|
||||
@@ -494,16 +494,6 @@ public class MagnificationControllerTest {
|
||||
eq(MODE_FULLSCREEN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setScaleOneThroughExternalRequest_fullScreenEnabled_removeMagnificationButton()
|
||||
throws RemoteException {
|
||||
setMagnificationEnabled(MODE_FULLSCREEN);
|
||||
mScreenMagnificationController.setScaleAndCenter(TEST_DISPLAY, 1.0f,
|
||||
MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y, false, TEST_SERVICE_ID);
|
||||
|
||||
verify(mWindowMagnificationManager).removeMagnificationButton(eq(TEST_DISPLAY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPerformScaleAction_magnifierEnabled_handleScaleChange() throws RemoteException {
|
||||
final float newScale = 4.0f;
|
||||
@@ -756,7 +746,7 @@ public class MagnificationControllerTest {
|
||||
|
||||
mMagnificationController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
|
||||
|
||||
assertFalse(mScreenMagnificationController.isMagnifying(TEST_DISPLAY));
|
||||
verify(mScreenMagnificationController).reset(eq(TEST_DISPLAY), eq(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user