TouchExplorer: allow service to initiate touch exploration and there are no pointers on the screen
We need to be able to initiate touch exploration even if there are no pointers on the screen in order to reliably cover the case where a user just taps the screen. The user expects to hear if they have tapped on anything. Bug: 223673301 Test: manual. Tap on the screen and confirm that talkback reads the item in that position. Change-Id: Id96fa8bd7f000ea153f45024e06915a43ca80826
This commit is contained in:
@@ -262,7 +262,7 @@ public final class TouchInteractionController {
|
||||
* interaction.
|
||||
*/
|
||||
public void requestTouchExploration() {
|
||||
checkState();
|
||||
validateTransitionRequest();
|
||||
final IAccessibilityServiceConnection connection =
|
||||
AccessibilityInteractionClient.getInstance()
|
||||
.getConnection(mService.getConnectionId());
|
||||
@@ -288,7 +288,7 @@ public final class TouchInteractionController {
|
||||
* @throws IllegalArgumentException if the pointer id is outside of the allowed range.
|
||||
*/
|
||||
public void requestDragging(int pointerId) {
|
||||
checkState();
|
||||
validateTransitionRequest();
|
||||
if (pointerId < 0 || pointerId > MAX_POINTER_COUNT) {
|
||||
throw new IllegalArgumentException("Invalid pointer id: " + pointerId);
|
||||
}
|
||||
@@ -313,7 +313,7 @@ public final class TouchInteractionController {
|
||||
* the duration of this interaction.
|
||||
*/
|
||||
public void requestDelegating() {
|
||||
checkState();
|
||||
validateTransitionRequest();
|
||||
final IAccessibilityServiceConnection connection =
|
||||
AccessibilityInteractionClient.getInstance()
|
||||
.getConnection(mService.getConnectionId());
|
||||
@@ -371,14 +371,14 @@ public final class TouchInteractionController {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkState() {
|
||||
private void validateTransitionRequest() {
|
||||
if (!mServiceDetectsGestures || mCallbacks.size() == 0) {
|
||||
throw new IllegalStateException(
|
||||
"State transitions are not allowed without first adding a callback.");
|
||||
}
|
||||
if (mState != STATE_TOUCH_INTERACTING && mState != STATE_DRAGGING) {
|
||||
if ((mState == STATE_DELEGATING || mState == STATE_TOUCH_EXPLORING)) {
|
||||
throw new IllegalStateException(
|
||||
"State transitions are not allowed in " + stateToString(mState));
|
||||
"State transition requests are not allowed in " + stateToString(mState));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1329,13 +1329,28 @@ public class TouchExplorer extends BaseEventStreamTransformation
|
||||
if (mState.isServiceDetectingGestures() && mState.isTouchInteracting()) {
|
||||
// Cancel without deleting events.
|
||||
mHandler.removeCallbacks(mSendHoverEnterAndMoveDelayed);
|
||||
final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
|
||||
int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
|
||||
if (pointerId == INVALID_POINTER_ID) {
|
||||
MotionEvent event = mState.getLastReceivedEvent();
|
||||
if (event != null) {
|
||||
// Use the first pointer of the most recent event.
|
||||
pointerId = event.getPointerId(0);
|
||||
}
|
||||
}
|
||||
if (pointerId == INVALID_POINTER_ID) {
|
||||
Slog.e(LOG_TAG, "Unable to find a valid pointer for touch exploration.");
|
||||
return;
|
||||
}
|
||||
final int pointerIdBits = (1 << pointerId);
|
||||
final int policyFlags = mState.getLastReceivedPolicyFlags();
|
||||
mSendHoverEnterAndMoveDelayed.setPointerIdBits(pointerIdBits);
|
||||
mSendHoverEnterAndMoveDelayed.setPolicyFlags(policyFlags);
|
||||
mSendHoverEnterAndMoveDelayed.run();
|
||||
mSendHoverEnterAndMoveDelayed.clear();
|
||||
if (mReceivedPointerTracker.getReceivedPointerDownCount() == 0) {
|
||||
// We need to send hover exit because there will be no future ACTION_UP
|
||||
sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user