Merge "[flexiglass] Always round up the remaining throttle milliseconds." into main
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index d968c1b..661c345 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -27,8 +27,6 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.scene.SceneTestUtils
 import com.google.common.truth.Truth.assertThat
-import kotlin.time.Duration.Companion.milliseconds
-import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
@@ -335,7 +333,7 @@
                     AuthenticationThrottlingModel(
                         failedAttemptCount =
                             FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
-                        remainingMs = FakeAuthenticationRepository.THROTTLE_DURATION_MS,
+                        remainingSeconds = FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS,
                     )
                 )
 
@@ -347,15 +345,12 @@
                     AuthenticationThrottlingModel(
                         failedAttemptCount =
                             FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
-                        remainingMs = FakeAuthenticationRepository.THROTTLE_DURATION_MS,
+                        remainingSeconds = FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS,
                     )
                 )
 
             // Move the clock forward to ALMOST skip the throttling, leaving one second to go:
-            val throttleTimeoutSec =
-                FakeAuthenticationRepository.THROTTLE_DURATION_MS.milliseconds.inWholeSeconds
-                    .toInt()
-            repeat(throttleTimeoutSec - 1) { time ->
+            repeat(FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS - 1) { time ->
                 advanceTimeBy(1000)
                 assertThat(throttling)
                     .isEqualTo(
@@ -363,9 +358,8 @@
                             failedAttemptCount =
                                 FakeAuthenticationRepository
                                     .MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
-                            remainingMs =
-                                ((throttleTimeoutSec - (time + 1)).seconds.inWholeMilliseconds)
-                                    .toInt(),
+                            remainingSeconds =
+                                FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS - (time + 1),
                         )
                     )
             }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 04f6cd3..3e3a1a9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.scene.SceneTestUtils
 import com.google.common.truth.Truth.assertThat
-import kotlin.math.ceil
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.advanceTimeBy
@@ -268,7 +267,7 @@
                     AuthenticationThrottlingModel(
                         failedAttemptCount =
                             FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING,
-                        remainingMs = FakeAuthenticationRepository.THROTTLE_DURATION_MS,
+                        remainingSeconds = FakeAuthenticationRepository.THROTTLE_DURATION_SECONDS,
                     )
                 )
             assertTryAgainMessage(
@@ -286,8 +285,7 @@
                     .toInt()
             )
 
-            throttling?.remainingMs?.let { remainingMs ->
-                val seconds = ceil(remainingMs / 1000f).toInt()
+            throttling?.remainingSeconds?.let { seconds ->
                 repeat(seconds) { time ->
                     advanceTimeBy(1000)
                     val remainingTimeSec = seconds - time - 1
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index 75d6a00..2b64d8e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.scene.SceneTestUtils
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flatMapLatest
@@ -144,7 +145,9 @@
             }
             assertThat(message?.isUpdateAnimated).isFalse()
 
-            throttling?.remainingMs?.let { remainingMs -> advanceTimeBy(remainingMs.toLong()) }
+            throttling?.remainingSeconds?.let { remainingSeconds ->
+                advanceTimeBy(remainingSeconds.seconds.inWholeMilliseconds)
+            }
             assertThat(message?.isUpdateAnimated).isTrue()
         }
 
@@ -167,7 +170,9 @@
             }
             assertThat(isInputEnabled).isFalse()
 
-            throttling?.remainingMs?.let { milliseconds -> advanceTimeBy(milliseconds.toLong()) }
+            throttling?.remainingSeconds?.let { remainingSeconds ->
+                advanceTimeBy(remainingSeconds.seconds.inWholeMilliseconds)
+            }
             assertThat(isInputEnabled).isTrue()
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 64f2946..a217d93 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -335,12 +335,12 @@
             repeat(failedAttemptCount) {
                 authenticationRepository.reportAuthenticationAttempt(false)
             }
-            val remainingTimeMs = 30_000
-            authenticationRepository.setThrottleDuration(remainingTimeMs)
+            val remainingTimeSeconds = 30
+            authenticationRepository.setThrottleDuration(remainingTimeSeconds * 1000)
             authenticationRepository.throttling.value =
                 AuthenticationThrottlingModel(
                     failedAttemptCount = failedAttemptCount,
-                    remainingMs = remainingTimeMs,
+                    remainingSeconds = remainingTimeSeconds,
                 )
         } else {
             authenticationRepository.reportAuthenticationAttempt(true)
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index 1ba0220..4e67771 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
+import kotlin.math.ceil
 import kotlin.math.max
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
@@ -283,7 +284,7 @@
                 if (remainingMs > 0) {
                     AuthenticationThrottlingModel(
                         failedAttemptCount = failedAttemptCount.await(),
-                        remainingMs = remainingMs.toInt(),
+                        remainingSeconds = ceil(remainingMs / 1000f).toInt(),
                     )
                 } else {
                     null // Throttling ended.
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationThrottlingModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationThrottlingModel.kt
index d0d398e..8392528 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationThrottlingModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationThrottlingModel.kt
@@ -23,10 +23,13 @@
     val failedAttemptCount: Int = 0,
 
     /**
-     * Remaining amount of time, in milliseconds, before another authentication attempt can be done.
-     * If not throttling this will be `0`.
+     * Remaining amount of time, in seconds, before another authentication attempt can be done. If
+     * not throttling this will be `0`.
      *
      * This number is changed throughout the timeout.
+     *
+     * Note: this isn't precise (in milliseconds), but rounded up to ensure "at most" this amount of
+     * seconds remains.
      */
-    val remainingMs: Int = 0,
+    val remainingSeconds: Int = 0,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index 1122877..677f60d 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.scene.shared.flag.SceneContainerFlags
 import com.android.systemui.util.kotlin.pairwise
 import javax.inject.Inject
-import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.async
 import kotlinx.coroutines.flow.MutableSharedFlow
@@ -259,7 +258,7 @@
             throttlingModel != null ->
                 applicationContext.getString(
                     com.android.internal.R.string.lockscreen_too_many_failed_attempts_countdown,
-                    throttlingModel.remainingMs.milliseconds.inWholeSeconds,
+                    throttlingModel.remainingSeconds,
                 )
             message != null -> message
             else -> ""
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index 58fa857..fefc3e3 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.user.ui.viewmodel.UserViewModel
 import dagger.Module
 import dagger.Provides
-import kotlin.math.ceil
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.SupervisorJob
@@ -205,7 +204,7 @@
                             applicationContext.getString(
                                 authMethodViewModel.throttlingMessageId,
                                 throttling.failedAttemptCount,
-                                ceil(throttling.remainingMs / 1000f).toInt(),
+                                throttling.remainingSeconds,
                             )
                         } else {
                             null
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
index 094616f..aa0d7b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerMessageInteractorTest.kt
@@ -35,7 +35,7 @@
 import com.android.systemui.bouncer.ui.BouncerView
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.SystemPropertiesHelper
 import com.android.systemui.keyguard.DismissCallbackRegistry
@@ -62,7 +62,6 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
-import org.mockito.Mockito
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
@@ -108,17 +107,18 @@
 
     suspend fun TestScope.init() {
         userRepository.setSelectedUserInfo(PRIMARY_USER)
-        val featureFlags = FakeFeatureFlags().apply { set(Flags.REVAMPED_BOUNCER_MESSAGES, true) }
+        val featureFlags =
+            FakeFeatureFlagsClassic().apply { set(Flags.REVAMPED_BOUNCER_MESSAGES, true) }
         primaryBouncerInteractor =
             PrimaryBouncerInteractor(
                 bouncerRepository,
-                Mockito.mock(BouncerView::class.java),
-                Mockito.mock(Handler::class.java),
-                Mockito.mock(KeyguardStateController::class.java),
-                Mockito.mock(KeyguardSecurityModel::class.java),
-                Mockito.mock(PrimaryBouncerCallbackInteractor::class.java),
-                Mockito.mock(FalsingCollector::class.java),
-                Mockito.mock(DismissCallbackRegistry::class.java),
+                mock(BouncerView::class.java),
+                mock(Handler::class.java),
+                mock(KeyguardStateController::class.java),
+                mock(KeyguardSecurityModel::class.java),
+                mock(PrimaryBouncerCallbackInteractor::class.java),
+                mock(FalsingCollector::class.java),
+                mock(DismissCallbackRegistry::class.java),
                 context,
                 keyguardUpdateMonitor,
                 fakeTrustRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
index 4fdea97..0327087 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
@@ -166,7 +166,8 @@
                 AuthenticationPatternCoordinate(0, 2),
             )
         const val MAX_FAILED_AUTH_TRIES_BEFORE_THROTTLING = 5
-        const val THROTTLE_DURATION_MS = 30000
+        const val THROTTLE_DURATION_SECONDS = 30
+        const val THROTTLE_DURATION_MS = THROTTLE_DURATION_SECONDS * 1000
         const val HINTING_PIN_LENGTH = 6
         val DEFAULT_PIN = buildList { repeat(HINTING_PIN_LENGTH) { add(it + 1) } }