Loading api/current.txt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -26054,9 +26054,13 @@ package android.view.accessibility { field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4 field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4 field public static final int TYPES_ALL_MASK = -1; // 0xffffffff field public static final int TYPES_ALL_MASK = -1; // 0xffffffff field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000 field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000 field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000 field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000 field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40 field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200 field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000 field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000 field public static final int TYPE_VIEW_CLICKED = 1; // 0x1 field public static final int TYPE_VIEW_CLICKED = 1; // 0x1 core/java/android/view/accessibility/AccessibilityEvent.java +80 −18 Original line number Original line Diff line number Diff line Loading @@ -424,6 +424,28 @@ import java.util.List; * </ul> * </ul> * </p> * </p> * <p> * <p> * <b>Touch interaction start</b> - represents the event of starting a touch * interaction, which is the user starts touching the screen.</br> * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_START}</br> * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * <p> * <b>Touch interaction end</b> - represents the event of ending a touch * interaction, which is the user stops touching the screen.</br> * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_END}</br> * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * <p> * <b>Touch exploration gesture start</b> - represents the event of starting a touch * <b>Touch exploration gesture start</b> - represents the event of starting a touch * exploring gesture.</br> * exploring gesture.</br> * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br> * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br> Loading @@ -431,15 +453,8 @@ import java.util.List; * <ul> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * </ul> * <em>Note:</em> This event type is not dispatched to descendants though * <em>Note:</em> This event is fired only by the system and is not passed to the * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) * view tree to be populated.</br> * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event * source {@link android.view.View} and the sub-tree rooted at it will not receive * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent) * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add * text content to such events is by setting the * {@link android.R.styleable#View_contentDescription contentDescription} of the source * view.</br> * </p> * </p> * <p> * <p> * <b>Touch exploration gesture end</b> - represents the event of ending a touch * <b>Touch exploration gesture end</b> - represents the event of ending a touch Loading @@ -449,15 +464,30 @@ import java.util.List; * <ul> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * </ul> * <em>Note:</em> This event type is not dispatched to descendants though * <em>Note:</em> This event is fired only by the system and is not passed to the * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) * view tree to be populated.</br> * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event * </p> * source {@link android.view.View} and the sub-tree rooted at it will not receive * <p> * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent) * <b>Touch gesture detection start</b> - represents the event of starting a user * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add * gesture detection.</br> * text content to such events is by setting the * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_START}</br> * {@link android.R.styleable#View_contentDescription contentDescription} of the source * <em>Properties:</em></br> * view.</br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * <p> * <b>Touch gesture detection end</b> - represents the event of ending a user * gesture detection.</br> * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_END}</br> * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * </p> * <p> * <p> * <b>MISCELLANEOUS TYPES</b></br> * <b>MISCELLANEOUS TYPES</b></br> Loading Loading @@ -609,6 +639,26 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par */ */ public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000; public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000; /** * Represents the event of beginning gesture detection. */ public static final int TYPE_GESTURE_DETECTION_START = 0x00040000; /** * Represents the event of ending gesture detection. */ public static final int TYPE_GESTURE_DETECTION_END = 0x00080000; /** * Represents the event of the user starting to touch the screen. */ public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000; /** * Represents the event of the user ending to touch the screen. */ public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000; /** /** * Mask for {@link AccessibilityEvent} all types. * Mask for {@link AccessibilityEvent} all types. * * Loading @@ -628,6 +678,10 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED * @see #TYPE_ANNOUNCEMENT * @see #TYPE_ANNOUNCEMENT * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY * @see #TYPE_GESTURE_DETECTION_START * @see #TYPE_GESTURE_DETECTION_END * @see #TYPE_TOUCH_INTERACTION_START * @see #TYPE_TOUCH_INTERACTION_END */ */ public static final int TYPES_ALL_MASK = 0xFFFFFFFF; public static final int TYPES_ALL_MASK = 0xFFFFFFFF; Loading Loading @@ -1120,6 +1174,14 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED"; return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED"; case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED"; return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED"; case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START"; case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END"; case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START"; case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END"; default: default: return null; return null; } } Loading services/java/com/android/server/accessibility/AccessibilityManagerService.java +0 −36 Original line number Original line Diff line number Diff line Loading @@ -173,10 +173,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private Service mQueryBridge; private Service mQueryBridge; private boolean mTouchExplorationGestureEnded; private boolean mTouchExplorationGestureStarted; private AlertDialog mEnableTouchExplorationDialog; private AlertDialog mEnableTouchExplorationDialog; /** /** Loading Loading @@ -400,18 +396,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } public boolean sendAccessibilityEvent(AccessibilityEvent event) { public boolean sendAccessibilityEvent(AccessibilityEvent event) { final int eventType = event.getEventType(); // The event for gesture start should be strictly before the // first hover enter event for the gesture. if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_ENTER && mTouchExplorationGestureStarted) { mTouchExplorationGestureStarted = false; AccessibilityEvent gestureStartEvent = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); sendAccessibilityEvent(gestureStartEvent); } synchronized (mLock) { synchronized (mLock) { if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) { if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) { mSecurityPolicy.updateActiveWindowAndEventSourceLocked(event); mSecurityPolicy.updateActiveWindowAndEventSourceLocked(event); Loading @@ -421,22 +405,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (mHasInputFilter && mInputFilter != null) { if (mHasInputFilter && mInputFilter != null) { mMainHandler.obtainMessage(MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER, mMainHandler.obtainMessage(MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER, AccessibilityEvent.obtain(event)).sendToTarget(); AccessibilityEvent.obtain(event)).sendToTarget(); } } event.recycle(); event.recycle(); mHandledFeedbackTypes = 0; mHandledFeedbackTypes = 0; } } // The event for gesture end should be strictly after the // last hover exit event for the gesture. if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT && mTouchExplorationGestureEnded) { mTouchExplorationGestureEnded = false; AccessibilityEvent gestureEndEvent = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END); sendAccessibilityEvent(gestureEndEvent); } return (OWN_PROCESS_ID != Binder.getCallingPid()); return (OWN_PROCESS_ID != Binder.getCallingPid()); } } Loading Loading @@ -628,14 +600,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return mQueryBridge; return mQueryBridge; } } public void touchExplorationGestureEnded() { mTouchExplorationGestureEnded = true; } public void touchExplorationGestureStarted() { mTouchExplorationGestureStarted = true; } private boolean notifyGestureLocked(int gestureId, boolean isDefault) { private boolean notifyGestureLocked(int gestureId, boolean isDefault) { // TODO: Now we are giving the gestures to the last enabled // TODO: Now we are giving the gestures to the last enabled // service that can handle them which is the last one // service that can handle them which is the last one Loading services/java/com/android/server/accessibility/TouchExplorer.java +115 −20 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.gesture.GestureStore; import android.gesture.GestureStroke; import android.gesture.GestureStroke; import android.gesture.Prediction; import android.gesture.Prediction; import android.graphics.Rect; import android.graphics.Rect; import android.os.Build; import android.os.Handler; import android.os.Handler; import android.os.SystemClock; import android.os.SystemClock; import android.util.Slog; import android.util.Slog; Loading @@ -35,6 +36,7 @@ import android.view.VelocityTracker; import android.view.ViewConfiguration; import android.view.ViewConfiguration; import android.view.WindowManagerPolicy; import android.view.WindowManagerPolicy; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import com.android.internal.R; import com.android.internal.R; Loading Loading @@ -168,6 +170,9 @@ class TouchExplorer implements EventStreamTransformation { // Temporary rectangle to avoid instantiation. // Temporary rectangle to avoid instantiation. private final Rect mTempRect = new Rect(); private final Rect mTempRect = new Rect(); // Context in which this explorer operates. private final Context mContext; // The X of the previous event. // The X of the previous event. private float mPreviousX; private float mPreviousX; Loading Loading @@ -198,6 +203,12 @@ class TouchExplorer implements EventStreamTransformation { // The id of the last touch explored window. // The id of the last touch explored window. private int mLastTouchedWindowId; private int mLastTouchedWindowId; // Whether touch exploration gesture has ended. private boolean mTouchExplorationGestureEnded; // Whether touch interaction has ended. private boolean mTouchInteractionEnded; /** /** * Creates a new instance. * Creates a new instance. * * Loading @@ -205,11 +216,12 @@ class TouchExplorer implements EventStreamTransformation { * @param context A context handle for accessing resources. * @param context A context handle for accessing resources. */ */ public TouchExplorer(Context context, AccessibilityManagerService service) { public TouchExplorer(Context context, AccessibilityManagerService service) { mContext = context; mAms = service; mAms = service; mReceivedPointerTracker = new ReceivedPointerTracker(context); mReceivedPointerTracker = new ReceivedPointerTracker(context); mInjectedPointerTracker = new InjectedPointerTracker(); mInjectedPointerTracker = new InjectedPointerTracker(); mTapTimeout = ViewConfiguration.getTapTimeout(); mTapTimeout = ViewConfiguration.getTapTimeout(); mDetermineUserIntentTimeout = (int) (mTapTimeout * 1.5f); mDetermineUserIntentTimeout = ViewConfiguration.getDoubleTapTimeout(); mDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); mDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop(); mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop(); Loading Loading @@ -317,9 +329,32 @@ class TouchExplorer implements EventStreamTransformation { } } public void onAccessibilityEvent(AccessibilityEvent event) { public void onAccessibilityEvent(AccessibilityEvent event) { final int eventType = event.getEventType(); // The event for gesture end should be strictly after the // last hover exit event. if (mTouchExplorationGestureEnded) { switch (eventType) { case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { mTouchExplorationGestureEnded = false; sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END); } break; } } // The event for touch interaction end should be strictly after the // last hover exit and the touch exploration gesture end events. if (mTouchInteractionEnded) { switch (eventType) { case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { mTouchInteractionEnded = false; sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); } break; } } // If a new window opens or the accessibility focus moves we no longer // If a new window opens or the accessibility focus moves we no longer // want to click/long press on the last touch explored location. // want to click/long press on the last touch explored location. final int eventType = event.getEventType(); switch (eventType) { switch (eventType) { case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { Loading Loading @@ -358,6 +393,15 @@ class TouchExplorer implements EventStreamTransformation { switch (event.getActionMasked()) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN: // The delayed enter not delivered implies that we have delivered // TYPE_TOUCH_INTERACTION_START and not TYPE_TOUCH_INTERACTION_END, // therefore we need to deliver the interaction end event here. if (mSendHoverEnterDelayed.isPending()) { sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); } // Announce the start of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_START); // Pre-feed the motion events to the gesture detector since we // Pre-feed the motion events to the gesture detector since we // have a distance slop before getting into gesture detection // have a distance slop before getting into gesture detection // mode and not using the points within this slop significantly // mode and not using the points within this slop significantly Loading Loading @@ -396,7 +440,7 @@ class TouchExplorer implements EventStreamTransformation { // to detect what the user is trying to do. // to detect what the user is trying to do. final int pointerId = receivedTracker.getPrimaryActivePointerId(); final int pointerId = receivedTracker.getPrimaryActivePointerId(); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); mSendHoverEnterDelayed.post(event, pointerIdBits, policyFlags); mSendHoverEnterDelayed.post(event, true, pointerIdBits, policyFlags); } break; } break; default: { default: { /* do nothing - let the code for ACTION_MOVE decide what to do */ /* do nothing - let the code for ACTION_MOVE decide what to do */ Loading Loading @@ -443,6 +487,10 @@ class TouchExplorer implements EventStreamTransformation { mSendHoverExitDelayed.remove(); mSendHoverExitDelayed.remove(); mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove(); mExitGestureDetectionModeDelayed.post(); mExitGestureDetectionModeDelayed.post(); // Send accessibility event to announce the start // of gesture recognition. sendAccessibilityEvent( AccessibilityEvent.TYPE_GESTURE_DETECTION_START); } else { } else { // We have just decided that the user is touch, // We have just decided that the user is touch, // exploring so start sending events. // exploring so start sending events. Loading Loading @@ -551,7 +599,8 @@ class TouchExplorer implements EventStreamTransformation { // If we have not delivered the enter schedule exit. // If we have not delivered the enter schedule exit. if (mSendHoverEnterDelayed.isPending()) { if (mSendHoverEnterDelayed.isPending()) { mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags); mSendHoverEnterDelayed.mTouchExplorationInProgress = false; mSendHoverExitDelayed.post(event, false, pointerIdBits, policyFlags); } else { } else { // The user is touch exploring so we send events for end. // The user is touch exploring so we send events for end. sendExitEventsIfNeeded(policyFlags); sendExitEventsIfNeeded(policyFlags); Loading Loading @@ -656,6 +705,9 @@ class TouchExplorer implements EventStreamTransformation { } } } break; } break; case MotionEvent.ACTION_UP: { case MotionEvent.ACTION_UP: { // Announce the end of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); mCurrentState = STATE_TOUCH_EXPLORING; mCurrentState = STATE_TOUCH_EXPLORING; } break; } break; case MotionEvent.ACTION_CANCEL: { case MotionEvent.ACTION_CANCEL: { Loading Loading @@ -687,6 +739,10 @@ class TouchExplorer implements EventStreamTransformation { } } } break; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP: // Announce the end of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); //$FALL-THROUGH$ case MotionEvent.ACTION_POINTER_UP: { case MotionEvent.ACTION_POINTER_UP: { mLongPressingPointerId = -1; mLongPressingPointerId = -1; mLongPressingPointerDeltaX = 0; mLongPressingPointerDeltaX = 0; Loading Loading @@ -725,6 +781,13 @@ class TouchExplorer implements EventStreamTransformation { } } } break; } break; case MotionEvent.ACTION_UP: { case MotionEvent.ACTION_UP: { // Announce the end of gesture recognition. sendAccessibilityEvent( AccessibilityEvent.TYPE_GESTURE_DETECTION_END); // Announce the end of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); float x = event.getX(); float x = event.getX(); float y = event.getY(); float y = event.getY(); mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime())); mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime())); Loading Loading @@ -759,6 +822,19 @@ class TouchExplorer implements EventStreamTransformation { } } } } /** * Sends an accessibility event of the given type. * * @param type The event type. */ private void sendAccessibilityEvent(int type) { AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext); if (accessibilityManager.isEnabled()) { AccessibilityEvent event = AccessibilityEvent.obtain(type); accessibilityManager.sendAccessibilityEvent(event); } } /** /** * Sends down events to the view hierarchy for all active pointers which are * Sends down events to the view hierarchy for all active pointers which are * not already being delivered i.e. pointers that are not yet injected. * not already being delivered i.e. pointers that are not yet injected. Loading Loading @@ -807,7 +883,8 @@ class TouchExplorer implements EventStreamTransformation { MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { if (event != null && event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); final int pointerIdBits = event.getPointerIdBits(); mAms.touchExplorationGestureEnded(); mTouchExplorationGestureEnded = true; mTouchInteractionEnded = true; sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); } } } } Loading @@ -822,7 +899,6 @@ class TouchExplorer implements EventStreamTransformation { MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); final int pointerIdBits = event.getPointerIdBits(); mAms.touchExplorationGestureStarted(); sendMotionEvent(event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags); sendMotionEvent(event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags); } } } } Loading Loading @@ -1080,16 +1156,24 @@ class TouchExplorer implements EventStreamTransformation { return; return; } } if (Build.IS_DEBUGGABLE) { if (mSendHoverEnterDelayed.isPending()) { throw new IllegalStateException("mSendHoverEnterDelayed must not be pending."); } if (mSendHoverExitDelayed.isPending()) { throw new IllegalStateException("mSendHoverExitDelayed must not be pending."); } if (!mPerformLongPressDelayed.isPending()) { throw new IllegalStateException( "mPerformLongPressDelayed must not be pending."); } } // Remove pending event deliveries. // Remove pending event deliveries. mSendHoverEnterDelayed.remove(); mSendHoverExitDelayed.remove(); mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove(); // This is a tap so do not send hover events since // The touch interaction has ended since we will send a click. // this events will result in firing the corresponding sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); // accessibility events confusing the user about what // is actually clicked. sendExitEventsIfNeeded(policyFlags); int clickLocationX; int clickLocationX; int clickLocationY; int clickLocationY; Loading Loading @@ -1257,13 +1341,13 @@ class TouchExplorer implements EventStreamTransformation { } } public void remove() { public void remove() { if (isPenidng()) { if (isPending()) { mHandler.removeCallbacks(this); mHandler.removeCallbacks(this); clear(); clear(); } } } } private boolean isPenidng() { public boolean isPending() { return (mEvent != null); return (mEvent != null); } } Loading Loading @@ -1326,7 +1410,7 @@ class TouchExplorer implements EventStreamTransformation { } } private void clear() { private void clear() { if (!isPenidng()) { if (!isPending()) { return; return; } } mEvent.recycle(); mEvent.recycle(); Loading @@ -1347,15 +1431,18 @@ class TouchExplorer implements EventStreamTransformation { private MotionEvent mPrototype; private MotionEvent mPrototype; private int mPointerIdBits; private int mPointerIdBits; private int mPolicyFlags; private int mPolicyFlags; private boolean mTouchExplorationInProgress; public SendHoverDelayed(int hoverAction, boolean gestureStarted) { public SendHoverDelayed(int hoverAction, boolean gestureStarted) { mHoverAction = hoverAction; mHoverAction = hoverAction; mGestureStarted = gestureStarted; mGestureStarted = gestureStarted; } } public void post(MotionEvent prototype, int pointerIdBits, int policyFlags) { public void post(MotionEvent prototype, boolean touchExplorationInProgress, int pointerIdBits, int policyFlags) { remove(); remove(); mPrototype = MotionEvent.obtain(prototype); mPrototype = MotionEvent.obtain(prototype); mTouchExplorationInProgress = touchExplorationInProgress; mPointerIdBits = pointerIdBits; mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mPolicyFlags = policyFlags; mHandler.postDelayed(this, mDetermineUserIntentTimeout); mHandler.postDelayed(this, mDetermineUserIntentTimeout); Loading Loading @@ -1392,6 +1479,7 @@ class TouchExplorer implements EventStreamTransformation { mPrototype = null; mPrototype = null; mPointerIdBits = -1; mPointerIdBits = -1; mPolicyFlags = 0; mPolicyFlags = 0; mTouchExplorationInProgress = false; } } public void forceSendAndRemove() { public void forceSendAndRemove() { Loading @@ -1408,10 +1496,17 @@ class TouchExplorer implements EventStreamTransformation { Slog.d(LOG_TAG_SEND_HOVER_DELAYED, mGestureStarted ? Slog.d(LOG_TAG_SEND_HOVER_DELAYED, mGestureStarted ? "touchExplorationGestureStarted" : "touchExplorationGestureEnded"); "touchExplorationGestureStarted" : "touchExplorationGestureEnded"); } } if (mTouchExplorationInProgress) { if (mGestureStarted) { if (mGestureStarted) { mAms.touchExplorationGestureStarted(); sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); } else { } else { mAms.touchExplorationGestureEnded(); mTouchExplorationGestureEnded = true; mTouchInteractionEnded = true; } } else { if (!mGestureStarted) { mTouchInteractionEnded = true; } } } sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags); sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags); clear(); clear(); Loading Loading
api/current.txt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -26054,9 +26054,13 @@ package android.view.accessibility { field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4 field public static final deprecated int MAX_TEXT_LENGTH = 500; // 0x1f4 field public static final int TYPES_ALL_MASK = -1; // 0xffffffff field public static final int TYPES_ALL_MASK = -1; // 0xffffffff field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000 field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000 field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000 field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000 field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40 field public static final int TYPE_NOTIFICATION_STATE_CHANGED = 64; // 0x40 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200 field public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200 field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000 field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000 field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000 field public static final int TYPE_VIEW_CLICKED = 1; // 0x1 field public static final int TYPE_VIEW_CLICKED = 1; // 0x1
core/java/android/view/accessibility/AccessibilityEvent.java +80 −18 Original line number Original line Diff line number Diff line Loading @@ -424,6 +424,28 @@ import java.util.List; * </ul> * </ul> * </p> * </p> * <p> * <p> * <b>Touch interaction start</b> - represents the event of starting a touch * interaction, which is the user starts touching the screen.</br> * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_START}</br> * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * <p> * <b>Touch interaction end</b> - represents the event of ending a touch * interaction, which is the user stops touching the screen.</br> * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_END}</br> * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * <p> * <b>Touch exploration gesture start</b> - represents the event of starting a touch * <b>Touch exploration gesture start</b> - represents the event of starting a touch * exploring gesture.</br> * exploring gesture.</br> * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br> * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br> Loading @@ -431,15 +453,8 @@ import java.util.List; * <ul> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * </ul> * <em>Note:</em> This event type is not dispatched to descendants though * <em>Note:</em> This event is fired only by the system and is not passed to the * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) * view tree to be populated.</br> * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event * source {@link android.view.View} and the sub-tree rooted at it will not receive * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent) * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add * text content to such events is by setting the * {@link android.R.styleable#View_contentDescription contentDescription} of the source * view.</br> * </p> * </p> * <p> * <p> * <b>Touch exploration gesture end</b> - represents the event of ending a touch * <b>Touch exploration gesture end</b> - represents the event of ending a touch Loading @@ -449,15 +464,30 @@ import java.util.List; * <ul> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * </ul> * <em>Note:</em> This event type is not dispatched to descendants though * <em>Note:</em> This event is fired only by the system and is not passed to the * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) * view tree to be populated.</br> * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event * </p> * source {@link android.view.View} and the sub-tree rooted at it will not receive * <p> * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent) * <b>Touch gesture detection start</b> - represents the event of starting a user * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add * gesture detection.</br> * text content to such events is by setting the * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_START}</br> * {@link android.R.styleable#View_contentDescription contentDescription} of the source * <em>Properties:</em></br> * view.</br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * <p> * <b>Touch gesture detection end</b> - represents the event of ending a user * gesture detection.</br> * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_END}</br> * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> * <em>Note:</em> This event is fired only by the system and is not passed to the * view tree to be populated.</br> * </p> * </p> * <p> * <p> * <b>MISCELLANEOUS TYPES</b></br> * <b>MISCELLANEOUS TYPES</b></br> Loading Loading @@ -609,6 +639,26 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par */ */ public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000; public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000; /** * Represents the event of beginning gesture detection. */ public static final int TYPE_GESTURE_DETECTION_START = 0x00040000; /** * Represents the event of ending gesture detection. */ public static final int TYPE_GESTURE_DETECTION_END = 0x00080000; /** * Represents the event of the user starting to touch the screen. */ public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000; /** * Represents the event of the user ending to touch the screen. */ public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000; /** /** * Mask for {@link AccessibilityEvent} all types. * Mask for {@link AccessibilityEvent} all types. * * Loading @@ -628,6 +678,10 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED * @see #TYPE_ANNOUNCEMENT * @see #TYPE_ANNOUNCEMENT * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY * @see #TYPE_GESTURE_DETECTION_START * @see #TYPE_GESTURE_DETECTION_END * @see #TYPE_TOUCH_INTERACTION_START * @see #TYPE_TOUCH_INTERACTION_END */ */ public static final int TYPES_ALL_MASK = 0xFFFFFFFF; public static final int TYPES_ALL_MASK = 0xFFFFFFFF; Loading Loading @@ -1120,6 +1174,14 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED"; return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED"; case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED"; return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED"; case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START"; case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END"; case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START"; case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END"; default: default: return null; return null; } } Loading
services/java/com/android/server/accessibility/AccessibilityManagerService.java +0 −36 Original line number Original line Diff line number Diff line Loading @@ -173,10 +173,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private Service mQueryBridge; private Service mQueryBridge; private boolean mTouchExplorationGestureEnded; private boolean mTouchExplorationGestureStarted; private AlertDialog mEnableTouchExplorationDialog; private AlertDialog mEnableTouchExplorationDialog; /** /** Loading Loading @@ -400,18 +396,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } public boolean sendAccessibilityEvent(AccessibilityEvent event) { public boolean sendAccessibilityEvent(AccessibilityEvent event) { final int eventType = event.getEventType(); // The event for gesture start should be strictly before the // first hover enter event for the gesture. if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_ENTER && mTouchExplorationGestureStarted) { mTouchExplorationGestureStarted = false; AccessibilityEvent gestureStartEvent = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); sendAccessibilityEvent(gestureStartEvent); } synchronized (mLock) { synchronized (mLock) { if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) { if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) { mSecurityPolicy.updateActiveWindowAndEventSourceLocked(event); mSecurityPolicy.updateActiveWindowAndEventSourceLocked(event); Loading @@ -421,22 +405,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { if (mHasInputFilter && mInputFilter != null) { if (mHasInputFilter && mInputFilter != null) { mMainHandler.obtainMessage(MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER, mMainHandler.obtainMessage(MSG_SEND_ACCESSIBILITY_EVENT_TO_INPUT_FILTER, AccessibilityEvent.obtain(event)).sendToTarget(); AccessibilityEvent.obtain(event)).sendToTarget(); } } event.recycle(); event.recycle(); mHandledFeedbackTypes = 0; mHandledFeedbackTypes = 0; } } // The event for gesture end should be strictly after the // last hover exit event for the gesture. if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT && mTouchExplorationGestureEnded) { mTouchExplorationGestureEnded = false; AccessibilityEvent gestureEndEvent = AccessibilityEvent.obtain( AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END); sendAccessibilityEvent(gestureEndEvent); } return (OWN_PROCESS_ID != Binder.getCallingPid()); return (OWN_PROCESS_ID != Binder.getCallingPid()); } } Loading Loading @@ -628,14 +600,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return mQueryBridge; return mQueryBridge; } } public void touchExplorationGestureEnded() { mTouchExplorationGestureEnded = true; } public void touchExplorationGestureStarted() { mTouchExplorationGestureStarted = true; } private boolean notifyGestureLocked(int gestureId, boolean isDefault) { private boolean notifyGestureLocked(int gestureId, boolean isDefault) { // TODO: Now we are giving the gestures to the last enabled // TODO: Now we are giving the gestures to the last enabled // service that can handle them which is the last one // service that can handle them which is the last one Loading
services/java/com/android/server/accessibility/TouchExplorer.java +115 −20 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.gesture.GestureStore; import android.gesture.GestureStroke; import android.gesture.GestureStroke; import android.gesture.Prediction; import android.gesture.Prediction; import android.graphics.Rect; import android.graphics.Rect; import android.os.Build; import android.os.Handler; import android.os.Handler; import android.os.SystemClock; import android.os.SystemClock; import android.util.Slog; import android.util.Slog; Loading @@ -35,6 +36,7 @@ import android.view.VelocityTracker; import android.view.ViewConfiguration; import android.view.ViewConfiguration; import android.view.WindowManagerPolicy; import android.view.WindowManagerPolicy; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import com.android.internal.R; import com.android.internal.R; Loading Loading @@ -168,6 +170,9 @@ class TouchExplorer implements EventStreamTransformation { // Temporary rectangle to avoid instantiation. // Temporary rectangle to avoid instantiation. private final Rect mTempRect = new Rect(); private final Rect mTempRect = new Rect(); // Context in which this explorer operates. private final Context mContext; // The X of the previous event. // The X of the previous event. private float mPreviousX; private float mPreviousX; Loading Loading @@ -198,6 +203,12 @@ class TouchExplorer implements EventStreamTransformation { // The id of the last touch explored window. // The id of the last touch explored window. private int mLastTouchedWindowId; private int mLastTouchedWindowId; // Whether touch exploration gesture has ended. private boolean mTouchExplorationGestureEnded; // Whether touch interaction has ended. private boolean mTouchInteractionEnded; /** /** * Creates a new instance. * Creates a new instance. * * Loading @@ -205,11 +216,12 @@ class TouchExplorer implements EventStreamTransformation { * @param context A context handle for accessing resources. * @param context A context handle for accessing resources. */ */ public TouchExplorer(Context context, AccessibilityManagerService service) { public TouchExplorer(Context context, AccessibilityManagerService service) { mContext = context; mAms = service; mAms = service; mReceivedPointerTracker = new ReceivedPointerTracker(context); mReceivedPointerTracker = new ReceivedPointerTracker(context); mInjectedPointerTracker = new InjectedPointerTracker(); mInjectedPointerTracker = new InjectedPointerTracker(); mTapTimeout = ViewConfiguration.getTapTimeout(); mTapTimeout = ViewConfiguration.getTapTimeout(); mDetermineUserIntentTimeout = (int) (mTapTimeout * 1.5f); mDetermineUserIntentTimeout = ViewConfiguration.getDoubleTapTimeout(); mDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); mDoubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop(); mDoubleTapSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop(); Loading Loading @@ -317,9 +329,32 @@ class TouchExplorer implements EventStreamTransformation { } } public void onAccessibilityEvent(AccessibilityEvent event) { public void onAccessibilityEvent(AccessibilityEvent event) { final int eventType = event.getEventType(); // The event for gesture end should be strictly after the // last hover exit event. if (mTouchExplorationGestureEnded) { switch (eventType) { case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { mTouchExplorationGestureEnded = false; sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END); } break; } } // The event for touch interaction end should be strictly after the // last hover exit and the touch exploration gesture end events. if (mTouchInteractionEnded) { switch (eventType) { case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { mTouchInteractionEnded = false; sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); } break; } } // If a new window opens or the accessibility focus moves we no longer // If a new window opens or the accessibility focus moves we no longer // want to click/long press on the last touch explored location. // want to click/long press on the last touch explored location. final int eventType = event.getEventType(); switch (eventType) { switch (eventType) { case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { Loading Loading @@ -358,6 +393,15 @@ class TouchExplorer implements EventStreamTransformation { switch (event.getActionMasked()) { switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN: // The delayed enter not delivered implies that we have delivered // TYPE_TOUCH_INTERACTION_START and not TYPE_TOUCH_INTERACTION_END, // therefore we need to deliver the interaction end event here. if (mSendHoverEnterDelayed.isPending()) { sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); } // Announce the start of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_START); // Pre-feed the motion events to the gesture detector since we // Pre-feed the motion events to the gesture detector since we // have a distance slop before getting into gesture detection // have a distance slop before getting into gesture detection // mode and not using the points within this slop significantly // mode and not using the points within this slop significantly Loading Loading @@ -396,7 +440,7 @@ class TouchExplorer implements EventStreamTransformation { // to detect what the user is trying to do. // to detect what the user is trying to do. final int pointerId = receivedTracker.getPrimaryActivePointerId(); final int pointerId = receivedTracker.getPrimaryActivePointerId(); final int pointerIdBits = (1 << pointerId); final int pointerIdBits = (1 << pointerId); mSendHoverEnterDelayed.post(event, pointerIdBits, policyFlags); mSendHoverEnterDelayed.post(event, true, pointerIdBits, policyFlags); } break; } break; default: { default: { /* do nothing - let the code for ACTION_MOVE decide what to do */ /* do nothing - let the code for ACTION_MOVE decide what to do */ Loading Loading @@ -443,6 +487,10 @@ class TouchExplorer implements EventStreamTransformation { mSendHoverExitDelayed.remove(); mSendHoverExitDelayed.remove(); mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove(); mExitGestureDetectionModeDelayed.post(); mExitGestureDetectionModeDelayed.post(); // Send accessibility event to announce the start // of gesture recognition. sendAccessibilityEvent( AccessibilityEvent.TYPE_GESTURE_DETECTION_START); } else { } else { // We have just decided that the user is touch, // We have just decided that the user is touch, // exploring so start sending events. // exploring so start sending events. Loading Loading @@ -551,7 +599,8 @@ class TouchExplorer implements EventStreamTransformation { // If we have not delivered the enter schedule exit. // If we have not delivered the enter schedule exit. if (mSendHoverEnterDelayed.isPending()) { if (mSendHoverEnterDelayed.isPending()) { mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags); mSendHoverEnterDelayed.mTouchExplorationInProgress = false; mSendHoverExitDelayed.post(event, false, pointerIdBits, policyFlags); } else { } else { // The user is touch exploring so we send events for end. // The user is touch exploring so we send events for end. sendExitEventsIfNeeded(policyFlags); sendExitEventsIfNeeded(policyFlags); Loading Loading @@ -656,6 +705,9 @@ class TouchExplorer implements EventStreamTransformation { } } } break; } break; case MotionEvent.ACTION_UP: { case MotionEvent.ACTION_UP: { // Announce the end of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); mCurrentState = STATE_TOUCH_EXPLORING; mCurrentState = STATE_TOUCH_EXPLORING; } break; } break; case MotionEvent.ACTION_CANCEL: { case MotionEvent.ACTION_CANCEL: { Loading Loading @@ -687,6 +739,10 @@ class TouchExplorer implements EventStreamTransformation { } } } break; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP: // Announce the end of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); //$FALL-THROUGH$ case MotionEvent.ACTION_POINTER_UP: { case MotionEvent.ACTION_POINTER_UP: { mLongPressingPointerId = -1; mLongPressingPointerId = -1; mLongPressingPointerDeltaX = 0; mLongPressingPointerDeltaX = 0; Loading Loading @@ -725,6 +781,13 @@ class TouchExplorer implements EventStreamTransformation { } } } break; } break; case MotionEvent.ACTION_UP: { case MotionEvent.ACTION_UP: { // Announce the end of gesture recognition. sendAccessibilityEvent( AccessibilityEvent.TYPE_GESTURE_DETECTION_END); // Announce the end of a new touch interaction. sendAccessibilityEvent( AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); float x = event.getX(); float x = event.getX(); float y = event.getY(); float y = event.getY(); mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime())); mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime())); Loading Loading @@ -759,6 +822,19 @@ class TouchExplorer implements EventStreamTransformation { } } } } /** * Sends an accessibility event of the given type. * * @param type The event type. */ private void sendAccessibilityEvent(int type) { AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext); if (accessibilityManager.isEnabled()) { AccessibilityEvent event = AccessibilityEvent.obtain(type); accessibilityManager.sendAccessibilityEvent(event); } } /** /** * Sends down events to the view hierarchy for all active pointers which are * Sends down events to the view hierarchy for all active pointers which are * not already being delivered i.e. pointers that are not yet injected. * not already being delivered i.e. pointers that are not yet injected. Loading Loading @@ -807,7 +883,8 @@ class TouchExplorer implements EventStreamTransformation { MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { if (event != null && event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); final int pointerIdBits = event.getPointerIdBits(); mAms.touchExplorationGestureEnded(); mTouchExplorationGestureEnded = true; mTouchInteractionEnded = true; sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); } } } } Loading @@ -822,7 +899,6 @@ class TouchExplorer implements EventStreamTransformation { MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); MotionEvent event = mInjectedPointerTracker.getLastInjectedHoverEvent(); if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { final int pointerIdBits = event.getPointerIdBits(); final int pointerIdBits = event.getPointerIdBits(); mAms.touchExplorationGestureStarted(); sendMotionEvent(event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags); sendMotionEvent(event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags); } } } } Loading Loading @@ -1080,16 +1156,24 @@ class TouchExplorer implements EventStreamTransformation { return; return; } } if (Build.IS_DEBUGGABLE) { if (mSendHoverEnterDelayed.isPending()) { throw new IllegalStateException("mSendHoverEnterDelayed must not be pending."); } if (mSendHoverExitDelayed.isPending()) { throw new IllegalStateException("mSendHoverExitDelayed must not be pending."); } if (!mPerformLongPressDelayed.isPending()) { throw new IllegalStateException( "mPerformLongPressDelayed must not be pending."); } } // Remove pending event deliveries. // Remove pending event deliveries. mSendHoverEnterDelayed.remove(); mSendHoverExitDelayed.remove(); mPerformLongPressDelayed.remove(); mPerformLongPressDelayed.remove(); // This is a tap so do not send hover events since // The touch interaction has ended since we will send a click. // this events will result in firing the corresponding sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); // accessibility events confusing the user about what // is actually clicked. sendExitEventsIfNeeded(policyFlags); int clickLocationX; int clickLocationX; int clickLocationY; int clickLocationY; Loading Loading @@ -1257,13 +1341,13 @@ class TouchExplorer implements EventStreamTransformation { } } public void remove() { public void remove() { if (isPenidng()) { if (isPending()) { mHandler.removeCallbacks(this); mHandler.removeCallbacks(this); clear(); clear(); } } } } private boolean isPenidng() { public boolean isPending() { return (mEvent != null); return (mEvent != null); } } Loading Loading @@ -1326,7 +1410,7 @@ class TouchExplorer implements EventStreamTransformation { } } private void clear() { private void clear() { if (!isPenidng()) { if (!isPending()) { return; return; } } mEvent.recycle(); mEvent.recycle(); Loading @@ -1347,15 +1431,18 @@ class TouchExplorer implements EventStreamTransformation { private MotionEvent mPrototype; private MotionEvent mPrototype; private int mPointerIdBits; private int mPointerIdBits; private int mPolicyFlags; private int mPolicyFlags; private boolean mTouchExplorationInProgress; public SendHoverDelayed(int hoverAction, boolean gestureStarted) { public SendHoverDelayed(int hoverAction, boolean gestureStarted) { mHoverAction = hoverAction; mHoverAction = hoverAction; mGestureStarted = gestureStarted; mGestureStarted = gestureStarted; } } public void post(MotionEvent prototype, int pointerIdBits, int policyFlags) { public void post(MotionEvent prototype, boolean touchExplorationInProgress, int pointerIdBits, int policyFlags) { remove(); remove(); mPrototype = MotionEvent.obtain(prototype); mPrototype = MotionEvent.obtain(prototype); mTouchExplorationInProgress = touchExplorationInProgress; mPointerIdBits = pointerIdBits; mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mPolicyFlags = policyFlags; mHandler.postDelayed(this, mDetermineUserIntentTimeout); mHandler.postDelayed(this, mDetermineUserIntentTimeout); Loading Loading @@ -1392,6 +1479,7 @@ class TouchExplorer implements EventStreamTransformation { mPrototype = null; mPrototype = null; mPointerIdBits = -1; mPointerIdBits = -1; mPolicyFlags = 0; mPolicyFlags = 0; mTouchExplorationInProgress = false; } } public void forceSendAndRemove() { public void forceSendAndRemove() { Loading @@ -1408,10 +1496,17 @@ class TouchExplorer implements EventStreamTransformation { Slog.d(LOG_TAG_SEND_HOVER_DELAYED, mGestureStarted ? Slog.d(LOG_TAG_SEND_HOVER_DELAYED, mGestureStarted ? "touchExplorationGestureStarted" : "touchExplorationGestureEnded"); "touchExplorationGestureStarted" : "touchExplorationGestureEnded"); } } if (mTouchExplorationInProgress) { if (mGestureStarted) { if (mGestureStarted) { mAms.touchExplorationGestureStarted(); sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START); } else { } else { mAms.touchExplorationGestureEnded(); mTouchExplorationGestureEnded = true; mTouchInteractionEnded = true; } } else { if (!mGestureStarted) { mTouchInteractionEnded = true; } } } sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags); sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags); clear(); clear(); Loading