Merge "Various minor magnification improvements"
This commit is contained in:
committed by
Android (Google) Code Review
commit
4310433ad6
@@ -365,6 +365,11 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventStreamTransformation getNext() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearEvents(int inputSource) {
|
||||
/* do nothing */
|
||||
|
||||
@@ -23,15 +23,12 @@ import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.MotionEvent.PointerCoords;
|
||||
import android.view.MotionEvent.PointerProperties;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
/**
|
||||
@@ -55,11 +52,10 @@ import android.view.accessibility.AccessibilityManager;
|
||||
*
|
||||
* Each instance is associated to a single user (and it does not handle user switch itself).
|
||||
*/
|
||||
public class AutoclickController implements EventStreamTransformation {
|
||||
public class AutoclickController extends BaseEventStreamTransformation {
|
||||
|
||||
private static final String LOG_TAG = AutoclickController.class.getSimpleName();
|
||||
|
||||
private EventStreamTransformation mNext;
|
||||
private final Context mContext;
|
||||
private final int mUserId;
|
||||
|
||||
@@ -88,9 +84,7 @@ public class AutoclickController implements EventStreamTransformation {
|
||||
mClickScheduler.cancel();
|
||||
}
|
||||
|
||||
if (mNext != null) {
|
||||
mNext.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
super.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,21 +97,7 @@ public class AutoclickController implements EventStreamTransformation {
|
||||
}
|
||||
}
|
||||
|
||||
if (mNext != null) {
|
||||
mNext.onKeyEvent(event, policyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
if (mNext != null) {
|
||||
mNext.onAccessibilityEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNext(EventStreamTransformation next) {
|
||||
mNext = next;
|
||||
super.onKeyEvent(event, policyFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,9 +106,7 @@ public class AutoclickController implements EventStreamTransformation {
|
||||
mClickScheduler.cancel();
|
||||
}
|
||||
|
||||
if (mNext != null) {
|
||||
mNext.clearEvents(inputSource);
|
||||
}
|
||||
super.clearEvents(inputSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -418,7 +396,7 @@ public class AutoclickController implements EventStreamTransformation {
|
||||
* Creates and forwards click event sequence.
|
||||
*/
|
||||
private void sendClick() {
|
||||
if (mLastMotionEvent == null || mNext == null) {
|
||||
if (mLastMotionEvent == null || getNext() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -448,10 +426,10 @@ public class AutoclickController implements EventStreamTransformation {
|
||||
MotionEvent upEvent = MotionEvent.obtain(downEvent);
|
||||
upEvent.setAction(MotionEvent.ACTION_UP);
|
||||
|
||||
mNext.onMotionEvent(downEvent, downEvent, mEventPolicyFlags);
|
||||
AutoclickController.super.onMotionEvent(downEvent, downEvent, mEventPolicyFlags);
|
||||
downEvent.recycle();
|
||||
|
||||
mNext.onMotionEvent(upEvent, upEvent, mEventPolicyFlags);
|
||||
AutoclickController.super.onMotionEvent(upEvent, upEvent, mEventPolicyFlags);
|
||||
upEvent.recycle();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
** Copyright 2017, 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;
|
||||
|
||||
abstract class BaseEventStreamTransformation implements EventStreamTransformation {
|
||||
private EventStreamTransformation mNext;
|
||||
|
||||
@Override
|
||||
public void setNext(EventStreamTransformation next) {
|
||||
mNext = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventStreamTransformation getNext() {
|
||||
return mNext;
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,12 @@ interface EventStreamTransformation {
|
||||
* @param rawEvent The raw motion event.
|
||||
* @param policyFlags Policy flags for the event.
|
||||
*/
|
||||
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags);
|
||||
default void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
|
||||
EventStreamTransformation next = getNext();
|
||||
if (next != null) {
|
||||
next.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives a key event.
|
||||
@@ -73,14 +78,24 @@ interface EventStreamTransformation {
|
||||
* @param event The key event.
|
||||
* @param policyFlags Policy flags for the event.
|
||||
*/
|
||||
public void onKeyEvent(KeyEvent event, int policyFlags);
|
||||
default void onKeyEvent(KeyEvent event, int policyFlags) {
|
||||
EventStreamTransformation next = getNext();
|
||||
if (next != null) {
|
||||
next.onKeyEvent(event, policyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives an accessibility event.
|
||||
*
|
||||
* @param event The accessibility event.
|
||||
*/
|
||||
public void onAccessibilityEvent(AccessibilityEvent event);
|
||||
default void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
EventStreamTransformation next = getNext();
|
||||
if (next != null) {
|
||||
next.onAccessibilityEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the next transformation.
|
||||
@@ -89,15 +104,27 @@ interface EventStreamTransformation {
|
||||
*/
|
||||
public void setNext(EventStreamTransformation next);
|
||||
|
||||
/**
|
||||
* Gets the next transformation.
|
||||
*
|
||||
* @return The next transformation.
|
||||
*/
|
||||
public EventStreamTransformation getNext();
|
||||
|
||||
/**
|
||||
* Clears internal state associated with events from specific input source.
|
||||
*
|
||||
* @param inputSource The input source class for which transformation state should be cleared.
|
||||
*/
|
||||
public void clearEvents(int inputSource);
|
||||
default void clearEvents(int inputSource) {
|
||||
EventStreamTransformation next = getNext();
|
||||
if (next != null) {
|
||||
next.clearEvents(inputSource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this transformation.
|
||||
*/
|
||||
public void onDestroy();
|
||||
default void onDestroy() {}
|
||||
}
|
||||
|
||||
@@ -22,14 +22,12 @@ import android.os.SystemClock;
|
||||
import android.util.Pools;
|
||||
import android.util.Slog;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowManagerPolicy;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
/**
|
||||
* Intercepts key events and forwards them to accessibility manager service.
|
||||
*/
|
||||
public class KeyboardInterceptor implements EventStreamTransformation, Handler.Callback {
|
||||
public class KeyboardInterceptor extends BaseEventStreamTransformation implements Handler.Callback {
|
||||
private static final int MESSAGE_PROCESS_QUEUED_EVENTS = 1;
|
||||
private static final String LOG_TAG = "KeyboardInterceptor";
|
||||
|
||||
@@ -37,7 +35,6 @@ public class KeyboardInterceptor implements EventStreamTransformation, Handler.C
|
||||
private final WindowManagerPolicy mPolicy;
|
||||
private final Handler mHandler;
|
||||
|
||||
private EventStreamTransformation mNext;
|
||||
private KeyEventHolder mEventQueueStart;
|
||||
private KeyEventHolder mEventQueueEnd;
|
||||
|
||||
@@ -64,13 +61,6 @@ public class KeyboardInterceptor implements EventStreamTransformation, Handler.C
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
|
||||
if (mNext != null) {
|
||||
mNext.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(KeyEvent event, int policyFlags) {
|
||||
/*
|
||||
@@ -89,29 +79,6 @@ public class KeyboardInterceptor implements EventStreamTransformation, Handler.C
|
||||
mAms.notifyKeyEvent(event, policyFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
if (mNext != null) {
|
||||
mNext.onAccessibilityEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNext(EventStreamTransformation next) {
|
||||
mNext = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearEvents(int inputSource) {
|
||||
if (mNext != null) {
|
||||
mNext.clearEvents(inputSource);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
if (msg.what != MESSAGE_PROCESS_QUEUED_EVENTS) {
|
||||
|
||||
@@ -42,14 +42,12 @@ import android.util.Slog;
|
||||
import android.util.TypedValue;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.MotionEvent.PointerCoords;
|
||||
import android.view.MotionEvent.PointerProperties;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.ScaleGestureDetector.OnScaleGestureListener;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
@@ -102,7 +100,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
* 7. The magnification scale will be persisted in settings and in the cloud.
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
class MagnificationGestureHandler extends BaseEventStreamTransformation {
|
||||
private static final String LOG_TAG = "MagnificationEventHandler";
|
||||
|
||||
private static final boolean DEBUG_ALL = false;
|
||||
@@ -110,13 +108,13 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
private static final boolean DEBUG_DETECTING = false || DEBUG_ALL;
|
||||
private static final boolean DEBUG_PANNING = false || DEBUG_ALL;
|
||||
|
||||
/** @see #handleMotionEventStateDelegating */
|
||||
/** @see DelegatingState */
|
||||
@VisibleForTesting static final int STATE_DELEGATING = 1;
|
||||
/** @see DetectingStateHandler */
|
||||
/** @see DetectingState */
|
||||
@VisibleForTesting static final int STATE_DETECTING = 2;
|
||||
/** @see ViewportDraggingStateHandler */
|
||||
/** @see ViewportDraggingState */
|
||||
@VisibleForTesting static final int STATE_VIEWPORT_DRAGGING = 3;
|
||||
/** @see PanningScalingStateHandler */
|
||||
/** @see PanningScalingState */
|
||||
@VisibleForTesting static final int STATE_PANNING_SCALING = 4;
|
||||
|
||||
private static final float MIN_SCALE = 2.0f;
|
||||
@@ -124,9 +122,10 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
|
||||
@VisibleForTesting final MagnificationController mMagnificationController;
|
||||
|
||||
@VisibleForTesting final DetectingStateHandler mDetectingStateHandler;
|
||||
@VisibleForTesting final PanningScalingStateHandler mPanningScalingStateHandler;
|
||||
@VisibleForTesting final ViewportDraggingStateHandler mViewportDraggingStateHandler;
|
||||
@VisibleForTesting final DelegatingState mDelegatingState;
|
||||
@VisibleForTesting final DetectingState mDetectingState;
|
||||
@VisibleForTesting final PanningScalingState mPanningScalingState;
|
||||
@VisibleForTesting final ViewportDraggingState mViewportDraggingState;
|
||||
|
||||
private final ScreenStateReceiver mScreenStateReceiver;
|
||||
|
||||
@@ -138,21 +137,12 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
final boolean mDetectTripleTap;
|
||||
|
||||
/**
|
||||
* Whether {@link #mShortcutTriggered shortcut} is enabled
|
||||
* Whether {@link DetectingState#mShortcutTriggered shortcut} is enabled
|
||||
*/
|
||||
final boolean mDetectShortcutTrigger;
|
||||
|
||||
EventStreamTransformation mNext;
|
||||
|
||||
@VisibleForTesting int mCurrentState;
|
||||
@VisibleForTesting int mPreviousState;
|
||||
|
||||
@VisibleForTesting boolean mShortcutTriggered;
|
||||
|
||||
/**
|
||||
* Time of last {@link MotionEvent#ACTION_DOWN} while in {@link #STATE_DELEGATING}
|
||||
*/
|
||||
long mDelegatingStateDownTime;
|
||||
@VisibleForTesting State mCurrentState;
|
||||
@VisibleForTesting State mPreviousState;
|
||||
|
||||
private PointerCoords[] mTempPointerCoords;
|
||||
private PointerProperties[] mTempPointerProperties;
|
||||
@@ -174,10 +164,10 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
boolean detectShortcutTrigger) {
|
||||
mMagnificationController = magnificationController;
|
||||
|
||||
mDetectingStateHandler = new DetectingStateHandler(context);
|
||||
mViewportDraggingStateHandler = new ViewportDraggingStateHandler();
|
||||
mPanningScalingStateHandler =
|
||||
new PanningScalingStateHandler(context);
|
||||
mDelegatingState = new DelegatingState();
|
||||
mDetectingState = new DetectingState(context);
|
||||
mViewportDraggingState = new ViewportDraggingState();
|
||||
mPanningScalingState = new PanningScalingState(context);
|
||||
|
||||
mDetectTripleTap = detectTripleTap;
|
||||
mDetectShortcutTrigger = detectShortcutTrigger;
|
||||
@@ -189,7 +179,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
mScreenStateReceiver = null;
|
||||
}
|
||||
|
||||
transitionTo(STATE_DETECTING);
|
||||
transitionTo(mDetectingState);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -199,52 +189,17 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
dispatchTransformedEvent(event, rawEvent, policyFlags);
|
||||
return;
|
||||
}
|
||||
// Local copy to avoid dispatching the same event to more than one state handler
|
||||
// in case mPanningScalingStateHandler changes mCurrentState
|
||||
int currentState = mCurrentState;
|
||||
mPanningScalingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
|
||||
switch (currentState) {
|
||||
case STATE_DELEGATING: {
|
||||
handleMotionEventStateDelegating(event, rawEvent, policyFlags);
|
||||
}
|
||||
break;
|
||||
case STATE_DETECTING: {
|
||||
mDetectingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
break;
|
||||
case STATE_VIEWPORT_DRAGGING: {
|
||||
mViewportDraggingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
break;
|
||||
case STATE_PANNING_SCALING: {
|
||||
// mPanningScalingStateHandler handles events only
|
||||
// if this is the current state since it uses ScaleGestureDetector
|
||||
// and a GestureDetector which need well formed event stream.
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
throw new IllegalStateException("Unknown state: " + currentState);
|
||||
}
|
||||
}
|
||||
|
||||
handleEventWith(mCurrentState, event, rawEvent, policyFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(KeyEvent event, int policyFlags) {
|
||||
if (mNext != null) {
|
||||
mNext.onKeyEvent(event, policyFlags);
|
||||
}
|
||||
}
|
||||
private void handleEventWith(State stateHandler,
|
||||
MotionEvent event, MotionEvent rawEvent, int policyFlags) {
|
||||
// To keep InputEventConsistencyVerifiers within GestureDetectors happy
|
||||
mPanningScalingState.mScrollGestureDetector.onTouchEvent(event);
|
||||
mPanningScalingState.mScaleGestureDetector.onTouchEvent(event);
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
if (mNext != null) {
|
||||
mNext.onAccessibilityEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNext(EventStreamTransformation next) {
|
||||
mNext = next;
|
||||
stateHandler.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -253,9 +208,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
clearAndTransitionToStateDetecting();
|
||||
}
|
||||
|
||||
if (mNext != null) {
|
||||
mNext.clearEvents(inputSource);
|
||||
}
|
||||
super.clearEvents(inputSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -272,60 +225,20 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
if (wasMagnifying) {
|
||||
clearAndTransitionToStateDetecting();
|
||||
} else {
|
||||
toggleShortcutTriggered();
|
||||
mDetectingState.toggleShortcutTriggered();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleShortcutTriggered() {
|
||||
setShortcutTriggered(!mShortcutTriggered);
|
||||
}
|
||||
|
||||
private void setShortcutTriggered(boolean state) {
|
||||
if (mShortcutTriggered == state) {
|
||||
return;
|
||||
}
|
||||
|
||||
mShortcutTriggered = state;
|
||||
mMagnificationController.setForceShowMagnifiableBounds(state);
|
||||
}
|
||||
|
||||
void clearAndTransitionToStateDetecting() {
|
||||
setShortcutTriggered(false);
|
||||
mCurrentState = STATE_DETECTING;
|
||||
mDetectingStateHandler.clear();
|
||||
mViewportDraggingStateHandler.clear();
|
||||
mPanningScalingStateHandler.clear();
|
||||
}
|
||||
|
||||
private void handleMotionEventStateDelegating(MotionEvent event,
|
||||
MotionEvent rawEvent, int policyFlags) {
|
||||
if (event.getActionMasked() == ACTION_UP) {
|
||||
transitionTo(STATE_DETECTING);
|
||||
}
|
||||
delegateEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
|
||||
void delegateEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
mDelegatingStateDownTime = event.getDownTime();
|
||||
}
|
||||
if (mNext != null) {
|
||||
// We cache some events to see if the user wants to trigger magnification.
|
||||
// If no magnification is triggered we inject these events with adjusted
|
||||
// time and down time to prevent subsequent transformations being confused
|
||||
// by stale events. After the cached events, which always have a down, are
|
||||
// injected we need to also update the down time of all subsequent non cached
|
||||
// events. All delegated events cached and non-cached are delivered here.
|
||||
event.setDownTime(mDelegatingStateDownTime);
|
||||
dispatchTransformedEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
mCurrentState = mDelegatingState;
|
||||
mDetectingState.clear();
|
||||
mViewportDraggingState.clear();
|
||||
mPanningScalingState.clear();
|
||||
}
|
||||
|
||||
private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
|
||||
int policyFlags) {
|
||||
if (mNext == null) return; // Nowhere to dispatch to
|
||||
|
||||
// If the touchscreen event is within the magnified portion of the screen we have
|
||||
// to change its location to be where the user thinks he is poking the
|
||||
// UI which may have been magnified and panned.
|
||||
@@ -351,7 +264,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(),
|
||||
event.getFlags());
|
||||
}
|
||||
mNext.onMotionEvent(event, rawEvent, policyFlags);
|
||||
super.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
|
||||
private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
|
||||
@@ -386,9 +299,10 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
return mTempPointerProperties;
|
||||
}
|
||||
|
||||
private void transitionTo(int state) {
|
||||
private void transitionTo(State state) {
|
||||
if (DEBUG_STATE_TRANSITIONS) {
|
||||
Slog.i(LOG_TAG, (stateToString(mCurrentState) + " -> " + stateToString(state)
|
||||
Slog.i(LOG_TAG,
|
||||
(State.nameOf(mCurrentState) + " -> " + State.nameOf(state)
|
||||
+ " at " + asList(copyOfRange(new RuntimeException().getStackTrace(), 1, 5)))
|
||||
.replace(getClass().getName(), ""));
|
||||
}
|
||||
@@ -396,40 +310,42 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
mCurrentState = state;
|
||||
}
|
||||
|
||||
private static String stateToString(int state) {
|
||||
switch (state) {
|
||||
case STATE_DELEGATING: return "STATE_DELEGATING";
|
||||
case STATE_DETECTING: return "STATE_DETECTING";
|
||||
case STATE_VIEWPORT_DRAGGING: return "STATE_VIEWPORT_DRAGGING";
|
||||
case STATE_PANNING_SCALING: return "STATE_PANNING_SCALING";
|
||||
case 0: return "0";
|
||||
default: throw new IllegalArgumentException("Unknown state: " + state);
|
||||
}
|
||||
}
|
||||
|
||||
private interface MotionEventHandler {
|
||||
|
||||
interface State {
|
||||
void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags);
|
||||
|
||||
void clear();
|
||||
default void clear() {}
|
||||
|
||||
default String name() {
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
static String nameOf(@Nullable State s) {
|
||||
return s != null ? s.name() : "null";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class determines if the user is performing a scale or pan gesture.
|
||||
*
|
||||
* Unlike when {@link ViewportDraggingState dragging the viewport}, in panning mode the viewport
|
||||
* moves in the same direction as the fingers, and allows to easily and precisely scale the
|
||||
* magnification level.
|
||||
* This makes it the preferred mode for one-off adjustments, due to its precision and ease of
|
||||
* triggering.
|
||||
*
|
||||
* @see #STATE_PANNING_SCALING
|
||||
*/
|
||||
final class PanningScalingStateHandler extends SimpleOnGestureListener
|
||||
implements OnScaleGestureListener, MotionEventHandler {
|
||||
final class PanningScalingState extends SimpleOnGestureListener
|
||||
implements OnScaleGestureListener, State {
|
||||
|
||||
private final ScaleGestureDetector mScaleGestureDetector;
|
||||
private final GestureDetector mGestureDetector;
|
||||
private final GestureDetector mScrollGestureDetector;
|
||||
final float mScalingThreshold;
|
||||
|
||||
float mInitialScaleFactor = -1;
|
||||
boolean mScaling;
|
||||
|
||||
public PanningScalingStateHandler(Context context) {
|
||||
public PanningScalingState(Context context) {
|
||||
final TypedValue scaleValue = new TypedValue();
|
||||
context.getResources().getValue(
|
||||
com.android.internal.R.dimen.config_screen_magnification_scaling_threshold,
|
||||
@@ -437,35 +353,27 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
mScalingThreshold = scaleValue.getFloat();
|
||||
mScaleGestureDetector = new ScaleGestureDetector(context, this);
|
||||
mScaleGestureDetector.setQuickScaleEnabled(false);
|
||||
mGestureDetector = new GestureDetector(context, this);
|
||||
mScrollGestureDetector = new GestureDetector(context, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
|
||||
// Dispatches #onScaleBegin, #onScale, #onScaleEnd
|
||||
mScaleGestureDetector.onTouchEvent(event);
|
||||
// Dispatches #onScroll
|
||||
mGestureDetector.onTouchEvent(event);
|
||||
|
||||
if (mCurrentState != STATE_PANNING_SCALING) {
|
||||
return;
|
||||
}
|
||||
|
||||
int action = event.getActionMasked();
|
||||
|
||||
if (action == ACTION_POINTER_UP
|
||||
&& event.getPointerCount() == 2 // includes the pointer currently being released
|
||||
&& mPreviousState == STATE_VIEWPORT_DRAGGING) {
|
||||
&& mPreviousState == mViewportDraggingState) {
|
||||
|
||||
persistScaleAndTransitionTo(STATE_VIEWPORT_DRAGGING);
|
||||
persistScaleAndTransitionTo(mViewportDraggingState);
|
||||
|
||||
} else if (action == ACTION_UP) {
|
||||
|
||||
persistScaleAndTransitionTo(STATE_DETECTING);
|
||||
persistScaleAndTransitionTo(mDetectingState);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void persistScaleAndTransitionTo(int state) {
|
||||
public void persistScaleAndTransitionTo(State state) {
|
||||
mMagnificationController.persistScale();
|
||||
clear();
|
||||
transitionTo(state);
|
||||
@@ -474,7 +382,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent first, MotionEvent second,
|
||||
float distanceX, float distanceY) {
|
||||
if (mCurrentState != STATE_PANNING_SCALING) {
|
||||
if (mCurrentState != mPanningScalingState) {
|
||||
return true;
|
||||
}
|
||||
if (DEBUG_PANNING) {
|
||||
@@ -483,7 +391,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
}
|
||||
mMagnificationController.offsetMagnifiedRegion(distanceX, distanceY,
|
||||
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
|
||||
return true;
|
||||
return /* event consumed: */ true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -525,12 +433,12 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
final float pivotY = detector.getFocusY();
|
||||
mMagnificationController.setScale(scale, pivotX, pivotY, false,
|
||||
AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
|
||||
return true;
|
||||
return /* handled: */ true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScaleBegin(ScaleGestureDetector detector) {
|
||||
return (mCurrentState == STATE_PANNING_SCALING);
|
||||
return /* continue recognizing: */ (mCurrentState == mPanningScalingState);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -546,7 +454,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MagnifiedContentInteractionStateHandler{" +
|
||||
return "PanningScalingState{" +
|
||||
"mInitialScaleFactor=" + mInitialScaleFactor +
|
||||
", mScaling=" + mScaling +
|
||||
'}';
|
||||
@@ -558,9 +466,13 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
* determined that the user is performing a single-finger drag of the
|
||||
* magnification viewport.
|
||||
*
|
||||
* Unlike when {@link PanningScalingState panning}, the viewport moves in the opposite direction
|
||||
* of the finger, and any part of the screen is reachable without lifting the finger.
|
||||
* This makes it the preferable mode for tasks like reading text spanning full screen width.
|
||||
*
|
||||
* @see #STATE_VIEWPORT_DRAGGING
|
||||
*/
|
||||
final class ViewportDraggingStateHandler implements MotionEventHandler {
|
||||
final class ViewportDraggingState implements State {
|
||||
|
||||
/** Whether to disable zoom after dragging ends */
|
||||
boolean mZoomedInBeforeDrag;
|
||||
@@ -572,7 +484,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
switch (action) {
|
||||
case ACTION_POINTER_DOWN: {
|
||||
clear();
|
||||
transitionTo(STATE_PANNING_SCALING);
|
||||
transitionTo(mPanningScalingState);
|
||||
}
|
||||
break;
|
||||
case ACTION_MOVE: {
|
||||
@@ -594,7 +506,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
case ACTION_UP: {
|
||||
if (!mZoomedInBeforeDrag) zoomOff();
|
||||
clear();
|
||||
transitionTo(STATE_DETECTING);
|
||||
transitionTo(mDetectingState);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -613,25 +525,53 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ViewportDraggingStateHandler{" +
|
||||
return "ViewportDraggingState{" +
|
||||
"mZoomedInBeforeDrag=" + mZoomedInBeforeDrag +
|
||||
", mLastMoveOutsideMagnifiedRegion=" + mLastMoveOutsideMagnifiedRegion +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
final class DelegatingState implements State {
|
||||
/**
|
||||
* Time of last {@link MotionEvent#ACTION_DOWN} while in {@link #STATE_DELEGATING}
|
||||
*/
|
||||
public long mLastDelegatedDownEventTime;
|
||||
|
||||
@Override
|
||||
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
|
||||
if (event.getActionMasked() == ACTION_UP) {
|
||||
transitionTo(mDetectingState);
|
||||
}
|
||||
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
mLastDelegatedDownEventTime = event.getDownTime();
|
||||
}
|
||||
if (getNext() != null) {
|
||||
// We cache some events to see if the user wants to trigger magnification.
|
||||
// If no magnification is triggered we inject these events with adjusted
|
||||
// time and down time to prevent subsequent transformations being confused
|
||||
// by stale events. After the cached events, which always have a down, are
|
||||
// injected we need to also update the down time of all subsequent non cached
|
||||
// events. All delegated events cached and non-cached are delivered here.
|
||||
event.setDownTime(mLastDelegatedDownEventTime);
|
||||
dispatchTransformedEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles motion events when the event dispatch has not yet
|
||||
* determined what the user is doing. It watches for various tap events.
|
||||
*
|
||||
* @see #STATE_DETECTING
|
||||
*/
|
||||
final class DetectingStateHandler implements MotionEventHandler, Handler.Callback {
|
||||
final class DetectingState implements State, Handler.Callback {
|
||||
|
||||
private static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1;
|
||||
private static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2;
|
||||
|
||||
final int mLongTapMinDelay = ViewConfiguration.getJumpTapTimeout();
|
||||
final int mLongTapMinDelay;
|
||||
final int mSwipeMinDistance;
|
||||
final int mMultiTapMaxDelay;
|
||||
final int mMultiTapMaxDistance;
|
||||
@@ -642,9 +582,12 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
private MotionEvent mLastUp;
|
||||
private MotionEvent mPreLastUp;
|
||||
|
||||
@VisibleForTesting boolean mShortcutTriggered;
|
||||
|
||||
Handler mHandler = new Handler(this);
|
||||
|
||||
public DetectingStateHandler(Context context) {
|
||||
public DetectingState(Context context) {
|
||||
mLongTapMinDelay = ViewConfiguration.getLongPressTimeout();
|
||||
mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout()
|
||||
+ context.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_screen_magnification_multi_tap_adjustment);
|
||||
@@ -661,7 +604,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
}
|
||||
break;
|
||||
case MESSAGE_TRANSITION_TO_DELEGATING_STATE: {
|
||||
transitionToDelegatingState(/* andClear */ true);
|
||||
transitionToDelegatingStateAndClear();
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
@@ -682,12 +625,12 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
if (!mMagnificationController.magnificationRegionContains(
|
||||
event.getX(), event.getY())) {
|
||||
|
||||
transitionToDelegatingState(/* andClear */ !mShortcutTriggered);
|
||||
transitionToDelegatingStateAndClear();
|
||||
|
||||
} else if (isMultiTapTriggered(2 /* taps */)) {
|
||||
|
||||
// 3tap and hold
|
||||
delayedTransitionToDraggingState(event);
|
||||
afterLongTapTimeoutTransitionToDraggingState(event);
|
||||
|
||||
} else if (mDetectTripleTap
|
||||
// If magnified, delay an ACTION_DOWN for mMultiTapMaxDelay
|
||||
@@ -695,21 +638,21 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
// STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN)
|
||||
|| mMagnificationController.isMagnifying()) {
|
||||
|
||||
delayedTransitionToDelegatingState();
|
||||
afterMultiTapTimeoutTransitionToDelegatingState();
|
||||
|
||||
} else {
|
||||
|
||||
// Delegate pending events without delay
|
||||
transitionToDelegatingState(/* andClear */ true);
|
||||
transitionToDelegatingStateAndClear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_POINTER_DOWN: {
|
||||
if (mMagnificationController.isMagnifying()) {
|
||||
transitionTo(STATE_PANNING_SCALING);
|
||||
transitionTo(mPanningScalingState);
|
||||
clear();
|
||||
} else {
|
||||
transitionToDelegatingState(/* andClear */ true);
|
||||
transitionToDelegatingStateAndClear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -722,7 +665,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
&& !isMultiTapTriggered(2 /* taps */)) {
|
||||
|
||||
// Swipe detected - delegate skipping timeout
|
||||
transitionToDelegatingState(/* andClear */ true);
|
||||
transitionToDelegatingStateAndClear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -733,7 +676,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
if (!mMagnificationController.magnificationRegionContains(
|
||||
event.getX(), event.getY())) {
|
||||
|
||||
transitionToDelegatingState(/* andClear */ !mShortcutTriggered);
|
||||
transitionToDelegatingStateAndClear();
|
||||
|
||||
} else if (isMultiTapTriggered(3 /* taps */)) {
|
||||
|
||||
@@ -742,12 +685,11 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
} else if (
|
||||
// Possible to be false on: 3tap&drag -> scale -> PTR_UP -> UP
|
||||
isFingerDown()
|
||||
//TODO long tap should never happen here
|
||||
&& (timeBetween(mLastDown, /* mLastUp */ event) >= mLongTapMinDelay)
|
||||
|| distance(mLastDown, /* mLastUp */ event)
|
||||
>= mSwipeMinDistance) {
|
||||
//TODO long tap should never happen here
|
||||
&& ((timeBetween(mLastDown, mLastUp) >= mLongTapMinDelay)
|
||||
|| (distance(mLastDown, mLastUp) >= mSwipeMinDistance))) {
|
||||
|
||||
transitionToDelegatingState(/* andClear */ true);
|
||||
transitionToDelegatingStateAndClear();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -796,14 +738,14 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
}
|
||||
|
||||
/** -> {@link #STATE_DELEGATING} */
|
||||
public void delayedTransitionToDelegatingState() {
|
||||
public void afterMultiTapTimeoutTransitionToDelegatingState() {
|
||||
mHandler.sendEmptyMessageDelayed(
|
||||
MESSAGE_TRANSITION_TO_DELEGATING_STATE,
|
||||
mMultiTapMaxDelay);
|
||||
}
|
||||
|
||||
/** -> {@link #STATE_VIEWPORT_DRAGGING} */
|
||||
public void delayedTransitionToDraggingState(MotionEvent event) {
|
||||
public void afterLongTapTimeoutTransitionToDraggingState(MotionEvent event) {
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(MESSAGE_ON_TRIPLE_TAP_AND_HOLD, event),
|
||||
ViewConfiguration.getLongPressTimeout());
|
||||
@@ -846,11 +788,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
MotionEventInfo info = mDelayedEventQueue;
|
||||
mDelayedEventQueue = info.mNext;
|
||||
|
||||
// Because MagnifiedInteractionStateHandler requires well-formed event stream
|
||||
mPanningScalingStateHandler.onMotionEvent(
|
||||
info.event, info.rawEvent, info.policyFlags);
|
||||
|
||||
delegateEvent(info.event, info.rawEvent, info.policyFlags);
|
||||
handleEventWith(mDelegatingState, info.event, info.rawEvent, info.policyFlags);
|
||||
|
||||
info.recycle();
|
||||
}
|
||||
@@ -868,10 +806,10 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
mLastUp = null;
|
||||
}
|
||||
|
||||
void transitionToDelegatingState(boolean andClear) {
|
||||
transitionTo(STATE_DELEGATING);
|
||||
void transitionToDelegatingStateAndClear() {
|
||||
transitionTo(mDelegatingState);
|
||||
sendDelayedMotionEvents();
|
||||
if (andClear) clear();
|
||||
clear();
|
||||
}
|
||||
|
||||
private void onTripleTap(MotionEvent up) {
|
||||
@@ -895,21 +833,35 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
if (DEBUG_DETECTING) Slog.i(LOG_TAG, "onTripleTapAndHold()");
|
||||
clear();
|
||||
|
||||
mViewportDraggingStateHandler.mZoomedInBeforeDrag =
|
||||
mViewportDraggingState.mZoomedInBeforeDrag =
|
||||
mMagnificationController.isMagnifying();
|
||||
|
||||
zoomOn(down.getX(), down.getY());
|
||||
|
||||
transitionTo(STATE_VIEWPORT_DRAGGING);
|
||||
transitionTo(mViewportDraggingState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DetectingStateHandler{" +
|
||||
return "DetectingState{" +
|
||||
"tapCount()=" + tapCount() +
|
||||
", mShortcutTriggered=" + mShortcutTriggered +
|
||||
", mDelayedEventQueue=" + MotionEventInfo.toString(mDelayedEventQueue) +
|
||||
'}';
|
||||
}
|
||||
|
||||
void toggleShortcutTriggered() {
|
||||
setShortcutTriggered(!mShortcutTriggered);
|
||||
}
|
||||
|
||||
void setShortcutTriggered(boolean state) {
|
||||
if (mShortcutTriggered == state) {
|
||||
return;
|
||||
}
|
||||
|
||||
mShortcutTriggered = state;
|
||||
mMagnificationController.setForceShowMagnifiableBounds(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void zoomOn(float centerX, float centerY) {
|
||||
@@ -935,16 +887,15 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MagnificationGestureHandler{" +
|
||||
"mDetectingStateHandler=" + mDetectingStateHandler +
|
||||
", mMagnifiedInteractionStateHandler=" + mPanningScalingStateHandler +
|
||||
", mViewportDraggingStateHandler=" + mViewportDraggingStateHandler +
|
||||
return "MagnificationGesture{" +
|
||||
"mDetectingState=" + mDetectingState +
|
||||
", mDelegatingState=" + mDelegatingState +
|
||||
", mMagnifiedInteractionState=" + mPanningScalingState +
|
||||
", mViewportDraggingState=" + mViewportDraggingState +
|
||||
", mDetectTripleTap=" + mDetectTripleTap +
|
||||
", mDetectShortcutTrigger=" + mDetectShortcutTrigger +
|
||||
", mCurrentState=" + stateToString(mCurrentState) +
|
||||
", mPreviousState=" + stateToString(mPreviousState) +
|
||||
", mShortcutTriggered=" + mShortcutTriggered +
|
||||
", mDelegatingStateDownTime=" + mDelegatingStateDownTime +
|
||||
", mCurrentState=" + State.nameOf(mCurrentState) +
|
||||
", mPreviousState=" + State.nameOf(mPreviousState) +
|
||||
", mMagnificationController=" + mMagnificationController +
|
||||
'}';
|
||||
}
|
||||
@@ -1051,7 +1002,7 @@ class MagnificationGestureHandler implements EventStreamTransformation {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mGestureHandler.setShortcutTriggered(false);
|
||||
mGestureHandler.mDetectingState.setShortcutTriggered(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,9 @@ import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowManagerPolicy;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import com.android.internal.os.SomeArgs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -45,7 +44,7 @@ import java.util.List;
|
||||
* <p>
|
||||
* All methods except {@code injectEvents} must be called only from the main thread.
|
||||
*/
|
||||
public class MotionEventInjector implements EventStreamTransformation, Handler.Callback {
|
||||
public class MotionEventInjector extends BaseEventStreamTransformation implements Handler.Callback {
|
||||
private static final String LOG_TAG = "MotionEventInjector";
|
||||
private static final int MESSAGE_SEND_MOTION_EVENT = 1;
|
||||
private static final int MESSAGE_INJECT_EVENTS = 2;
|
||||
@@ -68,7 +67,6 @@ public class MotionEventInjector implements EventStreamTransformation, Handler.C
|
||||
private final Handler mHandler;
|
||||
private final SparseArray<Boolean> mOpenGesturesInProgress = new SparseArray<>();
|
||||
|
||||
private EventStreamTransformation mNext;
|
||||
private IAccessibilityServiceClient mServiceInterfaceForCurrentGesture;
|
||||
private IntArray mSequencesInProgress = new IntArray(5);
|
||||
private boolean mIsDestroyed = false;
|
||||
@@ -116,25 +114,6 @@ public class MotionEventInjector implements EventStreamTransformation, Handler.C
|
||||
sendMotionEventToNext(event, rawEvent, policyFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(KeyEvent event, int policyFlags) {
|
||||
if (mNext != null) {
|
||||
mNext.onKeyEvent(event, policyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
if (mNext != null) {
|
||||
mNext.onAccessibilityEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNext(EventStreamTransformation next) {
|
||||
mNext = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearEvents(int inputSource) {
|
||||
/*
|
||||
@@ -187,7 +166,7 @@ public class MotionEventInjector implements EventStreamTransformation, Handler.C
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNext == null) {
|
||||
if (getNext() == null) {
|
||||
notifyService(serviceInterface, sequence, false);
|
||||
return;
|
||||
}
|
||||
@@ -292,8 +271,8 @@ public class MotionEventInjector implements EventStreamTransformation, Handler.C
|
||||
|
||||
private void sendMotionEventToNext(MotionEvent event, MotionEvent rawEvent,
|
||||
int policyFlags) {
|
||||
if (mNext != null) {
|
||||
mNext.onMotionEvent(event, rawEvent, policyFlags);
|
||||
if (getNext() != null) {
|
||||
super.onMotionEvent(event, rawEvent, policyFlags);
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
mOpenGesturesInProgress.put(event.getSource(), true);
|
||||
}
|
||||
@@ -305,7 +284,7 @@ public class MotionEventInjector implements EventStreamTransformation, Handler.C
|
||||
}
|
||||
|
||||
private void cancelAnyGestureInProgress(int source) {
|
||||
if ((mNext != null) && mOpenGesturesInProgress.get(source, false)) {
|
||||
if ((getNext() != null) && mOpenGesturesInProgress.get(source, false)) {
|
||||
long now = SystemClock.uptimeMillis();
|
||||
MotionEvent cancelEvent =
|
||||
obtainMotionEvent(now, now, MotionEvent.ACTION_CANCEL, getLastTouchPoints(), 1);
|
||||
|
||||
@@ -55,7 +55,8 @@ import java.util.List;
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDetector.Listener {
|
||||
class TouchExplorer extends BaseEventStreamTransformation
|
||||
implements AccessibilityGestureDetector.Listener {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
@@ -131,9 +132,6 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe
|
||||
// the two dragging pointers as opposed to use the location of the primary one.
|
||||
private final int mScaledMinPointerDistanceToUseMiddleLocation;
|
||||
|
||||
// The handler to which to delegate events.
|
||||
private EventStreamTransformation mNext;
|
||||
|
||||
// Helper class to track received pointers.
|
||||
private final ReceivedPointerTracker mReceivedPointerTracker;
|
||||
|
||||
@@ -198,9 +196,7 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe
|
||||
if (inputSource == InputDevice.SOURCE_TOUCHSCREEN) {
|
||||
clear();
|
||||
}
|
||||
if (mNext != null) {
|
||||
mNext.clearEvents(inputSource);
|
||||
}
|
||||
super.clearEvents(inputSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -257,17 +253,10 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe
|
||||
mAms.onTouchInteractionEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNext(EventStreamTransformation next) {
|
||||
mNext = next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
|
||||
if (!event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) {
|
||||
if (mNext != null) {
|
||||
mNext.onMotionEvent(event, rawEvent, policyFlags);
|
||||
}
|
||||
super.onMotionEvent(event, rawEvent, policyFlags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -310,13 +299,6 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyEvent(KeyEvent event, int policyFlags) {
|
||||
if (mNext != null) {
|
||||
mNext.onKeyEvent(event, policyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
final int eventType = event.getEventType();
|
||||
@@ -353,9 +335,7 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe
|
||||
mLastTouchedWindowId = event.getWindowId();
|
||||
} break;
|
||||
}
|
||||
if (mNext != null) {
|
||||
mNext.onAccessibilityEvent(event);
|
||||
}
|
||||
super.onAccessibilityEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -969,12 +949,10 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe
|
||||
|
||||
// Make sure that the user will see the event.
|
||||
policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER;
|
||||
if (mNext != null) {
|
||||
// TODO: For now pass null for the raw event since the touch
|
||||
// explorer is the last event transformation and it does
|
||||
// not care about the raw event.
|
||||
mNext.onMotionEvent(event, null, policyFlags);
|
||||
}
|
||||
// TODO: For now pass null for the raw event since the touch
|
||||
// explorer is the last event transformation and it does
|
||||
// not care about the raw event.
|
||||
super.onMotionEvent(event, null, policyFlags);
|
||||
|
||||
mInjectedPointerTracker.onMotionEvent(event);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.server.accessibility;
|
||||
|
||||
import static android.util.ExceptionUtils.propagate;
|
||||
import static android.view.MotionEvent.ACTION_DOWN;
|
||||
import static android.view.MotionEvent.ACTION_MOVE;
|
||||
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
|
||||
@@ -105,8 +104,8 @@ public class MagnificationGestureHandlerTest {
|
||||
MagnificationGestureHandler h = new MagnificationGestureHandler(
|
||||
mContext, mMagnificationController,
|
||||
detectTripleTap, detectShortcutTrigger);
|
||||
mHandler = new TestHandler(h.mDetectingStateHandler, mClock);
|
||||
h.mDetectingStateHandler.mHandler = mHandler;
|
||||
mHandler = new TestHandler(h.mDetectingState, mClock);
|
||||
h.mDetectingState.mHandler = mHandler;
|
||||
h.setNext(strictMock(EventStreamTransformation.class));
|
||||
return h;
|
||||
}
|
||||
@@ -229,7 +228,7 @@ public class MagnificationGestureHandlerTest {
|
||||
allowEventDelegation();
|
||||
tap();
|
||||
// no fast forward
|
||||
verify(mMgh.mNext, times(2)).onMotionEvent(any(), any(), anyInt());
|
||||
verify(mMgh.getNext(), times(2)).onMotionEvent(any(), any(), anyInt());
|
||||
}
|
||||
|
||||
private void assertTransition(int fromState, Runnable transitionAction, int toState) {
|
||||
@@ -250,7 +249,7 @@ public class MagnificationGestureHandlerTest {
|
||||
}
|
||||
|
||||
private void allowEventDelegation() {
|
||||
doNothing().when(mMgh.mNext).onMotionEvent(any(), any(), anyInt());
|
||||
doNothing().when(mMgh.getNext()).onMotionEvent(any(), any(), anyInt());
|
||||
}
|
||||
|
||||
private void fastForward1sec() {
|
||||
@@ -272,7 +271,7 @@ public class MagnificationGestureHandlerTest {
|
||||
|
||||
case STATE_IDLE: {
|
||||
check(tapCount() < 2, state);
|
||||
check(!mMgh.mShortcutTriggered, state);
|
||||
check(!mMgh.mDetectingState.mShortcutTriggered, state);
|
||||
check(!isZoomed(), state);
|
||||
} break;
|
||||
case STATE_ZOOMED: {
|
||||
@@ -288,28 +287,28 @@ public class MagnificationGestureHandlerTest {
|
||||
check(tapCount() == 2, state);
|
||||
} break;
|
||||
case STATE_DRAGGING: {
|
||||
check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_VIEWPORT_DRAGGING,
|
||||
check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
|
||||
state);
|
||||
check(mMgh.mViewportDraggingStateHandler.mZoomedInBeforeDrag, state);
|
||||
check(mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
|
||||
} break;
|
||||
case STATE_DRAGGING_TMP: {
|
||||
check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_VIEWPORT_DRAGGING,
|
||||
check(mMgh.mCurrentState == mMgh.mViewportDraggingState,
|
||||
state);
|
||||
check(!mMgh.mViewportDraggingStateHandler.mZoomedInBeforeDrag, state);
|
||||
check(!mMgh.mViewportDraggingState.mZoomedInBeforeDrag, state);
|
||||
} break;
|
||||
case STATE_SHORTCUT_TRIGGERED: {
|
||||
check(mMgh.mShortcutTriggered, state);
|
||||
check(mMgh.mDetectingState.mShortcutTriggered, state);
|
||||
check(!isZoomed(), state);
|
||||
} break;
|
||||
case STATE_PANNING: {
|
||||
check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_PANNING_SCALING,
|
||||
check(mMgh.mCurrentState == mMgh.mPanningScalingState,
|
||||
state);
|
||||
check(!mMgh.mPanningScalingStateHandler.mScaling, state);
|
||||
check(!mMgh.mPanningScalingState.mScaling, state);
|
||||
} break;
|
||||
case STATE_SCALING_AND_PANNING: {
|
||||
check(mMgh.mCurrentState == MagnificationGestureHandler.STATE_PANNING_SCALING,
|
||||
check(mMgh.mCurrentState == mMgh.mPanningScalingState,
|
||||
state);
|
||||
check(mMgh.mPanningScalingStateHandler.mScaling, state);
|
||||
check(mMgh.mPanningScalingState.mScaling, state);
|
||||
} break;
|
||||
default: throw new IllegalArgumentException("Illegal state: " + state);
|
||||
}
|
||||
@@ -432,7 +431,7 @@ public class MagnificationGestureHandlerTest {
|
||||
}
|
||||
|
||||
private int tapCount() {
|
||||
return mMgh.mDetectingStateHandler.tapCount();
|
||||
return mMgh.mDetectingState.tapCount();
|
||||
}
|
||||
|
||||
private static String stateToString(int state) {
|
||||
@@ -492,7 +491,7 @@ public class MagnificationGestureHandlerTest {
|
||||
}
|
||||
|
||||
private long defaultDownTime() {
|
||||
MotionEvent lastDown = mMgh.mDetectingStateHandler.mLastDown;
|
||||
MotionEvent lastDown = mMgh.mDetectingState.mLastDown;
|
||||
return lastDown == null ? mClock.now() - 1 : lastDown.getDownTime();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user