summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt2
5 files changed, 62 insertions, 6 deletions
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 af3ddfca14b6..29ee87466f1a 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
@@ -17,6 +17,9 @@
package com.android.systemui.bouncer.ui.viewmodel
import android.content.pm.UserInfo
+import android.platform.test.annotations.EnableFlags
+import android.view.KeyEvent
+import androidx.compose.ui.input.key.KeyEventType
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.SceneKey
@@ -27,6 +30,7 @@ import com.android.systemui.authentication.shared.model.AuthenticationMethodMode
import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.inputmethod.data.model.InputMethodModel
import com.android.systemui.inputmethod.data.repository.fakeInputMethodRepository
import com.android.systemui.inputmethod.domain.interactor.inputMethodInteractor
@@ -67,11 +71,12 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
private val inputMethodInteractor by lazy { kosmos.inputMethodInteractor }
private val isInputEnabled = MutableStateFlow(true)
- private val underTest =
+ private val underTest by lazy {
kosmos.passwordBouncerViewModelFactory.create(
isInputEnabled = isInputEnabled,
onIntentionalUserInput = {},
)
+ }
@Before
fun setUp() {
@@ -345,6 +350,37 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
assertThat(textInputFocusRequested).isFalse()
}
+ @EnableFlags(com.android.systemui.Flags.FLAG_COMPOSE_BOUNCER)
+ @Test
+ fun consumeConfirmKeyEvents_toPreventItFromPropagating() =
+ testScope.runTest { verifyConfirmKeyEventsBehavior(keyUpEventConsumed = true) }
+
+ @EnableFlags(com.android.systemui.Flags.FLAG_COMPOSE_BOUNCER)
+ @EnableSceneContainer
+ @Test
+ fun noops_whenSceneContainerIsAlsoEnabled() =
+ testScope.runTest { verifyConfirmKeyEventsBehavior(keyUpEventConsumed = false) }
+
+ private fun verifyConfirmKeyEventsBehavior(keyUpEventConsumed: Boolean) {
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyDown, KeyEvent.KEYCODE_DPAD_CENTER))
+ .isFalse()
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyUp, KeyEvent.KEYCODE_DPAD_CENTER))
+ .isEqualTo(keyUpEventConsumed)
+
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyDown, KeyEvent.KEYCODE_ENTER)).isFalse()
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyUp, KeyEvent.KEYCODE_ENTER))
+ .isEqualTo(keyUpEventConsumed)
+
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyDown, KeyEvent.KEYCODE_NUMPAD_ENTER))
+ .isFalse()
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyUp, KeyEvent.KEYCODE_NUMPAD_ENTER))
+ .isEqualTo(keyUpEventConsumed)
+
+ // space is ignored.
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyUp, KeyEvent.KEYCODE_SPACE)).isFalse()
+ assertThat(underTest.onKeyEvent(KeyEventType.KeyDown, KeyEvent.KEYCODE_SPACE)).isFalse()
+ }
+
private fun TestScope.switchToScene(toScene: SceneKey) {
val currentScene by collectLastValue(sceneInteractor.currentScene)
val bouncerHidden = currentScene == Scenes.Bouncer && toScene != Scenes.Bouncer
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
index 148b9ea61e2c..1bcc1eeb4f12 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.bouncer.ui.viewmodel
import android.annotation.StringRes
+import androidx.compose.ui.input.key.KeyEventType
import com.android.systemui.authentication.domain.interactor.AuthenticationResult
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
@@ -122,6 +123,13 @@ sealed class AuthMethodBouncerViewModel(
/** Invoked after a successful authentication. */
protected open fun onSuccessfulAuthentication() = Unit
+ /**
+ * Invoked for any key events on the bouncer.
+ *
+ * @return whether the event was consumed by this method and should not be propagated further.
+ */
+ open fun onKeyEvent(type: KeyEventType, keyCode: Int): Boolean = false
+
/** Perform authentication result haptics */
private fun performAuthenticationHapticFeedback(result: AuthenticationResult) {
if (result == AuthenticationResult.SKIPPED) return
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt
index 5f973917440c..8427b27b78e1 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt
@@ -337,10 +337,8 @@ constructor(
* @return `true` when the [KeyEvent] was consumed as user input on bouncer; `false` otherwise.
*/
fun onKeyEvent(keyEvent: KeyEvent): Boolean {
- return (authMethodViewModel.value as? PinBouncerViewModel)?.onKeyEvent(
- keyEvent.type,
- keyEvent.nativeKeyEvent.keyCode,
- ) ?: false
+ return authMethodViewModel.value?.onKeyEvent(keyEvent.type, keyEvent.nativeKeyEvent.keyCode)
+ ?: false
}
data class DialogViewModel(
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
index 1427d787ea86..b8c6ab3783d5 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
@@ -16,9 +16,12 @@
package com.android.systemui.bouncer.ui.viewmodel
+import android.view.KeyEvent
import androidx.annotation.VisibleForTesting
+import androidx.compose.ui.input.key.KeyEventType
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.inputmethod.domain.interactor.InputMethodInteractor
import com.android.systemui.res.R
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
@@ -150,6 +153,17 @@ constructor(
return _password.value.toCharArray().toList()
}
+ override fun onKeyEvent(type: KeyEventType, keyCode: Int): Boolean {
+ // Ignore SPACE as a confirm key to allow the space character within passwords.
+ val isKeyboardEnterKey =
+ KeyEvent.isConfirmKey(keyCode) &&
+ keyCode != KeyEvent.KEYCODE_SPACE &&
+ type == KeyEventType.KeyUp
+ // consume confirm key events while on the bouncer. This prevents it from propagating
+ // and avoids other parent elements from receiving it.
+ return isKeyboardEnterKey && ComposeBouncerFlags.isOnlyComposeBouncerEnabled()
+ }
+
override fun onSuccessfulAuthentication() {
wasSuccessfullyAuthenticated = true
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
index 0cb4260e4d7f..5c8a9a692baf 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
@@ -251,7 +251,7 @@ constructor(
*
* @return `true` when the [KeyEvent] was consumed as user input on bouncer; `false` otherwise.
*/
- fun onKeyEvent(type: KeyEventType, keyCode: Int): Boolean {
+ override fun onKeyEvent(type: KeyEventType, keyCode: Int): Boolean {
return when (type) {
KeyEventType.KeyUp -> {
if (isConfirmKey(keyCode)) {