Loading core/java/android/view/MotionEvent.java +0 −31 Original line number Diff line number Diff line Loading @@ -486,23 +486,6 @@ public final class MotionEvent extends InputEvent implements Parcelable { */ public static final int FLAG_TAINTED = 0x80000000; /** * Private flag indicating that this event was synthesized by the system and * should be delivered to the accessibility focused view first. When being * dispatched such an event is not handled by predecessors of the accessibility * focused view and after the event reaches that view the flag is cleared and * normal event dispatch is performed. This ensures that the platform can click * on any view that has accessibility focus which is semantically equivalent to * asking the view to perform a click accessibility action but more generic as * views not implementing click action correctly can still be activated. * * @hide * @see #isTargetAccessibilityFocus() * @see #setTargetAccessibilityFocus(boolean) */ public static final int FLAG_TARGET_ACCESSIBILITY_FOCUS = 0x40000000; /** * Flag indicating the motion event intersected the top edge of the screen. */ Loading Loading @@ -2120,20 +2103,6 @@ public final class MotionEvent extends InputEvent implements Parcelable { nativeSetFlags(mNativePtr, tainted ? flags | FLAG_TAINTED : flags & ~FLAG_TAINTED); } /** @hide */ public final boolean isTargetAccessibilityFocus() { final int flags = getFlags(); return (flags & FLAG_TARGET_ACCESSIBILITY_FOCUS) != 0; } /** @hide */ public final void setTargetAccessibilityFocus(boolean targetsFocus) { final int flags = getFlags(); nativeSetFlags(mNativePtr, targetsFocus ? flags | FLAG_TARGET_ACCESSIBILITY_FOCUS : flags & ~FLAG_TARGET_ACCESSIBILITY_FOCUS); } /** @hide */ public final boolean isHoverExitPending() { final int flags = getFlags(); Loading core/java/android/view/View.java +0 −9 Original line number Diff line number Diff line Loading @@ -13866,15 +13866,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public boolean dispatchTouchEvent(MotionEvent event) { // If the event should be handled by accessibility focus first. if (event.isTargetAccessibilityFocus()) { // We don't have focus or no virtual descendant has it, do not handle the event. if (!isAccessibilityFocusedViewOrHost()) { return false; } // We have focus and got the event, then use normal event dispatch. event.setTargetAccessibilityFocus(false); } boolean result = false; if (mInputEventConsistencyVerifier != null) { core/java/android/view/ViewGroup.java +0 −68 Original line number Diff line number Diff line Loading @@ -2580,12 +2580,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mInputEventConsistencyVerifier.onTouchEvent(ev, 1); } // If the event targets the accessibility focused view and this is it, start // normal event dispatch. Maybe a descendant is what will handle the click. if (ev.isTargetAccessibilityFocus() && isAccessibilityFocusedViewOrHost()) { ev.setTargetAccessibilityFocus(false); } boolean handled = false; if (onFilterTouchEventForSecurity(ev)) { final int action = ev.getAction(); Loading Loading @@ -2616,13 +2610,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // so this view group continues to intercept touches. intercepted = true; } // If intercepted, start normal event dispatch. Also if there is already // a view that is handling the gesture, do normal event dispatch. if (intercepted || mFirstTouchTarget != null) { ev.setTargetAccessibilityFocus(false); } // Check for cancelation. final boolean canceled = resetCancelNextUpFlag(this) || actionMasked == MotionEvent.ACTION_CANCEL; Loading @@ -2632,15 +2619,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager TouchTarget newTouchTarget = null; boolean alreadyDispatchedToNewTouchTarget = false; if (!canceled && !intercepted) { // If the event is targeting accessibility focus we give it to the // view that has accessibility focus and if it does not handle it // we clear the flag and dispatch the event to all children as usual. // We are looking up the accessibility focused host to avoid keeping // state since these events are very rare. View childWithAccessibilityFocus = ev.isTargetAccessibilityFocus() ? findChildWithAccessibilityFocus() : null; if (actionMasked == MotionEvent.ACTION_DOWN || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN) || actionMasked == MotionEvent.ACTION_HOVER_MOVE) { Loading @@ -2667,22 +2645,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView( preorderedList, children, childIndex); // If there is a view that has accessibility focus we want it // to get the event first and if not handled we will perform a // normal dispatch. We may do a double iteration but this is // safer given the timeframe. if (childWithAccessibilityFocus != null) { if (childWithAccessibilityFocus != child) { continue; } childWithAccessibilityFocus = null; i = childrenCount - 1; } if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { ev.setTargetAccessibilityFocus(false); continue; } Loading Loading @@ -2715,10 +2679,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager alreadyDispatchedToNewTouchTarget = true; break; } // The accessibility focus didn't handle the event, so clear // the flag and do a normal dispatch to all children. ev.setTargetAccessibilityFocus(false); } if (preorderedList != null) preorderedList.clear(); } Loading Loading @@ -2802,34 +2762,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return buildOrderedChildList(); } /** * Finds the child which has accessibility focus. * * @return The child that has focus. */ private View findChildWithAccessibilityFocus() { ViewRootImpl viewRoot = getViewRootImpl(); if (viewRoot == null) { return null; } View current = viewRoot.getAccessibilityFocusedHost(); if (current == null) { return null; } ViewParent parent = current.getParent(); while (parent instanceof View) { if (parent == this) { return current; } current = (View) parent; parent = current.getParent(); } return null; } /** * Resets all touch state in preparation for a new cycle. */ Loading services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +1 −60 Original line number Diff line number Diff line Loading @@ -1021,18 +1021,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return mMotionEventInjector; } /** * Gets a point within the accessibility focused node where we can send down * and up events to perform a click. * * @param outPoint The click point to populate. * @return Whether accessibility a click point was found and set. */ // TODO: (multi-display) Make sure this works for multiple displays. boolean getAccessibilityFocusClickPointInScreen(Point outPoint) { return getInteractionBridge().getAccessibilityFocusClickPointInScreenNotLocked(outPoint); } /** * Perform an accessibility action on the view that currently has accessibility focus. * Has no effect if no item has accessibility focus, if the item with accessibility Loading Loading @@ -1067,12 +1055,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return false; } boolean accessibilityFocusOnlyInActiveWindow() { synchronized (mLock) { return mWindowsForAccessibilityCallback == null; } } int getActiveWindowId() { return mSecurityPolicy.getActiveWindowId(); } Loading Loading @@ -1870,11 +1852,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub for (int i = 0; i < boundServiceCount; i++) { AccessibilityServiceConnection boundService = boundServices.get(i); if (boundService.canRetrieveInteractiveWindowsLocked()) { userState.mAccessibilityFocusOnlyInActiveWindow = false; return; } } userState.mAccessibilityFocusOnlyInActiveWindow = true; } private void updateWindowsForAccessibilityCallbackLocked(UserState userState) { Loading Loading @@ -3081,43 +3061,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return focus.performAction(action.getId()); } public boolean getAccessibilityFocusClickPointInScreenNotLocked(Point outPoint) { AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked(); if (focus == null) { return false; } synchronized (mLock) { Rect boundsInScreen = mTempRect; focus.getBoundsInScreen(boundsInScreen); // Apply magnification if needed. MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId()); if (spec != null && !spec.isNop()) { boundsInScreen.offset((int) -spec.offsetX, (int) -spec.offsetY); boundsInScreen.scale(1 / spec.scale); } // Clip to the window bounds. Rect windowBounds = mTempRect1; getWindowBounds(focus.getWindowId(), windowBounds); if (!boundsInScreen.intersect(windowBounds)) { return false; } // Clip to the screen bounds. Point screenSize = mTempPoint; mDefaultDisplay.getRealSize(screenSize); if (!boundsInScreen.intersect(0, 0, screenSize.x, screenSize.y)) { return false; } outPoint.set(boundsInScreen.centerX(), boundsInScreen.centerY()); } return true; } private AccessibilityNodeInfo getAccessibilityFocusNotLocked() { final int focusedWindowId; synchronized (mLock) { Loading Loading @@ -3578,8 +3521,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // the active window. Look at updateAccessibilityFocusBehaviorLocked // for details. if (oldActiveWindow != mSecurityPolicy.mActiveWindowId && mAccessibilityFocusedWindowId == oldActiveWindow && getCurrentUserStateLocked().mAccessibilityFocusOnlyInActiveWindow) { && mAccessibilityFocusedWindowId == oldActiveWindow) { mMainHandler.sendMessage(obtainMessage( AccessibilityManagerService::clearAccessibilityFocus, AccessibilityManagerService.this, box(oldActiveWindow))); Loading Loading @@ -4010,7 +3952,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub public boolean mIsAutoclickEnabled; public boolean mIsPerformGesturesEnabled; public boolean mIsFilterKeyEventsEnabled; public boolean mAccessibilityFocusOnlyInActiveWindow; public int mUserNonInteractiveUiTimeout; public int mUserInteractiveUiTimeout; Loading services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +7 −123 Original line number Diff line number Diff line Loading @@ -46,8 +46,7 @@ import java.util.List; * <li>3. Two close fingers moving in the same direction perform a drag.</li> * <li>4. Multi-finger gestures are delivered to view hierarchy.</li> * <li>5. Two fingers moving in different directions are considered a multi-finger gesture.</li> * <li>7. Double tapping clicks on the on the last touch explored location if it was in * a window that does not take focus, otherwise the click is within the accessibility * <li>6. Double tapping performs a click action on the accessibility * focused rectangle.</li> * <li>7. Tapping and holding for a while performs a long press in a similar fashion * as the click above.</li> Loading @@ -69,10 +68,6 @@ class TouchExplorer extends BaseEventStreamTransformation private static final int STATE_DELEGATING = 0x00000004; private static final int STATE_GESTURE_DETECTING = 0x00000005; private static final int CLICK_LOCATION_NONE = 0; private static final int CLICK_LOCATION_ACCESSIBILITY_FOCUS = 1; private static final int CLICK_LOCATION_LAST_TOUCH_EXPLORED = 2; // The maximum of the cosine between the vectors of two moving // pointers so they can be considered moving in the same direction. private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4) Loading Loading @@ -156,8 +151,6 @@ class TouchExplorer extends BaseEventStreamTransformation // 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; Loading Loading @@ -335,23 +328,6 @@ class TouchExplorer extends BaseEventStreamTransformation mSendTouchInteractionEndDelayed.cancel(); sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); } // If a new window opens or the accessibility focus moves we no longer // want to click/long press on the last touch explored location. switch (eventType) { case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { if (mInjectedPointerTracker.mLastInjectedHoverEventForClick != null) { 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; } super.onAccessibilityEvent(event); } Loading @@ -366,25 +342,12 @@ class TouchExplorer extends BaseEventStreamTransformation if (mReceivedPointerTracker.getLastReceivedEvent().getPointerCount() == 0) { return; } final int pointerIndex = event.getActionIndex(); final int pointerId = event.getPointerId(pointerIndex); Point clickLocation = mTempPoint; final int result = computeClickLocation(clickLocation); if (result == CLICK_LOCATION_NONE) { return; // Try to use the standard accessibility API to long click if (!mAms.performActionOnAccessibilityFocusedItem( AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK)) { Slog.e(LOG_TAG, "ACTION_LONG_CLICK failed."); } mLongPressingPointerId = pointerId; mLongPressingPointerDeltaX = (int) event.getX(pointerIndex) - clickLocation.x; mLongPressingPointerDeltaY = (int) event.getY(pointerIndex) - clickLocation.y; sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); mCurrentState = STATE_DELEGATING; sendDownForAllNotInjectedPointers(event, policyFlags); } @Override Loading @@ -407,38 +370,10 @@ class TouchExplorer extends BaseEventStreamTransformation sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); // Try to use the standard accessibility API to click if (mAms.performActionOnAccessibilityFocusedItem( if (!mAms.performActionOnAccessibilityFocusedItem( AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK)) { return true; Slog.e(LOG_TAG, "ACTION_CLICK failed."); } Slog.e(LOG_TAG, "ACTION_CLICK failed. Dispatching motion events to simulate click."); final int pointerIndex = event.getActionIndex(); final int pointerId = event.getPointerId(pointerIndex); Point clickLocation = mTempPoint; final int result = computeClickLocation(clickLocation); if (result == CLICK_LOCATION_NONE) { // We can't send a click to no location, but the gesture was still // consumed. return true; } // Do the click. PointerProperties[] properties = new PointerProperties[1]; properties[0] = new PointerProperties(); event.getPointerProperties(pointerIndex, properties[0]); PointerCoords[] coords = new PointerCoords[1]; coords[0] = new PointerCoords(); coords[0].x = clickLocation.x; coords[0].y = clickLocation.y; MotionEvent click_event = MotionEvent.obtain(event.getDownTime(), event.getEventTime(), MotionEvent.ACTION_DOWN, 1, properties, coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(), event.getDisplayId(), event.getFlags()); final boolean targetAccessibilityFocus = (result == CLICK_LOCATION_ACCESSIBILITY_FOCUS); sendActionDownAndUp(click_event, policyFlags, targetAccessibilityFocus); click_event.recycle(); return true; } Loading Loading @@ -923,24 +858,6 @@ class TouchExplorer extends BaseEventStreamTransformation } } /** * Sends an up and down events. * * @param prototype The prototype from which to create the injected events. * @param policyFlags The policy flags associated with the event. * @param targetAccessibilityFocus Whether the event targets the accessibility focus. */ private void sendActionDownAndUp(MotionEvent prototype, int policyFlags, boolean targetAccessibilityFocus) { // Tap with the pointer that last explored. final int pointerId = prototype.getPointerId(prototype.getActionIndex()); final int pointerIdBits = (1 << pointerId); prototype.setTargetAccessibilityFocus(targetAccessibilityFocus); sendMotionEvent(prototype, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); prototype.setTargetAccessibilityFocus(targetAccessibilityFocus); sendMotionEvent(prototype, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); } /** * Sends an event. * Loading Loading @@ -1093,27 +1010,6 @@ class TouchExplorer extends BaseEventStreamTransformation MAX_DRAGGING_ANGLE_COS); } private int computeClickLocation(Point outLocation) { MotionEvent lastExploreEvent = mInjectedPointerTracker.getLastInjectedHoverEventForClick(); if (lastExploreEvent != null) { final int lastExplorePointerIndex = lastExploreEvent.getActionIndex(); outLocation.x = (int) lastExploreEvent.getX(lastExplorePointerIndex); outLocation.y = (int) lastExploreEvent.getY(lastExplorePointerIndex); if (!mAms.accessibilityFocusOnlyInActiveWindow() || mLastTouchedWindowId == mAms.getActiveWindowId()) { if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) { return CLICK_LOCATION_ACCESSIBILITY_FOCUS; } else { return CLICK_LOCATION_LAST_TOUCH_EXPLORED; } } } if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) { return CLICK_LOCATION_ACCESSIBILITY_FOCUS; } return CLICK_LOCATION_NONE; } /** * Gets the symbolic name of a state. * Loading Loading @@ -1341,7 +1237,6 @@ class TouchExplorer extends BaseEventStreamTransformation ", mLongPressingPointerId: " + mLongPressingPointerId + ", mLongPressingPointerDeltaX: " + mLongPressingPointerDeltaX + ", mLongPressingPointerDeltaY: " + mLongPressingPointerDeltaY + ", mLastTouchedWindowId: " + mLastTouchedWindowId + ", mScaledMinPointerDistanceToUseMiddleLocation: " + mScaledMinPointerDistanceToUseMiddleLocation + ", mTempPoint: " + mTempPoint + Loading @@ -1361,9 +1256,6 @@ class TouchExplorer extends BaseEventStreamTransformation // The last injected hover event. private MotionEvent mLastInjectedHoverEvent; // The last injected hover event used for performing clicks. private MotionEvent mLastInjectedHoverEventForClick; /** * Processes an injected {@link MotionEvent} event. * Loading Loading @@ -1395,10 +1287,6 @@ class TouchExplorer extends BaseEventStreamTransformation mLastInjectedHoverEvent.recycle(); } mLastInjectedHoverEvent = MotionEvent.obtain(event); if (mLastInjectedHoverEventForClick != null) { mLastInjectedHoverEventForClick.recycle(); } mLastInjectedHoverEventForClick = MotionEvent.obtain(event); } break; } if (DEBUG) { Loading Loading @@ -1455,10 +1343,6 @@ class TouchExplorer extends BaseEventStreamTransformation /** * @return The the last injected hover event. */ public MotionEvent getLastInjectedHoverEventForClick() { return mLastInjectedHoverEventForClick; } @Override public String toString() { StringBuilder builder = new StringBuilder(); Loading Loading
core/java/android/view/MotionEvent.java +0 −31 Original line number Diff line number Diff line Loading @@ -486,23 +486,6 @@ public final class MotionEvent extends InputEvent implements Parcelable { */ public static final int FLAG_TAINTED = 0x80000000; /** * Private flag indicating that this event was synthesized by the system and * should be delivered to the accessibility focused view first. When being * dispatched such an event is not handled by predecessors of the accessibility * focused view and after the event reaches that view the flag is cleared and * normal event dispatch is performed. This ensures that the platform can click * on any view that has accessibility focus which is semantically equivalent to * asking the view to perform a click accessibility action but more generic as * views not implementing click action correctly can still be activated. * * @hide * @see #isTargetAccessibilityFocus() * @see #setTargetAccessibilityFocus(boolean) */ public static final int FLAG_TARGET_ACCESSIBILITY_FOCUS = 0x40000000; /** * Flag indicating the motion event intersected the top edge of the screen. */ Loading Loading @@ -2120,20 +2103,6 @@ public final class MotionEvent extends InputEvent implements Parcelable { nativeSetFlags(mNativePtr, tainted ? flags | FLAG_TAINTED : flags & ~FLAG_TAINTED); } /** @hide */ public final boolean isTargetAccessibilityFocus() { final int flags = getFlags(); return (flags & FLAG_TARGET_ACCESSIBILITY_FOCUS) != 0; } /** @hide */ public final void setTargetAccessibilityFocus(boolean targetsFocus) { final int flags = getFlags(); nativeSetFlags(mNativePtr, targetsFocus ? flags | FLAG_TARGET_ACCESSIBILITY_FOCUS : flags & ~FLAG_TARGET_ACCESSIBILITY_FOCUS); } /** @hide */ public final boolean isHoverExitPending() { final int flags = getFlags(); Loading
core/java/android/view/View.java +0 −9 Original line number Diff line number Diff line Loading @@ -13866,15 +13866,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public boolean dispatchTouchEvent(MotionEvent event) { // If the event should be handled by accessibility focus first. if (event.isTargetAccessibilityFocus()) { // We don't have focus or no virtual descendant has it, do not handle the event. if (!isAccessibilityFocusedViewOrHost()) { return false; } // We have focus and got the event, then use normal event dispatch. event.setTargetAccessibilityFocus(false); } boolean result = false; if (mInputEventConsistencyVerifier != null) {
core/java/android/view/ViewGroup.java +0 −68 Original line number Diff line number Diff line Loading @@ -2580,12 +2580,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mInputEventConsistencyVerifier.onTouchEvent(ev, 1); } // If the event targets the accessibility focused view and this is it, start // normal event dispatch. Maybe a descendant is what will handle the click. if (ev.isTargetAccessibilityFocus() && isAccessibilityFocusedViewOrHost()) { ev.setTargetAccessibilityFocus(false); } boolean handled = false; if (onFilterTouchEventForSecurity(ev)) { final int action = ev.getAction(); Loading Loading @@ -2616,13 +2610,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // so this view group continues to intercept touches. intercepted = true; } // If intercepted, start normal event dispatch. Also if there is already // a view that is handling the gesture, do normal event dispatch. if (intercepted || mFirstTouchTarget != null) { ev.setTargetAccessibilityFocus(false); } // Check for cancelation. final boolean canceled = resetCancelNextUpFlag(this) || actionMasked == MotionEvent.ACTION_CANCEL; Loading @@ -2632,15 +2619,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager TouchTarget newTouchTarget = null; boolean alreadyDispatchedToNewTouchTarget = false; if (!canceled && !intercepted) { // If the event is targeting accessibility focus we give it to the // view that has accessibility focus and if it does not handle it // we clear the flag and dispatch the event to all children as usual. // We are looking up the accessibility focused host to avoid keeping // state since these events are very rare. View childWithAccessibilityFocus = ev.isTargetAccessibilityFocus() ? findChildWithAccessibilityFocus() : null; if (actionMasked == MotionEvent.ACTION_DOWN || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN) || actionMasked == MotionEvent.ACTION_HOVER_MOVE) { Loading @@ -2667,22 +2645,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView( preorderedList, children, childIndex); // If there is a view that has accessibility focus we want it // to get the event first and if not handled we will perform a // normal dispatch. We may do a double iteration but this is // safer given the timeframe. if (childWithAccessibilityFocus != null) { if (childWithAccessibilityFocus != child) { continue; } childWithAccessibilityFocus = null; i = childrenCount - 1; } if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { ev.setTargetAccessibilityFocus(false); continue; } Loading Loading @@ -2715,10 +2679,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager alreadyDispatchedToNewTouchTarget = true; break; } // The accessibility focus didn't handle the event, so clear // the flag and do a normal dispatch to all children. ev.setTargetAccessibilityFocus(false); } if (preorderedList != null) preorderedList.clear(); } Loading Loading @@ -2802,34 +2762,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return buildOrderedChildList(); } /** * Finds the child which has accessibility focus. * * @return The child that has focus. */ private View findChildWithAccessibilityFocus() { ViewRootImpl viewRoot = getViewRootImpl(); if (viewRoot == null) { return null; } View current = viewRoot.getAccessibilityFocusedHost(); if (current == null) { return null; } ViewParent parent = current.getParent(); while (parent instanceof View) { if (parent == this) { return current; } current = (View) parent; parent = current.getParent(); } return null; } /** * Resets all touch state in preparation for a new cycle. */ Loading
services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +1 −60 Original line number Diff line number Diff line Loading @@ -1021,18 +1021,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return mMotionEventInjector; } /** * Gets a point within the accessibility focused node where we can send down * and up events to perform a click. * * @param outPoint The click point to populate. * @return Whether accessibility a click point was found and set. */ // TODO: (multi-display) Make sure this works for multiple displays. boolean getAccessibilityFocusClickPointInScreen(Point outPoint) { return getInteractionBridge().getAccessibilityFocusClickPointInScreenNotLocked(outPoint); } /** * Perform an accessibility action on the view that currently has accessibility focus. * Has no effect if no item has accessibility focus, if the item with accessibility Loading Loading @@ -1067,12 +1055,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return false; } boolean accessibilityFocusOnlyInActiveWindow() { synchronized (mLock) { return mWindowsForAccessibilityCallback == null; } } int getActiveWindowId() { return mSecurityPolicy.getActiveWindowId(); } Loading Loading @@ -1870,11 +1852,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub for (int i = 0; i < boundServiceCount; i++) { AccessibilityServiceConnection boundService = boundServices.get(i); if (boundService.canRetrieveInteractiveWindowsLocked()) { userState.mAccessibilityFocusOnlyInActiveWindow = false; return; } } userState.mAccessibilityFocusOnlyInActiveWindow = true; } private void updateWindowsForAccessibilityCallbackLocked(UserState userState) { Loading Loading @@ -3081,43 +3061,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return focus.performAction(action.getId()); } public boolean getAccessibilityFocusClickPointInScreenNotLocked(Point outPoint) { AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked(); if (focus == null) { return false; } synchronized (mLock) { Rect boundsInScreen = mTempRect; focus.getBoundsInScreen(boundsInScreen); // Apply magnification if needed. MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId()); if (spec != null && !spec.isNop()) { boundsInScreen.offset((int) -spec.offsetX, (int) -spec.offsetY); boundsInScreen.scale(1 / spec.scale); } // Clip to the window bounds. Rect windowBounds = mTempRect1; getWindowBounds(focus.getWindowId(), windowBounds); if (!boundsInScreen.intersect(windowBounds)) { return false; } // Clip to the screen bounds. Point screenSize = mTempPoint; mDefaultDisplay.getRealSize(screenSize); if (!boundsInScreen.intersect(0, 0, screenSize.x, screenSize.y)) { return false; } outPoint.set(boundsInScreen.centerX(), boundsInScreen.centerY()); } return true; } private AccessibilityNodeInfo getAccessibilityFocusNotLocked() { final int focusedWindowId; synchronized (mLock) { Loading Loading @@ -3578,8 +3521,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub // the active window. Look at updateAccessibilityFocusBehaviorLocked // for details. if (oldActiveWindow != mSecurityPolicy.mActiveWindowId && mAccessibilityFocusedWindowId == oldActiveWindow && getCurrentUserStateLocked().mAccessibilityFocusOnlyInActiveWindow) { && mAccessibilityFocusedWindowId == oldActiveWindow) { mMainHandler.sendMessage(obtainMessage( AccessibilityManagerService::clearAccessibilityFocus, AccessibilityManagerService.this, box(oldActiveWindow))); Loading Loading @@ -4010,7 +3952,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub public boolean mIsAutoclickEnabled; public boolean mIsPerformGesturesEnabled; public boolean mIsFilterKeyEventsEnabled; public boolean mAccessibilityFocusOnlyInActiveWindow; public int mUserNonInteractiveUiTimeout; public int mUserInteractiveUiTimeout; Loading
services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +7 −123 Original line number Diff line number Diff line Loading @@ -46,8 +46,7 @@ import java.util.List; * <li>3. Two close fingers moving in the same direction perform a drag.</li> * <li>4. Multi-finger gestures are delivered to view hierarchy.</li> * <li>5. Two fingers moving in different directions are considered a multi-finger gesture.</li> * <li>7. Double tapping clicks on the on the last touch explored location if it was in * a window that does not take focus, otherwise the click is within the accessibility * <li>6. Double tapping performs a click action on the accessibility * focused rectangle.</li> * <li>7. Tapping and holding for a while performs a long press in a similar fashion * as the click above.</li> Loading @@ -69,10 +68,6 @@ class TouchExplorer extends BaseEventStreamTransformation private static final int STATE_DELEGATING = 0x00000004; private static final int STATE_GESTURE_DETECTING = 0x00000005; private static final int CLICK_LOCATION_NONE = 0; private static final int CLICK_LOCATION_ACCESSIBILITY_FOCUS = 1; private static final int CLICK_LOCATION_LAST_TOUCH_EXPLORED = 2; // The maximum of the cosine between the vectors of two moving // pointers so they can be considered moving in the same direction. private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4) Loading Loading @@ -156,8 +151,6 @@ class TouchExplorer extends BaseEventStreamTransformation // 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; Loading Loading @@ -335,23 +328,6 @@ class TouchExplorer extends BaseEventStreamTransformation mSendTouchInteractionEndDelayed.cancel(); sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); } // If a new window opens or the accessibility focus moves we no longer // want to click/long press on the last touch explored location. switch (eventType) { case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: { if (mInjectedPointerTracker.mLastInjectedHoverEventForClick != null) { 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; } super.onAccessibilityEvent(event); } Loading @@ -366,25 +342,12 @@ class TouchExplorer extends BaseEventStreamTransformation if (mReceivedPointerTracker.getLastReceivedEvent().getPointerCount() == 0) { return; } final int pointerIndex = event.getActionIndex(); final int pointerId = event.getPointerId(pointerIndex); Point clickLocation = mTempPoint; final int result = computeClickLocation(clickLocation); if (result == CLICK_LOCATION_NONE) { return; // Try to use the standard accessibility API to long click if (!mAms.performActionOnAccessibilityFocusedItem( AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK)) { Slog.e(LOG_TAG, "ACTION_LONG_CLICK failed."); } mLongPressingPointerId = pointerId; mLongPressingPointerDeltaX = (int) event.getX(pointerIndex) - clickLocation.x; mLongPressingPointerDeltaY = (int) event.getY(pointerIndex) - clickLocation.y; sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags); mCurrentState = STATE_DELEGATING; sendDownForAllNotInjectedPointers(event, policyFlags); } @Override Loading @@ -407,38 +370,10 @@ class TouchExplorer extends BaseEventStreamTransformation sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END); // Try to use the standard accessibility API to click if (mAms.performActionOnAccessibilityFocusedItem( if (!mAms.performActionOnAccessibilityFocusedItem( AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK)) { return true; Slog.e(LOG_TAG, "ACTION_CLICK failed."); } Slog.e(LOG_TAG, "ACTION_CLICK failed. Dispatching motion events to simulate click."); final int pointerIndex = event.getActionIndex(); final int pointerId = event.getPointerId(pointerIndex); Point clickLocation = mTempPoint; final int result = computeClickLocation(clickLocation); if (result == CLICK_LOCATION_NONE) { // We can't send a click to no location, but the gesture was still // consumed. return true; } // Do the click. PointerProperties[] properties = new PointerProperties[1]; properties[0] = new PointerProperties(); event.getPointerProperties(pointerIndex, properties[0]); PointerCoords[] coords = new PointerCoords[1]; coords[0] = new PointerCoords(); coords[0].x = clickLocation.x; coords[0].y = clickLocation.y; MotionEvent click_event = MotionEvent.obtain(event.getDownTime(), event.getEventTime(), MotionEvent.ACTION_DOWN, 1, properties, coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(), event.getDisplayId(), event.getFlags()); final boolean targetAccessibilityFocus = (result == CLICK_LOCATION_ACCESSIBILITY_FOCUS); sendActionDownAndUp(click_event, policyFlags, targetAccessibilityFocus); click_event.recycle(); return true; } Loading Loading @@ -923,24 +858,6 @@ class TouchExplorer extends BaseEventStreamTransformation } } /** * Sends an up and down events. * * @param prototype The prototype from which to create the injected events. * @param policyFlags The policy flags associated with the event. * @param targetAccessibilityFocus Whether the event targets the accessibility focus. */ private void sendActionDownAndUp(MotionEvent prototype, int policyFlags, boolean targetAccessibilityFocus) { // Tap with the pointer that last explored. final int pointerId = prototype.getPointerId(prototype.getActionIndex()); final int pointerIdBits = (1 << pointerId); prototype.setTargetAccessibilityFocus(targetAccessibilityFocus); sendMotionEvent(prototype, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags); prototype.setTargetAccessibilityFocus(targetAccessibilityFocus); sendMotionEvent(prototype, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); } /** * Sends an event. * Loading Loading @@ -1093,27 +1010,6 @@ class TouchExplorer extends BaseEventStreamTransformation MAX_DRAGGING_ANGLE_COS); } private int computeClickLocation(Point outLocation) { MotionEvent lastExploreEvent = mInjectedPointerTracker.getLastInjectedHoverEventForClick(); if (lastExploreEvent != null) { final int lastExplorePointerIndex = lastExploreEvent.getActionIndex(); outLocation.x = (int) lastExploreEvent.getX(lastExplorePointerIndex); outLocation.y = (int) lastExploreEvent.getY(lastExplorePointerIndex); if (!mAms.accessibilityFocusOnlyInActiveWindow() || mLastTouchedWindowId == mAms.getActiveWindowId()) { if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) { return CLICK_LOCATION_ACCESSIBILITY_FOCUS; } else { return CLICK_LOCATION_LAST_TOUCH_EXPLORED; } } } if (mAms.getAccessibilityFocusClickPointInScreen(outLocation)) { return CLICK_LOCATION_ACCESSIBILITY_FOCUS; } return CLICK_LOCATION_NONE; } /** * Gets the symbolic name of a state. * Loading Loading @@ -1341,7 +1237,6 @@ class TouchExplorer extends BaseEventStreamTransformation ", mLongPressingPointerId: " + mLongPressingPointerId + ", mLongPressingPointerDeltaX: " + mLongPressingPointerDeltaX + ", mLongPressingPointerDeltaY: " + mLongPressingPointerDeltaY + ", mLastTouchedWindowId: " + mLastTouchedWindowId + ", mScaledMinPointerDistanceToUseMiddleLocation: " + mScaledMinPointerDistanceToUseMiddleLocation + ", mTempPoint: " + mTempPoint + Loading @@ -1361,9 +1256,6 @@ class TouchExplorer extends BaseEventStreamTransformation // The last injected hover event. private MotionEvent mLastInjectedHoverEvent; // The last injected hover event used for performing clicks. private MotionEvent mLastInjectedHoverEventForClick; /** * Processes an injected {@link MotionEvent} event. * Loading Loading @@ -1395,10 +1287,6 @@ class TouchExplorer extends BaseEventStreamTransformation mLastInjectedHoverEvent.recycle(); } mLastInjectedHoverEvent = MotionEvent.obtain(event); if (mLastInjectedHoverEventForClick != null) { mLastInjectedHoverEventForClick.recycle(); } mLastInjectedHoverEventForClick = MotionEvent.obtain(event); } break; } if (DEBUG) { Loading Loading @@ -1455,10 +1343,6 @@ class TouchExplorer extends BaseEventStreamTransformation /** * @return The the last injected hover event. */ public MotionEvent getLastInjectedHoverEventForClick() { return mLastInjectedHoverEventForClick; } @Override public String toString() { StringBuilder builder = new StringBuilder(); Loading