diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 8cfd225fc4df0..9aa03a922c729 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -265,7 +265,7 @@ public class LockIconViewController extends ViewController impleme boolean wasShowingUnlockIcon = mShowUnlockIcon; mShowLockIcon = !mCanDismissLockScreen && !mUserUnlockedWithBiometric && isLockScreen() && (!mUdfpsEnrolled || !mRunningFPS); - mShowUnlockIcon = mCanDismissLockScreen && isLockScreen(); + mShowUnlockIcon = (mCanDismissLockScreen || mUserUnlockedWithBiometric) && isLockScreen(); mShowAODFpIcon = mIsDozing && mUdfpsEnrolled && !mRunningFPS; final CharSequence prevContentDescription = mView.getContentDescription(); @@ -477,13 +477,15 @@ public class LockIconViewController extends ViewController impleme @Override public void onBiometricRunningStateChanged(boolean running, BiometricSourceType biometricSourceType) { + final boolean wasRunningFps = mRunningFPS; + final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric; mUserUnlockedWithBiometric = mKeyguardUpdateMonitor.getUserUnlockedWithBiometric( KeyguardUpdateMonitor.getCurrentUser()); if (biometricSourceType == FINGERPRINT) { mRunningFPS = running; - if (!mRunningFPS) { + if (wasRunningFps && !mRunningFPS) { if (mCancelDelayedUpdateVisibilityRunnable != null) { mCancelDelayedUpdateVisibilityRunnable.run(); } @@ -493,10 +495,14 @@ public class LockIconViewController extends ViewController impleme // button in this case, so we delay updating the visibility by 50ms. mCancelDelayedUpdateVisibilityRunnable = mExecutor.executeDelayed(() -> updateVisibility(), 50); - } else { - updateVisibility(); + return; } } + + if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric + || wasRunningFps != mRunningFPS) { + updateVisibility(); + } } }; diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java index c464cad3e0b24..ddf1d7033b825 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/LockIconViewControllerTest.java @@ -18,14 +18,18 @@ package com.android.systemui.keyguard; import static junit.framework.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; import android.graphics.PointF; +import android.graphics.drawable.AnimatedVectorDrawable; +import android.hardware.biometrics.BiometricSourceType; import android.hardware.biometrics.SensorLocationInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Vibrator; @@ -39,15 +43,18 @@ import android.view.accessibility.AccessibilityManager; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardViewController; import com.android.keyguard.LockIconView; import com.android.keyguard.LockIconViewController; +import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.DelayableExecutor; @@ -69,7 +76,10 @@ import java.util.List; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class LockIconViewControllerTest extends SysuiTestCase { + private static final String UNLOCKED_LABEL = "unlocked"; + private @Mock LockIconView mLockIconView; + private @Mock AnimatedVectorDrawable mIconDrawable; private @Mock Context mContext; private @Mock Resources mResources; private @Mock DisplayMetrics mDisplayMetrics; @@ -97,6 +107,11 @@ public class LockIconViewControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor mAuthControllerCallbackCaptor; private AuthController.Callback mAuthControllerCallback; + @Captor private ArgumentCaptor + mKeyguardUpdateMonitorCallbackCaptor = + ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class); + private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback; + @Captor private ArgumentCaptor mPointCaptor; @Before @@ -108,6 +123,13 @@ public class LockIconViewControllerTest extends SysuiTestCase { when(mContext.getResources()).thenReturn(mResources); when(mResources.getDisplayMetrics()).thenReturn(mDisplayMetrics); when(mLockIconView.findViewById(anyInt())).thenReturn(mAodFp); + when(mResources.getString(R.string.accessibility_unlock_button)).thenReturn(UNLOCKED_LABEL); + when(mResources.getDrawable(anyInt(), anyObject())).thenReturn(mIconDrawable); + + when(mKeyguardStateController.isShowing()).thenReturn(true); + when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false); + when(mStatusBarStateController.isDozing()).thenReturn(false); + when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); mLockIconViewController = new LockIconViewController( mLockIconView, @@ -192,6 +214,29 @@ public class LockIconViewControllerTest extends SysuiTestCase { verify(mLockIconView).setUseBackground(false); } + @Test + public void testUnlockIconShows_biometricUnlockedTrue() { + // GIVEN UDFPS sensor location is available + setupUdfps(); + + // GIVEN lock icon controller is initialized and view is attached + mLockIconViewController.init(); + captureAttachListener(); + mAttachListener.onViewAttachedToWindow(mLockIconView); + captureKeyguardUpdateMonitorCallback(); + + // GIVEN user has unlocked with a biometric auth (ie: face auth) + when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); + reset(mLockIconView); + + // WHEN face auth's biometric running state changes + mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false, + BiometricSourceType.FACE); + + // THEN the unlock icon is shown + verify(mLockIconView).setContentDescription(UNLOCKED_LABEL); + } + private Pair setupUdfps() { final PointF udfpsLocation = new PointF(50, 75); final int radius = 33; @@ -220,4 +265,10 @@ public class LockIconViewControllerTest extends SysuiTestCase { verify(mLockIconView).addOnAttachStateChangeListener(mAttachCaptor.capture()); mAttachListener = mAttachCaptor.getValue(); } + + private void captureKeyguardUpdateMonitorCallback() { + verify(mKeyguardUpdateMonitor).registerCallback( + mKeyguardUpdateMonitorCallbackCaptor.capture()); + mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue(); + } }