diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index b2bcb0554b0dd..25ccc1658744a 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -396,6 +396,7 @@ public class BrightLineFalsingManager implements FalsingManager { || mDataProvider.isDocked() || mAccessibilityManager.isTouchExplorationEnabled() || mDataProvider.isA11yAction() + || mDataProvider.isFromTrackpad() || (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED) && mDataProvider.isUnfolded()); } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java index d6c85fbaf5a9d..809d5b289caba 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java @@ -261,6 +261,16 @@ public class FalsingDataProvider { return mLastMotionEvent.getY() < mFirstRecentMotionEvent.getY(); } + public boolean isFromTrackpad() { + if (mRecentMotionEvents.isEmpty()) { + return false; + } + + int classification = mRecentMotionEvents.get(0).getClassification(); + return classification == MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE + || classification == MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE; + } + private void recalculateData() { if (!mDirty) { return; @@ -343,7 +353,9 @@ public class FalsingDataProvider { motionEvent.getDeviceId(), motionEvent.getEdgeFlags(), motionEvent.getSource(), - motionEvent.getFlags() + motionEvent.getDisplayId(), + motionEvent.getFlags(), + motionEvent.getClassification() )); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java index 292fdff0027d0..f770a3885aad7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java @@ -187,4 +187,11 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { when(mFalsingDataProvider.isUnfolded()).thenReturn(true); assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); } + + @Test + public void testTrackpadGesture() { + assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); + when(mFalsingDataProvider.isFromTrackpad()).thenReturn(true); + assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java index 9254617655463..4da151c3ca04b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java @@ -18,8 +18,11 @@ package com.android.systemui.classifier; import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.util.DisplayMetrics; +import android.view.InputDevice; import android.view.MotionEvent; +import androidx.test.uiautomator.Configurator; + import com.android.systemui.SysuiTestCase; import com.android.systemui.dock.DockManagerFake; import com.android.systemui.statusbar.policy.BatteryController; @@ -80,6 +83,10 @@ public class ClassifierTest extends SysuiTestCase { mDataProvider.onSessionEnd(); } + protected static int getPointerAction(int actionType, int index) { + return actionType + (index << MotionEvent.ACTION_POINTER_INDEX_SHIFT); + } + protected MotionEvent appendDownEvent(float x, float y) { return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y); } @@ -124,4 +131,55 @@ public class ClassifierTest extends SysuiTestCase { return motionEvent; } + + protected MotionEvent appendTrackpadDownEvent(float x, float y) { + return appendTrackpadMotionEvent(MotionEvent.ACTION_DOWN, x, y, 1); + } + + protected MotionEvent appendTrackpadMoveEvent(float x, float y, int pointerCount) { + return appendTrackpadMotionEvent(MotionEvent.ACTION_MOVE, x, y, pointerCount); + } + + protected MotionEvent appendTrackpadPointerDownEvent(int actionType, float x, float y, + int pointerCount) { + return appendTrackpadMotionEvent(actionType, x, y, pointerCount); + } + + private MotionEvent appendTrackpadMotionEvent(int actionType, float x, float y, + int pointerCount) { + long eventTime = mMotionEvents.isEmpty() ? 1 : mMotionEvents.get( + mMotionEvents.size() - 1).getEventTime() + 1; + return appendTrackpadMotionEvent(actionType, x, y, pointerCount, eventTime); + } + + private MotionEvent appendTrackpadMotionEvent(int actionType, float x, float y, + int pointerCount, long eventTime) { + MotionEvent.PointerProperties[] pointerProperties = + new MotionEvent.PointerProperties[pointerCount]; + MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount]; + for (int i = 0; i < pointerCount; i++) { + pointerProperties[i] = getPointerProperties(i); + pointerCoords[i] = getPointerCoords(x, y); + } + return MotionEvent.obtain(1, eventTime, actionType, pointerCount, pointerProperties, + pointerCoords, 0, 0, 1.0f, 1.0f, 0, 0, + InputDevice.SOURCE_TOUCHPAD | InputDevice.SOURCE_MOUSE, 0, 0, + MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE); + } + + private static MotionEvent.PointerProperties getPointerProperties(int pointerId) { + MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties(); + properties.id = pointerId; + properties.toolType = Configurator.getInstance().getToolType(); + return properties; + } + + private static MotionEvent.PointerCoords getPointerCoords(float x, float y) { + MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); + coords.pressure = 1; + coords.size = 1; + coords.x = x; + coords.y = y; + return coords; + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java index 7e066808b5bde..0353f87ae9b43 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java @@ -281,6 +281,22 @@ public class FalsingDataProviderTest extends ClassifierTest { mDataProvider.onSessionEnd(); } + @Test + public void test_IsFromTrackpad() { + MotionEvent motionEventOrigin = appendTrackpadDownEvent(0, 0); + + mDataProvider.onMotionEvent(motionEventOrigin); + mDataProvider.onMotionEvent( + appendTrackpadPointerDownEvent(getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 1), + 0, 0, 2)); + mDataProvider.onMotionEvent( + appendTrackpadPointerDownEvent(getPointerAction(MotionEvent.ACTION_POINTER_DOWN, 2), + 0, 0, 3)); + mDataProvider.onMotionEvent(appendTrackpadMoveEvent(1, -1, 3)); + assertThat(mDataProvider.isFromTrackpad()).isTrue(); + mDataProvider.onSessionEnd(); + } + @Test public void test_isWirelessCharging() { assertThat(mDataProvider.isDocked()).isFalse();