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:
Jamie Garside
2021-05-14 18:55:25 +01:00
parent dc87f5e0e2
commit 3b6a942029
4 changed files with 269 additions and 171 deletions

View File

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

View File

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

View File

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

View File

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