Pass interaction type to FalsingManager.isFalse

This ensures that the falsing manager always is testing against the
correct interaction type when it is asked. Prior to this change, we
could end up in states where a user was swiping down (opening the
quick settings) but the falsing manager believed the user was trying
to unlock the phone.

Fixes: 160967364
Test: atest SystemUITests && manual
Change-Id: I176f54a768622dec3e758a7f01ed8aec26223648
Merged-In: I176f54a768622dec3e758a7f01ed8aec26223648
This commit is contained in:
Dave Mankoff
2020-08-17 15:33:21 -04:00
parent 557838f550
commit bf88e9faf1
15 changed files with 62 additions and 28 deletions

View File

@@ -30,7 +30,7 @@ import java.io.PrintWriter;
*/
@ProvidesInterface(version = FalsingManager.VERSION)
public interface FalsingManager {
int VERSION = 4;
int VERSION = 5;
void onSuccessfulUnlock();
@@ -42,7 +42,8 @@ public interface FalsingManager {
boolean isUnlockingDisabled();
boolean isFalseTouch();
/** Returns true if the gesture should be rejected. */
boolean isFalseTouch(int interactionType);
void onNotificatonStopDraggingDown();

View File

@@ -14,16 +14,16 @@
package com.android.systemui.plugins.statusbar;
import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
@ProvidesInterface(version = NotificationSwipeActionHelper.VERSION)
@DependsOn(target = SnoozeOption.class)
public interface NotificationSwipeActionHelper {
@@ -52,7 +52,8 @@ public interface NotificationSwipeActionHelper {
public boolean isDismissGesture(MotionEvent ev);
public boolean isFalseGesture(MotionEvent ev);
/** Returns true if the gesture should be rejected. */
boolean isFalseGesture();
public boolean swipedFarEnough(float translation, float viewSize);

View File

@@ -16,6 +16,8 @@
package com.android.systemui;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -697,14 +699,15 @@ public class SwipeHelper implements Gefingerpoken {
float translation = getTranslation(mCurrView);
return ev.getActionMasked() == MotionEvent.ACTION_UP
&& !mFalsingManager.isUnlockingDisabled()
&& !isFalseGesture(ev) && (swipedFastEnough() || swipedFarEnough())
&& !isFalseGesture() && (swipedFastEnough() || swipedFarEnough())
&& mCallback.canChildBeDismissedInDirection(mCurrView, translation > 0);
}
public boolean isFalseGesture(MotionEvent ev) {
/** Returns true if the gesture should be rejected. */
public boolean isFalseGesture() {
boolean falsingDetected = mCallback.isAntiFalsingNeeded();
if (mFalsingManager.isClassifierEnabled()) {
falsingDetected = falsingDetected && mFalsingManager.isFalseTouch();
falsingDetected = falsingDetected && mFalsingManager.isFalseTouch(NOTIFICATION_DISMISS);
} else {
falsingDetected = falsingDetected && !mTouchAboveFalsingThreshold;
}

View File

@@ -70,7 +70,7 @@ public class FalsingManagerFake implements FalsingManager {
}
@Override
public boolean isFalseTouch() {
public boolean isFalseTouch(@Classifier.InteractionType int interactionType) {
return mIsFalseTouch;
}

View File

@@ -262,7 +262,7 @@ public class FalsingManagerImpl implements FalsingManager {
/**
* @return true if the classifier determined that this is not a human interacting with the phone
*/
public boolean isFalseTouch() {
public boolean isFalseTouch(@Classifier.InteractionType int interactionType) {
if (FalsingLog.ENABLED) {
// We're getting some false wtfs from touches that happen after the device went
// to sleep. Only report missing sessions that happen when the device is interactive.

View File

@@ -187,8 +187,8 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
}
@Override
public boolean isFalseTouch() {
return mInternalFalsingManager.isFalseTouch();
public boolean isFalseTouch(@Classifier.InteractionType int interactionType) {
return mInternalFalsingManager.isFalseTouch(interactionType);
}
@Override

View File

@@ -189,7 +189,8 @@ public class BrightLineFalsingManager implements FalsingManager {
}
@Override
public boolean isFalseTouch() {
public boolean isFalseTouch(@Classifier.InteractionType int interactionType) {
mDataProvider.setInteractionType(interactionType);
if (!mDataProvider.isDirty()) {
return mPreviousResult;
}

View File

@@ -116,7 +116,10 @@ public class FalsingDataProvider {
* interactionType is defined by {@link com.android.systemui.classifier.Classifier}.
*/
final void setInteractionType(@Classifier.InteractionType int interactionType) {
this.mInteractionType = interactionType;
if (mInteractionType != interactionType) {
mInteractionType = interactionType;
mDirty = true;
}
}
public boolean isDirty() {

View File

@@ -30,6 +30,7 @@ import com.android.settingslib.Utils
import com.android.systemui.Gefingerpoken
import com.android.systemui.qs.PageIndicator
import com.android.systemui.R
import com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.util.animation.PhysicsAnimator
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -315,7 +316,8 @@ class MediaCarouselScrollHandler(
return false
}
private fun isFalseTouch() = falsingProtectionNeeded && falsingManager.isFalseTouch
private fun isFalseTouch() = falsingProtectionNeeded &&
falsingManager.isFalseTouch(NOTIFICATION_DISMISS)
private fun getMaxTranslation() = if (showsSettingsButton) {
settingsButton.width

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -163,7 +165,7 @@ public class DragDownHelper implements Gefingerpoken {
if (!mDragDownCallback.isFalsingCheckNeeded()) {
return false;
}
return mFalsingManager.isFalseTouch() || !mDraggedFarEnough;
return mFalsingManager.isFalseTouch(NOTIFICATION_DRAG_DOWN) || !mDraggedFarEnough;
}
private void captureStartingChild(float x, float y) {

View File

@@ -30,6 +30,7 @@ import android.view.ViewConfiguration
import com.android.systemui.Gefingerpoken
import com.android.systemui.Interpolators
import com.android.systemui.R
import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
@@ -106,7 +107,7 @@ constructor(
private var velocityTracker: VelocityTracker? = null
private val isFalseTouch: Boolean
get() = falsingManager.isFalseTouch
get() = falsingManager.isFalseTouch(NOTIFICATION_DRAG_DOWN)
var qsExpanded: Boolean = false
var pulseExpandAbortListener: Runnable? = null
var bouncerShowing: Boolean = false

View File

@@ -209,7 +209,7 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|| (isFastNonDismissGesture && isAbleToShowMenu);
int menuSnapTarget = menuRow.getMenuSnapTarget();
boolean isNonFalseMenuRevealingGesture =
!isFalseGesture(ev) && isMenuRevealingGestureAwayFromMenu;
!isFalseGesture() && isMenuRevealingGestureAwayFromMenu;
if ((isNonDismissGestureTowardsMenu || isNonFalseMenuRevealingGesture)
&& menuSnapTarget != 0) {
// Menu has not been snapped to previously and this is menu revealing gesture

View File

@@ -27,6 +27,7 @@ import android.view.ViewConfiguration;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -317,7 +318,9 @@ public class KeyguardAffordanceHelper {
// We snap back if the current translation is not far enough
boolean snapBack = false;
if (mCallback.needsAntiFalsing()) {
snapBack = snapBack || mFalsingManager.isFalseTouch();
snapBack = snapBack || mFalsingManager.isFalseTouch(
mTargetedView == mRightIcon
? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE);
}
snapBack = snapBack || isBelowFalsingThreshold();

View File

@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone;
import static android.view.View.GONE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
@@ -69,6 +70,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.DejankUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
@@ -1204,7 +1206,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
private boolean flingExpandsQs(float vel) {
if (mFalsingManager.isUnlockingDisabled() || isFalseTouch()) {
if (mFalsingManager.isUnlockingDisabled() || isFalseTouch(QUICK_SETTINGS)) {
return false;
}
if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
@@ -1214,12 +1216,12 @@ public class NotificationPanelViewController extends PanelViewController {
}
}
private boolean isFalseTouch() {
private boolean isFalseTouch(@Classifier.InteractionType int interactionType) {
if (!mKeyguardAffordanceHelperCallback.needsAntiFalsing()) {
return false;
}
if (mFalsingManager.isClassifierEnabled()) {
return mFalsingManager.isFalseTouch();
return mFalsingManager.isFalseTouch(interactionType);
}
return !mQsTouchAboveFalsingThreshold;
}

View File

@@ -16,6 +16,10 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.UNLOCK;
import static java.lang.Float.isNaN;
import android.animation.Animator;
@@ -41,6 +45,7 @@ import com.android.internal.util.LatencyTracker;
import com.android.systemui.DejankUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -397,7 +402,12 @@ public abstract class PanelViewController {
mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_UNLOCK, heightDp, velocityDp);
mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_UNLOCK);
}
fling(vel, expand, isFalseTouch(x, y));
@Classifier.InteractionType int interactionType = vel > 0
? QUICK_SETTINGS : (
mKeyguardStateController.canDismissLockScreen()
? UNLOCK : BOUNCER_UNLOCK);
fling(vel, expand, isFalseTouch(x, y, interactionType));
onTrackingStopped(expand);
mUpdateFlingOnLayout = expand && mPanelClosedOnDown && !mHasLayoutedSinceDown;
if (mUpdateFlingOnLayout) {
@@ -492,7 +502,11 @@ public abstract class PanelViewController {
return true;
}
if (isFalseTouch(x, y)) {
@Classifier.InteractionType int interactionType = vel > 0
? QUICK_SETTINGS : (
mKeyguardStateController.canDismissLockScreen() ? UNLOCK : BOUNCER_UNLOCK);
if (isFalseTouch(x, y, interactionType)) {
return true;
}
if (Math.abs(vectorVel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
@@ -511,12 +525,13 @@ public abstract class PanelViewController {
* @param y the final y-coordinate when the finger was lifted
* @return whether this motion should be regarded as a false touch
*/
private boolean isFalseTouch(float x, float y) {
private boolean isFalseTouch(float x, float y,
@Classifier.InteractionType int interactionType) {
if (!mStatusBar.isFalsingThresholdNeeded()) {
return false;
}
if (mFalsingManager.isClassifierEnabled()) {
return mFalsingManager.isFalseTouch();
return mFalsingManager.isFalseTouch(interactionType);
}
if (!mTouchAboveFalsingThreshold) {
return true;