Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 967a2eaf authored by Beverly's avatar Beverly
Browse files

Only show auth UI after screen-off UDFPS fail

On the first two UDFPS screen-off soft or hard errors,
only show the fingerprint sensor icon and keyguard
indication area (auth error messages surface there).
After 3+ failed attempts, show the full AOD UI.

This CL doesn't update this logic, but continues
to support:
When the user gets locked out (due to too many failed
fingerprints), the device wakes up and the bouncer shows.

To accomplish this, this CL:
  * Updates DozeTriggering logic so that the auth UI only
  shows when the udfps screen off feature is enabled and
  aod is not enabled
  * Updates the fingerprint pulse so that the auth UI-only
  state gets triggered on the first two soft/hard errors,
  and then shows the full AOD UI on subsequent errors
  * Introduces nonAuthUIAlpha to DozingTransitionFlows which
  gets consumed by <KeyguardState>ToDozingTransitionViewModels
  and then used in the KeyguardRootViewModel
  * Update ClockEventController to update the dozeAmount
  based on the nonAuthUIAlpha since it may be hidden
  while DOZING due to the dozing auth pulse
Test: atest DozeServiceHostTest DozingTransitionFlowsTest
Flag: com.android.systemui.new_dozing_keyguard_states
Bug: 415704030

Change-Id: If77b6ebebef8d48bddb208d2c74feda2b0e06ffe
parent 2219f18c
Loading
Loading
Loading
Loading
+131 −6
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ class DozingTransitionFlowsTest : SysuiTestCase() {
    @Test
    fun lockscreenAlpha_dozing_dozePulsing() =
        testScope.runTest {
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha)
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
@@ -65,7 +65,7 @@ class DozingTransitionFlowsTest : SysuiTestCase() {
    @Test
    fun lockscreenAlpha_dozing_dozePulsingAuthUI() =
        testScope.runTest {
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha)
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
@@ -81,7 +81,7 @@ class DozingTransitionFlowsTest : SysuiTestCase() {
    @Test
    fun lockscreenAlpha_keyguardStateDozing_dozeTransitionModelDoze() =
        testScope.runTest {
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha)
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
@@ -97,7 +97,7 @@ class DozingTransitionFlowsTest : SysuiTestCase() {
    @Test
    fun lockscreenAlpha_keyguardStateDozing_dozeTransitionModelDozePulsingWithoutUI() =
        testScope.runTest {
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha)
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
@@ -113,7 +113,7 @@ class DozingTransitionFlowsTest : SysuiTestCase() {
    @Test
    fun lockscreenAlpha_keyguardStateDozing_dozeTransitionModelUnhandledStates() =
        testScope.runTest {
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha)
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
@@ -140,7 +140,7 @@ class DozingTransitionFlowsTest : SysuiTestCase() {
    @Test
    fun lockscreenAlpha_notKeyguardStateDozing_nothingEmits() =
        testScope.runTest {
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha)
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))
            // Last startedKeyguardTransitionStep is to AOD (not DOZING)
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToAodStep(0f, STARTED)
@@ -158,6 +158,131 @@ class DozingTransitionFlowsTest : SysuiTestCase() {
            assertThat(lockscreenAlpha).isNull()
        }

    @Test
    fun nonAuthUIAlpha_dozing_dozePulsing() =
        testScope.runTest {
            val nonAuthUIAlpha by collectLastValue(underTest.nonAuthUIAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
            )
            runCurrent()
            kosmos.fakeKeyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(to = DozeStateModel.DOZE_PULSING)
            )
            runCurrent()
            assertThat(nonAuthUIAlpha).isEqualTo(1f)
        }

    @Test
    fun nonAuthUIAlpha_dozing_dozePulsingAuthUI() =
        testScope.runTest {
            val nonAuthUIAlpha by collectLastValue(underTest.nonAuthUIAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
            )
            runCurrent()
            kosmos.fakeKeyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(to = DozeStateModel.DOZE_PULSING_AUTH_UI)
            )
            runCurrent()
            assertThat(nonAuthUIAlpha).isEqualTo(0f)
        }

    @Test
    fun nonAuthUIAlpha_notKeyguardStateDozing_nothingEmits() =
        testScope.runTest {
            val nonAuthUIAlpha by collectLastValue(underTest.nonAuthUIAlpha(null))
            // Last startedKeyguardTransitionStep is to AOD (not DOZING)
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToAodStep(0f, STARTED)
            )
            runCurrent()
            kosmos.fakeKeyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(to = DozeStateModel.DOZE_PULSING)
            )
            runCurrent()
            assertThat(nonAuthUIAlpha).isNull()
            kosmos.fakeKeyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(to = DozeStateModel.DOZE_PULSING_BRIGHT)
            )
            runCurrent()
            assertThat(nonAuthUIAlpha).isNull()
        }

    @Test
    fun wasHiddenAuthUIShowingWhileDozing_falseFromLockscreenAlpha() =
        testScope.runTest {
            val wasHiddenAuthUIShowingWhileDozing by
                collectLastValue(underTest.wasHiddenAuthUIShowingWhileDozing)
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))

            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
            )
            runCurrent()
            kosmos.fakeKeyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(to = DozeStateModel.DOZE)
            )
            runCurrent()

            // GIVEN lockscreen alpha is 0f
            assertThat(lockscreenAlpha).isEqualTo(0f)

            // THEN wasHiddenAuthUIShowingWhileDozing should be false
            assertThat(wasHiddenAuthUIShowingWhileDozing).isEqualTo(false)
        }

    @Test
    fun wasHiddenAuthUIShowingWhileDozing_falseFromNonAuthUIAlpha() =
        testScope.runTest {
            val wasHiddenAuthUIShowingWhileDozing by
                collectLastValue(underTest.wasHiddenAuthUIShowingWhileDozing)
            val nonAuthUIAlpha by collectLastValue(underTest.nonAuthUIAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
            )
            runCurrent()
            kosmos.fakeKeyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(to = DozeStateModel.DOZE_PULSING_AUTH_UI)
            )
            runCurrent()

            // GIVEN nonAuthUIAlpha alpha is 0f
            assertThat(nonAuthUIAlpha).isEqualTo(0f)

            // THEN wasHiddenAuthUIShowingWhileDozing should be false
            assertThat(wasHiddenAuthUIShowingWhileDozing).isEqualTo(false)
        }

    @Test
    fun wasHiddenAuthUIShowingWhileDozing_true() =
        testScope.runTest {
            val wasHiddenAuthUIShowingWhileDozing by
                collectLastValue(underTest.wasHiddenAuthUIShowingWhileDozing)
            val nonAuthUIAlpha by collectLastValue(underTest.nonAuthUIAlpha(null))
            val lockscreenAlpha by collectLastValue(underTest.lockscreenAlpha(null))
            // Last startedKeyguardTransitionStep is to DOZING
            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(
                lockscreenToDozingStep(0f, STARTED)
            )
            runCurrent()
            kosmos.fakeKeyguardRepository.setDozeTransitionModel(
                DozeTransitionModel(to = DozeStateModel.DOZE_PULSING)
            )
            runCurrent()

            // GIVEN nonAuthUIAlpha and lockscreen alphas are 1f
            assertThat(nonAuthUIAlpha).isEqualTo(1f)
            assertThat(lockscreenAlpha).isEqualTo(1f)

            // THEN wasHiddenAuthUIShowingWhileDozing should be true
            assertThat(wasHiddenAuthUIShowingWhileDozing).isEqualTo(true)
        }

    private fun lockscreenToDozingStep(value: Float, transitionState: TransitionState = RUNNING) =
        TransitionStep(
            from = KeyguardState.LOCKSCREEN,
+12 −5
Original line number Diff line number Diff line
@@ -197,13 +197,15 @@ public class DozeServiceHostTest extends SysuiTestCase {
                        DozeLog.REASON_SENSOR_QUICK_PICKUP,
                        DozeLog.PULSE_REASON_FINGERPRINT_ACTIVATED,
                        DozeLog.REASON_SENSOR_TAP,
                        DozeLog.PULSE_REASON_MINMODE));
                        DozeLog.PULSE_REASON_MINMODE,
                        DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS, // auth interrupt occurs elsewhere
                        DozeLog.PULSE_REASON_FINGERPRINT_PULSE_SHOW_FULL_UI,
                        DozeLog.PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI));
        // These are full wakeups, not pulses:
        HashSet<Integer> reasonsThatDontPulse = new HashSet<>(
                Arrays.asList(DozeLog.REASON_SENSOR_PICKUP,
                        DozeLog.REASON_SENSOR_DOUBLE_TAP,
                        DozeLog.REASON_SENSOR_TAP,
                        DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS,
                        DozeLog.PULSE_REASON_FINGERPRINT_PULSE));
                        DozeLog.REASON_SENSOR_TAP));

        doAnswer(invocation -> {
            DozeHost.PulseCallback callback = invocation.getArgument(0);
@@ -261,6 +263,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_NEW_DOZING_KEYGUARD_STATES)
    @EnableFlags(Flags.FLAG_UDFPS_SCREEN_OFF_UNLOCK_FLICKER)
    public void testCollectingUsUdfpsPulseEvents_shouldNotCollect() {
        // Should not collect pulse events if not usudfps.
@@ -291,7 +294,10 @@ public class DozeServiceHostTest extends SysuiTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_UDFPS_SCREEN_OFF_UNLOCK_FLICKER)
    @DisableFlags({
            Flags.FLAG_UDFPS_SCREEN_OFF_UNLOCK_FLICKER,
            Flags.FLAG_NEW_DOZING_KEYGUARD_STATES
    })
    public void testCollectingUsUdfpsPulseEvents_shouldNotCollect_flagDisabled() {
        // Should not collect pulse events if the bug flag is disabled.
        mKosmos.getFingerprintPropertyRepository().setProperties(
@@ -308,6 +314,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
    }

    @Test
    @DisableFlags(Flags.FLAG_NEW_DOZING_KEYGUARD_STATES)
    @EnableFlags(Flags.FLAG_UDFPS_SCREEN_OFF_UNLOCK_FLICKER)
    public void testCollectingUsUdfpsPulseEvents() {
        mKosmos.getFingerprintPropertyRepository().setProperties(
+9 −5
Original line number Diff line number Diff line
@@ -579,7 +579,8 @@ public class DozeLog implements Dumpable {
            case REASON_SENSOR_UDFPS_LONG_PRESS: return "udfps";
            case REASON_SENSOR_QUICK_PICKUP: return "quickPickup";
            case PULSE_REASON_FINGERPRINT_ACTIVATED: return "fingerprint-triggered";
            case PULSE_REASON_FINGERPRINT_PULSE: return "fingerprint-pulse";
            case PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI: return "fingerprint-pulse-auth-ui";
            case PULSE_REASON_FINGERPRINT_PULSE_SHOW_FULL_UI: return "fingerprint-pulse-full-ui";
            case PULSE_REASON_MINMODE: return "minmode";
            default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
        }
@@ -611,7 +612,9 @@ public class DozeLog implements Dumpable {
            PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
            PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP_PRESENCE,
            PULSE_REASON_SENSOR_WAKE_REACH, REASON_SENSOR_TAP,
            PULSE_REASON_FINGERPRINT_PULSE, REASON_SENSOR_QUICK_PICKUP,
            PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI,
            PULSE_REASON_FINGERPRINT_PULSE_SHOW_FULL_UI,
            REASON_SENSOR_QUICK_PICKUP,
            PULSE_REASON_FINGERPRINT_ACTIVATED, PULSE_REASON_MINMODE
    })
    public @interface Reason {}
@@ -629,8 +632,9 @@ public class DozeLog implements Dumpable {
    public static final int REASON_SENSOR_UDFPS_LONG_PRESS = 10;
    public static final int REASON_SENSOR_QUICK_PICKUP = 11;
    public static final int PULSE_REASON_FINGERPRINT_ACTIVATED = 12;
    public static final int PULSE_REASON_FINGERPRINT_PULSE = 13;
    public static final int PULSE_REASON_MINMODE = 14;
    public static final int PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI = 13;
    public static final int PULSE_REASON_FINGERPRINT_PULSE_SHOW_FULL_UI = 14;
    public static final int PULSE_REASON_MINMODE = 15;

    public static final int TOTAL_REASONS = 15;
    public static final int TOTAL_REASONS = 16;
}
+5 −3
Original line number Diff line number Diff line
@@ -606,7 +606,7 @@ public class DozeTriggers implements DozeMachine.Part {
        // When we're already showing selective UI (or no UI) while pulsing, we can directly
        // go to other pulsing states.
        if (selectiveUiPulsing) {
            if (reason == DozeLog.PULSE_REASON_FINGERPRINT_PULSE) {
            if (reason == DozeLog.PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI) {
                mMachine.requestState(State.DOZE_PULSING_AUTH_UI);
            }  else {
                mMachine.requestState(State.DOZE_PULSING);
@@ -760,7 +760,7 @@ public class DozeTriggers implements DozeMachine.Part {
        public void onUltrasonicUdfpsPulseWhileScreenOff(FingerprintAuthenticationStatus state) {
            if (!udfpsScreenOffUnlockFlicker()) return;
            mDozeLog.traceUltrasonicScreenOffPulseEvent(state);
            requestPulse(DozeLog.PULSE_REASON_FINGERPRINT_PULSE, true, null);
            requestPulse(DozeLog.PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI, true, null);

        }
        @Override
@@ -768,7 +768,9 @@ public class DozeTriggers implements DozeMachine.Part {
            mUdfpsHelpMessagesThisAodSession++;
            mDozeLog.traceFingerprintScreenOffPulseEvent(state, mUdfpsHelpMessagesThisAodSession);
            if (mUdfpsHelpMessagesThisAodSession >= 3) {
                requestPulse(DozeLog.PULSE_REASON_FINGERPRINT_PULSE, true, null);
                requestPulse(DozeLog.PULSE_REASON_FINGERPRINT_PULSE_SHOW_FULL_UI, true, null);
            } else {
                requestPulse(DozeLog.PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI, true, null);
            }
        }
    };
+4 −2
Original line number Diff line number Diff line
@@ -103,10 +103,12 @@ public class DozeUi implements DozeMachine.Part {
                                requestState = DozeMachine.State.DOZE_PULSING_BRIGHT;
                            }

                            if (com.android.systemui.Flags.newDozingKeyguardStates()) {
                            if (com.android.systemui.Flags.newDozingKeyguardStates()
                                    && !mDozeParameters.getAlwaysOn()) {
                                if (reason == DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS) {
                                    requestState = DozeMachine.State.DOZE_PULSING_WITHOUT_UI;
                                } else if (reason == DozeLog.PULSE_REASON_FINGERPRINT_PULSE) {
                                } else if (reason
                                        == DozeLog.PULSE_REASON_FINGERPRINT_PULSE_SHOW_AUTH_UI) {
                                    requestState = DozeMachine.State.DOZE_PULSING_AUTH_UI;
                                }
                            }
Loading