Make one-handed bouncer properly inhibit falsing.
Previously, the falsing manager would take all taps that weren't on the bouncer (ish) as potential false taps, eventually dismissing the bouncer. This causes issues for the one-handed bouncer; taps on the "other" side were registered as false taps, so in many cases, tapping to move the bouncer would cause the falsing to kick in. To fix, this CL inhibits falsing for gestures that begin on the "opposite" bouncer side. This also refactors a bunch of the code to decide whether to use a one handed bouncer, to move a lot of logic into the ContainerController. The animations on change, and tap to change are still handled in the View, but the decision of whether to enter one-handed mode, and which side to open on, are now handled in the Controller. FYI - this CL still attempts to load from settings; that will be cleaned up in a follow-up CL. Bug: 182982037 Bug: 170858298 Test: Tests updated and pass. Change-Id: Icb36a3b88032c4bcad8530d518a97a8d8717244e
This commit is contained in:
@@ -42,7 +42,6 @@ import android.view.WindowInsetsAnimation;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
@@ -104,7 +103,6 @@ public class KeyguardSecurityContainer extends FrameLayout {
|
||||
|
||||
private boolean mIsSecurityViewLeftAligned = true;
|
||||
private boolean mOneHandedMode = false;
|
||||
private SecurityMode mSecurityMode = SecurityMode.Invalid;
|
||||
private ViewPropertyAnimator mRunningOneHandedAnimator;
|
||||
|
||||
private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
|
||||
@@ -248,66 +246,47 @@ public class KeyguardSecurityContainer extends FrameLayout {
|
||||
}
|
||||
|
||||
void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
|
||||
mSecurityMode = securityMode;
|
||||
mSecurityViewFlipper.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
|
||||
updateBiometricRetry(securityMode, faceAuthEnabled);
|
||||
|
||||
updateLayoutForSecurityMode(securityMode);
|
||||
}
|
||||
|
||||
void updateLayoutForSecurityMode(SecurityMode securityMode) {
|
||||
mSecurityMode = securityMode;
|
||||
mOneHandedMode = canUseOneHandedBouncer();
|
||||
|
||||
if (mOneHandedMode) {
|
||||
mIsSecurityViewLeftAligned = isOneHandedKeyguardLeftAligned(mContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this security container is in one handed mode. If so, it will measure its
|
||||
* child SecurityViewFlipper in one half of the screen, and move it when tapping on the opposite
|
||||
* side of the screen.
|
||||
*/
|
||||
public void setOneHandedMode(boolean oneHandedMode) {
|
||||
mOneHandedMode = oneHandedMode;
|
||||
updateSecurityViewGravity();
|
||||
updateSecurityViewLocation(false);
|
||||
}
|
||||
|
||||
/** Update keyguard position based on a tapped X coordinate. */
|
||||
public void updateKeyguardPosition(float x) {
|
||||
if (mOneHandedMode) {
|
||||
moveBouncerForXCoordinate(x, /* animate= */false);
|
||||
}
|
||||
/** Returns whether this security container is in one-handed mode. */
|
||||
public boolean isOneHandedMode() {
|
||||
return mOneHandedMode;
|
||||
}
|
||||
|
||||
/** Return whether the one-handed keyguard should be enabled. */
|
||||
private boolean canUseOneHandedBouncer() {
|
||||
// Is it enabled?
|
||||
if (!getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enableDynamicKeyguardPositioning)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!KeyguardSecurityModel.isSecurityViewOneHanded(mSecurityMode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getResources().getBoolean(R.bool.can_use_one_handed_bouncer);
|
||||
/**
|
||||
* When in one-handed mode, sets if the inner SecurityViewFlipper should be aligned to the
|
||||
* left-hand side of the screen or not, and whether to animate when moving between the two.
|
||||
*/
|
||||
public void setOneHandedModeLeftAligned(boolean leftAligned, boolean animate) {
|
||||
mIsSecurityViewLeftAligned = leftAligned;
|
||||
updateSecurityViewLocation(animate);
|
||||
}
|
||||
|
||||
/** Read whether the one-handed keyguard should be on the left/right from settings. */
|
||||
private boolean isOneHandedKeyguardLeftAligned(Context context) {
|
||||
try {
|
||||
return Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.ONE_HANDED_KEYGUARD_SIDE)
|
||||
== Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT;
|
||||
} catch (Settings.SettingNotFoundException ex) {
|
||||
return true;
|
||||
}
|
||||
/** Returns whether the inner SecurityViewFlipper is left-aligned when in one-handed mode. */
|
||||
public boolean isOneHandedModeLeftAligned() {
|
||||
return mIsSecurityViewLeftAligned;
|
||||
}
|
||||
|
||||
private void updateSecurityViewGravity() {
|
||||
View securityView = findKeyguardSecurityView();
|
||||
|
||||
if (securityView == null) {
|
||||
if (mSecurityViewFlipper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) securityView.getLayoutParams();
|
||||
FrameLayout.LayoutParams lp =
|
||||
(FrameLayout.LayoutParams) mSecurityViewFlipper.getLayoutParams();
|
||||
|
||||
if (mOneHandedMode) {
|
||||
lp.gravity = Gravity.LEFT | Gravity.BOTTOM;
|
||||
@@ -315,7 +294,7 @@ public class KeyguardSecurityContainer extends FrameLayout {
|
||||
lp.gravity = Gravity.CENTER_HORIZONTAL;
|
||||
}
|
||||
|
||||
securityView.setLayoutParams(lp);
|
||||
mSecurityViewFlipper.setLayoutParams(lp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,14 +303,12 @@ public class KeyguardSecurityContainer extends FrameLayout {
|
||||
* by the security view .
|
||||
*/
|
||||
private void updateSecurityViewLocation(boolean animate) {
|
||||
View securityView = findKeyguardSecurityView();
|
||||
|
||||
if (securityView == null) {
|
||||
if (mSecurityViewFlipper == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mOneHandedMode) {
|
||||
securityView.setTranslationX(0);
|
||||
mSecurityViewFlipper.setTranslationX(0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -343,7 +320,8 @@ public class KeyguardSecurityContainer extends FrameLayout {
|
||||
int targetTranslation = mIsSecurityViewLeftAligned ? 0 : (int) (getMeasuredWidth() / 2f);
|
||||
|
||||
if (animate) {
|
||||
mRunningOneHandedAnimator = securityView.animate().translationX(targetTranslation);
|
||||
mRunningOneHandedAnimator =
|
||||
mSecurityViewFlipper.animate().translationX(targetTranslation);
|
||||
mRunningOneHandedAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
mRunningOneHandedAnimator.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -355,27 +333,10 @@ public class KeyguardSecurityContainer extends FrameLayout {
|
||||
mRunningOneHandedAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
|
||||
mRunningOneHandedAnimator.start();
|
||||
} else {
|
||||
securityView.setTranslationX(targetTranslation);
|
||||
mSecurityViewFlipper.setTranslationX(targetTranslation);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private KeyguardSecurityViewFlipper findKeyguardSecurityView() {
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View child = getChildAt(i);
|
||||
|
||||
if (isKeyguardSecurityView(child)) {
|
||||
return (KeyguardSecurityViewFlipper) child;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isKeyguardSecurityView(View view) {
|
||||
return view instanceof KeyguardSecurityViewFlipper;
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
if (mAlertDialog != null) {
|
||||
mAlertDialog.dismiss();
|
||||
@@ -635,7 +596,7 @@ public class KeyguardSecurityContainer extends FrameLayout {
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
final View view = getChildAt(i);
|
||||
if (view.getVisibility() != GONE) {
|
||||
if (mOneHandedMode && isKeyguardSecurityView(view)) {
|
||||
if (mOneHandedMode && view == mSecurityViewFlipper) {
|
||||
measureChildWithMargins(view, halfWidthMeasureSpec, 0,
|
||||
heightMeasureSpec, 0);
|
||||
} else {
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.view.MotionEvent;
|
||||
@@ -49,6 +50,8 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.keyguard.dagger.KeyguardBouncerScope;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.systemui.Gefingerpoken;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.shared.system.SysUiStatsLog;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
@@ -74,12 +77,14 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController;
|
||||
private final SecurityCallback mSecurityCallback;
|
||||
private final ConfigurationController mConfigurationController;
|
||||
private final FalsingCollector mFalsingCollector;
|
||||
|
||||
private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
|
||||
private SecurityMode mCurrentSecurityMode = SecurityMode.Invalid;
|
||||
|
||||
private final Gefingerpoken mGlobalTouchListener = new Gefingerpoken() {
|
||||
@VisibleForTesting
|
||||
final Gefingerpoken mGlobalTouchListener = new Gefingerpoken() {
|
||||
private MotionEvent mTouchDown;
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
@@ -91,6 +96,17 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
// Do just a bit of our own falsing. People should only be tapping on the input, not
|
||||
// swiping.
|
||||
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
|
||||
// If we're in one handed mode, the user can tap on the opposite side of the screen
|
||||
// to move the bouncer across. In that case, inhibit the falsing (otherwise the taps
|
||||
// to move the bouncer to each screen side can end up closing it instead).
|
||||
if (mView.isOneHandedMode()) {
|
||||
if ((mView.isOneHandedModeLeftAligned() && ev.getX() > mView.getWidth() / 2f)
|
||||
|| (!mView.isOneHandedModeLeftAligned()
|
||||
&& ev.getX() <= mView.getWidth() / 2f)) {
|
||||
mFalsingCollector.avoidGesture();
|
||||
}
|
||||
}
|
||||
|
||||
if (mTouchDown != null) {
|
||||
mTouchDown.recycle();
|
||||
mTouchDown = null;
|
||||
@@ -202,7 +218,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
KeyguardStateController keyguardStateController,
|
||||
SecurityCallback securityCallback,
|
||||
KeyguardSecurityViewFlipperController securityViewFlipperController,
|
||||
ConfigurationController configurationController) {
|
||||
ConfigurationController configurationController,
|
||||
FalsingCollector falsingCollector) {
|
||||
super(view);
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
mUpdateMonitor = keyguardUpdateMonitor;
|
||||
@@ -216,6 +233,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
mKeyguardSecurityCallback);
|
||||
mConfigurationController = configurationController;
|
||||
mLastOrientation = getResources().getConfiguration().orientation;
|
||||
mFalsingCollector = falsingCollector;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -440,13 +458,49 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
if (newView != null) {
|
||||
newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
|
||||
mSecurityViewFlipperController.show(newView);
|
||||
mView.updateLayoutForSecurityMode(securityMode);
|
||||
configureOneHandedMode();
|
||||
}
|
||||
|
||||
mSecurityCallback.onSecurityModeChanged(
|
||||
securityMode, newView != null && newView.needsInput());
|
||||
}
|
||||
|
||||
/** Read whether the one-handed keyguard should be on the left/right from settings. */
|
||||
private boolean isOneHandedKeyguardLeftAligned() {
|
||||
try {
|
||||
return Settings.Global.getInt(mView.getContext().getContentResolver(),
|
||||
Settings.Global.ONE_HANDED_KEYGUARD_SIDE)
|
||||
== Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT;
|
||||
} catch (Settings.SettingNotFoundException ex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canUseOneHandedBouncer() {
|
||||
// Is it enabled?
|
||||
if (!getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enableDynamicKeyguardPositioning)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!KeyguardSecurityModel.isSecurityViewOneHanded(mCurrentSecurityMode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getResources().getBoolean(R.bool.can_use_one_handed_bouncer);
|
||||
}
|
||||
|
||||
private void configureOneHandedMode() {
|
||||
boolean oneHandedMode = canUseOneHandedBouncer();
|
||||
|
||||
mView.setOneHandedMode(oneHandedMode);
|
||||
|
||||
if (oneHandedMode) {
|
||||
mView.setOneHandedModeLeftAligned(
|
||||
isOneHandedKeyguardLeftAligned(), /* animate= */false);
|
||||
}
|
||||
}
|
||||
|
||||
public void reportFailedUnlockAttempt(int userId, int timeoutMs) {
|
||||
// +1 for this time
|
||||
final int failedAttempts = mLockPatternUtils.getCurrentFailedPasswordAttempts(userId) + 1;
|
||||
@@ -511,13 +565,15 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
int newOrientation = getResources().getConfiguration().orientation;
|
||||
if (newOrientation != mLastOrientation) {
|
||||
mLastOrientation = newOrientation;
|
||||
mView.updateLayoutForSecurityMode(mCurrentSecurityMode);
|
||||
configureOneHandedMode();
|
||||
}
|
||||
}
|
||||
|
||||
/** Update keyguard position based on a tapped X coordinate. */
|
||||
public void updateKeyguardPosition(float x) {
|
||||
mView.updateKeyguardPosition(x);
|
||||
if (mView.isOneHandedMode()) {
|
||||
mView.setOneHandedModeLeftAligned(x <= mView.getWidth() / 2f, false);
|
||||
}
|
||||
}
|
||||
|
||||
static class Factory {
|
||||
@@ -533,6 +589,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController;
|
||||
private final ConfigurationController mConfigurationController;
|
||||
private final FalsingCollector mFalsingCollector;
|
||||
|
||||
@Inject
|
||||
Factory(KeyguardSecurityContainer view,
|
||||
@@ -545,7 +602,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
UiEventLogger uiEventLogger,
|
||||
KeyguardStateController keyguardStateController,
|
||||
KeyguardSecurityViewFlipperController securityViewFlipperController,
|
||||
ConfigurationController configurationController) {
|
||||
ConfigurationController configurationController,
|
||||
FalsingCollector falsingCollector) {
|
||||
mView = view;
|
||||
mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
@@ -556,6 +614,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mSecurityViewFlipperController = securityViewFlipperController;
|
||||
mConfigurationController = configurationController;
|
||||
mFalsingCollector = falsingCollector;
|
||||
}
|
||||
|
||||
public KeyguardSecurityContainerController create(
|
||||
@@ -564,7 +623,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
|
||||
mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
|
||||
mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
|
||||
mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
|
||||
mConfigurationController);
|
||||
mConfigurationController, mFalsingCollector);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@ package com.android.keyguard;
|
||||
import static android.view.WindowInsets.Type.ime;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -33,6 +35,7 @@ import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowInsetsController;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -43,6 +46,7 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
@@ -58,6 +62,7 @@ import org.mockito.junit.MockitoRule;
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper()
|
||||
public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
private static final int VIEW_WIDTH = 1600;
|
||||
|
||||
@Rule
|
||||
public MockitoRule mRule = MockitoJUnit.rule();
|
||||
@@ -100,6 +105,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
private EmergencyButtonController mEmergencyButtonController;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
@Mock
|
||||
private FalsingCollector mFalsingCollector;
|
||||
private Configuration mConfiguration;
|
||||
|
||||
private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
|
||||
@@ -112,7 +119,9 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
mConfiguration.setToDefaults(); // Defaults to ORIENTATION_UNDEFINED.
|
||||
|
||||
when(mResources.getConfiguration()).thenReturn(mConfiguration);
|
||||
when(mView.getContext()).thenReturn(mContext);
|
||||
when(mView.getResources()).thenReturn(mResources);
|
||||
when(mView.getWidth()).thenReturn(VIEW_WIDTH);
|
||||
when(mAdminSecondaryLockScreenControllerFactory.create(any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn(mAdminSecondaryLockScreenController);
|
||||
when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController);
|
||||
@@ -131,7 +140,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
|
||||
mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
|
||||
mKeyguardStateController, mKeyguardSecurityViewFlipperController,
|
||||
mConfigurationController)
|
||||
mConfigurationController, mFalsingCollector)
|
||||
.create(mSecurityCallback);
|
||||
}
|
||||
|
||||
@@ -169,18 +178,156 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
public void onResourcesUpdate_callsThroughOnRotationChange() {
|
||||
// Rotation is the same, shouldn't cause an update
|
||||
mKeyguardSecurityContainerController.updateResources();
|
||||
verify(mView, times(0)).updateLayoutForSecurityMode(any());
|
||||
verify(mView, times(0)).setOneHandedMode(anyBoolean());
|
||||
|
||||
// Update rotation. Should trigger update
|
||||
mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;
|
||||
|
||||
mKeyguardSecurityContainerController.updateResources();
|
||||
verify(mView, times(1)).updateLayoutForSecurityMode(any());
|
||||
verify(mView, times(1)).setOneHandedMode(anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateKeyguardPosition_callsThroughToView() {
|
||||
public void updateKeyguardPosition_callsThroughToViewInOneHandedMode() {
|
||||
when(mView.isOneHandedMode()).thenReturn(true);
|
||||
mKeyguardSecurityContainerController.updateKeyguardPosition(VIEW_WIDTH / 3f);
|
||||
verify(mView).setOneHandedModeLeftAligned(true, false);
|
||||
|
||||
mKeyguardSecurityContainerController.updateKeyguardPosition((VIEW_WIDTH / 3f) * 2);
|
||||
verify(mView).setOneHandedModeLeftAligned(false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateKeyguardPosition_ignoredInTwoHandedMode() {
|
||||
when(mView.isOneHandedMode()).thenReturn(false);
|
||||
mKeyguardSecurityContainerController.updateKeyguardPosition(1.0f);
|
||||
verify(mView).updateKeyguardPosition(1.0f);
|
||||
verify(mView, never()).setOneHandedModeLeftAligned(anyBoolean(), anyBoolean());
|
||||
}
|
||||
|
||||
private void touchDownLeftSide() {
|
||||
mKeyguardSecurityContainerController.mGlobalTouchListener.onTouchEvent(
|
||||
MotionEvent.obtain(
|
||||
/* downTime= */0,
|
||||
/* eventTime= */0,
|
||||
MotionEvent.ACTION_DOWN,
|
||||
/* x= */VIEW_WIDTH / 3f,
|
||||
/* y= */0,
|
||||
/* metaState= */0));
|
||||
}
|
||||
|
||||
private void touchDownRightSide() {
|
||||
mKeyguardSecurityContainerController.mGlobalTouchListener.onTouchEvent(
|
||||
MotionEvent.obtain(
|
||||
/* downTime= */0,
|
||||
/* eventTime= */0,
|
||||
MotionEvent.ACTION_DOWN,
|
||||
/* x= */(VIEW_WIDTH / 3f) * 2,
|
||||
/* y= */0,
|
||||
/* metaState= */0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onInterceptTap_inhibitsFalsingInOneHandedMode() {
|
||||
when(mView.isOneHandedMode()).thenReturn(true);
|
||||
when(mView.isOneHandedModeLeftAligned()).thenReturn(true);
|
||||
|
||||
touchDownLeftSide();
|
||||
verify(mFalsingCollector, never()).avoidGesture();
|
||||
|
||||
// Now on the right.
|
||||
touchDownRightSide();
|
||||
verify(mFalsingCollector).avoidGesture();
|
||||
|
||||
// Move and re-test
|
||||
reset(mFalsingCollector);
|
||||
when(mView.isOneHandedModeLeftAligned()).thenReturn(false);
|
||||
|
||||
// On the right...
|
||||
touchDownRightSide();
|
||||
verify(mFalsingCollector, never()).avoidGesture();
|
||||
|
||||
touchDownLeftSide();
|
||||
verify(mFalsingCollector).avoidGesture();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showSecurityScreen_oneHandedMode_bothFlagsDisabled_noOneHandedMode() {
|
||||
setUpKeyguardFlags(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */false,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */false);
|
||||
|
||||
when(mKeyguardSecurityViewFlipperController.getSecurityView(
|
||||
eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
|
||||
|
||||
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
|
||||
verify(mView).setOneHandedMode(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showSecurityScreen_oneHandedMode_deviceFlagDisabled_noOneHandedMode() {
|
||||
setUpKeyguardFlags(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */false,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */true);
|
||||
|
||||
when(mKeyguardSecurityViewFlipperController.getSecurityView(
|
||||
eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
|
||||
|
||||
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
|
||||
verify(mView).setOneHandedMode(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showSecurityScreen_oneHandedMode_sysUiFlagDisabled_noOneHandedMode() {
|
||||
setUpKeyguardFlags(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */true,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */false);
|
||||
|
||||
when(mKeyguardSecurityViewFlipperController.getSecurityView(
|
||||
eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
|
||||
|
||||
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
|
||||
verify(mView).setOneHandedMode(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showSecurityScreen_oneHandedMode_bothFlagsEnabled_oneHandedMode() {
|
||||
setUpKeyguardFlags(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */true,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */true);
|
||||
|
||||
when(mKeyguardSecurityViewFlipperController.getSecurityView(
|
||||
eq(SecurityMode.Pattern), any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
|
||||
|
||||
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
|
||||
verify(mView).setOneHandedMode(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void showSecurityScreen_twoHandedMode_bothFlagsEnabled_noOneHandedMode() {
|
||||
setUpKeyguardFlags(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */true,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */true);
|
||||
|
||||
when(mKeyguardSecurityViewFlipperController.getSecurityView(
|
||||
eq(SecurityMode.Password), any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);
|
||||
|
||||
mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
|
||||
verify(mView).setOneHandedMode(false);
|
||||
}
|
||||
|
||||
private void setUpKeyguardFlags(
|
||||
boolean deviceConfigCanUseOneHandedKeyguard,
|
||||
boolean sysuiResourceCanUseOneHandedKeyguard) {
|
||||
when(mResources.getBoolean(
|
||||
com.android.internal.R.bool.config_enableDynamicKeyguardPositioning))
|
||||
.thenReturn(deviceConfigCanUseOneHandedKeyguard);
|
||||
when(mResources.getBoolean(
|
||||
R.bool.can_use_one_handed_bouncer))
|
||||
.thenReturn(sysuiResourceCanUseOneHandedKeyguard);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import static org.mockito.Mockito.when;
|
||||
import android.graphics.Insets;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableResources;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
@@ -37,8 +36,6 @@ import android.widget.FrameLayout;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -57,11 +54,6 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
|
||||
private static final int FAKE_MEASURE_SPEC =
|
||||
View.MeasureSpec.makeMeasureSpec(SCREEN_WIDTH, View.MeasureSpec.EXACTLY);
|
||||
|
||||
private static final SecurityMode ONE_HANDED_SECURITY_MODE = SecurityMode.PIN;
|
||||
private static final SecurityMode TWO_HANDED_SECURITY_MODE = SecurityMode.Password;
|
||||
|
||||
|
||||
|
||||
@Rule
|
||||
public MockitoRule mRule = MockitoJUnit.rule();
|
||||
|
||||
@@ -90,45 +82,8 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMeasure_usesFullWidthWithoutOneHandedMode() {
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */false,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ false,
|
||||
ONE_HANDED_SECURITY_MODE);
|
||||
|
||||
mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
|
||||
verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMeasure_usesFullWidthWithDeviceFlagDisabled() {
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */false,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ true,
|
||||
ONE_HANDED_SECURITY_MODE);
|
||||
|
||||
mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMeasure_usesFullWidthWithSysUIFlagDisabled() {
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */true,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ false,
|
||||
ONE_HANDED_SECURITY_MODE);
|
||||
|
||||
mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMeasure_usesHalfWidthWithFlagsEnabled() {
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */true,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ true,
|
||||
ONE_HANDED_SECURITY_MODE);
|
||||
public void onMeasure_usesHalfWidthWithOneHandedModeEnabled() {
|
||||
mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */true);
|
||||
|
||||
int halfWidthMeasureSpec =
|
||||
View.MeasureSpec.makeMeasureSpec(SCREEN_WIDTH / 2, View.MeasureSpec.EXACTLY);
|
||||
@@ -138,11 +93,8 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onMeasure_usesFullWidthForFullScreenIme() {
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */true,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ true,
|
||||
TWO_HANDED_SECURITY_MODE);
|
||||
public void onMeasure_usesFullWidthWithOneHandedModeDisabled() {
|
||||
mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false);
|
||||
|
||||
mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
@@ -153,10 +105,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
|
||||
int imeInsetAmount = 100;
|
||||
int systemBarInsetAmount = 10;
|
||||
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */false,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ false,
|
||||
ONE_HANDED_SECURITY_MODE);
|
||||
mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false);
|
||||
|
||||
Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
|
||||
Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
|
||||
@@ -180,10 +129,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
|
||||
int imeInsetAmount = 0;
|
||||
int systemBarInsetAmount = 10;
|
||||
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */false,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ false,
|
||||
ONE_HANDED_SECURITY_MODE);
|
||||
mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false);
|
||||
|
||||
Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
|
||||
Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
|
||||
@@ -201,56 +147,41 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
|
||||
verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, expectedHeightMeasureSpec);
|
||||
}
|
||||
|
||||
private void setupForUpdateKeyguardPosition(SecurityMode securityMode) {
|
||||
setUpKeyguard(
|
||||
/* deviceConfigCanUseOneHandedKeyguard= */true,
|
||||
/* sysuiResourceCanUseOneHandedKeyguard= */ true,
|
||||
securityMode);
|
||||
private void setupForUpdateKeyguardPosition(boolean oneHandedMode) {
|
||||
mKeyguardSecurityContainer.setOneHandedMode(oneHandedMode);
|
||||
mKeyguardSecurityContainer.setOneHandedModeLeftAligned(true, false);
|
||||
|
||||
mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
|
||||
mKeyguardSecurityContainer.layout(0, 0, SCREEN_WIDTH, SCREEN_WIDTH);
|
||||
|
||||
// Start off left-aligned. This should happen anyway, but just do this to ensure
|
||||
// definitely move to the left.
|
||||
mKeyguardSecurityContainer.updateKeyguardPosition(0.0f);
|
||||
|
||||
// Clear any interactions with the mock so we know the interactions definitely come from the
|
||||
// below testing.
|
||||
reset(mSecurityViewFlipper);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateKeyguardPosition_movesKeyguard() {
|
||||
setupForUpdateKeyguardPosition(ONE_HANDED_SECURITY_MODE);
|
||||
public void setIsLeftAligned_movesKeyguard() {
|
||||
setupForUpdateKeyguardPosition(/* oneHandedMode= */ true);
|
||||
|
||||
mKeyguardSecurityContainer.updateKeyguardPosition((SCREEN_WIDTH / 4f) * 3f);
|
||||
mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
|
||||
/* leftAligned= */false, /* animate= */false);
|
||||
verify(mSecurityViewFlipper).setTranslationX(SCREEN_WIDTH / 2.0f);
|
||||
|
||||
mKeyguardSecurityContainer.updateKeyguardPosition(0.0f);
|
||||
mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
|
||||
/* leftAligned= */true, /* animate= */false);
|
||||
verify(mSecurityViewFlipper).setTranslationX(0.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateKeyguardPosition_doesntMoveTwoHandedKeyguard() {
|
||||
setupForUpdateKeyguardPosition(TWO_HANDED_SECURITY_MODE);
|
||||
public void setIsLeftAligned_doesntMoveTwoHandedKeyguard() {
|
||||
setupForUpdateKeyguardPosition(/* oneHandedMode= */ false);
|
||||
|
||||
mKeyguardSecurityContainer.updateKeyguardPosition((SCREEN_WIDTH / 4f) * 3f);
|
||||
mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
|
||||
/* leftAligned= */false, /* animate= */false);
|
||||
verify(mSecurityViewFlipper, never()).setTranslationX(anyInt());
|
||||
|
||||
mKeyguardSecurityContainer.updateKeyguardPosition(0.0f);
|
||||
mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
|
||||
/* leftAligned= */true, /* animate= */false);
|
||||
verify(mSecurityViewFlipper, never()).setTranslationX(anyInt());
|
||||
}
|
||||
|
||||
private void setUpKeyguard(
|
||||
boolean deviceConfigCanUseOneHandedKeyguard,
|
||||
boolean sysuiResourceCanUseOneHandedKeyguard,
|
||||
SecurityMode securityMode) {
|
||||
TestableResources testableResources = mContext.getOrCreateTestableResources();
|
||||
testableResources.addOverride(
|
||||
com.android.internal.R.bool.config_enableDynamicKeyguardPositioning,
|
||||
deviceConfigCanUseOneHandedKeyguard);
|
||||
testableResources.addOverride(R.bool.can_use_one_handed_bouncer,
|
||||
sysuiResourceCanUseOneHandedKeyguard);
|
||||
mKeyguardSecurityContainer.updateLayoutForSecurityMode(securityMode);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user