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

Commit ffa9d87b authored by Curtis Belmonte's avatar Curtis Belmonte
Browse files

Check for null receiver in biometric AuthController

We've witnessed at least one crash due to mReceiver being null while
trying to handle callbacks such as onTryAgainPressed in AuthController
(formerly BiometricDialogImpl). In these cases, not running the callback
is likely better than crashing, so this commit adds null-checks where
they're currently missing. It also adds unit test cases to exercise the
new logic.

Test: atest AuthControllerTest
Fixes: 143251337
Change-Id: I3c46c7fab0dfe802de499180c7bb0c756f7e652b
parent ede9fb07
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -93,10 +93,13 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
                        Log.w(TAG, "Evicting client due to: " + topPackage);
                        mCurrentDialog.dismissWithoutCallback(true /* animate */);
                        mCurrentDialog = null;
                        mReceiver.onDialogDismissed(BiometricPrompt.DISMISSED_REASON_USER_CANCEL);
                        if (mReceiver != null) {
                            mReceiver.onDialogDismissed(
                                    BiometricPrompt.DISMISSED_REASON_USER_CANCEL);
                            mReceiver = null;
                        }
                    }
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Remote exception", e);
            }
@@ -105,6 +108,10 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,

    @Override
    public void onTryAgainPressed() {
        if (mReceiver == null) {
            Log.e(TAG, "onTryAgainPressed: Receiver is null");
            return;
        }
        try {
            mReceiver.onTryAgainPressed();
        } catch (RemoteException e) {
@@ -114,6 +121,10 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,

    @Override
    public void onDeviceCredentialPressed() {
        if (mReceiver == null) {
            Log.e(TAG, "onDeviceCredentialPressed: Receiver is null");
            return;
        }
        try {
            mReceiver.onDeviceCredentialPressed();
        } catch (RemoteException e) {
@@ -161,7 +172,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,

    private void sendResultAndCleanUp(@DismissedReason int reason) {
        if (mReceiver == null) {
            Log.e(TAG, "Receiver is null");
            Log.e(TAG, "sendResultAndCleanUp: Receiver is null");
            return;
        }
        try {
+14 −0
Original line number Diff line number Diff line
@@ -389,6 +389,20 @@ public class AuthControllerTest extends SysuiTestCase {
        verify(mReceiver).onDialogDismissed(eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL));
    }

    @Test
    public void testDoesNotCrash_whenTryAgainPressedAfterDismissal() {
        showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
        mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED);
        mAuthController.onTryAgainPressed();
    }

    @Test
    public void testDoesNotCrash_whenDeviceCredentialPressedAfterDismissal() {
        showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
        mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED);
        mAuthController.onDeviceCredentialPressed();
    }

    // Helpers

    private void showDialog(int authenticators, int biometricModality) {