Merge "Show only first face error message for coex." into udc-qpr-dev
This commit is contained in:
@@ -479,10 +479,10 @@ private class Spaghetti(
|
||||
failureReason,
|
||||
messageAfterError = modalities.asDefaultHelpMessage(applicationContext),
|
||||
authenticateAfterError = modalities.hasFingerprint,
|
||||
suppressIf = { currentMessage ->
|
||||
suppressIf = { currentMessage, history ->
|
||||
modalities.hasFaceAndFingerprint &&
|
||||
failedModality == BiometricModality.Face &&
|
||||
currentMessage.isError
|
||||
(currentMessage.isError || history.faceFailed)
|
||||
},
|
||||
failedModality = failedModality,
|
||||
)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.biometrics.ui.viewmodel
|
||||
|
||||
import com.android.systemui.biometrics.shared.model.BiometricModality
|
||||
|
||||
/** Contains metadata about key events that have occurred while biometric prompt is showing. */
|
||||
interface PromptHistory {
|
||||
|
||||
/** If face authentication has failed at least once. */
|
||||
val faceFailed: Boolean
|
||||
|
||||
/** If fingerprint authentication has failed at least once. */
|
||||
val fingerprintFailed: Boolean
|
||||
}
|
||||
|
||||
class PromptHistoryImpl : PromptHistory {
|
||||
private var failures = mutableSetOf<BiometricModality>()
|
||||
|
||||
override val faceFailed
|
||||
get() = failures.contains(BiometricModality.Face)
|
||||
|
||||
override val fingerprintFailed
|
||||
get() = failures.contains(BiometricModality.Fingerprint)
|
||||
|
||||
/** Record a failure event. */
|
||||
fun failure(modality: BiometricModality) {
|
||||
if (modality != BiometricModality.None) {
|
||||
failures.add(modality)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,7 @@ constructor(
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
|
||||
private val history = PromptHistoryImpl()
|
||||
private var messageJob: Job? = null
|
||||
|
||||
/**
|
||||
@@ -214,13 +215,13 @@ constructor(
|
||||
* is set (or via [showHelp] when not set) after the error is dismissed.
|
||||
*
|
||||
* The error is ignored if the user has already authenticated or if [suppressIf] is true given
|
||||
* the currently showing [PromptMessage].
|
||||
* the currently showing [PromptMessage] and [PromptHistory].
|
||||
*/
|
||||
suspend fun showTemporaryError(
|
||||
message: String,
|
||||
messageAfterError: String,
|
||||
authenticateAfterError: Boolean,
|
||||
suppressIf: (PromptMessage) -> Boolean = { false },
|
||||
suppressIf: (PromptMessage, PromptHistory) -> Boolean = { _, _ -> false },
|
||||
hapticFeedback: Boolean = true,
|
||||
failedModality: BiometricModality = BiometricModality.None,
|
||||
) = coroutineScope {
|
||||
@@ -230,7 +231,9 @@ constructor(
|
||||
|
||||
_canTryAgainNow.value = supportsRetry(failedModality)
|
||||
|
||||
if (suppressIf(_message.value)) {
|
||||
val suppress = suppressIf(_message.value, history)
|
||||
history.failure(failedModality)
|
||||
if (suppress) {
|
||||
return@coroutineScope
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.biometrics.ui.viewmodel
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.biometrics.shared.model.BiometricModality
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
|
||||
@SmallTest
|
||||
@RunWith(JUnit4::class)
|
||||
class PromptHistoryImplTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var history: PromptHistoryImpl
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
history = PromptHistoryImpl()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun empty() {
|
||||
assertThat(history.faceFailed).isFalse()
|
||||
assertThat(history.fingerprintFailed).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun faceFailed() =
|
||||
repeat(2) {
|
||||
history.failure(BiometricModality.None)
|
||||
history.failure(BiometricModality.Face)
|
||||
|
||||
assertThat(history.faceFailed).isTrue()
|
||||
assertThat(history.fingerprintFailed).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fingerprintFailed() =
|
||||
repeat(2) {
|
||||
history.failure(BiometricModality.None)
|
||||
history.failure(BiometricModality.Fingerprint)
|
||||
|
||||
assertThat(history.faceFailed).isFalse()
|
||||
assertThat(history.fingerprintFailed).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun coexFailed() =
|
||||
repeat(2) {
|
||||
history.failure(BiometricModality.Face)
|
||||
history.failure(BiometricModality.Fingerprint)
|
||||
|
||||
assertThat(history.faceFailed).isTrue()
|
||||
assertThat(history.fingerprintFailed).isTrue()
|
||||
|
||||
history.failure(BiometricModality.None)
|
||||
}
|
||||
}
|
||||
@@ -335,7 +335,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
|
||||
error,
|
||||
messageAfterError = "or me",
|
||||
authenticateAfterError = false,
|
||||
suppressIf = { _ -> true },
|
||||
suppressIf = { _, _ -> true },
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -364,7 +364,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa
|
||||
error,
|
||||
messageAfterError = "$error $afterSuffix",
|
||||
authenticateAfterError = false,
|
||||
suppressIf = { currentMessage -> suppress && currentMessage.isError },
|
||||
suppressIf = { currentMessage, _ -> suppress && currentMessage.isError },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user