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
This commit is contained in:
Lucas Dupin
2020-04-17 15:20:58 -07:00
parent 21095a62eb
commit 8d54074d26
7 changed files with 71 additions and 8 deletions

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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() {};
}

View File

@@ -400,6 +400,9 @@ public class KeyguardBouncer {
mExpansionCallback.onFullyHidden();
} else if (fraction != EXPANSION_VISIBLE && oldExpansion == EXPANSION_VISIBLE) {
mExpansionCallback.onStartingToHide();
if (mKeyguardView != null) {
mKeyguardView.onStartingToHide();
}
}
}

View File

@@ -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();
}
}

View File

@@ -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<Integer>) 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