From 8d0f687b31bb8eb35955e7904794ff2dd5a22483 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Thu, 23 Feb 2023 15:49:35 -0800 Subject: [PATCH] Ensure keyboard is hidden when bouncer is... not showing. There are still cases where the keyboard will show. The most common case that I have observed is that when the falsing manager closes the bouncer after detecting a potential false touch. This can be done by clicking on a notification, and double tapping the alternate boucner overlay twice very quickly. The issue is that when we send a signal to show the keyboard, there is no way to stop that signal before the keyboard shows (from my understanding). The solution here is to listen to onApplyWindowInsets, which is called when the keyboard shows, and hide the keyboard if the bouncer is not showing. Fixes: 266816405 Test: Test as described above. Change-Id: I71419781ab91d8a1404d3571cd7e7d16b2a3afc9 --- .../KeyguardPasswordViewController.java | 10 ++++++++++ .../KeyguardPasswordViewControllerTest.kt | 20 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java index d221e22a4fcd7..a010c9a165174 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java @@ -26,6 +26,7 @@ import android.text.method.TextKeyListener; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup.MarginLayoutParams; +import android.view.WindowInsets; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; @@ -156,6 +157,15 @@ public class KeyguardPasswordViewController // TODO: Remove this workaround by ensuring such a race condition never happens. mMainExecutor.executeDelayed( this::updateSwitchImeButton, DELAY_MILLIS_TO_REEVALUATE_IME_SWITCH_ICON); + mView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @Override + public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { + if (!mKeyguardViewController.isBouncerShowing()) { + mView.hideKeyboard(); + } + return insets; + } + }); } @Override diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt index d912793993415..ed928702b981c 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt @@ -18,8 +18,10 @@ package com.android.keyguard import android.testing.AndroidTestingRunner import android.testing.TestableLooper +import android.view.View import android.view.inputmethod.InputMethodManager import android.widget.EditText +import android.widget.ImageView import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils @@ -30,6 +32,7 @@ import com.android.systemui.util.concurrency.DelayableExecutor import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyString import org.mockito.Mock @@ -37,6 +40,7 @@ import org.mockito.Mockito import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.`when` +import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations @SmallTest @@ -76,7 +80,9 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() { Mockito.`when`(keyguardPasswordView.findViewById(R.id.passwordEntry)) .thenReturn(passwordEntry) `when`(keyguardPasswordView.resources).thenReturn(context.resources) - keyguardPasswordViewController = + `when`(keyguardPasswordView.findViewById(R.id.switch_ime_button)) + .thenReturn(mock(ImageView::class.java)) + keyguardPasswordViewController = KeyguardPasswordViewController( keyguardPasswordView, keyguardUpdateMonitor, @@ -112,6 +118,18 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() { verify(keyguardPasswordView, never()).requestFocus() } + @Test + fun onApplyWindowInsetsListener_onApplyWindowInsets() { + `when`(keyguardViewController.isBouncerShowing).thenReturn(false) + val argumentCaptor = ArgumentCaptor.forClass(View.OnApplyWindowInsetsListener::class.java) + + keyguardPasswordViewController.onViewAttached() + verify(keyguardPasswordView).setOnApplyWindowInsetsListener(argumentCaptor.capture()) + argumentCaptor.value.onApplyWindowInsets(keyguardPasswordView, null) + + verify(keyguardPasswordView).hideKeyboard() + } + @Test fun testHideKeyboardWhenOnPause() { keyguardPasswordViewController.onPause()