[Bouncer] hide/show keyboard when focus is...

regained. For the bonuncer, often times the UDFPS overlay, or AOD can
take the window focus. This will prevent the window of the bouncer from
sending signals to the input manager to hide/show the keyboard. Add an
override method for the password view to show or hide the keyboard
contingent upon the visibility of the view. Also refocus edit text when
changing orientation of device.

Fixes: 259552291
Test: Open scrimmed bouncer from AOD.
Test: Open bouncer and hide bouncer a bunch.
Test: Open bouncer from udfps overlay.
Test: Unit test.
Test: change view mode from landscape to portrait when on bouncer on tablet.

Change-Id: Ic30099408086f6dcc63506cac6ca2fb015504d17
This commit is contained in:
Aaron Liu
2022-11-30 09:47:28 -08:00
parent e7aef726bb
commit 9ce60a5ab8
3 changed files with 71 additions and 14 deletions

View File

@@ -34,6 +34,7 @@ import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Trace;
import android.util.AttributeSet;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimationControlListener;
import android.view.WindowInsetsAnimationController;
import android.view.animation.AnimationUtils;
@@ -236,4 +237,50 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
return getResources().getString(
com.android.internal.R.string.keyguard_accessibility_password_unlock);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (!mPasswordEntry.isFocused() && isVisibleToUser()) {
mPasswordEntry.requestFocus();
}
return super.onApplyWindowInsets(insets);
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (hasWindowFocus) {
if (isVisibleToUser()) {
showKeyboard();
} else {
hideKeyboard();
}
}
}
/**
* Sends signal to the focused window to show the keyboard.
*/
public void showKeyboard() {
post(() -> {
if (mPasswordEntry.isAttachedToWindow()
&& !mPasswordEntry.getRootWindowInsets().isVisible(WindowInsets.Type.ime())) {
mPasswordEntry.requestFocus();
mPasswordEntry.getWindowInsetsController().show(WindowInsets.Type.ime());
}
});
}
/**
* Sends signal to the focused window to hide the keyboard.
*/
public void hideKeyboard() {
post(() -> {
if (mPasswordEntry.isAttachedToWindow()
&& mPasswordEntry.getRootWindowInsets().isVisible(WindowInsets.Type.ime())) {
mPasswordEntry.clearFocus();
mPasswordEntry.getWindowInsetsController().hide(WindowInsets.Type.ime());
}
});
}
}

View File

@@ -27,7 +27,6 @@ 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;
@@ -214,12 +213,9 @@ public class KeyguardPasswordViewController
return;
}
mView.post(() -> {
if (mView.isShown()) {
mPasswordEntry.requestFocus();
mPasswordEntry.getWindowInsetsController().show(WindowInsets.Type.ime());
}
});
if (mView.isShown()) {
mView.showKeyboard();
}
}
@Override
@@ -241,16 +237,12 @@ public class KeyguardPasswordViewController
super.onPause();
});
}
if (mPasswordEntry.isAttachedToWindow()) {
mPasswordEntry.getWindowInsetsController().hide(WindowInsets.Type.ime());
}
mView.hideKeyboard();
}
@Override
public void onStartingToHide() {
if (mPasswordEntry.isAttachedToWindow()) {
mPasswordEntry.getWindowInsetsController().hide(WindowInsets.Type.ime());
}
mView.hideKeyboard();
}
private void updateSwitchImeButton() {

View File

@@ -19,6 +19,7 @@ package com.android.keyguard
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.test.filters.SmallTest
import com.android.internal.util.LatencyTracker
import com.android.internal.widget.LockPatternUtils
@@ -43,6 +44,8 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var keyguardPasswordView: KeyguardPasswordView
@Mock
private lateinit var passwordEntry: EditText
@Mock
lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock
lateinit var securityMode: KeyguardSecurityModel.SecurityMode
@@ -81,6 +84,9 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
).thenReturn(mKeyguardMessageArea)
Mockito.`when`(messageAreaControllerFactory.create(mKeyguardMessageArea))
.thenReturn(mKeyguardMessageAreaController)
Mockito.`when`(keyguardPasswordView.passwordTextViewId).thenReturn(R.id.passwordEntry)
Mockito.`when`(keyguardPasswordView.findViewById<EditText>(R.id.passwordEntry)
).thenReturn(passwordEntry)
keyguardPasswordViewController = KeyguardPasswordViewController(
keyguardPasswordView,
keyguardUpdateMonitor,
@@ -103,7 +109,10 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(true)
Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
keyguardPasswordView.post { verify(keyguardPasswordView).requestFocus() }
keyguardPasswordView.post {
verify(keyguardPasswordView).requestFocus()
verify(keyguardPasswordView).showKeyboard()
}
}
@Test
@@ -114,6 +123,15 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
verify(keyguardPasswordView, never()).requestFocus()
}
@Test
fun testHideKeyboardWhenOnPause() {
keyguardPasswordViewController.onPause()
keyguardPasswordView.post {
verify(keyguardPasswordView).clearFocus()
verify(keyguardPasswordView).hideKeyboard()
}
}
@Test
fun startAppearAnimation() {
keyguardPasswordViewController.startAppearAnimation()