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

Commit 51ac901b authored by Sally's avatar Sally Committed by Sally Yuen
Browse files

Remove a check for hovered child when dispatching events to TouchDelegates

Bug: If there is a touch delegate on a target's non-direct ancestor,
a hover event may not be dispatched to the target if the hover
event intersects an ancestor's bounds. This manifests as a bug in
Youtube's playlist page, where the target does not get the event sent to their grandparent's delegate.

Investigation: The "pointInHoveredChild" check causing the issue was
introduced in the case of the delegate's bounds covering the hovered
child's bounds completely.

Settings in Android P, a switch bar with a TextView
and Button has a delegate covering its entire area with the button as
the target. Since touching the text should dispatch the hover event to the text, not to the delegate nor button, this check was added so pointInHoveredChild would return true, i.e. the delegate wouldn't dispatch the event.

Since this case no longer exists in Settings, and this is not a common
pattern (covering another view with enlarged bounds) when adding touch delegates, we remove the check and the
corresponding CTS test completely (flagged).But if this manifests again we should re-investigate.

Flag: android.view.accessibility.remove_child_hover_check_for_touch_exploration
Bug: 304770837
Test: atest AccessibilityEndToEndTest with flag on/off, manual check
of youtube

Change-Id: I09fb51d4451a82591afdbdc95a11779baecec9a8
parent 976207c4
Loading
Loading
Loading
Loading
+27 −10
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
import static android.view.accessibility.Flags.removeChildHoverCheckForTouchExploration;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN;
@@ -16905,9 +16906,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * Dispatching hover events to {@link TouchDelegate} to improve accessibility.
     * <p>
     * This method is dispatching hover events to the delegate target to support explore by touch.
     * Similar to {@link ViewGroup#dispatchTouchEvent}, this method send proper hover events to
     * Similar to {@link ViewGroup#dispatchTouchEvent}, this method sends proper hover events to
     * the delegate target according to the pointer and the touch area of the delegate while touch
     * exploration enabled.
     * exploration is enabled.
     * </p>
     *
     * @param event The motion event dispatch to the delegate target.
@@ -16939,12 +16940,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        // hover events but receive accessibility focus, it should also not delegate to these
        // views when hovered.
        if (!oldHoveringTouchDelegate) {
            if (removeChildHoverCheckForTouchExploration()) {
                if ((action == MotionEvent.ACTION_HOVER_ENTER
                        || action == MotionEvent.ACTION_HOVER_MOVE) && pointInDelegateRegion) {
                    mHoveringTouchDelegate = true;
                }
            } else {
                if ((action == MotionEvent.ACTION_HOVER_ENTER
                        || action == MotionEvent.ACTION_HOVER_MOVE)
                        && !pointInHoveredChild(event)
                        && pointInDelegateRegion) {
                    mHoveringTouchDelegate = true;
                }
            }
        } else {
            if (removeChildHoverCheckForTouchExploration()) {
                if (action == MotionEvent.ACTION_HOVER_EXIT
                        || (action == MotionEvent.ACTION_HOVER_MOVE)) {
                    if (!pointInDelegateRegion) {
                        mHoveringTouchDelegate = false;
                    }
                }
            } else {
                if (action == MotionEvent.ACTION_HOVER_EXIT
                        || (action == MotionEvent.ACTION_HOVER_MOVE
@@ -16952,6 +16968,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    mHoveringTouchDelegate = false;
                }
            }
        }
        switch (action) {
            case MotionEvent.ACTION_HOVER_MOVE:
                if (oldHoveringTouchDelegate && mHoveringTouchDelegate) {
+7 −0
Original line number Diff line number Diff line
@@ -93,6 +93,13 @@ flag {
    bug: "277305460"
}

flag {
    namespace: "accessibility"
    name: "remove_child_hover_check_for_touch_exploration"
    description: "Remove a check for a hovered child that prevents touch events from being delegated to non-direct descendants"
    bug: "304770837"
}

flag {
    name: "skip_accessibility_warning_dialog_for_trusted_services"
    namespace: "accessibility"