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

Commit 50d71a20 authored by Nigel Tao's avatar Nigel Tao
Browse files

Treat touchpad taps as mouse taps

This is similar to
https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:recyclerview/recyclerview-selection/src/main/java/androidx/recyclerview/selection/MotionEvents.java;l=34-40;drc=f0fab6de9e079afce5bc7a1d9213f26b4ceb43c1

Bug: 389814214
Test: atest DocumentsUIGoogleTests:com.android.documentsui.dirlist.DragStartListenerTest
Flag: EXEMPT bugfix
Change-Id: Ia693e6e52e4c2213659f6f8ead607658db1f9dd5
parent 11c1b638
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.documentsui.base;

import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;

@@ -24,8 +25,18 @@ import android.view.MotionEvent;
 */
public final class Events {

    public static boolean isMouseEvent(MotionEvent e) {
        return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
    public static boolean isMousyEvent(MotionEvent e) {
        int toolType = e.getToolType(0);
        if (toolType == MotionEvent.TOOL_TYPE_MOUSE) {
            return true;
        } else if (toolType == MotionEvent.TOOL_TYPE_FINGER) {
            // For compatibility reasons, some touchpads (but not on ChromeOS
            // ARC devices) fire SOURCE_MOUSE and TOOL_TYPE_FINGER events even
            // though the source should be SOURCE_TOUCHPAD and the tool type
            // could arguably be TOOL_TYPE_MOUSE.
            return e.getSource() == InputDevice.SOURCE_MOUSE;
        }
        return false;
    }

    public static boolean isActionDown(MotionEvent e) {
+3 −2
Original line number Diff line number Diff line
@@ -17,9 +17,10 @@ package com.android.documentsui.dirlist;

import static androidx.core.util.Preconditions.checkState;

import android.view.MotionEvent;

import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
import android.view.MotionEvent;

import com.android.documentsui.base.BooleanConsumer;
import com.android.documentsui.base.Events;
@@ -38,7 +39,7 @@ final class RefreshHelper {
    }

    private boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        if (Events.isMouseEvent(e)) {
        if (Events.isMousyEvent(e)) {
            if (Events.isActionDown(e)) {
                mRefreshLayoutEnabler.accept(false);
            }
+1 −1
Original line number Diff line number Diff line
@@ -243,7 +243,7 @@ public class RootsFragment extends Fragment {
                new OnGenericMotionListener() {
                    @Override
                    public boolean onGenericMotion(View v, MotionEvent event) {
                        if (Events.isMouseEvent(event)
                        if (Events.isMousyEvent(event)
                                && event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
                            int x = (int) event.getX();
                            int y = (int) event.getY();
+35 −6
Original line number Diff line number Diff line
@@ -16,13 +16,15 @@

package com.android.documentsui.testing;

import androidx.annotation.IntDef;
import android.graphics.Point;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;

import androidx.annotation.IntDef;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashSet;
@@ -62,7 +64,7 @@ public final class TestEvents {
    static final int ACTION_UNSET = -1;

    // Add other actions from MotionEvent.ACTION_ as needed.
    @IntDef(flag = true, value = {
    @IntDef(value = {
            MotionEvent.ACTION_DOWN,
            MotionEvent.ACTION_MOVE,
            MotionEvent.ACTION_UP
@@ -70,8 +72,17 @@ public final class TestEvents {
    @Retention(RetentionPolicy.SOURCE)
    public @interface Action {}

    // Add other types from InputDevice.SOURCE_ as needed.
    @IntDef(value = {
            InputDevice.SOURCE_MOUSE,
            InputDevice.SOURCE_TOUCHSCREEN,
            InputDevice.SOURCE_UNKNOWN
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Source {}

    // Add other types from MotionEvent.TOOL_TYPE_ as needed.
    @IntDef(flag = true, value = {
    @IntDef(value = {
            MotionEvent.TOOL_TYPE_FINGER,
            MotionEvent.TOOL_TYPE_MOUSE,
            MotionEvent.TOOL_TYPE_STYLUS,
@@ -96,6 +107,7 @@ public final class TestEvents {

    private static final class State {
        private @Action int mAction = ACTION_UNSET;
        private @Source int mSource = InputDevice.SOURCE_UNKNOWN;
        private @ToolType int mToolType = MotionEvent.TOOL_TYPE_UNKNOWN;
        private int mPointerCount = 1;
        private Set<Integer> mButtons = new HashSet<>();
@@ -124,6 +136,11 @@ public final class TestEvents {
            return this;
        }

        public Builder source(@Source int source) {
            mState.mSource = source;
            return this;
        }

        public Builder type(@ToolType int type) {
            mState.mToolType = type;
            return this;
@@ -184,13 +201,25 @@ public final class TestEvents {
            return this;
        }

        public Builder mouse() {
            source(InputDevice.SOURCE_MOUSE);
            type(MotionEvent.TOOL_TYPE_MOUSE);
            return this;
        }

        public Builder touch() {
            source(InputDevice.SOURCE_TOUCHSCREEN);
            type(MotionEvent.TOOL_TYPE_FINGER);
            return this;
        }

        public Builder mouse() {
            type(MotionEvent.TOOL_TYPE_MOUSE);
        public Builder touchpad() {
            // For compatibility reasons, some touchpads (but not on ChromeOS
            // ARC devices) fire SOURCE_MOUSE and TOOL_TYPE_FINGER events even
            // though the source should be SOURCE_TOUCHPAD and the tool type
            // could arguably be TOOL_TYPE_MOUSE.
            source(InputDevice.SOURCE_MOUSE);
            type(MotionEvent.TOOL_TYPE_FINGER);
            return this;
        }

@@ -273,7 +302,7 @@ public final class TestEvents {
                    1.0f,  // y precision
                    0,     // device id
                    0,     // edge flags
                    0,     // int source,
                    mState.mSource,
                    0      // int flags
                    );
        }
+13 −1
Original line number Diff line number Diff line
@@ -106,11 +106,23 @@ public class DragStartListenerTest {
    public void testMouseEvent() {
        MotionEvent e = mEvent.build();
        // Assert it is a mouse drag event.
        assertTrue(Events.isMouseEvent(e));
        assertTrue(Events.isMousyEvent(e));
        assertTrue(e.getActionMasked() == MotionEvent.ACTION_MOVE);
        assertTrue(e.isButtonPressed(MotionEvent.BUTTON_PRIMARY));
    }

    @Test
    public void testTouchEventIsNotMousy() {
        MotionEvent e = TestEvents.builder().touch().build();
        assertFalse(Events.isMousyEvent(e));
    }

    @Test
    public void testTouchpadEventIsMousy() {
        MotionEvent e = TestEvents.builder().touchpad().build();
        assertTrue(Events.isMousyEvent(e));
    }

    @Test
    public void testDragStarted_OnMouseMove() {
        assertTrue(mListener.onDragEvent(mEvent.build()));