From 6259298cd84cdc98ff0963ea4b26515c3830b1ef Mon Sep 17 00:00:00 2001 From: ryanlwlin Date: Tue, 24 Dec 2019 11:19:20 +0800 Subject: [PATCH] Gesture detection for window magnification (1/n) To change the gesturehandler easily for different magnification mode, we rename MagnificationGestureHandler to FullScreenMagnificationGestureHandler and add a common class MagnificationGestureHandler. We will create different MagnificationGestureHandler based on magnification mode. Bug: 146400227 Test:FullScreenMagnificationGestureHandlerTest Test: AccessibilityInputFilterTest.java Change-Id: Ib7a45300a1f1323e1005b89694bb66932b22ab1b --- .../AccessibilityInputFilter.java | 3 +- ...ullScreenMagnificationGestureHandler.java} | 95 ++++++++++--------- .../MagnificationGestureHandler.java | 30 ++++++ .../AccessibilityInputFilterTest.java | 2 +- ...creenMagnificationGestureHandlerTest.java} | 20 ++-- 5 files changed, 93 insertions(+), 57 deletions(-) rename services/accessibility/java/com/android/server/accessibility/{MagnificationGestureHandler.java => FullScreenMagnificationGestureHandler.java} (93%) create mode 100644 services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java rename services/tests/servicestests/src/com/android/server/accessibility/{MagnificationGestureHandlerTest.java => FullScreenMagnificationGestureHandlerTest.java} (96%) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index c733d3bee6b63..49582a97b8908 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -31,6 +31,7 @@ import android.view.accessibility.AccessibilityEvent; import com.android.server.LocalServices; import com.android.server.accessibility.gestures.TouchExplorer; +import com.android.server.accessibility.magnification.MagnificationGestureHandler; import com.android.server.policy.WindowManagerPolicy; import java.util.ArrayList; @@ -402,7 +403,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo final boolean triggerable = (mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0; MagnificationGestureHandler magnificationGestureHandler = - new MagnificationGestureHandler(displayContext, + new FullScreenMagnificationGestureHandler(displayContext, mAms.getMagnificationController(), detectControlGestures, triggerable, displayId); addFirstEventHandler(displayId, magnificationGestureHandler); diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java similarity index 93% rename from services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java rename to services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java index 06ca054db14aa..9e4fd80c9e6ba 100644 --- a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java @@ -53,14 +53,16 @@ import android.view.ScaleGestureDetector; import android.view.ScaleGestureDetector.OnScaleGestureListener; import android.view.ViewConfiguration; +import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.server.accessibility.gestures.GestureUtils; +import com.android.server.accessibility.magnification.MagnificationGestureHandler; import java.util.ArrayDeque; import java.util.Queue; /** - * This class handles magnification in response to touch events. + * This class handles full screen magnification in response to touch events. * * The behavior is as follows: * @@ -108,14 +110,14 @@ import java.util.Queue; * 7. The magnification scale will be persisted in settings and in the cloud. */ @SuppressWarnings("WeakerAccess") -class MagnificationGestureHandler extends BaseEventStreamTransformation { - private static final String LOG_TAG = "MagnificationGestureHandler"; +class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler { + private static final String LOG_TAG = "FullScreenMagnificationGestureHandler"; private static final boolean DEBUG_ALL = false; - private static final boolean DEBUG_STATE_TRANSITIONS = false || DEBUG_ALL; - private static final boolean DEBUG_DETECTING = false || DEBUG_ALL; - private static final boolean DEBUG_PANNING_SCALING = false || DEBUG_ALL; - private static final boolean DEBUG_EVENT_STREAM = false || DEBUG_ALL; + private static final boolean DEBUG_STATE_TRANSITIONS = false | DEBUG_ALL; + private static final boolean DEBUG_DETECTING = false | DEBUG_ALL; + private static final boolean DEBUG_PANNING_SCALING = false | DEBUG_ALL; + private static final boolean DEBUG_EVENT_STREAM = false | DEBUG_ALL; // The MIN_SCALE is different from MagnificationController.MIN_SCALE due // to AccessibilityService.MagnificationController#setScale() has @@ -167,14 +169,14 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { * {@code false} if it should ignore such triggers. * @param displayId The logical display id. */ - public MagnificationGestureHandler(Context context, + FullScreenMagnificationGestureHandler(Context context, MagnificationController magnificationController, boolean detectTripleTap, boolean detectShortcutTrigger, int displayId) { if (DEBUG_ALL) { Log.i(LOG_TAG, - "MagnificationGestureHandler(detectTripleTap = " + detectTripleTap + "FullScreenMagnificationGestureHandler(detectTripleTap = " + detectTripleTap + ", detectShortcutTrigger = " + detectShortcutTrigger + ")"); } @@ -263,7 +265,8 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { clearAndTransitionToStateDetecting(); } - void notifyShortcutTriggered() { + @Override + public void notifyShortcutTriggered() { if (mDetectShortcutTrigger) { boolean wasMagnifying = mMagnificationController.resetIfNeeded(mDisplayId, /* animate */ true); @@ -383,10 +386,10 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { float mInitialScaleFactor = -1; boolean mScaling; - public PanningScalingState(Context context) { + PanningScalingState(Context context) { final TypedValue scaleValue = new TypedValue(); context.getResources().getValue( - com.android.internal.R.dimen.config_screen_magnification_scaling_threshold, + R.dimen.config_screen_magnification_scaling_threshold, scaleValue, false); mScalingThreshold = scaleValue.getFloat(); mScaleGestureDetector = new ScaleGestureDetector(context, this, Handler.getMain()); @@ -407,7 +410,6 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { } else if (action == ACTION_UP || action == ACTION_CANCEL) { persistScaleAndTransitionTo(mDetectingState); - } } @@ -489,10 +491,9 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { @Override public String toString() { - return "PanningScalingState{" + - "mInitialScaleFactor=" + mInitialScaleFactor + - ", mScaling=" + mScaling + - '}'; + return "PanningScalingState{" + "mInitialScaleFactor=" + mInitialScaleFactor + + ", mScaling=" + mScaling + + '}'; } } @@ -544,7 +545,7 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { clear(); transitionTo(mDetectingState); } - break; + break; case ACTION_DOWN: case ACTION_POINTER_UP: { @@ -561,10 +562,10 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { @Override public String toString() { - return "ViewportDraggingState{" + - "mZoomedInBeforeDrag=" + mZoomedInBeforeDrag + - ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion + - '}'; + return "ViewportDraggingState{" + + "mZoomedInBeforeDrag=" + mZoomedInBeforeDrag + + ", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion + + '}'; } } @@ -577,16 +578,17 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { - // Ensure that the state at the end of delegation is consistent with the last delegated + // 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()) { case ACTION_UP: case ACTION_CANCEL: { transitionTo(mDetectingState); - } break; + } + break; case ACTION_DOWN: { - transitionTo(mDelegatingState); + transitionTo(mDelegatingState); mLastDelegatedDownEventTime = event.getDownTime(); } break; } @@ -630,11 +632,11 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { @VisibleForTesting Handler mHandler = new Handler(Looper.getMainLooper(), this); - public DetectingState(Context context) { + DetectingState(Context context) { mLongTapMinDelay = ViewConfiguration.getLongPressTimeout(); mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout() + context.getResources().getInteger( - com.android.internal.R.integer.config_screen_magnification_multi_tap_adjustment); + R.integer.config_screen_magnification_multi_tap_adjustment); mSwipeMinDistance = ViewConfiguration.get(context).getScaledTouchSlop(); mMultiTapMaxDistance = ViewConfiguration.get(context).getScaledDoubleTapSlop(); } @@ -913,11 +915,11 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { @Override public String toString() { - return "DetectingState{" + - "tapCount()=" + tapCount() + - ", mShortcutTriggered=" + mShortcutTriggered + - ", mDelayedEventQueue=" + MotionEventInfo.toString(mDelayedEventQueue) + - '}'; + return "DetectingState{" + + "tapCount()=" + tapCount() + + ", mShortcutTriggered=" + mShortcutTriggered + + ", mDelayedEventQueue=" + MotionEventInfo.toString(mDelayedEventQueue) + + '}'; } void toggleShortcutTriggered() { @@ -986,18 +988,18 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { @Override public String toString() { - return "MagnificationGesture{" + - "mDetectingState=" + mDetectingState + - ", mDelegatingState=" + mDelegatingState + - ", mMagnifiedInteractionState=" + mPanningScalingState + - ", mViewportDraggingState=" + mViewportDraggingState + - ", mDetectTripleTap=" + mDetectTripleTap + - ", mDetectShortcutTrigger=" + mDetectShortcutTrigger + - ", mCurrentState=" + State.nameOf(mCurrentState) + - ", mPreviousState=" + State.nameOf(mPreviousState) + - ", mMagnificationController=" + mMagnificationController + - ", mDisplayId=" + mDisplayId + - '}'; + return "MagnificationGesture{" + + "mDetectingState=" + mDetectingState + + ", mDelegatingState=" + mDelegatingState + + ", mMagnifiedInteractionState=" + mPanningScalingState + + ", mViewportDraggingState=" + mViewportDraggingState + + ", mDetectTripleTap=" + mDetectTripleTap + + ", mDetectShortcutTrigger=" + mDetectShortcutTrigger + + ", mCurrentState=" + State.nameOf(mCurrentState) + + ", mPreviousState=" + State.nameOf(mPreviousState) + + ", mMagnificationController=" + mMagnificationController + + ", mDisplayId=" + mDisplayId + + '}'; } private static final class MotionEventInfo { @@ -1085,9 +1087,10 @@ class MagnificationGestureHandler extends BaseEventStreamTransformation { */ private static class ScreenStateReceiver extends BroadcastReceiver { private final Context mContext; - private final MagnificationGestureHandler mGestureHandler; + private final FullScreenMagnificationGestureHandler mGestureHandler; - public ScreenStateReceiver(Context context, MagnificationGestureHandler gestureHandler) { + ScreenStateReceiver(Context context, + FullScreenMagnificationGestureHandler gestureHandler) { mContext = context; mGestureHandler = gestureHandler; } diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java new file mode 100644 index 0000000000000..aa500b5b627f6 --- /dev/null +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.accessibility.magnification; + +import com.android.server.accessibility.BaseEventStreamTransformation; + +/** + * A base class that detects gestures and defines common methods for magnification. + */ +public abstract class MagnificationGestureHandler extends BaseEventStreamTransformation { + + /** + * Called when the shortcut target is magnification. + */ + public abstract void notifyShortcutTriggered(); +} diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java index 193f540246e66..87b56586ee653 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java @@ -80,7 +80,7 @@ public class AccessibilityInputFilterTest { // The expected order of EventStreamTransformations. private final Class[] mExpectedEventHandlerTypes = {KeyboardInterceptor.class, MotionEventInjector.class, - MagnificationGestureHandler.class, TouchExplorer.class, + FullScreenMagnificationGestureHandler.class, TouchExplorer.class, AutoclickController.class, AccessibilityInputFilter.class}; private MagnificationController mMockMagnificationController; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java similarity index 96% rename from services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java rename to services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java index de7d77d4b9631..2007d4fff8c17 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java @@ -59,7 +59,7 @@ import org.junit.runner.RunWith; import java.util.function.IntConsumer; /** - * Tests the state transitions of {@link MagnificationGestureHandler} + * Tests the state transitions of {@link FullScreenMagnificationGestureHandler} * * Here's a dot graph describing the transitions being tested: * {@code @@ -87,7 +87,7 @@ import java.util.function.IntConsumer; * } */ @RunWith(AndroidJUnit4.class) -public class MagnificationGestureHandlerTest { +public class FullScreenMagnificationGestureHandlerTest { public static final int STATE_IDLE = 1; public static final int STATE_ZOOMED = 2; @@ -113,7 +113,7 @@ public class MagnificationGestureHandlerTest { MagnificationController mMagnificationController; private OffsettableClock mClock; - private MagnificationGestureHandler mMgh; + private FullScreenMagnificationGestureHandler mMgh; private TestHandler mHandler; private long mLastDownTime = Integer.MIN_VALUE; @@ -154,16 +154,17 @@ public class MagnificationGestureHandlerTest { } @NonNull - private MagnificationGestureHandler newInstance(boolean detectTripleTap, + private FullScreenMagnificationGestureHandler newInstance(boolean detectTripleTap, boolean detectShortcutTrigger) { - MagnificationGestureHandler h = new MagnificationGestureHandler( + FullScreenMagnificationGestureHandler h = new FullScreenMagnificationGestureHandler( mContext, mMagnificationController, detectTripleTap, detectShortcutTrigger, DISPLAY_0); mHandler = new TestHandler(h.mDetectingState, mClock) { @Override protected String messageToString(Message m) { return DebugUtils.valueToString( - MagnificationGestureHandler.DetectingState.class, "MESSAGE_", m.what); + FullScreenMagnificationGestureHandler.DetectingState.class, "MESSAGE_", + m.what); } }; h.mDetectingState.mHandler = mHandler; @@ -541,7 +542,8 @@ public class MagnificationGestureHandlerTest { } private static String stateToString(int state) { - return DebugUtils.valueToString(MagnificationGestureHandlerTest.class, "STATE_", state); + return DebugUtils.valueToString(FullScreenMagnificationGestureHandlerTest.class, "STATE_", + state); } private void tap() { @@ -591,7 +593,7 @@ public class MagnificationGestureHandlerTest { private MotionEvent moveEvent(float x, float y) { return fromTouchscreen( - MotionEvent.obtain(mLastDownTime, mClock.now(), ACTION_MOVE, x, y, 0)); + MotionEvent.obtain(mLastDownTime, mClock.now(), ACTION_MOVE, x, y, 0)); } private MotionEvent downEvent() { @@ -638,7 +640,7 @@ public class MagnificationGestureHandlerTest { /* action */ action, /* pointerCount */ 2, /* pointerProperties */ new MotionEvent.PointerProperties[] { - defPointerProperties, pointerProperties }, + defPointerProperties, pointerProperties}, /* pointerCoords */ new MotionEvent.PointerCoords[] { defPointerCoords, pointerCoords }, /* metaState */ 0, /* buttonState */ 0,