From 8d412fe18b9ce8cf71ce57c380e7f312e4667667 Mon Sep 17 00:00:00 2001 From: Svetoslav Date: Fri, 19 Sep 2014 15:37:02 -0700 Subject: [PATCH] TouchExploer computes incorectly the click location. If there is accessibilty focus and the user touch explores location that does not change accessibility focus that is not in the app window, e.g. system bar, double tap does not click on the system UI affordance. This is due to obsolete logic from the time where accessibility focus was only in the active window at the time of double clicking. bug:17588024 Change-Id: Ib780103e873d8a2afd3b35de3227d54116f1a1b0 --- .../AccessibilityManagerService.java | 30 ----- .../server/accessibility/TouchExplorer.java | 110 +++++------------- 2 files changed, 32 insertions(+), 108 deletions(-) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 24bfba640c590..ac78630af171b 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -758,29 +758,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { .getAccessibilityFocusClickPointInScreenNotLocked(outPoint); } - /** - * Gets the bounds of the active window. - * - * @param outBounds The output to which to write the bounds. - */ - boolean getActiveWindowBounds(Rect outBounds) { - // TODO: This should be refactored to work with accessibility - // focus in multiple windows. - IBinder token; - synchronized (mLock) { - final int windowId = mSecurityPolicy.mActiveWindowId; - token = mGlobalWindowTokens.get(windowId); - if (token == null) { - token = getCurrentUserStateLocked().mWindowTokens.get(windowId); - } - } - mWindowManagerService.getWindowFrame(token, outBounds); - if (!outBounds.isEmpty()) { - return true; - } - return false; - } - int getActiveWindowId() { return mSecurityPolicy.mActiveWindowId; } @@ -3196,13 +3173,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { point.y = (int) (point.y * (1 / spec.scale)); } - // Make sure the point is within the window. - Rect windowBounds = mTempRect; - getActiveWindowBounds(windowBounds); - if (!windowBounds.contains(point.x, point.y)) { - return false; - } - // Make sure the point is within the screen. Point screenSize = mTempPoint; mDefaultDisplay.getRealSize(screenSize); diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java index 9e63433fd1f49..94befad3670df 100644 --- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java @@ -205,9 +205,6 @@ class TouchExplorer implements EventStreamTransformation { // The long pressing pointer Y if coordinate remapping is needed. private int mLongPressingPointerDeltaY; - // The id of the last touch explored window. - private int mLastTouchedWindowId; - // Whether touch exploration is in progress. private boolean mTouchExplorationInProgress; @@ -368,11 +365,6 @@ class TouchExplorer implements EventStreamTransformation { mInjectedPointerTracker.mLastInjectedHoverEventForClick.recycle(); mInjectedPointerTracker.mLastInjectedHoverEventForClick = null; } - mLastTouchedWindowId = -1; - } break; - case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: - case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: { - mLastTouchedWindowId = event.getWindowId(); } break; } if (mNext != null) { @@ -1151,42 +1143,12 @@ class TouchExplorer implements EventStreamTransformation { mSendTouchInteractionEndDelayed.forceSendAndRemove(); } - int clickLocationX; - int clickLocationY; - final int pointerId = secondTapUp.getPointerId(secondTapUp.getActionIndex()); final int pointerIndex = secondTapUp.findPointerIndex(pointerId); - MotionEvent lastExploreEvent = - mInjectedPointerTracker.getLastInjectedHoverEventForClick(); - if (lastExploreEvent == null) { - // No last touch explored event but there is accessibility focus in - // the active window. We click in the focus bounds. - Point point = mTempPoint; - if (mAms.getAccessibilityFocusClickPointInScreen(point)) { - clickLocationX = point.x; - clickLocationY = point.y; - } else { - // Out of luck - do nothing. - return; - } - } else { - // If the click is within the active window but not within the - // accessibility focus bounds we click in the focus bounds. - final int lastExplorePointerIndex = lastExploreEvent.getActionIndex(); - clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex); - clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex); - Rect activeWindowBounds = mTempRect; - if (mLastTouchedWindowId == mAms.getActiveWindowId()) { - mAms.getActiveWindowBounds(activeWindowBounds); - if (activeWindowBounds.contains(clickLocationX, clickLocationY)) { - Point point = mTempPoint; - if (mAms.getAccessibilityFocusClickPointInScreen(point)) { - clickLocationX = point.x; - clickLocationY = point.y; - } - } - } + Point clickLocation = mTempPoint; + if (!computeClickLocation(clickLocation)) { + return; } // Do the click. @@ -1195,8 +1157,8 @@ class TouchExplorer implements EventStreamTransformation { secondTapUp.getPointerProperties(pointerIndex, properties[0]); PointerCoords[] coords = new PointerCoords[1]; coords[0] = new PointerCoords(); - coords[0].x = clickLocationX; - coords[0].y = clickLocationY; + coords[0].x = clickLocation.x; + coords[0].y = clickLocation.y; MotionEvent event = MotionEvent.obtain(secondTapUp.getDownTime(), secondTapUp.getEventTime(), MotionEvent.ACTION_DOWN, 1, properties, coords, 0, 0, 1.0f, 1.0f, secondTapUp.getDeviceId(), 0, @@ -1322,47 +1284,18 @@ class TouchExplorer implements EventStreamTransformation { return; } - int clickLocationX; - int clickLocationY; - final int pointerId = mEvent.getPointerId(mEvent.getActionIndex()); final int pointerIndex = mEvent.findPointerIndex(pointerId); - MotionEvent lastExploreEvent = - mInjectedPointerTracker.getLastInjectedHoverEventForClick(); - if (lastExploreEvent == null) { - // No last touch explored event but there is accessibility focus in - // the active window. We click in the focus bounds. - Point point = mTempPoint; - if (mAms.getAccessibilityFocusClickPointInScreen(point)) { - clickLocationX = point.x; - clickLocationY = point.y; - } else { - // Out of luck - do nothing. - return; - } - } else { - // If the click is within the active window but not within the - // accessibility focus bounds we click in the focus bounds. - final int lastExplorePointerIndex = lastExploreEvent.getActionIndex(); - clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex); - clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex); - Rect activeWindowBounds = mTempRect; - if (mLastTouchedWindowId == mAms.getActiveWindowId()) { - mAms.getActiveWindowBounds(activeWindowBounds); - if (activeWindowBounds.contains(clickLocationX, clickLocationY)) { - Point point = mTempPoint; - if (mAms.getAccessibilityFocusClickPointInScreen(point)) { - clickLocationX = point.x; - clickLocationY = point.y; - } - } - } + + Point clickLocation = mTempPoint; + if (!computeClickLocation(clickLocation)) { + return; } mLongPressingPointerId = pointerId; - mLongPressingPointerDeltaX = (int) mEvent.getX(pointerIndex) - clickLocationX; - mLongPressingPointerDeltaY = (int) mEvent.getY(pointerIndex) - clickLocationY; + mLongPressingPointerDeltaX = (int) mEvent.getX(pointerIndex) - clickLocation.x; + mLongPressingPointerDeltaY = (int) mEvent.getY(pointerIndex) - clickLocation.y; sendHoverExitAndTouchExplorationGestureEndIfNeeded(mPolicyFlags); @@ -1378,6 +1311,27 @@ class TouchExplorer implements EventStreamTransformation { } } + private boolean computeClickLocation(Point outPoint) { + // Try to click on the accessiblity focused view and if that + // fails try the last touch explored location, if such. + Point point = mTempPoint; + if (mAms.getAccessibilityFocusClickPointInScreen(point)) { + outPoint.x = point.x; + outPoint.y = point.y; + return true; + } else { + MotionEvent lastExploreEvent = + mInjectedPointerTracker.getLastInjectedHoverEventForClick(); + if (lastExploreEvent != null) { + final int lastExplorePointerIndex = lastExploreEvent.getActionIndex(); + outPoint.x = (int) lastExploreEvent.getX(lastExplorePointerIndex); + outPoint.y = (int) lastExploreEvent.getY(lastExplorePointerIndex); + return true; + } + } + return false; + } + /** * Class for delayed sending of hover enter and move events. */