Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b6a9420 authored by Jamie Garside's avatar Jamie Garside
Browse files

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
parent dc87f5e0
Loading
Loading
Loading
Loading
+30 −69
Original line number Diff line number Diff line
@@ -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);
        }
    }

    /** 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;
    /** Returns whether this security container is in one-handed mode. */
    public boolean isOneHandedMode() {
        return mOneHandedMode;
    }

        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 {
+66 −7
Original line number Diff line number Diff line
@@ -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);
        }

    }
+152 −5
Original line number Diff line number Diff line
@@ -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);
    }
}
+21 −90

File changed.

Preview size limit exceeded, changes collapsed.