From 2b6edba838bbd6de9eb2f549f6cc30714d4fac6b Mon Sep 17 00:00:00 2001 From: Beverly Date: Mon, 16 May 2022 16:09:37 +0000 Subject: Update aod face-auth transition Previously unlocking via face-auth on AoD (can be triggered on a UDFPS failures on AoD), the transition had poor scrim & light reveal animations. Fixes: 232050211 Test: atest AuthRippleControllerTest ScrimControllerTest Test: manual Change-Id: I3d250794181841c0389e1e72cbbebb2e7378f217 --- .../systemui/biometrics/AuthRippleController.kt | 83 ++++++++-------------- .../statusbar/phone/CentralSurfacesImpl.java | 3 +- .../systemui/statusbar/phone/ScrimState.java | 2 +- .../biometrics/AuthRippleControllerTest.kt | 21 +++++- .../statusbar/phone/ScrimControllerTest.java | 47 +++++++++++- 5 files changed, 99 insertions(+), 57 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index 86e501670440..38fab8ffbfad 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -23,7 +23,6 @@ import android.content.Context import android.graphics.PointF import android.hardware.biometrics.BiometricFingerprintConstants import android.hardware.biometrics.BiometricSourceType -import android.util.DisplayMetrics import android.util.Log import androidx.annotation.VisibleForTesting import com.android.keyguard.KeyguardUpdateMonitor @@ -46,7 +45,6 @@ import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.Cent import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.ViewController -import com.android.systemui.util.leak.RotationUtils import java.io.PrintWriter import javax.inject.Inject import javax.inject.Provider @@ -127,17 +125,37 @@ class AuthRippleController @Inject constructor( } updateSensorLocation() - if (biometricSourceType == BiometricSourceType.FINGERPRINT && - fingerprintSensorLocation != null) { - mView.setFingerprintSensorLocation(fingerprintSensorLocation!!, udfpsRadius) - showUnlockedRipple() - } else if (biometricSourceType == BiometricSourceType.FACE && - faceSensorLocation != null) { - if (!bypassController.canBypass()) { + if (biometricSourceType == BiometricSourceType.FINGERPRINT) { + fingerprintSensorLocation?.let { + mView.setFingerprintSensorLocation(it, udfpsRadius) + circleReveal = CircleReveal( + it.x, + it.y, + 0f, + Math.max( + Math.max(it.x, centralSurfaces.displayWidth - it.x), + Math.max(it.y, centralSurfaces.displayHeight - it.y) + ) + ) + showUnlockedRipple() + } + } else if (biometricSourceType == BiometricSourceType.FACE) { + if (!bypassController.canBypass() && !authController.isUdfpsFingerDown) { return } - mView.setSensorLocation(faceSensorLocation!!) - showUnlockedRipple() + faceSensorLocation?.let { + mView.setSensorLocation(it) + circleReveal = CircleReveal( + it.x, + it.y, + 0f, + Math.max( + Math.max(it.x, centralSurfaces.displayWidth - it.x), + Math.max(it.y, centralSurfaces.displayHeight - it.y) + ) + ) + showUnlockedRipple() + } } } @@ -209,48 +227,8 @@ class AuthRippleController @Inject constructor( } fun updateSensorLocation() { - updateFingerprintLocation() + fingerprintSensorLocation = authController.fingerprintSensorLocation faceSensorLocation = authController.faceAuthSensorLocation - fingerprintSensorLocation?.let { - circleReveal = CircleReveal( - it.x, - it.y, - 0f, - Math.max( - Math.max(it.x, centralSurfaces.displayWidth - it.x), - Math.max(it.y, centralSurfaces.displayHeight - it.y) - ) - ) - } - } - - private fun updateFingerprintLocation() { - val displayMetrics = DisplayMetrics() - sysuiContext.display?.getRealMetrics(displayMetrics) - val width = displayMetrics.widthPixels - val height = displayMetrics.heightPixels - - authController.fingerprintSensorLocation?.let { - fingerprintSensorLocation = when (RotationUtils.getRotation(sysuiContext)) { - RotationUtils.ROTATION_LANDSCAPE -> { - val normalizedYPos: Float = it.y / width - val normalizedXPos: Float = it.x / height - PointF(width * normalizedYPos, height * (1 - normalizedXPos)) - } - RotationUtils.ROTATION_UPSIDE_DOWN -> { - PointF(width - it.x, height - it.y) - } - RotationUtils.ROTATION_SEASCAPE -> { - val normalizedYPos: Float = it.y / width - val normalizedXPos: Float = it.x / height - PointF(width * (1 - normalizedYPos), height * normalizedXPos) - } - else -> { - // ROTATION_NONE - PointF(it.x, it.y) - } - } - } } private fun updateRippleColor() { @@ -372,6 +350,7 @@ class AuthRippleController @Inject constructor( showUnlockRipple(BiometricSourceType.FINGERPRINT) } "face" -> { + // note: only shows when about to proceed to the home screen updateSensorLocation() pw.println("face ripple sensorLocation=$faceSensorLocation") showUnlockRipple(BiometricSourceType.FACE) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index b6a3b7ca1758..e3cc9f6b7508 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -3907,7 +3907,8 @@ public class CentralSurfacesImpl extends CoreStartable implements mScrimController.transitionTo(ScrimState.AOD); } else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) { mScrimController.transitionTo(ScrimState.KEYGUARD); - } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming()) { + } else if (mKeyguardStateController.isShowing() && mKeyguardUpdateMonitor.isDreaming() + && !unlocking) { mScrimController.transitionTo(ScrimState.DREAMING); } else { mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java index 4a5f712d587c..b447f0d36c10 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java @@ -252,7 +252,7 @@ public enum ScrimState { mBehindTint = Color.BLACK; mBlankScreen = false; - if (previousState == ScrimState.AOD) { + if (mDisplayRequiresBlanking && previousState == ScrimState.AOD) { // Set all scrims black, before they fade transparent. updateScrimColor(mScrimInFront, 1f /* alpha */, Color.BLACK /* tint */); updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK /* tint */); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt index 7f8656c1ecbc..d6afd6d192ec 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt @@ -292,7 +292,7 @@ class AuthRippleControllerTest : SysuiTestCase() { @Test @RunWithLooper(setAsMainLooper = true) - fun testAnimatorRunWhenWakeAndUnlock() { + fun testAnimatorRunWhenWakeAndUnlock_fingerprint() { val fpsLocation = PointF(5f, 5f) `when`(authController.fingerprintSensorLocation).thenReturn(fpsLocation) controller.onViewAttached() @@ -308,6 +308,25 @@ class AuthRippleControllerTest : SysuiTestCase() { controller.startLightRevealScrimOnKeyguardFadingAway) } + @Test + @RunWithLooper(setAsMainLooper = true) + fun testAnimatorRunWhenWakeAndUnlock_faceUdfpsFingerDown() { + val faceLocation = PointF(5f, 5f) + `when`(authController.faceAuthSensorLocation).thenReturn(faceLocation) + controller.onViewAttached() + `when`(keyguardUpdateMonitor.isKeyguardVisible).thenReturn(true) + `when`(biometricUnlockController.isWakeAndUnlock).thenReturn(true) + `when`(authController.isUdfpsFingerDown).thenReturn(true) + + controller.showUnlockRipple(BiometricSourceType.FACE) + assertTrue("reveal didn't start on keyguardFadingAway", + controller.startLightRevealScrimOnKeyguardFadingAway) + `when`(keyguardStateController.isKeyguardFadingAway).thenReturn(true) + controller.onKeyguardFadingAwayChanged() + assertFalse("reveal triggers multiple times", + controller.startLightRevealScrimOnKeyguardFadingAway) + } + @Test fun testUpdateRippleColor() { controller.onViewAttached() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 5f8dda359563..431de1c89ae9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -831,7 +831,7 @@ public class ScrimControllerTest extends SysuiTestCase { } @Test - public void scrimBlanksWhenUnlockingFromPulse() { + public void scrimBlankCallbackWhenUnlockingFromPulse() { boolean[] blanked = {false}; // Simulate unlock with fingerprint mScrimController.transitionTo(ScrimState.PULSING); @@ -844,7 +844,50 @@ public class ScrimControllerTest extends SysuiTestCase { } }); finishAnimationsImmediately(); - Assert.assertTrue("Scrim should blank when unlocking from pulse.", blanked[0]); + Assert.assertTrue("Scrim should send display blanked callback when unlocking " + + "from pulse.", blanked[0]); + } + + @Test + public void blankingNotRequired_leavingAoD() { + // GIVEN display does NOT need blanking + when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(false); + + mScrimController = new ScrimController(mLightBarController, + mDozeParameters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder, + new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor, + mDockManager, mConfigurationController, new FakeExecutor(new FakeSystemClock()), + mScreenOffAnimationController, + mPanelExpansionStateManager, + mKeyguardUnlockAnimationController, + mStatusBarKeyguardViewManager); + mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible); + mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront); + mScrimController.setAnimatorListener(mAnimatorListener); + mScrimController.setHasBackdrop(false); + mScrimController.setWallpaperSupportsAmbientMode(false); + mScrimController.transitionTo(ScrimState.KEYGUARD); + finishAnimationsImmediately(); + + // WHEN Simulate unlock with fingerprint + mScrimController.transitionTo(ScrimState.AOD); + finishAnimationsImmediately(); + + // WHEN transitioning to UNLOCKED, onDisplayCallbackBlanked callback called to continue + // the transition but the scrim was not actually blanked + mScrimController.transitionTo(ScrimState.UNLOCKED, + new ScrimController.Callback() { + @Override + public void onDisplayBlanked() { + // Front scrim should not be black nor opaque + Assert.assertTrue("Scrim should NOT be visible during transition." + + " Alpha: " + mScrimInFront.getViewAlpha(), + mScrimInFront.getViewAlpha() == 0f); + Assert.assertSame("Scrim should not be visible during transition.", + mScrimVisibility, TRANSPARENT); + } + }); + finishAnimationsImmediately(); } @Test -- cgit v1.2.3-59-g8ed1b