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

Commit 6c467212 authored by Austin Delgado's avatar Austin Delgado
Browse files

Add check for matching RequestId before resetting BP

Test: atest com.android.systemui.biometrics
Bug: 339531860
Flag: None
Change-Id: Id3b395005be0eec0eb5d1cc35f4ae796f66d6a1a
parent 71875b5f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -362,7 +362,7 @@ public class AuthContainerView extends LinearLayout

        mPromptSelectorInteractorProvider = promptSelectorInteractorProvider;
        mPromptSelectorInteractorProvider.get().setPrompt(mConfig.mPromptInfo, mEffectiveUserId,
                biometricModalities, mConfig.mOperationId, mConfig.mOpPackageName,
                getRequestId(), biometricModalities, mConfig.mOperationId, mConfig.mOpPackageName,
                false /*onSwitchToCredential*/);

        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
@@ -436,7 +436,7 @@ public class AuthContainerView extends LinearLayout
                addCredentialView(true, false);
            }
        } else {
            mPromptSelectorInteractorProvider.get().resetPrompt();
            mPromptSelectorInteractorProvider.get().resetPrompt(getRequestId());
        }
    }

@@ -884,7 +884,8 @@ public class AuthContainerView extends LinearLayout
        final Runnable endActionRunnable = () -> {
            setVisibility(View.INVISIBLE);
            if (Flags.customBiometricPrompt() && constraintBp()) {
                mPromptSelectorInteractorProvider.get().resetPrompt();
                // TODO(b/288175645): resetPrompt calls should be lifecycle aware
                mPromptSelectorInteractorProvider.get().resetPrompt(getRequestId());
            }
            removeWindowIfAttached();
        };
+22 −7
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics.data.repository

import android.hardware.biometrics.PromptInfo
import android.util.Log
import com.android.systemui.biometrics.AuthController
import com.android.systemui.biometrics.shared.model.PromptKind
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -49,6 +50,9 @@ interface PromptRepository {
    /** The user that the prompt is for. */
    val userId: StateFlow<Int?>

    /** The request that the prompt is for. */
    val requestId: StateFlow<Long?>

    /** The gatekeeper challenge, if one is associated with this prompt. */
    val challenge: StateFlow<Long?>

@@ -69,13 +73,14 @@ interface PromptRepository {
    fun setPrompt(
        promptInfo: PromptInfo,
        userId: Int,
        requestId: Long,
        gatekeeperChallenge: Long?,
        kind: PromptKind,
        opPackageName: String,
    )

    /** Unset the prompt info. */
    fun unsetPrompt()
    fun unsetPrompt(requestId: Long)
}

@SysUISingleton
@@ -109,6 +114,9 @@ constructor(
    private val _userId: MutableStateFlow<Int?> = MutableStateFlow(null)
    override val userId = _userId.asStateFlow()

    private val _requestId: MutableStateFlow<Long?> = MutableStateFlow(null)
    override val requestId = _requestId.asStateFlow()

    private val _promptKind: MutableStateFlow<PromptKind> = MutableStateFlow(PromptKind.None)
    override val promptKind = _promptKind.asStateFlow()

@@ -132,23 +140,30 @@ constructor(
    override fun setPrompt(
        promptInfo: PromptInfo,
        userId: Int,
        requestId: Long,
        gatekeeperChallenge: Long?,
        kind: PromptKind,
        opPackageName: String,
    ) {
        _promptKind.value = kind
        _userId.value = userId
        _requestId.value = requestId
        _challenge.value = gatekeeperChallenge
        _promptInfo.value = promptInfo
        _opPackageName.value = opPackageName
    }

    override fun unsetPrompt() {
    override fun unsetPrompt(requestId: Long) {
        if (requestId == _requestId.value) {
            _promptInfo.value = null
            _userId.value = null
            _requestId.value = null
            _challenge.value = null
            _promptKind.value = PromptKind.None
            _opPackageName.value = null
        } else {
            Log.w(TAG, "Ignoring unsetPrompt - requestId mismatch")
        }
    }

    companion object {
+7 −3
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ interface PromptSelectorInteractor {
    fun setPrompt(
        promptInfo: PromptInfo,
        effectiveUserId: Int,
        requestId: Long,
        modalities: BiometricModalities,
        challenge: Long,
        opPackageName: String,
@@ -93,7 +94,7 @@ interface PromptSelectorInteractor {
    )

    /** Unset the current authentication request. */
    fun resetPrompt()
    fun resetPrompt(requestId: Long)
}

@SysUISingleton
@@ -161,6 +162,7 @@ constructor(
        setPrompt(
            promptRepository.promptInfo.value!!,
            promptRepository.userId.value!!,
            promptRepository.requestId.value!!,
            modalities,
            promptRepository.challenge.value!!,
            promptRepository.opPackageName.value!!,
@@ -171,6 +173,7 @@ constructor(
    override fun setPrompt(
        promptInfo: PromptInfo,
        effectiveUserId: Int,
        requestId: Long,
        modalities: BiometricModalities,
        challenge: Long,
        opPackageName: String,
@@ -198,13 +201,14 @@ constructor(
        promptRepository.setPrompt(
            promptInfo = promptInfo,
            userId = effectiveUserId,
            requestId = requestId,
            gatekeeperChallenge = challenge,
            kind = kind,
            opPackageName = opPackageName,
        )
    }

    override fun resetPrompt() {
        promptRepository.unsetPrompt()
    override fun resetPrompt(requestId: Long) {
        promptRepository.unsetPrompt(requestId)
    }
}
+29 −3
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit

private const val USER_ID = 9
private const val REQUEST_ID = 9L
private const val WRONG_REQUEST_ID = 10L
private const val CHALLENGE = 90L
private const val OP_PACKAGE_NAME = "biometric.testapp"

@@ -105,6 +107,7 @@ class PromptRepositoryImplTest : SysuiTestCase() {
                repository.setPrompt(
                    PromptInfo().apply { isConfirmationRequested = case },
                    USER_ID,
                    REQUEST_ID,
                    CHALLENGE,
                    PromptKind.Biometric(),
                    OP_PACKAGE_NAME
@@ -124,6 +127,7 @@ class PromptRepositoryImplTest : SysuiTestCase() {
                repository.setPrompt(
                    PromptInfo().apply { isConfirmationRequested = case },
                    USER_ID,
                    REQUEST_ID,
                    CHALLENGE,
                    PromptKind.Biometric(),
                    OP_PACKAGE_NAME
@@ -134,12 +138,12 @@ class PromptRepositoryImplTest : SysuiTestCase() {
        }

    @Test
    fun setsAndUnsetsPrompt() =
    fun setsAndUnsetsPrompt_whenRequestIdMatches() =
        testScope.runTest {
            val kind = PromptKind.Pin
            val promptInfo = PromptInfo()

            repository.setPrompt(promptInfo, USER_ID, CHALLENGE, kind, OP_PACKAGE_NAME)
            repository.setPrompt(promptInfo, USER_ID, REQUEST_ID, CHALLENGE, kind, OP_PACKAGE_NAME)

            assertThat(repository.promptKind.value).isEqualTo(kind)
            assertThat(repository.userId.value).isEqualTo(USER_ID)
@@ -147,11 +151,33 @@ class PromptRepositoryImplTest : SysuiTestCase() {
            assertThat(repository.promptInfo.value).isSameInstanceAs(promptInfo)
            assertThat(repository.opPackageName.value).isEqualTo(OP_PACKAGE_NAME)

            repository.unsetPrompt()
            repository.unsetPrompt(REQUEST_ID)

            assertThat(repository.promptInfo.value).isNull()
            assertThat(repository.userId.value).isNull()
            assertThat(repository.challenge.value).isNull()
            assertThat(repository.opPackageName.value).isNull()
        }

    @Test
    fun setsAndUnsetsPrompt_whenRequestIdDoesNotMatch() =
        testScope.runTest {
            val kind = PromptKind.Pin
            val promptInfo = PromptInfo()

            repository.setPrompt(promptInfo, USER_ID, REQUEST_ID, CHALLENGE, kind, OP_PACKAGE_NAME)

            assertThat(repository.promptKind.value).isEqualTo(kind)
            assertThat(repository.userId.value).isEqualTo(USER_ID)
            assertThat(repository.challenge.value).isEqualTo(CHALLENGE)
            assertThat(repository.promptInfo.value).isSameInstanceAs(promptInfo)
            assertThat(repository.opPackageName.value).isEqualTo(OP_PACKAGE_NAME)

            repository.unsetPrompt(WRONG_REQUEST_ID)

            assertThat(repository.promptInfo.value).isNotNull()
            assertThat(repository.userId.value).isNotNull()
            assertThat(repository.challenge.value).isNotNull()
            assertThat(repository.opPackageName.value).isNotNull()
        }
}
+10 −3
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import org.junit.runners.JUnit4
import org.mockito.junit.MockitoJUnit

private const val USER_ID = 22
private const val REQUEST_ID = 22L
private const val OPERATION_ID = 100L
private const val OP_PACKAGE_NAME = "biometric.testapp"

@@ -112,6 +113,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
                },
                kind = PromptKind.Pin,
                userId = USER_ID,
                requestId = REQUEST_ID,
                challenge = OPERATION_ID,
                opPackageName = OP_PACKAGE_NAME
            )
@@ -137,6 +139,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
                },
                kind = PromptKind.Pin,
                userId = USER_ID,
                requestId = REQUEST_ID,
                challenge = OPERATION_ID,
                opPackageName = OP_PACKAGE_NAME
            )
@@ -165,6 +168,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
                },
                kind = PromptKind.Pin,
                userId = USER_ID,
                requestId = REQUEST_ID,
                challenge = OPERATION_ID,
                opPackageName = OP_PACKAGE_NAME
            )
@@ -198,6 +202,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
                },
                kind = kind,
                userId = USER_ID,
                requestId = REQUEST_ID,
                challenge = OPERATION_ID,
                opPackageName = OP_PACKAGE_NAME
            )
@@ -223,7 +228,7 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
                assertThat(pattern.stealthMode).isEqualTo(isStealth)
            }

            interactor.resetPrompt()
            interactor.resetPrompt(REQUEST_ID)

            assertThat(prompt).isNull()
        }
@@ -346,12 +351,14 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
        promptInfo: PromptInfo,
        kind: PromptKind,
        userId: Int,
        requestId: Long,
        challenge: Long,
        opPackageName: String,
    ) {
        biometricPromptRepository.setPrompt(
            promptInfo,
            userId,
            requestId,
            challenge,
            kind,
            opPackageName,
@@ -359,8 +366,8 @@ class PromptCredentialInteractorTest : SysuiTestCase() {
    }

    /** Unset the current authentication request. */
    private fun PromptCredentialInteractor.resetPrompt() {
        biometricPromptRepository.unsetPrompt()
    private fun PromptCredentialInteractor.resetPrompt(requestId: Long) {
        biometricPromptRepository.unsetPrompt(requestId)
    }
}

Loading