From 8d54074d26d378a474fd226030e5d5ed8dd155c0 Mon Sep 17 00:00:00 2001 From: Lucas Dupin Date: Fri, 17 Apr 2020 15:20:58 -0700 Subject: [PATCH] Fix issue where keyboard would not be dismissed When swiping down from the top of the screen to dismiss the bouncer, the input field should hide the keyboard, otherwise it would get stuck on the lock screen. Test: manual Test: atest KeyguardHostViewTest Test: atest KeyguardBouncerTest Fixes: 154245193 Fixes: 152882608 Change-Id: I99ee2cff85df1ab0b6544e9b5b472e105fca7b72 --- .../android/keyguard/KeyguardHostView.java | 13 +++++++-- .../keyguard/KeyguardPasswordView.java | 5 ++++ .../keyguard/KeyguardSecurityContainer.java | 7 +++++ .../keyguard/KeyguardSecurityView.java | 5 ++++ .../statusbar/phone/KeyguardBouncer.java | 3 ++ .../keyguard/KeyguardHostViewTest.java | 28 ++++++++++++++++++- .../statusbar/phone/KeyguardBouncerTest.java | 18 ++++++++---- 7 files changed, 71 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java index aa2fe3c7f8fc7..57b3761c294f8 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java @@ -16,7 +16,6 @@ package com.android.keyguard; -import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.content.res.ColorStateList; @@ -31,6 +30,8 @@ import android.util.Log; import android.view.KeyEvent; import android.widget.FrameLayout; +import androidx.annotation.VisibleForTesting; + import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; @@ -101,7 +102,8 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback { public static final boolean DEBUG = KeyguardConstants.DEBUG; private static final String TAG = "KeyguardViewBase"; - private KeyguardSecurityContainer mSecurityContainer; + @VisibleForTesting + protected KeyguardSecurityContainer mSecurityContainer; public KeyguardHostView(Context context) { this(context, null); @@ -446,4 +448,11 @@ public class KeyguardHostView extends FrameLayout implements SecurityCallback { public SecurityMode getCurrentSecurityMode() { return mSecurityContainer.getCurrentSecurityMode(); } + + /** + * When bouncer was visible and is starting to become hidden. + */ + public void onStartingToHide() { + mSecurityContainer.onStartingToHide(); + } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 718bcf16c832c..65bf7e6e50252 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -152,6 +152,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView mImm.hideSoftInputFromWindow(getWindowToken(), 0); } + @Override + public void onStartingToHide() { + mImm.hideSoftInputFromWindow(getWindowToken(), 0); + } + private void updateSwitchImeButton() { // If there's more than one IME, enable the IME switcher button final boolean wasVisible = mSwitchImeButton.getVisibility() == View.VISIBLE; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 5c3d17ce0e2b7..c2bc003aa5619 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -177,6 +177,13 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe } } + @Override + public void onStartingToHide() { + if (mCurrentSecuritySelection != SecurityMode.None) { + getSecurityView(mCurrentSecuritySelection).onStartingToHide(); + } + } + @Override public boolean shouldDelayChildPressedState() { return true; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java index 20b1e0d2c8220..43cef3acf1479 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityView.java @@ -159,4 +159,9 @@ public interface KeyguardSecurityView { default boolean disallowInterceptTouch(MotionEvent event) { return false; } + + /** + * When bouncer was visible but is being dragged down or dismissed. + */ + default void onStartingToHide() {}; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 82e02b47974cc..39949c82661f2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -400,6 +400,9 @@ public class KeyguardBouncer { mExpansionCallback.onFullyHidden(); } else if (fraction != EXPANSION_VISIBLE && oldExpansion == EXPANSION_VISIBLE) { mExpansionCallback.onStartingToHide(); + if (mKeyguardView != null) { + mKeyguardView.onStartingToHide(); + } } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java index 25f279b45d04f..dd5c8335eefa7 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java @@ -17,30 +17,50 @@ package com.android.keyguard; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import com.android.internal.widget.LockPatternUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; @SmallTest @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class KeyguardHostViewTest extends SysuiTestCase { + @Mock + private KeyguardSecurityContainer mSecurityContainer; + @Mock + private LockPatternUtils mLockPatternUtils; + @Rule + public MockitoRule mMockitoRule = MockitoJUnit.rule(); + private KeyguardHostView mKeyguardHostView; @Before public void setup() { mDependency.injectMockDependency(KeyguardUpdateMonitor.class); - mKeyguardHostView = new KeyguardHostView(getContext()); + mKeyguardHostView = new KeyguardHostView(getContext()) { + @Override + protected void onFinishInflate() { + mSecurityContainer = KeyguardHostViewTest.this.mSecurityContainer; + mLockPatternUtils = KeyguardHostViewTest.this.mLockPatternUtils; + } + }; + mKeyguardHostView.onFinishInflate(); } @Test @@ -50,4 +70,10 @@ public class KeyguardHostViewTest extends SysuiTestCase { null /* cancelAction */); Assert.assertTrue("Action should exist", mKeyguardHostView.hasDismissActions()); } + + @Test + public void testOnStartingToHide() { + mKeyguardHostView.onStartingToHide(); + verify(mSecurityContainer).onStartingToHide(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index e052ae2653f0e..0a041e4a4dc57 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -26,7 +26,6 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; @@ -37,6 +36,7 @@ import android.graphics.Color; import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout; @@ -64,6 +64,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import org.mockito.stubbing.Answer; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -94,9 +95,11 @@ public class KeyguardBouncerTest extends SysuiTestCase { private Handler mHandler; @Mock private KeyguardSecurityModel mKeyguardSecurityModel; + @Mock + private ViewGroup mRootView; @Rule public MockitoRule mRule = MockitoJUnit.rule(); - private ViewGroup mRootView; + private Integer mRootVisibility = View.INVISIBLE; private KeyguardBouncer mBouncer; @Before @@ -105,6 +108,11 @@ public class KeyguardBouncerTest extends SysuiTestCase { mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor); mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel); mDependency.injectMockDependency(KeyguardStateController.class); + when(mRootView.getVisibility()).thenAnswer((Answer) invocation -> mRootVisibility); + doAnswer(invocation -> { + mRootVisibility = invocation.getArgument(0); + return null; + }).when(mRootView).setVisibility(anyInt()); when(mKeyguardSecurityModel.getSecurityMode(anyInt())) .thenReturn(KeyguardSecurityModel.SecurityMode.None); DejankUtils.setImmediate(true); @@ -117,10 +125,8 @@ public class KeyguardBouncerTest extends SysuiTestCase { mKeyguardBypassController, mHandler) { @Override protected void inflateView() { - super.inflateView(); mKeyguardView = mKeyguardHostView; - mRoot = spy(mRoot); - mRootView = mRoot; + mRoot = mRootView; } }; } @@ -212,8 +218,10 @@ public class KeyguardBouncerTest extends SysuiTestCase { verify(mExpansionCallback).onFullyShown(); verify(mExpansionCallback, never()).onStartingToHide(); + verify(mKeyguardHostView, never()).onStartingToHide(); mBouncer.setExpansion(0.9f); verify(mExpansionCallback).onStartingToHide(); + verify(mKeyguardHostView).onStartingToHide(); } @Test