From 5cece5336229f5a15d481c8da02844e8307be0a4 Mon Sep 17 00:00:00 2001 From: Curtis Belmonte Date: Tue, 15 Oct 2019 09:44:28 -0700 Subject: [PATCH] Fix fingerprint listening delay when locking phone Currently, when the user presses the power button to lock their phone, there's a delay before the device starts listening for fingerprint to unclock the phone again. This commit resets the keyguard going away state earlier when the phone is going to sleep in order to remove this delay. It also adds a new unit test to exercise this behavior. Test: atest KeyguardViewMediatorTest Test: Lock screen, quickly tap fingerprint, verify there is no delay Fixes: 141445468 Change-Id: Ib2f7d956122eec39e5164e865001a08fa70f47cc --- .../keyguard/KeyguardViewMediator.java | 50 ++++++---- .../keyguard/KeyguardViewMediatorTest.java | 93 +++++++++++++++++++ 2 files changed, 127 insertions(+), 16 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e0270decff08f..5e38f2e667ff5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -68,6 +68,7 @@ import android.view.WindowManagerPolicyConstants; import android.view.animation.Animation; import android.view.animation.AnimationUtils; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.IKeyguardDrawnCallback; import com.android.internal.policy.IKeyguardExitCallback; @@ -685,16 +686,22 @@ public class KeyguardViewMediator extends SystemUI { Context context, FalsingManager falsingManager, LockPatternUtils lockPatternUtils) { + this(context, falsingManager, lockPatternUtils, SystemUIFactory.getInstance()); + } + + @VisibleForTesting + KeyguardViewMediator( + Context context, + FalsingManager falsingManager, + LockPatternUtils lockPatternUtils, + SystemUIFactory systemUIFactory) { super(context); - mFalsingManager = falsingManager; - mLockPatternUtils = lockPatternUtils; - mStatusBarKeyguardViewManager = - SystemUIFactory.getInstance().createStatusBarKeyguardViewManager( - mContext, - mViewMediatorCallback, - mLockPatternUtils); + mStatusBarKeyguardViewManager = systemUIFactory.createStatusBarKeyguardViewManager( + mContext, + mViewMediatorCallback, + mLockPatternUtils); } public void userActivity() { @@ -826,6 +833,9 @@ public class KeyguardViewMediator extends SystemUI { mDeviceInteractive = false; mGoingToSleep = true; + // Reset keyguard going away state so we can start listening for biometric auth + setKeyguardGoingAway(false); + // Lock immediately based on setting if secure (user has a pin/pattern/password). // This also "locks" the device when not secure to provide easy access to the // camera while preventing unwanted input. @@ -1572,12 +1582,14 @@ public class KeyguardViewMediator extends SystemUI { handleNotifyFinishedGoingToSleep(); break; case NOTIFY_SCREEN_TURNING_ON: - Trace.beginSection("KeyguardViewMediator#handleMessage NOTIFY_SCREEN_TURNING_ON"); + Trace.beginSection( + "KeyguardViewMediator#handleMessage NOTIFY_SCREEN_TURNING_ON"); handleNotifyScreenTurningOn((IKeyguardDrawnCallback) msg.obj); Trace.endSection(); break; case NOTIFY_SCREEN_TURNED_ON: - Trace.beginSection("KeyguardViewMediator#handleMessage NOTIFY_SCREEN_TURNED_ON"); + Trace.beginSection( + "KeyguardViewMediator#handleMessage NOTIFY_SCREEN_TURNED_ON"); handleNotifyScreenTurnedOn(); Trace.endSection(); break; @@ -1585,7 +1597,8 @@ public class KeyguardViewMediator extends SystemUI { handleNotifyScreenTurnedOff(); break; case NOTIFY_STARTED_WAKING_UP: - Trace.beginSection("KeyguardViewMediator#handleMessage NOTIFY_STARTED_WAKING_UP"); + Trace.beginSection( + "KeyguardViewMediator#handleMessage NOTIFY_STARTED_WAKING_UP"); handleNotifyStartedWakingUp(); Trace.endSection(); break; @@ -1614,14 +1627,16 @@ public class KeyguardViewMediator extends SystemUI { handleDismiss(message.getCallback(), message.getMessage()); break; case START_KEYGUARD_EXIT_ANIM: - Trace.beginSection("KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); + Trace.beginSection( + "KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration); mFalsingManager.onSucccessfulUnlock(); Trace.endSection(); break; case KEYGUARD_DONE_PENDING_TIMEOUT: - Trace.beginSection("KeyguardViewMediator#handleMessage KEYGUARD_DONE_PENDING_TIMEOUT"); + Trace.beginSection("KeyguardViewMediator#handleMessage" + + " KEYGUARD_DONE_PENDING_TIMEOUT"); Log.w(TAG, "Timeout while waiting for activity drawn!"); Trace.endSection(); break; @@ -1799,8 +1814,7 @@ public class KeyguardViewMediator extends SystemUI { mHideAnimationRun = false; adjustStatusBarLocked(); userActivity(); - mUpdateMonitor.setKeyguardGoingAway(false /* away */); - mStatusBarWindowController.setKeyguardGoingAway(false /* goingAway */); + setKeyguardGoingAway(false); mShowKeyguardWakeLock.release(); } mKeyguardDisplayManager.show(); @@ -1832,8 +1846,7 @@ public class KeyguardViewMediator extends SystemUI { .KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS; } - mUpdateMonitor.setKeyguardGoingAway(true /* goingAway */); - mStatusBarWindowController.setKeyguardGoingAway(true /* goingAway */); + setKeyguardGoingAway(true); // Don't actually hide the Keyguard at the moment, wait for window // manager until it tells us it's safe to do so with @@ -2068,6 +2081,11 @@ public class KeyguardViewMediator extends SystemUI { mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT); } + private void setKeyguardGoingAway(boolean goingAway) { + mUpdateMonitor.setKeyguardGoingAway(goingAway); + mStatusBarWindowController.setKeyguardGoingAway(goingAway); + } + @Override public void onBootCompleted() { mUpdateMonitor.dispatchBootCompleted(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java new file mode 100644 index 0000000000000..c385e8fadb8e8 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard; + +import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; + +import androidx.test.filters.SmallTest; + +import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.SystemUIFactory; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingManagerFake; +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.StatusBarWindowController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidTestingRunner.class) +@RunWithLooper +@SmallTest +public class KeyguardViewMediatorTest extends SysuiTestCase { + private KeyguardViewMediator mViewMediator; + + private @Mock DevicePolicyManager mDevicePolicyManager; + private @Mock LockPatternUtils mLockPatternUtils; + private @Mock KeyguardUpdateMonitor mUpdateMonitor; + private @Mock StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + private @Mock StatusBarWindowController mStatusBarWindowController; + private @Mock SystemUIFactory mSystemUIFactory; + + private FalsingManagerFake mFalsingManager; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mFalsingManager = new FalsingManagerFake(); + + mDependency.injectTestDependency(FalsingManager.class, mFalsingManager); + mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mUpdateMonitor); + mDependency.injectTestDependency(StatusBarWindowController.class, + mStatusBarWindowController); + + when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager); + when(mSystemUIFactory.createStatusBarKeyguardViewManager( + any(Context.class), + any(ViewMediatorCallback.class), + any(LockPatternUtils.class))).thenReturn(mStatusBarKeyguardViewManager); + + TestableLooper.get(this).runWithLooper(() -> { + mViewMediator = new KeyguardViewMediator( + mContext, mFalsingManager, mLockPatternUtils, mSystemUIFactory); + }); + } + + @Test + public void testOnGoingToSleep_UpdatesKeyguardGoingAway() { + mViewMediator.start(); + mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER); + verify(mUpdateMonitor).setKeyguardGoingAway(false); + verify(mStatusBarWindowController).setKeyguardGoingAway(false); + } +}