Skip to content

Commit fe304b8

Browse files
committed
Some accessibility events not sent from touch explorer if apps misbehave.
1. The touch explorer is relying on the hover exit accessibility event to be sent from the app's view tree before sending the exploration end and last touch accessibility events. However, if the app is buggy and does not send the hover exit event, then the interaction ending events are never sent. Now there is a timeout in which we wait for the hover exit accessibility event before sending the gesture end and last touch accessibility events. Hence, we are making a best effort to have a consistent event stream. 2. Sneaking in the new nine patch for the border around the magnified region since the current one is engineering art. bug:7233616 Change-Id: Ie64f23659c25ab914565d50537b9a82bdc6a44a0
1 parent 95841ac commit fe304b8

File tree

5 files changed

+58
-0
lines changed

5 files changed

+58
-0
lines changed
190 Bytes
Loading
172 Bytes
Loading
-741 Bytes
Binary file not shown.
205 Bytes
Loading

services/java/com/android/server/accessibility/TouchExplorer.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ class TouchExplorer implements EventStreamTransformation {
102102
// The timeout after which we are no longer trying to detect a gesture.
103103
private static final int EXIT_GESTURE_DETECTION_TIMEOUT = 2000;
104104

105+
// The timeout to send interaction end events in case we did not
106+
// receive the expected hover exit event due to a misbehaving app.
107+
private static final int SEND_INTERACTION_END_EVENTS_TIMEOUT = 200;
108+
105109
// Temporary array for storing pointer IDs.
106110
private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT];
107111

@@ -135,6 +139,9 @@ class TouchExplorer implements EventStreamTransformation {
135139
// Command for delayed sending of a hover exit event.
136140
private final SendHoverDelayed mSendHoverExitDelayed;
137141

142+
// Command for delayed sending of interaction ending events.
143+
private final SendInteractionEndEventsDelayed mSendInteractionEndEventsDelayed;
144+
138145
// Command for delayed sending of a long press.
139146
private final PerformLongPressDelayed mPerformLongPressDelayed;
140147

@@ -233,6 +240,7 @@ public TouchExplorer(Context context, AccessibilityManagerService service) {
233240
mGestureLibrary.load();
234241
mSendHoverEnterDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_ENTER, true);
235242
mSendHoverExitDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_EXIT, false);
243+
mSendInteractionEndEventsDelayed = new SendInteractionEndEventsDelayed();
236244
mDoubleTapDetector = new DoubleTapDetector();
237245
final float density = context.getResources().getDisplayMetrics().density;
238246
mScaledMinPointerDistanceToUseMiddleLocation =
@@ -278,6 +286,7 @@ private void clear(MotionEvent event, int policyFlags) {
278286
mSendHoverExitDelayed.remove();
279287
mPerformLongPressDelayed.remove();
280288
mExitGestureDetectionModeDelayed.remove();
289+
mSendInteractionEndEventsDelayed.remove();
281290
// Reset the pointer trackers.
282291
mReceivedPointerTracker.clear();
283292
mInjectedPointerTracker.clear();
@@ -334,6 +343,7 @@ public void onAccessibilityEvent(AccessibilityEvent event) {
334343
// last hover exit event.
335344
if (mTouchExplorationGestureEnded
336345
&& eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
346+
mSendInteractionEndEventsDelayed.remove();
337347
mTouchExplorationGestureEnded = false;
338348
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END);
339349
}
@@ -342,6 +352,7 @@ public void onAccessibilityEvent(AccessibilityEvent event) {
342352
// last hover exit and the touch exploration gesture end events.
343353
if (mTouchInteractionEnded
344354
&& eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
355+
mSendInteractionEndEventsDelayed.remove();
345356
mTouchInteractionEnded = false;
346357
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
347358
}
@@ -416,6 +427,10 @@ private void handleMotionEventStateTouchExploring(MotionEvent event, int policyF
416427
mSendHoverExitDelayed.remove();
417428
}
418429

430+
if (mSendInteractionEndEventsDelayed.isPending()) {
431+
mSendInteractionEndEventsDelayed.forceSendAndRemove();
432+
}
433+
419434
mPerformLongPressDelayed.remove();
420435

421436
// If we have the first tap schedule a long press and break
@@ -873,6 +888,9 @@ private void sendExitEventsIfNeeded(int policyFlags) {
873888
final int pointerIdBits = event.getPointerIdBits();
874889
mTouchExplorationGestureEnded = true;
875890
mTouchInteractionEnded = true;
891+
if (!mSendInteractionEndEventsDelayed.isPending()) {
892+
mSendInteractionEndEventsDelayed.post();
893+
}
876894
sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags);
877895
}
878896
}
@@ -1484,17 +1502,57 @@ public void run() {
14841502
} else {
14851503
mTouchExplorationGestureEnded = true;
14861504
mTouchInteractionEnded = true;
1505+
if (!mSendInteractionEndEventsDelayed.isPending()) {
1506+
mSendInteractionEndEventsDelayed.post();
1507+
}
14871508
}
14881509
} else {
14891510
if (!mGestureStarted) {
14901511
mTouchInteractionEnded = true;
1512+
if (!mSendInteractionEndEventsDelayed.isPending()) {
1513+
mSendInteractionEndEventsDelayed.post();
1514+
}
14911515
}
14921516
}
14931517
sendMotionEvent(mPrototype, mHoverAction, mPointerIdBits, mPolicyFlags);
14941518
clear();
14951519
}
14961520
}
14971521

1522+
private class SendInteractionEndEventsDelayed implements Runnable {
1523+
1524+
public void remove() {
1525+
mHandler.removeCallbacks(this);
1526+
}
1527+
1528+
public void post() {
1529+
mHandler.postDelayed(this, SEND_INTERACTION_END_EVENTS_TIMEOUT);
1530+
}
1531+
1532+
public boolean isPending() {
1533+
return mHandler.hasCallbacks(this);
1534+
}
1535+
1536+
public void forceSendAndRemove() {
1537+
if (isPending()) {
1538+
run();
1539+
remove();
1540+
}
1541+
}
1542+
1543+
@Override
1544+
public void run() {
1545+
if (mTouchExplorationGestureEnded) {
1546+
mTouchExplorationGestureEnded = false;
1547+
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END);
1548+
}
1549+
if (mTouchInteractionEnded) {
1550+
mTouchInteractionEnded = false;
1551+
sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
1552+
}
1553+
}
1554+
}
1555+
14981556
@Override
14991557
public String toString() {
15001558
return LOG_TAG;

0 commit comments

Comments
 (0)