Added anti-falsing logic to the keyguard.
Newly enforcing a threshold for the following cases:
Unlocking, Dismissing Notifications, Swiping Down Quick settings.
Also increased the affordance threshold slightly.
Bug: 15433087
Change-Id: I723346dedf9ae0e3f8b103182992ab572fc394b9
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index a18b0c0..8e603ba 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -81,6 +81,8 @@
private long mLongPressTimeout;
final private int[] mTmpPos = new int[2];
+ private int mFalsingThreshold;
+ private boolean mTouchAboveFalsingThreshold;
public SwipeHelper(int swipeDirection, Callback callback, Context context) {
mCallback = callback;
@@ -93,6 +95,8 @@
mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press!
mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
android.R.interpolator.fast_out_linear_in);
+ mFalsingThreshold = context.getResources().getDimensionPixelSize(
+ R.dimen.swipe_helper_falsing_threshold);
}
public void setLongPressListener(LongPressListener listener) {
@@ -222,6 +226,7 @@
switch (action) {
case MotionEvent.ACTION_DOWN:
+ mTouchAboveFalsingThreshold = false;
mDragging = false;
mLongPressSent = false;
mCurrView = mCallback.getChildAtPosition(ev);
@@ -406,12 +411,16 @@
case MotionEvent.ACTION_MOVE:
if (mCurrView != null) {
float delta = getPos(ev) - mInitialTouchPos;
+ float absDelta = Math.abs(delta);
+ if (absDelta >= mFalsingThreshold) {
+ mTouchAboveFalsingThreshold = true;
+ }
// don't let items that can't be dismissed be dragged more than
// maxScrollDistance
if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
float size = getSize(mCurrAnimView);
float maxScrollDistance = 0.15f * size;
- if (Math.abs(delta) >= size) {
+ if (absDelta >= size) {
delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
} else {
delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2));
@@ -437,9 +446,11 @@
boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) &&
(Math.abs(velocity) > Math.abs(perpendicularVelocity)) &&
(velocity > 0) == (getTranslation(mCurrAnimView) > 0);
+ boolean falsingDetected = mCallback.isAntiFalsingNeeded()
+ && !mTouchAboveFalsingThreshold;
- boolean dismissChild = mCallback.canChildBeDismissed(mCurrView) &&
- (childSwipedFastEnough || childSwipedFarEnough);
+ boolean dismissChild = mCallback.canChildBeDismissed(mCurrView)
+ && !falsingDetected && (childSwipedFastEnough || childSwipedFarEnough);
if (dismissChild) {
// flingadingy
@@ -462,6 +473,8 @@
boolean canChildBeDismissed(View v);
+ boolean isAntiFalsingNeeded();
+
void onBeginDrag(View v);
void onChildDismissed(View v);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 25a62ae..bdb0ad3 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -191,6 +191,11 @@
return true;
}
+ @Override
+ public boolean isAntiFalsingNeeded() {
+ return false;
+ }
+
public void dismissChild(View v) {
mSwipeHelper.dismissChild(v, 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index e8e9d52..47c096f 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -199,6 +199,11 @@
return true;
}
+ @Override
+ public boolean isAntiFalsingNeeded() {
+ return false;
+ }
+
public void dismissChild(View v) {
mSwipeHelper.dismissChild(v, 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 387abc3..d3c3f56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -160,6 +160,8 @@
private boolean mQsScrimEnabled = true;
private boolean mLastAnnouncementWasQuickSettings;
+ private boolean mQsTouchAboveFalsingThreshold;
+ private int mQsFalsingThreshold;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -230,6 +232,8 @@
mClockPositionAlgorithm.loadDimens(getResources());
mNotificationScrimWaitDistance =
getResources().getDimensionPixelSize(R.dimen.notification_scrim_wait_distance);
+ mQsFalsingThreshold = getResources().getDimensionPixelSize(
+ R.dimen.qs_falsing_threshold);
}
public void updateResources() {
@@ -526,6 +530,7 @@
private void resetDownStates(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
mOnlyAffordanceInThisMotion = false;
+ mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
}
}
@@ -546,6 +551,9 @@
}
private boolean flingExpandsQs(float vel) {
+ if (!mQsTouchAboveFalsingThreshold && mStatusBarState == StatusBarState.KEYGUARD) {
+ return false;
+ }
if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
return getQsExpansionFraction() > 0.5f;
} else {
@@ -690,6 +698,9 @@
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
setQsExpansion(h + mInitialHeightOnTouch);
+ if (h >= mQsFalsingThreshold) {
+ mQsTouchAboveFalsingThreshold = true;
+ }
trackMovement(event);
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index b175fd5..e818d23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -68,6 +68,8 @@
protected boolean mHintAnimationRunning;
private boolean mOverExpandedBeforeFling;
private float mOriginalIndicationY;
+ private boolean mTouchAboveFalsingThreshold;
+ private int mUnlockFalsingThreshold;
private ValueAnimator mHeightAnimator;
private ObjectAnimator mPeekAnimator;
@@ -183,6 +185,7 @@
mTouchSlop = configuration.getScaledTouchSlop();
mHintDistance = res.getDimension(R.dimen.hint_move_distance);
mEdgeTapAreaWidth = res.getDimensionPixelSize(R.dimen.edge_tap_area_width);
+ mUnlockFalsingThreshold = res.getDimensionPixelSize(R.dimen.unlock_falsing_threshold);
}
private void trackMovement(MotionEvent event) {
@@ -234,6 +237,7 @@
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mPeekTouching = mPanelClosedOnDown;
+ mTouchAboveFalsingThreshold = false;
if (mVelocityTracker == null) {
initVelocityTracker();
}
@@ -298,6 +302,9 @@
}
mJustPeeked = false;
}
+ if (-h >= mUnlockFalsingThreshold) {
+ mTouchAboveFalsingThreshold = true;
+ }
if (!mJustPeeked && (!waitForTouchSlop || mTracking) && !isTrackingBlocked()) {
setExpandedHeightInternal(newHeight);
}
@@ -399,6 +406,7 @@
mPanelClosedOnDown = mExpandedHeight == 0.0f;
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
+ mTouchAboveFalsingThreshold = false;
initVelocityTracker();
trackMovement(event);
break;
@@ -471,6 +479,9 @@
* @return whether a fling should expands the panel; contracts otherwise
*/
protected boolean flingExpands(float vel, float vectorVel) {
+ if (!mTouchAboveFalsingThreshold && mStatusBar.isFalsingThresholdNeeded()) {
+ return true;
+ }
if (Math.abs(vectorVel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
return getExpandedFraction() > 0.5f;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 620d3ec..21dc27e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -686,6 +686,7 @@
mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
R.id.notification_stack_scroller);
mStackScroller.setLongPressListener(getNotificationLongClicker());
+ mStackScroller.setPhoneStatusBar(this);
mKeyguardIconOverflowContainer =
(NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
@@ -2053,6 +2054,12 @@
return mNotificationPanel.isQsExpanded();
}
+ public boolean isFalsingThresholdNeeded() {
+ boolean onKeyguard = getBarState() == StatusBarState.KEYGUARD;
+ boolean isMethodInSecure = mUnlockMethodCache.isMethodInsecure();
+ return onKeyguard && isMethodInSecure;
+ }
+
@Override // NotificationData.Environment
public String getCurrentMediaNotificationKey() {
return mMediaNotificationKey;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 6ae076f..b2009c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -301,6 +301,11 @@
}
@Override
+ public boolean isAntiFalsingNeeded() {
+ return false;
+ }
+
+ @Override
public void onChildDismissed(View v) {
Log.v(TAG, "User swiped heads up to dismiss");
mBar.onHeadsUpDismissed();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 82efd1d..0aa1114 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -40,6 +40,7 @@
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.SpeedBumpView;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.policy.ScrollAdapter;
import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
@@ -195,6 +196,7 @@
return true;
}
};
+ private PhoneStatusBar mPhoneStatusBar;
public NotificationStackScrollLayout(Context context) {
this(context, null);
@@ -640,6 +642,11 @@
return (veto != null && veto.getVisibility() != View.GONE);
}
+ @Override
+ public boolean isAntiFalsingNeeded() {
+ return mPhoneStatusBar.isFalsingThresholdNeeded();
+ }
+
private void setSwipingInProgress(boolean isSwiped) {
mSwipingInProgress = isSwiped;
if(isSwiped) {
@@ -2185,6 +2192,10 @@
mStackScrollAlgorithm.updateIsSmallScreen(mMaxLayoutHeight - qsMinHeight);
}
+ public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
+ this.mPhoneStatusBar = phoneStatusBar;
+ }
+
/**
* A listener that is notified when some child locations might have changed.
*/