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

Commit 49a77025 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Bouncer update #2"

parents 6a15605c bbc2b983
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ The bouncer contains a hierarchy of controllers/views to render the user's secur

1. [KeyguardBouncer][1] - Entrypoint for managing the bouncer visibility.
    1. [KeyguardHostViewController][2] - Intercepts media keys. Can most likely be merged with the next item.
        1. [KeyguardSecurityContainerController][3] - Manages unlock attempt responses, one-handed use
        1. [KeyguardSecurityContainerController][3] - Manages unlock attempt responses, determines the correct security view layout, which may include a user switcher or enable one-handed use.
            1. [KeyguardSecurityViewFlipperController][4] - Based upon the [KeyguardSecurityModel#SecurityMode][5], will instantiate the required view and controller. PIN, Pattern, etc.

Fun fact: Naming comes from the concept of a bouncer at a bar or nightclub, who prevent troublemakers from entering or eject them from the premises.
+330 −201

File changed.

Preview size limit exceeded, changes collapsed.

+38 −43
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ 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;
@@ -56,6 +55,7 @@ import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.settings.GlobalSettings;

import javax.inject.Inject;

@@ -78,6 +78,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
    private final SecurityCallback mSecurityCallback;
    private final ConfigurationController mConfigurationController;
    private final FalsingCollector mFalsingCollector;
    private final GlobalSettings mGlobalSettings;

    private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;

@@ -99,10 +100,10 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                // 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)) {
                if (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) {
                    boolean isLeftAligned = mView.isOneHandedModeLeftAligned();
                    if ((isLeftAligned && ev.getX() > mView.getWidth() / 2f)
                            || (!isLeftAligned && ev.getX() <= mView.getWidth() / 2f)) {
                        mFalsingCollector.avoidGesture();
                    }
                }
@@ -152,8 +153,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard

        public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) {
            int bouncerSide = SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__DEFAULT;
            if (canUseOneHandedBouncer()) {
                bouncerSide = isOneHandedKeyguardLeftAligned()
            if (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) {
                bouncerSide = mView.isOneHandedModeLeftAligned()
                        ? SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__LEFT
                        : SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__RIGHT;
            }
@@ -230,7 +231,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
            SecurityCallback securityCallback,
            KeyguardSecurityViewFlipperController securityViewFlipperController,
            ConfigurationController configurationController,
            FalsingCollector falsingCollector) {
            FalsingCollector falsingCollector,
            GlobalSettings globalSettings) {
        super(view);
        mLockPatternUtils = lockPatternUtils;
        mUpdateMonitor = keyguardUpdateMonitor;
@@ -245,6 +247,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        mConfigurationController = configurationController;
        mLastOrientation = getResources().getConfiguration().orientation;
        mFalsingCollector = falsingCollector;
        mGlobalSettings = globalSettings;
    }

    @Override
@@ -324,7 +327,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
    public void onResume(int reason) {
        if (mCurrentSecurityMode != SecurityMode.None) {
            int state = SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN;
            if (canUseOneHandedBouncer()) {
            if (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) {
                state = mView.isOneHandedModeLeftAligned()
                        ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_LEFT
                        : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_RIGHT;
@@ -477,50 +480,41 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        if (newView != null) {
            newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
            mSecurityViewFlipperController.show(newView);
            configureOneHandedMode();
            configureMode();
        }

        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() {
        if (!isSecurityViewOneHanded(mCurrentSecurityMode)) {
            return false;
        }

        return getResources().getBoolean(R.bool.can_use_one_handed_bouncer);
    }

    /**
     * Returns whether the given security view should be used in a "one handed" way. This can be
     * used to change how the security view is drawn (e.g. take up less of the screen, and align to
     * one side).
     */
    private boolean isSecurityViewOneHanded(SecurityMode securityMode) {
        return securityMode == SecurityMode.Pattern || securityMode == SecurityMode.PIN;
    private boolean canUseOneHandedBouncer() {
        if (!(mCurrentSecurityMode == SecurityMode.Pattern
                || mCurrentSecurityMode == SecurityMode.PIN)) {
            return false;
        }

    private void configureOneHandedMode() {
        boolean oneHandedMode = canUseOneHandedBouncer();
        return getResources().getBoolean(R.bool.can_use_one_handed_bouncer);
    }

        mView.setOneHandedMode(oneHandedMode);
    private boolean canDisplayUserSwitcher() {
        return getResources().getBoolean(R.bool.bouncer_display_user_switcher);
    }

        if (oneHandedMode) {
            mView.setOneHandedModeLeftAligned(
                    isOneHandedKeyguardLeftAligned(), /* animate= */false);
    private void configureMode() {
        // One-handed mode and user-switcher are currently mutually exclusive, and enforced here
        int mode = KeyguardSecurityContainer.MODE_DEFAULT;
        if (canDisplayUserSwitcher()) {
            mode = KeyguardSecurityContainer.MODE_USER_SWITCHER;
        } else if (canUseOneHandedBouncer()) {
            mode = KeyguardSecurityContainer.MODE_ONE_HANDED;
        }

        mView.initMode(mode, mGlobalSettings);
    }

    public void reportFailedUnlockAttempt(int userId, int timeoutMs) {
@@ -587,15 +581,13 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        int newOrientation = getResources().getConfiguration().orientation;
        if (newOrientation != mLastOrientation) {
            mLastOrientation = newOrientation;
            configureOneHandedMode();
            configureMode();
        }
    }

    /** Update keyguard position based on a tapped X coordinate. */
    public void updateKeyguardPosition(float x) {
        if (mView.isOneHandedMode()) {
            mView.setOneHandedModeLeftAligned(x <= mView.getWidth() / 2f, false);
        }
        mView.updatePositionByTouchX(x);
    }

    static class Factory {
@@ -612,6 +604,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
        private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController;
        private final ConfigurationController mConfigurationController;
        private final FalsingCollector mFalsingCollector;
        private final GlobalSettings mGlobalSettings;

        @Inject
        Factory(KeyguardSecurityContainer view,
@@ -625,7 +618,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                KeyguardStateController keyguardStateController,
                KeyguardSecurityViewFlipperController securityViewFlipperController,
                ConfigurationController configurationController,
                FalsingCollector falsingCollector) {
                FalsingCollector falsingCollector,
                GlobalSettings globalSettings) {
            mView = view;
            mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
            mLockPatternUtils = lockPatternUtils;
@@ -637,6 +631,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
            mSecurityViewFlipperController = securityViewFlipperController;
            mConfigurationController = configurationController;
            mFalsingCollector = falsingCollector;
            mGlobalSettings = globalSettings;
        }

        public KeyguardSecurityContainerController create(
@@ -645,7 +640,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
                    mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
                    mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
                    mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
                    mConfigurationController, mFalsingCollector);
                    mConfigurationController, mFalsingCollector, mGlobalSettings);
        }

    }
+13 −26
Original line number Diff line number Diff line
@@ -18,8 +18,10 @@ package com.android.keyguard;

import static android.view.WindowInsets.Type.ime;

import static com.android.keyguard.KeyguardSecurityContainer.MODE_DEFAULT;
import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED;

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;
@@ -27,7 +29,6 @@ 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;
import static org.mockito.Mockito.when;

@@ -49,6 +50,7 @@ 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;
import com.android.systemui.util.settings.GlobalSettings;

import org.junit.Before;
import org.junit.Rule;
@@ -107,6 +109,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
    private Resources mResources;
    @Mock
    private FalsingCollector mFalsingCollector;
    @Mock
    private GlobalSettings mGlobalSettings;
    private Configuration mConfiguration;

    private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
@@ -140,7 +144,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
                mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
                mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
                mKeyguardStateController, mKeyguardSecurityViewFlipperController,
                mConfigurationController, mFalsingCollector)
                mConfigurationController, mFalsingCollector, mGlobalSettings)
                .create(mSecurityCallback);
    }

@@ -178,30 +182,13 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
    public void onResourcesUpdate_callsThroughOnRotationChange() {
        // Rotation is the same, shouldn't cause an update
        mKeyguardSecurityContainerController.updateResources();
        verify(mView, times(0)).setOneHandedMode(anyBoolean());
        verify(mView, never()).initMode(MODE_DEFAULT, mGlobalSettings);

        // Update rotation. Should trigger update
        mConfiguration.orientation = Configuration.ORIENTATION_LANDSCAPE;

        mKeyguardSecurityContainerController.updateResources();
        verify(mView, times(1)).setOneHandedMode(anyBoolean());
    }

    @Test
    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, never()).setOneHandedModeLeftAligned(anyBoolean(), anyBoolean());
        verify(mView).initMode(MODE_DEFAULT, mGlobalSettings);
    }

    private void touchDownLeftSide() {
@@ -228,7 +215,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {

    @Test
    public void onInterceptTap_inhibitsFalsingInOneHandedMode() {
        when(mView.isOneHandedMode()).thenReturn(true);
        when(mView.getMode()).thenReturn(MODE_ONE_HANDED);
        when(mView.isOneHandedModeLeftAligned()).thenReturn(true);

        touchDownLeftSide();
@@ -258,7 +245,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
                .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);

        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
        verify(mView).setOneHandedMode(false);
        verify(mView).initMode(MODE_DEFAULT, mGlobalSettings);
    }

    @Test
@@ -269,7 +256,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
                .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);

        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Pattern);
        verify(mView).setOneHandedMode(true);
        verify(mView).initMode(MODE_ONE_HANDED, mGlobalSettings);
    }

    @Test
@@ -280,6 +267,6 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
                .thenReturn((KeyguardInputViewController) mKeyguardPasswordViewController);

        mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.Password);
        verify(mView).setOneHandedMode(false);
        verify(mView).initMode(MODE_DEFAULT, mGlobalSettings);
    }
}
+21 −17
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ package com.android.keyguard;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.systemBars;

import static com.android.keyguard.KeyguardSecurityContainer.MODE_DEFAULT;
import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -37,6 +40,7 @@ import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;
import com.android.systemui.util.settings.GlobalSettings;

import org.junit.Before;
import org.junit.Rule;
@@ -59,9 +63,10 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {

    @Mock
    private WindowInsetsController mWindowInsetsController;

    @Mock
    private KeyguardSecurityViewFlipper mSecurityViewFlipper;
    @Mock
    private GlobalSettings mGlobalSettings;

    private KeyguardSecurityContainer mKeyguardSecurityContainer;

@@ -83,7 +88,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {

    @Test
    public void onMeasure_usesHalfWidthWithOneHandedModeEnabled() {
        mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */true);
        mKeyguardSecurityContainer.initMode(MODE_ONE_HANDED, mGlobalSettings);

        int halfWidthMeasureSpec =
                View.MeasureSpec.makeMeasureSpec(SCREEN_WIDTH / 2, View.MeasureSpec.EXACTLY);
@@ -94,7 +99,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {

    @Test
    public void onMeasure_usesFullWidthWithOneHandedModeDisabled() {
        mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false);
        mKeyguardSecurityContainer.initMode(MODE_DEFAULT, mGlobalSettings);

        mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
        verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
@@ -105,7 +110,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
        int imeInsetAmount = 100;
        int systemBarInsetAmount = 10;

        mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false);
        mKeyguardSecurityContainer.initMode(MODE_DEFAULT, mGlobalSettings);

        Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
        Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
@@ -129,7 +134,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
        int imeInsetAmount = 0;
        int systemBarInsetAmount = 10;

        mKeyguardSecurityContainer.setOneHandedMode(/* oneHandedMode= */false);
        mKeyguardSecurityContainer.initMode(MODE_DEFAULT, mGlobalSettings);

        Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
        Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
@@ -148,8 +153,8 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
    }

    private void setupForUpdateKeyguardPosition(boolean oneHandedMode) {
        mKeyguardSecurityContainer.setOneHandedMode(oneHandedMode);
        mKeyguardSecurityContainer.setOneHandedModeLeftAligned(true, false);
        int mode = oneHandedMode ? MODE_ONE_HANDED : MODE_DEFAULT;
        mKeyguardSecurityContainer.initMode(mode, mGlobalSettings);

        mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
        mKeyguardSecurityContainer.layout(0, 0, SCREEN_WIDTH, SCREEN_WIDTH);
@@ -160,29 +165,28 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
    }

    @Test
    public void setIsLeftAligned_movesKeyguard() {
    public void updatePosition_movesKeyguard() {
        setupForUpdateKeyguardPosition(/* oneHandedMode= */ true);
        mKeyguardSecurityContainer.updatePositionByTouchX(
                mKeyguardSecurityContainer.getWidth() - 1f);

        mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
                /* leftAligned= */false, /* animate= */false);
        verify(mSecurityViewFlipper).setTranslationX(
                mKeyguardSecurityContainer.getWidth() - mSecurityViewFlipper.getWidth());

        mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
                /* leftAligned= */true, /* animate= */false);
        mKeyguardSecurityContainer.updatePositionByTouchX(1f);

        verify(mSecurityViewFlipper).setTranslationX(0.0f);
    }

    @Test
    public void setIsLeftAligned_doesntMoveTwoHandedKeyguard() {
    public void updatePosition_doesntMoveTwoHandedKeyguard() {
        setupForUpdateKeyguardPosition(/* oneHandedMode= */ false);

        mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
                /* leftAligned= */false, /* animate= */false);
        mKeyguardSecurityContainer.updatePositionByTouchX(
                mKeyguardSecurityContainer.getWidth() - 1f);
        verify(mSecurityViewFlipper, never()).setTranslationX(anyInt());

        mKeyguardSecurityContainer.setOneHandedModeLeftAligned(
                /* leftAligned= */true, /* animate= */false);
        mKeyguardSecurityContainer.updatePositionByTouchX(1f);
        verify(mSecurityViewFlipper, never()).setTranslationX(anyInt());
    }
}