@@ -205,6 +205,9 @@ class TouchExplorer implements EventStreamTransformation {
205205 // The long pressing pointer Y if coordinate remapping is needed.
206206 private int mLongPressingPointerDeltaY ;
207207
208+ // The id of the last touch explored window.
209+ private int mLastTouchedWindowId ;
210+
208211 // Whether touch exploration is in progress.
209212 private boolean mTouchExplorationInProgress ;
210213
@@ -365,6 +368,11 @@ public void onAccessibilityEvent(AccessibilityEvent event) {
365368 mInjectedPointerTracker .mLastInjectedHoverEventForClick .recycle ();
366369 mInjectedPointerTracker .mLastInjectedHoverEventForClick = null ;
367370 }
371+ mLastTouchedWindowId = -1 ;
372+ } break ;
373+ case AccessibilityEvent .TYPE_VIEW_HOVER_ENTER :
374+ case AccessibilityEvent .TYPE_VIEW_HOVER_EXIT : {
375+ mLastTouchedWindowId = event .getWindowId ();
368376 } break ;
369377 }
370378 if (mNext != null ) {
@@ -1143,12 +1151,42 @@ public void onDoubleTap(MotionEvent secondTapUp, int policyFlags) {
11431151 mSendTouchInteractionEndDelayed .forceSendAndRemove ();
11441152 }
11451153
1154+ int clickLocationX ;
1155+ int clickLocationY ;
1156+
11461157 final int pointerId = secondTapUp .getPointerId (secondTapUp .getActionIndex ());
11471158 final int pointerIndex = secondTapUp .findPointerIndex (pointerId );
11481159
1149- Point clickLocation = mTempPoint ;
1150- if (!computeClickLocation (clickLocation )) {
1151- return ;
1160+ MotionEvent lastExploreEvent =
1161+ mInjectedPointerTracker .getLastInjectedHoverEventForClick ();
1162+ if (lastExploreEvent == null ) {
1163+ // No last touch explored event but there is accessibility focus in
1164+ // the active window. We click in the focus bounds.
1165+ Point point = mTempPoint ;
1166+ if (mAms .getAccessibilityFocusClickPointInScreen (point )) {
1167+ clickLocationX = point .x ;
1168+ clickLocationY = point .y ;
1169+ } else {
1170+ // Out of luck - do nothing.
1171+ return ;
1172+ }
1173+ } else {
1174+ // If the click is within the active window but not within the
1175+ // accessibility focus bounds we click in the focus bounds.
1176+ final int lastExplorePointerIndex = lastExploreEvent .getActionIndex ();
1177+ clickLocationX = (int ) lastExploreEvent .getX (lastExplorePointerIndex );
1178+ clickLocationY = (int ) lastExploreEvent .getY (lastExplorePointerIndex );
1179+ Rect activeWindowBounds = mTempRect ;
1180+ if (mLastTouchedWindowId == mAms .getActiveWindowId ()) {
1181+ mAms .getActiveWindowBounds (activeWindowBounds );
1182+ if (activeWindowBounds .contains (clickLocationX , clickLocationY )) {
1183+ Point point = mTempPoint ;
1184+ if (mAms .getAccessibilityFocusClickPointInScreen (point )) {
1185+ clickLocationX = point .x ;
1186+ clickLocationY = point .y ;
1187+ }
1188+ }
1189+ }
11521190 }
11531191
11541192 // Do the click.
@@ -1157,8 +1195,8 @@ public void onDoubleTap(MotionEvent secondTapUp, int policyFlags) {
11571195 secondTapUp .getPointerProperties (pointerIndex , properties [0 ]);
11581196 PointerCoords [] coords = new PointerCoords [1 ];
11591197 coords [0 ] = new PointerCoords ();
1160- coords [0 ].x = clickLocation . x ;
1161- coords [0 ].y = clickLocation . y ;
1198+ coords [0 ].x = clickLocationX ;
1199+ coords [0 ].y = clickLocationY ;
11621200 MotionEvent event = MotionEvent .obtain (secondTapUp .getDownTime (),
11631201 secondTapUp .getEventTime (), MotionEvent .ACTION_DOWN , 1 , properties ,
11641202 coords , 0 , 0 , 1.0f , 1.0f , secondTapUp .getDeviceId (), 0 ,
@@ -1284,18 +1322,47 @@ public void run() {
12841322 return ;
12851323 }
12861324
1325+ int clickLocationX ;
1326+ int clickLocationY ;
1327+
12871328 final int pointerId = mEvent .getPointerId (mEvent .getActionIndex ());
12881329 final int pointerIndex = mEvent .findPointerIndex (pointerId );
12891330
1290-
1291- Point clickLocation = mTempPoint ;
1292- if (!computeClickLocation (clickLocation )) {
1293- return ;
1331+ MotionEvent lastExploreEvent =
1332+ mInjectedPointerTracker .getLastInjectedHoverEventForClick ();
1333+ if (lastExploreEvent == null ) {
1334+ // No last touch explored event but there is accessibility focus in
1335+ // the active window. We click in the focus bounds.
1336+ Point point = mTempPoint ;
1337+ if (mAms .getAccessibilityFocusClickPointInScreen (point )) {
1338+ clickLocationX = point .x ;
1339+ clickLocationY = point .y ;
1340+ } else {
1341+ // Out of luck - do nothing.
1342+ return ;
1343+ }
1344+ } else {
1345+ // If the click is within the active window but not within the
1346+ // accessibility focus bounds we click in the focus bounds.
1347+ final int lastExplorePointerIndex = lastExploreEvent .getActionIndex ();
1348+ clickLocationX = (int ) lastExploreEvent .getX (lastExplorePointerIndex );
1349+ clickLocationY = (int ) lastExploreEvent .getY (lastExplorePointerIndex );
1350+ Rect activeWindowBounds = mTempRect ;
1351+ if (mLastTouchedWindowId == mAms .getActiveWindowId ()) {
1352+ mAms .getActiveWindowBounds (activeWindowBounds );
1353+ if (activeWindowBounds .contains (clickLocationX , clickLocationY )) {
1354+ Point point = mTempPoint ;
1355+ if (mAms .getAccessibilityFocusClickPointInScreen (point )) {
1356+ clickLocationX = point .x ;
1357+ clickLocationY = point .y ;
1358+ }
1359+ }
1360+ }
12941361 }
12951362
12961363 mLongPressingPointerId = pointerId ;
1297- mLongPressingPointerDeltaX = (int ) mEvent .getX (pointerIndex ) - clickLocation . x ;
1298- mLongPressingPointerDeltaY = (int ) mEvent .getY (pointerIndex ) - clickLocation . y ;
1364+ mLongPressingPointerDeltaX = (int ) mEvent .getX (pointerIndex ) - clickLocationX ;
1365+ mLongPressingPointerDeltaY = (int ) mEvent .getY (pointerIndex ) - clickLocationY ;
12991366
13001367 sendHoverExitAndTouchExplorationGestureEndIfNeeded (mPolicyFlags );
13011368
@@ -1311,27 +1378,6 @@ private void clear() {
13111378 }
13121379 }
13131380
1314- private boolean computeClickLocation (Point outPoint ) {
1315- // Try to click on the accessiblity focused view and if that
1316- // fails try the last touch explored location, if such.
1317- Point point = mTempPoint ;
1318- if (mAms .getAccessibilityFocusClickPointInScreen (point )) {
1319- outPoint .x = point .x ;
1320- outPoint .y = point .y ;
1321- return true ;
1322- } else {
1323- MotionEvent lastExploreEvent =
1324- mInjectedPointerTracker .getLastInjectedHoverEventForClick ();
1325- if (lastExploreEvent != null ) {
1326- final int lastExplorePointerIndex = lastExploreEvent .getActionIndex ();
1327- outPoint .x = (int ) lastExploreEvent .getX (lastExplorePointerIndex );
1328- outPoint .y = (int ) lastExploreEvent .getY (lastExplorePointerIndex );
1329- return true ;
1330- }
1331- }
1332- return false ;
1333- }
1334-
13351381 /**
13361382 * Class for delayed sending of hover enter and move events.
13371383 */
0 commit comments