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

Commit 64d77cc3 authored by Beverly's avatar Beverly Committed by Beverly Tai
Browse files

onTrustChanged callback triggered before onTrustGrantedForCurrentUser

KeyguardStateControllerImpl updates its internal state onTrustChanged,
which is then used onTrustGrantedForUser when the keyguard may be
dismissed, so the #onTrustChanged callback needs to be called
first, or else we may mistakenly end up preventing a keyguard
dismissal: "KeyguardSecurityView: Tried to dismiss keyguard when lockscreen is not dismissible and user was not authenticated with a primary security method (pin/password/pattern)."

Test: atest KeyguardUpdateMonitorTest
Fixes: 279547063
Change-Id: I239ffa1cfc1a252aaa7ea89f259f1f9bf97f2da3
parent 322a9ee2
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -522,6 +522,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                    FACE_AUTH_TRIGGERED_TRUST_DISABLED);
        }

        mLogger.logTrustChanged(wasTrusted, enabled, userId);
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onTrustChanged(userId);
            }
        }

        if (enabled) {
            String message = null;
            if (KeyguardUpdateMonitor.getCurrentUser() == userId
@@ -560,14 +568,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                }
            }
        }

        mLogger.logTrustChanged(wasTrusted, enabled, userId);
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onTrustChanged(userId);
            }
        }
    }

    /**
+32 −0
Original line number Diff line number Diff line
@@ -151,7 +151,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import org.mockito.internal.util.reflection.FieldSetter;
@@ -2737,6 +2739,36 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
        verifyFingerprintAuthenticateCall();
    }

    @Test
    public void onTrustChangedCallbacksCalledBeforeOnTrustGrantedForCurrentUserCallback() {
        // GIVEN device is interactive
        deviceIsInteractive();

        // GIVEN callback is registered
        KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
        mKeyguardUpdateMonitor.registerCallback(callback);

        // WHEN onTrustChanged enabled=true
        mKeyguardUpdateMonitor.onTrustChanged(
                true /* enabled */,
                true /* newlyUnlocked */,
                getCurrentUser() /* userId */,
                TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD /* flags */,
                null /* trustGrantedMessages */);

        // THEN onTrustChanged is called FIRST
        final InOrder inOrder = Mockito.inOrder(callback);
        inOrder.verify(callback).onTrustChanged(eq(getCurrentUser()));

        // AND THEN onTrustGrantedForCurrentUser callback called
        inOrder.verify(callback).onTrustGrantedForCurrentUser(
                eq(true) /* dismissKeyguard */,
                eq(true) /* newlyUnlocked */,
                eq(new TrustGrantFlags(TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD)),
                eq(null) /* message */
        );
    }

    private void verifyFingerprintAuthenticateNeverCalled() {
        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), any());
        verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),