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

Commit 6fd22923 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou Committed by Android (Google) Code Review
Browse files

Merge "A11yInputFilter: only multiplex pointer events" into main

parents b693882e 0a5dd6e8
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.accessibility;

import static android.view.InputDevice.SOURCE_CLASS_POINTER;
import static android.view.MotionEvent.ACTION_SCROLL;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;

@@ -425,6 +427,12 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo

    boolean shouldProcessMultiDeviceEvent(InputEvent event, int policyFlags) {
        if (event instanceof MotionEvent motion) {
            if (!motion.isFromSource(SOURCE_CLASS_POINTER) || motion.getAction() == ACTION_SCROLL) {
                // Non-pointer events are focus-dispatched and don't require special logic.
                // Scroll events are stand-alone and therefore can be considered to not be part of
                // a stream.
                return true;
            }
            // Only allow 1 device to be sending motion events at a time
            // If the event is from an active device, let it through.
            // If the event is not from an active device, only let it through if it starts a new
@@ -481,7 +489,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
    }

    private void processMotionEvent(EventStreamState state, MotionEvent event, int policyFlags) {
        if (!state.shouldProcessScroll() && event.getActionMasked() == MotionEvent.ACTION_SCROLL) {
        if (!state.shouldProcessScroll() && event.getActionMasked() == ACTION_SCROLL) {
            super.onInputEvent(event, policyFlags);
            return;
        }
+25 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.view.Display.DEFAULT_DISPLAY
import android.view.DisplayAdjustments
import android.view.DisplayInfo
import android.view.IInputFilterHost
import android.view.InputDevice.SOURCE_JOYSTICK
import android.view.InputDevice.SOURCE_STYLUS
import android.view.InputDevice.SOURCE_TOUCHSCREEN
import android.view.InputEvent
@@ -130,6 +131,8 @@ class AccessibilityInputFilterInputTest {
    private val fromTouchScreen = allOf(withDeviceId(touchDeviceId), withSource(SOURCE_TOUCHSCREEN))
    private val stylusDeviceId = 2
    private val fromStylus = allOf(withDeviceId(stylusDeviceId), withSource(STYLUS_SOURCE))
    private val joystickDeviceId = 3
    private val fromJoystick = allOf(withDeviceId(joystickDeviceId), withSource(SOURCE_JOYSTICK))

    @Before
    fun setUp() {
@@ -457,6 +460,23 @@ class AccessibilityInputFilterInputTest {
        verifier.assertNoEvents()
    }

    /**
     * Send some joystick events and ensure they pass through normally.
     */
    @Test
    fun testJoystickEvents() {
        enableFeatures(ALL_A11Y_FEATURES)

        sendJoystickEvent()
        verifier.assertReceivedMotion(fromJoystick)

        sendJoystickEvent()
        verifier.assertReceivedMotion(fromJoystick)

        sendJoystickEvent()
        verifier.assertReceivedMotion(fromJoystick)
    }

    private fun createStubDisplay(displayId: Int, displayInfo: DisplayInfo): Display {
        val display = Display(DisplayManagerGlobal.getInstance(), displayId,
            displayInfo, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS)
@@ -477,6 +497,11 @@ class AccessibilityInputFilterInputTest {
        send(createMotionEvent(action, downTime, eventTime, STYLUS_SOURCE, stylusDeviceId))
    }

    private fun sendJoystickEvent() {
        val time = SystemClock.uptimeMillis()
        send(createMotionEvent(ACTION_MOVE, time, time, SOURCE_JOYSTICK, joystickDeviceId))
    }

    private fun send(event: InputEvent) {
        // We need to make a copy of the event before sending it to the filter, because the filter
        // will recycle it, but the caller of this function might want to still be able to use