Loading packages/SystemUI/aconfig/systemui.aconfig +6 −0 Original line number Diff line number Diff line Loading @@ -1396,3 +1396,9 @@ flag { } } flag { name: "non_touchscreen_devices_bypass_falsing" namespace: "systemui" description: "Allow non-touchscreen devices to bypass falsing" bug: "319809270" } No newline at end of file packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList); when(mKeyguardStateController.isShowing()).thenReturn(true); when(mFalsingDataProvider.isUnfolded()).thenReturn(false); when(mFalsingDataProvider.isTouchScreenSource()).thenReturn(true); mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier, mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController, Loading Loading @@ -192,6 +193,13 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); } @Test public void testSkipNonTouchscreenDevices() { assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); when(mFalsingDataProvider.isTouchScreenSource()).thenReturn(false); assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); } @Test public void testTrackpadGesture() { assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); Loading packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java→packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/FalsingDataProviderTest.java +88 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.classifier; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -25,13 +26,20 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.hardware.input.IInputManager; import android.hardware.input.InputManagerGlobal; import android.os.RemoteException; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.util.DisplayMetrics; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.systemui.Flags; import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener; import com.android.systemui.dock.DockManagerFake; import com.android.systemui.statusbar.policy.BatteryController; Loading @@ -56,11 +64,15 @@ public class FalsingDataProviderTest extends ClassifierTest { private FoldStateListener mFoldStateListener; private final DockManagerFake mDockManager = new DockManagerFake(); private DisplayMetrics mDisplayMetrics; private IInputManager mIInputManager; private InputManagerGlobal.TestSession inputManagerGlobalTestSession; @Before public void setup() { super.setup(); MockitoAnnotations.initMocks(this); mIInputManager = mock(IInputManager.Stub.class); inputManagerGlobalTestSession = InputManagerGlobal.createTestSession(mIInputManager); mDisplayMetrics = new DisplayMetrics(); mDisplayMetrics.xdpi = 100; mDisplayMetrics.ydpi = 100; Loading @@ -73,6 +85,7 @@ public class FalsingDataProviderTest extends ClassifierTest { public void tearDown() { super.tearDown(); mDataProvider.onSessionEnd(); inputManagerGlobalTestSession.close(); } @Test Loading Loading @@ -377,6 +390,79 @@ public class FalsingDataProviderTest extends ClassifierTest { assertThat(mDataProvider.isA11yAction()).isTrue(); } @Test @DisableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_flagOff_alwaysTrue() { assertThat(mDataProvider.isTouchScreenSource()).isTrue(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_recentEventsEmpty_true() { //send no events into the data provider assertThat(mDataProvider.isTouchScreenSource()).isTrue(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_latestDeviceTouchscreen_true() throws RemoteException { int deviceId = 999; InputDevice device = new InputDevice.Builder() .setSources(InputDevice.SOURCE_CLASS_TRACKBALL | InputDevice.SOURCE_TOUCHSCREEN) .setId(deviceId) .build(); when(mIInputManager.getInputDeviceIds()).thenReturn(new int[]{deviceId}); when(mIInputManager.getInputDevice(anyInt())).thenReturn(device); MotionEvent event = MotionEvent.obtain(1, 0, MotionEvent.ACTION_UP, 1, MotionEvent.PointerProperties.createArray(1), MotionEvent.PointerCoords.createArray(1), 0, 0, 1.0f, 1.0f, deviceId, 0, InputDevice.SOURCE_CLASS_NONE, 0, 0, 0); mDataProvider.onMotionEvent(event); boolean result = mDataProvider.isTouchScreenSource(); assertThat(result).isTrue(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_latestDeviceNonTouchscreen_false() throws RemoteException { int deviceId = 9999; InputDevice device = new InputDevice.Builder() .setSources(InputDevice.SOURCE_CLASS_TRACKBALL) .setId(deviceId) .build(); when(mIInputManager.getInputDeviceIds()).thenReturn(new int[]{deviceId}); when(mIInputManager.getInputDevice(anyInt())).thenReturn(device); MotionEvent event = MotionEvent.obtain(1, 0, MotionEvent.ACTION_UP, 1, MotionEvent.PointerProperties.createArray(1), MotionEvent.PointerCoords.createArray(1), 0, 0, 1.0f, 1.0f, deviceId, 0, InputDevice.SOURCE_CLASS_NONE, 0, 0, 0); mDataProvider.onMotionEvent(event); boolean result = mDataProvider.isTouchScreenSource(); assertThat(result).isFalse(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_latestDeviceNull_true() { // Do not mock InputManager for this test inputManagerGlobalTestSession.close(); int nonExistentDeviceId = 9997; MotionEvent event = MotionEvent.obtain(1, 0, MotionEvent.ACTION_UP, 1, MotionEvent.PointerProperties.createArray(1), MotionEvent.PointerCoords.createArray(1), 0, 0, 1.0f, 1.0f, nonExistentDeviceId, 0, InputDevice.SOURCE_CLASS_NONE, 0, 0, 0); mDataProvider.onMotionEvent(event); assertThat(mDataProvider.isTouchScreenSource()).isTrue(); } @Test public void test_UnfoldedState_Folded() { FalsingDataProvider falsingDataProvider = createWithFoldCapability(true); Loading Loading @@ -413,7 +499,7 @@ public class FalsingDataProviderTest extends ClassifierTest { } private FalsingDataProvider createWithFoldCapability(boolean foldable) { return new FalsingDataProvider( mDisplayMetrics, mBatteryController, mFoldStateListener, mDockManager, foldable); return new FalsingDataProvider(mDisplayMetrics, mBatteryController, mFoldStateListener, mDockManager, foldable); } } packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +1 −2 Original line number Diff line number Diff line Loading @@ -34,8 +34,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.systemui.classifier.FalsingDataProvider.SessionListener; import com.android.systemui.classifier.HistoryTracker.BeliefListener; import com.android.systemui.dagger.qualifiers.TestHarness; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.policy.KeyguardStateController; Loading Loading @@ -396,6 +394,7 @@ public class BrightLineFalsingManager implements FalsingManager { || mDataProvider.isA11yAction() || mDataProvider.isFromTrackpad() || mDataProvider.isFromKeyboard() || !mDataProvider.isTouchScreenSource() || mDataProvider.isUnfolded(); } Loading packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +21 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.systemui.dock.DockManager.DockEventListener; import android.hardware.SensorManager; import android.hardware.biometrics.BiometricSourceType; import android.util.Log; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; Loading @@ -28,6 +29,7 @@ import androidx.annotation.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.Flags; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; Loading Loading @@ -343,7 +345,9 @@ class FalsingCollectorImpl implements FalsingCollector { // will be ignored by the collector until another MotionEvent.ACTION_DOWN is passed in. // avoidGesture must be called immediately following the MotionEvent.ACTION_DOWN, before // any other events are processed, otherwise the whole gesture will be recorded. if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { // // We should only delay processing of these events for touchscreen sources if (ev.getActionMasked() == MotionEvent.ACTION_DOWN && isTouchscreenSource(ev)) { // Make a copy of ev, since it will be recycled after we exit this method. mPendingDownEvent = MotionEvent.obtain(ev); mAvoidGesture = false; Loading Loading @@ -410,6 +414,22 @@ class FalsingCollectorImpl implements FalsingCollector { mFalsingDataProvider.onA11yAction(); } /** * returns {@code true} if the device supports Touchscreen, {@code false} otherwise. Defaults to * {@code true} if the device is {@code null} */ private boolean isTouchscreenSource(MotionEvent ev) { if (!Flags.nonTouchscreenDevicesBypassFalsing()) { return true; } InputDevice device = ev.getDevice(); if (device != null) { return device.supportsSource(InputDevice.SOURCE_TOUCHSCREEN); } else { return true; } } private boolean shouldSessionBeActive() { return mScreenOn && (mState == StatusBarState.KEYGUARD) Loading Loading
packages/SystemUI/aconfig/systemui.aconfig +6 −0 Original line number Diff line number Diff line Loading @@ -1396,3 +1396,9 @@ flag { } } flag { name: "non_touchscreen_devices_bypass_falsing" namespace: "systemui" description: "Allow non-touchscreen devices to bypass falsing" bug: "319809270" } No newline at end of file
packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList); when(mKeyguardStateController.isShowing()).thenReturn(true); when(mFalsingDataProvider.isUnfolded()).thenReturn(false); when(mFalsingDataProvider.isTouchScreenSource()).thenReturn(true); mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier, mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController, Loading Loading @@ -192,6 +193,13 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); } @Test public void testSkipNonTouchscreenDevices() { assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); when(mFalsingDataProvider.isTouchScreenSource()).thenReturn(false); assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); } @Test public void testTrackpadGesture() { assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); Loading
packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java→packages/SystemUI/multivalentTests/src/com/android/systemui/classifier/FalsingDataProviderTest.java +88 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.classifier; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; Loading @@ -25,13 +26,20 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.hardware.input.IInputManager; import android.hardware.input.InputManagerGlobal; import android.os.RemoteException; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.util.DisplayMetrics; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.systemui.Flags; import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener; import com.android.systemui.dock.DockManagerFake; import com.android.systemui.statusbar.policy.BatteryController; Loading @@ -56,11 +64,15 @@ public class FalsingDataProviderTest extends ClassifierTest { private FoldStateListener mFoldStateListener; private final DockManagerFake mDockManager = new DockManagerFake(); private DisplayMetrics mDisplayMetrics; private IInputManager mIInputManager; private InputManagerGlobal.TestSession inputManagerGlobalTestSession; @Before public void setup() { super.setup(); MockitoAnnotations.initMocks(this); mIInputManager = mock(IInputManager.Stub.class); inputManagerGlobalTestSession = InputManagerGlobal.createTestSession(mIInputManager); mDisplayMetrics = new DisplayMetrics(); mDisplayMetrics.xdpi = 100; mDisplayMetrics.ydpi = 100; Loading @@ -73,6 +85,7 @@ public class FalsingDataProviderTest extends ClassifierTest { public void tearDown() { super.tearDown(); mDataProvider.onSessionEnd(); inputManagerGlobalTestSession.close(); } @Test Loading Loading @@ -377,6 +390,79 @@ public class FalsingDataProviderTest extends ClassifierTest { assertThat(mDataProvider.isA11yAction()).isTrue(); } @Test @DisableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_flagOff_alwaysTrue() { assertThat(mDataProvider.isTouchScreenSource()).isTrue(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_recentEventsEmpty_true() { //send no events into the data provider assertThat(mDataProvider.isTouchScreenSource()).isTrue(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_latestDeviceTouchscreen_true() throws RemoteException { int deviceId = 999; InputDevice device = new InputDevice.Builder() .setSources(InputDevice.SOURCE_CLASS_TRACKBALL | InputDevice.SOURCE_TOUCHSCREEN) .setId(deviceId) .build(); when(mIInputManager.getInputDeviceIds()).thenReturn(new int[]{deviceId}); when(mIInputManager.getInputDevice(anyInt())).thenReturn(device); MotionEvent event = MotionEvent.obtain(1, 0, MotionEvent.ACTION_UP, 1, MotionEvent.PointerProperties.createArray(1), MotionEvent.PointerCoords.createArray(1), 0, 0, 1.0f, 1.0f, deviceId, 0, InputDevice.SOURCE_CLASS_NONE, 0, 0, 0); mDataProvider.onMotionEvent(event); boolean result = mDataProvider.isTouchScreenSource(); assertThat(result).isTrue(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_latestDeviceNonTouchscreen_false() throws RemoteException { int deviceId = 9999; InputDevice device = new InputDevice.Builder() .setSources(InputDevice.SOURCE_CLASS_TRACKBALL) .setId(deviceId) .build(); when(mIInputManager.getInputDeviceIds()).thenReturn(new int[]{deviceId}); when(mIInputManager.getInputDevice(anyInt())).thenReturn(device); MotionEvent event = MotionEvent.obtain(1, 0, MotionEvent.ACTION_UP, 1, MotionEvent.PointerProperties.createArray(1), MotionEvent.PointerCoords.createArray(1), 0, 0, 1.0f, 1.0f, deviceId, 0, InputDevice.SOURCE_CLASS_NONE, 0, 0, 0); mDataProvider.onMotionEvent(event); boolean result = mDataProvider.isTouchScreenSource(); assertThat(result).isFalse(); } @Test @EnableFlags(Flags.FLAG_NON_TOUCHSCREEN_DEVICES_BYPASS_FALSING) public void test_isTouchscreenSource_latestDeviceNull_true() { // Do not mock InputManager for this test inputManagerGlobalTestSession.close(); int nonExistentDeviceId = 9997; MotionEvent event = MotionEvent.obtain(1, 0, MotionEvent.ACTION_UP, 1, MotionEvent.PointerProperties.createArray(1), MotionEvent.PointerCoords.createArray(1), 0, 0, 1.0f, 1.0f, nonExistentDeviceId, 0, InputDevice.SOURCE_CLASS_NONE, 0, 0, 0); mDataProvider.onMotionEvent(event); assertThat(mDataProvider.isTouchScreenSource()).isTrue(); } @Test public void test_UnfoldedState_Folded() { FalsingDataProvider falsingDataProvider = createWithFoldCapability(true); Loading Loading @@ -413,7 +499,7 @@ public class FalsingDataProviderTest extends ClassifierTest { } private FalsingDataProvider createWithFoldCapability(boolean foldable) { return new FalsingDataProvider( mDisplayMetrics, mBatteryController, mFoldStateListener, mDockManager, foldable); return new FalsingDataProvider(mDisplayMetrics, mBatteryController, mFoldStateListener, mDockManager, foldable); } }
packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +1 −2 Original line number Diff line number Diff line Loading @@ -34,8 +34,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.systemui.classifier.FalsingDataProvider.SessionListener; import com.android.systemui.classifier.HistoryTracker.BeliefListener; import com.android.systemui.dagger.qualifiers.TestHarness; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.policy.KeyguardStateController; Loading Loading @@ -396,6 +394,7 @@ public class BrightLineFalsingManager implements FalsingManager { || mDataProvider.isA11yAction() || mDataProvider.isFromTrackpad() || mDataProvider.isFromKeyboard() || !mDataProvider.isTouchScreenSource() || mDataProvider.isUnfolded(); } Loading
packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +21 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.systemui.dock.DockManager.DockEventListener; import android.hardware.SensorManager; import android.hardware.biometrics.BiometricSourceType; import android.util.Log; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; Loading @@ -28,6 +29,7 @@ import androidx.annotation.VisibleForTesting; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.Flags; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; Loading Loading @@ -343,7 +345,9 @@ class FalsingCollectorImpl implements FalsingCollector { // will be ignored by the collector until another MotionEvent.ACTION_DOWN is passed in. // avoidGesture must be called immediately following the MotionEvent.ACTION_DOWN, before // any other events are processed, otherwise the whole gesture will be recorded. if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { // // We should only delay processing of these events for touchscreen sources if (ev.getActionMasked() == MotionEvent.ACTION_DOWN && isTouchscreenSource(ev)) { // Make a copy of ev, since it will be recycled after we exit this method. mPendingDownEvent = MotionEvent.obtain(ev); mAvoidGesture = false; Loading Loading @@ -410,6 +414,22 @@ class FalsingCollectorImpl implements FalsingCollector { mFalsingDataProvider.onA11yAction(); } /** * returns {@code true} if the device supports Touchscreen, {@code false} otherwise. Defaults to * {@code true} if the device is {@code null} */ private boolean isTouchscreenSource(MotionEvent ev) { if (!Flags.nonTouchscreenDevicesBypassFalsing()) { return true; } InputDevice device = ev.getDevice(); if (device != null) { return device.supportsSource(InputDevice.SOURCE_TOUCHSCREEN); } else { return true; } } private boolean shouldSessionBeActive() { return mScreenOn && (mState == StatusBarState.KEYGUARD) Loading