Dismiss keyguard on udfps touch if can dismiss LS

In case face auth has suceeded, finger down on the udfps area should
trigger device entry.

Test: atest UdfpsControllerTest
Test: manual
Bug: 192680255
Change-Id: I36fe693bc88a0aa1784cd1ce1b268cd07f6ced4d
This commit is contained in:
Beverly
2021-07-13 17:43:57 -04:00
parent e7701b84d3
commit 71089198bf
2 changed files with 115 additions and 5 deletions

View File

@@ -69,6 +69,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.Execution;
@@ -106,6 +107,7 @@ public class UdfpsController implements DozeReceiver {
private final DelayableExecutor mFgExecutor;
@NonNull private final StatusBar mStatusBar;
@NonNull private final StatusBarStateController mStatusBarStateController;
@NonNull private final KeyguardStateController mKeyguardStateController;
@NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
@NonNull private final DumpManager mDumpManager;
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -148,6 +150,7 @@ public class UdfpsController implements DozeReceiver {
private boolean mScreenOn;
private Runnable mAodInterruptRunnable;
private boolean mOnFingerDown;
private boolean mAttemptedToDismissKeyguard;
@VisibleForTesting
public static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
@@ -379,8 +382,12 @@ public class UdfpsController implements DozeReceiver {
// ACTION_DOWN, in that case we should just reuse the old instance.
mVelocityTracker.clear();
}
if (isWithinSensorArea(udfpsView, event.getX(), event.getY(), fromUdfpsView)) {
boolean withinSensorArea =
isWithinSensorArea(udfpsView, event.getX(), event.getY(), fromUdfpsView);
if (withinSensorArea) {
Trace.beginAsyncSection("UdfpsController.e2e.onPointerDown", 0);
Log.v(TAG, "onTouch | action down");
// The pointer that causes ACTION_DOWN is always at index 0.
// We need to persist its ID to track it during ACTION_MOVE that could include
// data for many other pointers because of multi-touch support.
@@ -388,6 +395,11 @@ public class UdfpsController implements DozeReceiver {
mVelocityTracker.addMovement(event);
handled = true;
}
if ((withinSensorArea || fromUdfpsView) && shouldTryToDismissKeyguard()) {
Log.v(TAG, "onTouch | dismiss keyguard from ACTION_DOWN");
mKeyguardViewManager.notifyKeyguardAuthenticated(false /* strongAuth */);
mAttemptedToDismissKeyguard = true;
}
Trace.endSection();
break;
@@ -398,8 +410,10 @@ public class UdfpsController implements DozeReceiver {
? event.getPointerId(0)
: event.findPointerIndex(mActivePointerId);
if (idx == event.getActionIndex()) {
if (isWithinSensorArea(udfpsView, event.getX(idx), event.getY(idx),
fromUdfpsView)) {
boolean actionMoveWithinSensorArea =
isWithinSensorArea(udfpsView, event.getX(idx), event.getY(idx),
fromUdfpsView);
if (actionMoveWithinSensorArea) {
if (mVelocityTracker == null) {
// touches could be injected, so the velocity tracker may not have
// been initialized (via ACTION_DOWN).
@@ -434,6 +448,12 @@ public class UdfpsController implements DozeReceiver {
Log.v(TAG, "onTouch | finger outside");
onFingerUp();
}
if ((fromUdfpsView || actionMoveWithinSensorArea)
&& shouldTryToDismissKeyguard()) {
Log.v(TAG, "onTouch | dismiss keyguard from ACTION_MOVE");
mKeyguardViewManager.notifyKeyguardAuthenticated(false /* strongAuth */);
mAttemptedToDismissKeyguard = true;
}
}
Trace.endSection();
break;
@@ -448,6 +468,7 @@ public class UdfpsController implements DozeReceiver {
mVelocityTracker = null;
}
Log.v(TAG, "onTouch | finger up");
mAttemptedToDismissKeyguard = false;
onFingerUp();
mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
Trace.endSection();
@@ -459,6 +480,13 @@ public class UdfpsController implements DozeReceiver {
return handled;
}
private boolean shouldTryToDismissKeyguard() {
return mView.getAnimationViewController() != null
&& mView.getAnimationViewController() instanceof UdfpsKeyguardViewController
&& mKeyguardStateController.canDismissLockScreen()
&& !mAttemptedToDismissKeyguard;
}
@Inject
public UdfpsController(@NonNull Context context,
@NonNull Execution execution,
@@ -479,7 +507,8 @@ public class UdfpsController implements DozeReceiver {
@NonNull ScreenLifecycle screenLifecycle,
@Nullable Vibrator vibrator,
@NonNull UdfpsHapticsSimulator udfpsHapticsSimulator,
@NonNull Optional<UdfpsHbmProvider> hbmProvider) {
@NonNull Optional<UdfpsHbmProvider> hbmProvider,
@NonNull KeyguardStateController keyguardStateController) {
mContext = context;
mExecution = execution;
// TODO (b/185124905): inject main handler and vibrator once done prototyping
@@ -493,6 +522,7 @@ public class UdfpsController implements DozeReceiver {
mFgExecutor = fgExecutor;
mStatusBar = statusBar;
mStatusBarStateController = statusBarStateController;
mKeyguardStateController = keyguardStateController;
mKeyguardViewManager = statusBarKeyguardViewManager;
mDumpManager = dumpManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -667,6 +697,7 @@ public class UdfpsController implements DozeReceiver {
mView.setSensorProperties(mSensorProps);
mView.setHbmProvider(mHbmProvider);
UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
mAttemptedToDismissKeyguard = false;
animation.init();
mView.setAnimationViewController(animation);
mOrientationListener.enable();

View File

@@ -21,6 +21,7 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
@@ -58,6 +59,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.Execution;
import com.android.systemui.util.concurrency.FakeExecution;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -130,6 +132,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
private Vibrator mVibrator;
@Mock
private UdfpsHapticsSimulator mUdfpsHapticsSimulator;
@Mock
private KeyguardStateController mKeyguardStateController;
private FakeExecutor mFgExecutor;
@@ -137,6 +141,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private UdfpsView mUdfpsView;
@Mock
private UdfpsKeyguardViewController mUdfpsKeyguardViewController;
@Mock
private TypedArray mBrightnessValues;
@Mock
private TypedArray mBrightnessBacklight;
@@ -149,6 +155,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Captor private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
private ScreenLifecycle.Observer mScreenObserver;
@Captor private ArgumentCaptor<UdfpsAnimationViewController> mAnimViewControllerCaptor;
@Before
public void setUp() {
setUpResources();
@@ -193,7 +201,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mScreenLifecycle,
mVibrator,
mUdfpsHapticsSimulator,
Optional.of(mHbmProvider));
Optional.of(mHbmProvider),
mKeyguardStateController);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
@@ -220,6 +229,76 @@ public class UdfpsControllerTest extends SysuiTestCase {
verify(mUdfpsView).dozeTimeTick();
}
@Test
public void onActionDownTouch_whenCanDismissLockScreen_entersDevice() throws RemoteException {
// GIVEN can dismiss lock screen and the current animation is an UdfpsKeyguardViewController
when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_DOWN is received
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
downEvent.recycle();
// THEN notify keyguard authenticate to dismiss the keyguard
verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
}
@Test
public void onActionMoveTouch_whenCanDismissLockScreen_entersDevice() throws RemoteException {
// GIVEN can dismiss lock screen and the current animation is an UdfpsKeyguardViewController
when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN ACTION_MOVE is received
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
moveEvent.recycle();
// THEN notify keyguard authenticate to dismiss the keyguard
verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
}
@Test
public void onMultipleTouch_whenCanDismissLockScreen_entersDeviceOnce() throws RemoteException {
// GIVEN can dismiss lock screen and the current animation is an UdfpsKeyguardViewController
when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
when(mUdfpsView.getAnimationViewController()).thenReturn(mUdfpsKeyguardViewController);
// GIVEN that the overlay is showing
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
mFgExecutor.runAllReady();
// WHEN multiple touches are received
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
downEvent.recycle();
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
moveEvent.recycle();
// THEN notify keyguard authenticate to dismiss the keyguard
verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
}
@Test
public void showUdfpsOverlay_addsViewToWindow() throws RemoteException {
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,