Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c62c684 authored by Ameer Armaly's avatar Ameer Armaly Committed by Automerger Merge Worker
Browse files

[DO NOT MERGE] Bring back touch events for double tap and double tap and hold....

[DO NOT MERGE] Bring back touch events for double tap and double tap and hold. am: 9e83d078 am: 887073e8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11955493

Change-Id: Ifd849218693ba395b66adc923e786ceaa711235a
parents 1a50efa2 887073e8
Loading
Loading
Loading
Loading
+29 −0
Original line number Original line Diff line number Diff line
@@ -486,6 +486,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
     */
     */
    public static final int FLAG_TAINTED = 0x80000000;
    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.
     * Flag indicating the motion event intersected the top edge of the screen.
     */
     */
@@ -2139,6 +2154,20 @@ public final class MotionEvent extends InputEvent implements Parcelable {
        nativeSetFlags(mNativePtr, tainted ? flags | FLAG_TAINTED : flags & ~FLAG_TAINTED);
        nativeSetFlags(mNativePtr, tainted ? flags | FLAG_TAINTED : flags & ~FLAG_TAINTED);
    }
    }


    /** @hide */
    public  boolean isTargetAccessibilityFocus() {
        final int flags = getFlags();
        return (flags & FLAG_TARGET_ACCESSIBILITY_FOCUS) != 0;
    }

    /** @hide */
    public void setTargetAccessibilityFocus(boolean targetsFocus) {
        final int flags = getFlags();
        nativeSetFlags(mNativePtr, targetsFocus
                ? flags | FLAG_TARGET_ACCESSIBILITY_FOCUS
                : flags & ~FLAG_TARGET_ACCESSIBILITY_FOCUS);
    }

    /** @hide */
    /** @hide */
    public final boolean isHoverExitPending() {
    public final boolean isHoverExitPending() {
        final int flags = getFlags();
        final int flags = getFlags();
+8 −0
Original line number Original line Diff line number Diff line
@@ -14274,6 +14274,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
     */
    public boolean dispatchTouchEvent(MotionEvent event) {
    public boolean dispatchTouchEvent(MotionEvent event) {
        // If the event should be handled by accessibility focus first.
        // 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;
        boolean result = false;
        if (mInputEventConsistencyVerifier != null) {
        if (mInputEventConsistencyVerifier != null) {
+77 −4
Original line number Original line Diff line number Diff line
@@ -2048,8 +2048,26 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            for (int i = childrenCount - 1; i >= 0; i--) {
            for (int i = childrenCount - 1; i >= 0; i--) {
                final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
                final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
                final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
                final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
                View childWithAccessibilityFocus =
                        event.isTargetAccessibilityFocus()
                                ? findChildWithAccessibilityFocus()
                                : null;

                if (!child.canReceivePointerEvents()
                if (!child.canReceivePointerEvents()
                        || !isTransformedTouchPointInView(x, y, child, null)) {
                        || !isTransformedTouchPointInView(x, y, child, null)) {

                    // 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;
                    }
                    event.setTargetAccessibilityFocus(false);
                    continue;
                    continue;
                }
                }
                final PointerIcon pointerIcon =
                final PointerIcon pointerIcon =
@@ -2617,6 +2635,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
            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;
        boolean handled = false;
        if (onFilterTouchEventForSecurity(ev)) {
        if (onFilterTouchEventForSecurity(ev)) {
            final int action = ev.getAction();
            final int action = ev.getAction();
@@ -2647,6 +2671,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                // so this view group continues to intercept touches.
                // so this view group continues to intercept touches.
                intercepted = true;
                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.
            // Check for cancelation.
            final boolean canceled = resetCancelNextUpFlag(this)
            final boolean canceled = resetCancelNextUpFlag(this)
                    || actionMasked == MotionEvent.ACTION_CANCEL;
                    || actionMasked == MotionEvent.ACTION_CANCEL;
@@ -2658,6 +2689,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            TouchTarget newTouchTarget = null;
            TouchTarget newTouchTarget = null;
            boolean alreadyDispatchedToNewTouchTarget = false;
            boolean alreadyDispatchedToNewTouchTarget = false;
            if (!canceled && !intercepted) {
            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
                if (actionMasked == MotionEvent.ACTION_DOWN
                        || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
                        || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
                        || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
                        || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
@@ -2720,6 +2759,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                                alreadyDispatchedToNewTouchTarget = true;
                                alreadyDispatchedToNewTouchTarget = true;
                                break;
                                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();
                        if (preorderedList != null) preorderedList.clear();
                    }
                    }
@@ -2803,6 +2846,34 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        return buildOrderedChildList();
        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.
     * Resets all touch state in preparation for a new cycle.
     */
     */
@@ -3257,9 +3328,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                break;
                break;
            }
            }
            default:
            default:
                throw new IllegalStateException("descendant focusability must be "
                throw new IllegalStateException(
                        + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS "
                        "descendant focusability must be one of FOCUS_BEFORE_DESCENDANTS,"
                        + "but is " + descendantFocusability);
                            + " FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS but is "
                                + descendantFocusability);
        }
        }
        if (result && !isLayoutValid() && ((mPrivateFlags & PFLAG_WANTS_FOCUS) == 0)) {
        if (result && !isLayoutValid() && ((mPrivateFlags & PFLAG_WANTS_FOCUS) == 0)) {
            mPrivateFlags |= PFLAG_WANTS_FOCUS;
            mPrivateFlags |= PFLAG_WANTS_FOCUS;
@@ -4925,7 +4997,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        if (params == null) {
        if (params == null) {
            params = generateDefaultLayoutParams();
            params = generateDefaultLayoutParams();
            if (params == null) {
            if (params == null) {
                throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
                throw new IllegalArgumentException(
                        "generateDefaultLayoutParams() cannot return null");
            }
            }
        }
        }
        addView(child, index, params);
        addView(child, index, params);
+96 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,8 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
import android.database.ContentObserver;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.IFingerprintService;
import android.hardware.fingerprint.IFingerprintService;
@@ -190,6 +192,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
    private final SimpleStringSplitter mStringColonSplitter =
    private final SimpleStringSplitter mStringColonSplitter =
            new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
            new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);


    private final Rect mTempRect = new Rect();
    private final Rect mTempRect1 = new Rect();

    private final PackageManager mPackageManager;
    private final PackageManager mPackageManager;


    private final PowerManager mPowerManager;
    private final PowerManager mPowerManager;
@@ -246,6 +251,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
    //TODO: Remove this hack
    //TODO: Remove this hack
    private boolean mInitialized;
    private boolean mInitialized;


    private Point mTempPoint;
    private boolean mIsAccessibilityButtonShown;
    private boolean mIsAccessibilityButtonShown;


    private AccessibilityUserState getCurrentUserStateLocked() {
    private AccessibilityUserState getCurrentUserStateLocked() {
@@ -1067,6 +1073,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        return motionEventInjector;
        return motionEventInjector;
    }
    }


    /**
     * 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.
    public boolean getAccessibilityFocusClickPointInScreen(Point outPoint) {
        return getInteractionBridge().getAccessibilityFocusClickPointInScreenNotLocked(outPoint);
    }

    /**
    /**
     * Perform an accessibility action on the view that currently has accessibility focus.
     * 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
     * Has no effect if no item has accessibility focus, if the item with accessibility
@@ -1081,6 +1099,32 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        return getInteractionBridge().performActionOnAccessibilityFocusedItemNotLocked(action);
        return getInteractionBridge().performActionOnAccessibilityFocusedItemNotLocked(action);
    }
    }


    /**
     * Returns true if accessibility focus is confined to the active window.
     */
    public boolean accessibilityFocusOnlyInActiveWindow() {
        synchronized (mLock) {
            return mA11yWindowManager.isTrackingWindowsLocked();
        }
    }

    /**
     * Gets the bounds of a window.
     *
     * @param outBounds The output to which to write the bounds.
     */
    boolean getWindowBounds(int windowId, Rect outBounds) {
        IBinder token;
        synchronized (mLock) {
            token = getWindowToken(windowId, mCurrentUserId);
        }
        mWindowManagerService.getWindowFrame(token, outBounds);
        if (!outBounds.isEmpty()) {
            return true;
        }
        return false;
    }

    public int getActiveWindowId() {
    public int getActiveWindowId() {
        return mA11yWindowManager.getActiveWindowId(mCurrentUserId);
        return mA11yWindowManager.getActiveWindowId(mCurrentUserId);
    }
    }
@@ -1824,9 +1868,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
        for (int i = 0; !observingWindows && (i < boundServiceCount); i++) {
        for (int i = 0; !observingWindows && (i < boundServiceCount); i++) {
            AccessibilityServiceConnection boundService = boundServices.get(i);
            AccessibilityServiceConnection boundService = boundServices.get(i);
            if (boundService.canRetrieveInteractiveWindowsLocked()) {
            if (boundService.canRetrieveInteractiveWindowsLocked()) {
                userState.setAccessibilityFocusOnlyInActiveWindow(false);
                observingWindows = true;
                observingWindows = true;
            }
            }
        }
        }
        userState.setAccessibilityFocusOnlyInActiveWindow(true);


        // Gets all valid displays and start tracking windows of each display if there is at least
        // Gets all valid displays and start tracking windows of each display if there is at least
        // one bound service that can retrieve window content.
        // one bound service that can retrieve window content.
@@ -2929,6 +2975,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
            mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
        }
        }


        /**
         * 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.
         * 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
         * Has no effect if no item has accessibility focus, if the item with accessibility
@@ -2947,6 +3006,43 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
            return focus.performAction(action.getId());
            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() {
        private AccessibilityNodeInfo getAccessibilityFocusNotLocked() {
            final int focusedWindowId;
            final int focusedWindowId;
            synchronized (mLock) {
            synchronized (mLock) {
+8 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,7 @@ class AccessibilityUserState {
    private boolean mIsDisplayMagnificationEnabled;
    private boolean mIsDisplayMagnificationEnabled;
    private boolean mIsFilterKeyEventsEnabled;
    private boolean mIsFilterKeyEventsEnabled;
    private boolean mIsPerformGesturesEnabled;
    private boolean mIsPerformGesturesEnabled;
    private boolean mAccessibilityFocusOnlyInActiveWindow;
    private boolean mIsTextHighContrastEnabled;
    private boolean mIsTextHighContrastEnabled;
    private boolean mIsTouchExplorationEnabled;
    private boolean mIsTouchExplorationEnabled;
    private boolean mServiceHandlesDoubleTap;
    private boolean mServiceHandlesDoubleTap;
@@ -685,6 +686,13 @@ class AccessibilityUserState {
        mIsPerformGesturesEnabled = enabled;
        mIsPerformGesturesEnabled = enabled;
    }
    }


    public boolean isAccessibilityFocusOnlyInActiveWindow() {
        return mAccessibilityFocusOnlyInActiveWindow;
    }

    public void setAccessibilityFocusOnlyInActiveWindow(boolean enabled) {
        mAccessibilityFocusOnlyInActiveWindow = enabled;
    }
    public ComponentName getServiceChangingSoftKeyboardModeLocked() {
    public ComponentName getServiceChangingSoftKeyboardModeLocked() {
        return mServiceChangingSoftKeyboardMode;
        return mServiceChangingSoftKeyboardMode;
    }
    }
Loading