Ignore ACTION_OUTSIDE in FalsingManager

Multipe outside motion events can be fired for a single tap. This
throws off the falsing manager, causing it to improperly increase
its belief in false touches. Ignore them.

A few other small cleanups in the interaction between the
WalletActivity and the FalsingManager are also included. There was
one touch interaction with the wallet carousel that was not being
analyzed by the FalsingManager. The WalletActivity was also making
some redundant checks that the FalsingManager is already performaing
internally.

Fixes: 215558965
Test: manual & atest SystemUITests
Change-Id: I51139fdaaa0214b7a9ddfb9b730a1c8b114c721d
This commit is contained in:
Dave Mankoff
2022-03-22 16:37:15 +00:00
parent 17c1c80c0b
commit 853d666fc8
5 changed files with 35 additions and 5 deletions

View File

@@ -309,6 +309,10 @@ class FalsingCollectorImpl implements FalsingCollector {
avoidGesture();
return;
}
if (ev.getActionMasked() == MotionEvent.ACTION_OUTSIDE) {
return;
}
// We delay processing down events to see if another component wants to process them.
// If #avoidGesture is called after a MotionEvent.ACTION_DOWN, all following motion events
// will be ignored by the collector until another MotionEvent.ACTION_DOWN is passed in.

View File

@@ -152,8 +152,7 @@ public class WalletActivity extends LifecycleActivity implements
Log.w(TAG, "Unable to create wallet app intent.");
return;
}
if (!mKeyguardStateController.isUnlocked()
&& mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}

View File

@@ -81,6 +81,12 @@ public class WalletCardCarousel extends RecyclerView {
private float mCardCenterToScreenCenterDistancePx = Float.MAX_VALUE;
interface OnSelectionListener {
/**
* A non-centered card was clicked.
* @param position
*/
void onUncenteredClick(int position);
/**
* The card was moved to the center, thus selecting it.
*/
@@ -403,7 +409,7 @@ public class WalletCardCarousel extends RecyclerView {
viewHolder.mCardView.setOnClickListener(
v -> {
if (position != mCenteredAdapterPosition) {
smoothScrollToPosition(position);
mSelectionListener.onUncenteredClick(position);
} else {
mSelectionListener.onCardClicked(cardViewInfo);
}

View File

@@ -180,6 +180,14 @@ public class WalletScreenController implements
queryWalletCards();
}
@Override
public void onUncenteredClick(int position) {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}
mCardCarousel.smoothScrollToPosition(position);
}
@Override
public void onCardSelected(@NonNull WalletCardViewInfo card) {
if (mIsDismissed) {
@@ -208,8 +216,7 @@ public class WalletScreenController implements
@Override
public void onCardClicked(@NonNull WalletCardViewInfo cardInfo) {
if (!mKeyguardStateController.isUnlocked()
&& mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return;
}
if (!(cardInfo instanceof QAWalletCardViewInfo)

View File

@@ -198,6 +198,20 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class));
}
@Test
public void testIgnoreActionOutside() {
MotionEvent outside = MotionEvent.obtain(0, 0, MotionEvent.ACTION_OUTSIDE, 0, 0, 0);
MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
// Nothing passed initially. The outside event will be completely ignored.
mFalsingCollector.onTouchEvent(outside);
verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class));
// Up event flushes, and the outside event isn't passed through.
mFalsingCollector.onTouchEvent(up);
verify(mFalsingDataProvider).onMotionEvent(up);
}
@Test
public void testAvoidUnlocked() {
MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);