diff options
7 files changed, 215 insertions, 115 deletions
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java index 0f10589dfcf9..bd628ccb3c08 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java @@ -29,7 +29,7 @@ import java.lang.annotation.RetentionPolicy; /** * Interface that decides whether a touch on the phone was accidental. i.e. Pocket Dialing. * - * {@see com.android.systemui.classifier.FalsingManagerImpl} + * {@see com.android.systemui.classifier.BrightLineFalsingManager} */ @ProvidesInterface(version = FalsingManager.VERSION) public interface FalsingManager { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 65c415b5272b..11519bf38516 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -375,10 +375,23 @@ public class KeyguardSecurityContainer extends FrameLayout { mViewMode.updatePositionByTouchX(x); } - /** Returns whether the inner SecurityViewFlipper is left-aligned when in one-handed mode. */ - public boolean isOneHandedModeLeftAligned() { - return mCurrentMode == MODE_ONE_HANDED - && ((OneHandedViewMode) mViewMode).isLeftAligned(); + public boolean isSidedSecurityMode() { + return mViewMode instanceof SidedSecurityMode; + } + + /** Returns whether the inner SecurityViewFlipper is left-aligned when in sided mode. */ + public boolean isSecurityLeftAligned() { + return mViewMode instanceof SidedSecurityMode + && ((SidedSecurityMode) mViewMode).isLeftAligned(); + } + + /** + * Returns whether the touch happened on the other side of security (like bouncer) when in + * sided mode. + */ + public boolean isTouchOnTheOtherSideOfSecurity(MotionEvent ev) { + return mViewMode instanceof SidedSecurityMode + && ((SidedSecurityMode) mViewMode).isTouchOnTheOtherSideOfSecurity(ev); } public void onPause() { @@ -437,12 +450,15 @@ public class KeyguardSecurityContainer extends FrameLayout { @Override public boolean onTouchEvent(MotionEvent event) { final int action = event.getActionMasked(); - mDoubleTapDetector.onTouchEvent(event); boolean result = mMotionEventListeners.stream() .anyMatch(listener -> listener.onTouchEvent(event)) || super.onTouchEvent(event); + // double tap detector should be called after listeners handle touches as listeners are + // helping with ignoring falsing. Otherwise falsing will be activated for some double taps + mDoubleTapDetector.onTouchEvent(event); + switch (action) { case MotionEvent.ACTION_MOVE: mVelocityTracker.addMovement(event); @@ -487,11 +503,16 @@ public class KeyguardSecurityContainer extends FrameLayout { private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { - if (!mIsDragging) { - mViewMode.handleDoubleTap(e); - } + return handleDoubleTap(e); + } + } + + @VisibleForTesting boolean handleDoubleTap(MotionEvent e) { + if (!mIsDragging) { + mViewMode.handleDoubleTap(e); return true; } + return false; } void addMotionEventListener(Gefingerpoken listener) { @@ -771,6 +792,70 @@ public class KeyguardSecurityContainer extends FrameLayout { } /** + * Base class for modes which support having on left/right side of the screen, used for large + * screen devices + */ + abstract static class SidedSecurityMode implements ViewMode { + private ViewGroup mView; + private GlobalSettings mGlobalSettings; + private int mDefaultSideSetting; + + public void init(ViewGroup v, GlobalSettings globalSettings, boolean leftAlignedByDefault) { + mView = v; + mGlobalSettings = globalSettings; + mDefaultSideSetting = + leftAlignedByDefault ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT + : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT; + } + + /** + * Determine if a double tap on this view is on the other side. If so, will animate + * positions and record the preference to always show on this side. + */ + @Override + public void handleDoubleTap(MotionEvent event) { + boolean currentlyLeftAligned = isLeftAligned(); + // Did the tap hit the "other" side of the bouncer? + if (isTouchOnTheOtherSideOfSecurity(event, currentlyLeftAligned)) { + boolean willBeLeftAligned = !currentlyLeftAligned; + updateSideSetting(willBeLeftAligned); + + int keyguardState = willBeLeftAligned + ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_LEFT + : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_RIGHT; + SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, keyguardState); + + updateSecurityViewLocation(willBeLeftAligned, /* animate= */ true); + } + } + + private boolean isTouchOnTheOtherSideOfSecurity(MotionEvent ev, boolean leftAligned) { + float x = ev.getX(); + return (leftAligned && (x > mView.getWidth() / 2f)) + || (!leftAligned && (x < mView.getWidth() / 2f)); + } + + public boolean isTouchOnTheOtherSideOfSecurity(MotionEvent ev) { + return isTouchOnTheOtherSideOfSecurity(ev, isLeftAligned()); + } + + protected abstract void updateSecurityViewLocation(boolean leftAlign, boolean animate); + + boolean isLeftAligned() { + return mGlobalSettings.getInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE, + mDefaultSideSetting) + == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT; + } + + protected void updateSideSetting(boolean leftAligned) { + mGlobalSettings.putInt( + Settings.Global.ONE_HANDED_KEYGUARD_SIDE, + leftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT + : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT); + } + } + + /** * Default bouncer is centered within the space */ static class DefaultViewMode implements ViewMode { @@ -802,7 +887,7 @@ public class KeyguardSecurityContainer extends FrameLayout { * User switcher mode will display both the current user icon as well as * a user switcher, in both portrait and landscape modes. */ - static class UserSwitcherViewMode implements ViewMode { + static class UserSwitcherViewMode extends SidedSecurityMode { private ViewGroup mView; private ViewGroup mUserSwitcherViewGroup; private KeyguardSecurityViewFlipper mViewFlipper; @@ -819,6 +904,7 @@ public class KeyguardSecurityContainer extends FrameLayout { @NonNull KeyguardSecurityViewFlipper viewFlipper, @NonNull FalsingManager falsingManager, @NonNull UserSwitcherController userSwitcherController) { + init(v, globalSettings, /* leftAlignedByDefault= */false); mView = v; mViewFlipper = viewFlipper; mFalsingManager = falsingManager; @@ -1030,6 +1116,10 @@ public class KeyguardSecurityContainer extends FrameLayout { @Override public void updateSecurityViewLocation() { + updateSecurityViewLocation(isLeftAligned(), /* animate= */false); + } + + public void updateSecurityViewLocation(boolean leftAlign, boolean animate) { int yTrans = mResources.getDimensionPixelSize(R.dimen.bouncer_user_switcher_y_trans); if (mResources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { @@ -1039,8 +1129,12 @@ public class KeyguardSecurityContainer extends FrameLayout { mUserSwitcherViewGroup.setTranslationY(yTrans); mViewFlipper.setTranslationY(-yTrans); } else { - updateViewGravity(mViewFlipper, Gravity.RIGHT | Gravity.BOTTOM); - updateViewGravity(mUserSwitcherViewGroup, Gravity.LEFT | Gravity.CENTER_VERTICAL); + int securityHorizontalGravity = leftAlign ? Gravity.LEFT : Gravity.RIGHT; + int userSwitcherHorizontalGravity = + securityHorizontalGravity == Gravity.LEFT ? Gravity.RIGHT : Gravity.LEFT; + updateViewGravity(mViewFlipper, securityHorizontalGravity | Gravity.BOTTOM); + updateViewGravity(mUserSwitcherViewGroup, + userSwitcherHorizontalGravity | Gravity.CENTER_VERTICAL); // Attempt to reposition a bit higher to make up for this frame being a bit lower // on the device @@ -1060,20 +1154,19 @@ public class KeyguardSecurityContainer extends FrameLayout { * Logic to enabled one-handed bouncer mode. Supports animating the bouncer * between alternate sides of the display. */ - static class OneHandedViewMode implements ViewMode { + static class OneHandedViewMode extends SidedSecurityMode { @Nullable private ValueAnimator mRunningOneHandedAnimator; private ViewGroup mView; private KeyguardSecurityViewFlipper mViewFlipper; - private GlobalSettings mGlobalSettings; @Override public void init(@NonNull ViewGroup v, @NonNull GlobalSettings globalSettings, @NonNull KeyguardSecurityViewFlipper viewFlipper, @NonNull FalsingManager falsingManager, @NonNull UserSwitcherController userSwitcherController) { + init(v, globalSettings, /* leftAlignedByDefault= */true); mView = v; mViewFlipper = viewFlipper; - mGlobalSettings = globalSettings; updateSecurityViewGravity(); updateSecurityViewLocation(isLeftAligned(), /* animate= */false); @@ -1107,43 +1200,6 @@ public class KeyguardSecurityContainer extends FrameLayout { updateSecurityViewLocation(isTouchOnLeft, /* animate= */false); } - boolean isLeftAligned() { - return mGlobalSettings.getInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE, - Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT) - == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT; - } - - private void updateSideSetting(boolean leftAligned) { - mGlobalSettings.putInt( - Settings.Global.ONE_HANDED_KEYGUARD_SIDE, - leftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT - : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT); - } - - /** - * Determine if a double tap on this view is on the other side. If so, will animate - * positions and record the preference to always show on this side. - */ - @Override - public void handleDoubleTap(MotionEvent event) { - float x = event.getX(); - boolean currentlyLeftAligned = isLeftAligned(); - // Did the tap hit the "other" side of the bouncer? - if ((currentlyLeftAligned && (x > mView.getWidth() / 2f)) - || (!currentlyLeftAligned && (x < mView.getWidth() / 2f))) { - - boolean willBeLeftAligned = !currentlyLeftAligned; - updateSideSetting(willBeLeftAligned); - - int keyguardState = willBeLeftAligned - ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_LEFT - : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SWITCH_RIGHT; - SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, keyguardState); - - updateSecurityViewLocation(willBeLeftAligned, true /* animate */); - } - } - @Override public void updateSecurityViewLocation() { updateSecurityViewLocation(isLeftAligned(), /* animate= */false); @@ -1151,10 +1207,10 @@ public class KeyguardSecurityContainer extends FrameLayout { /** * Moves the inner security view to the correct location (in one handed mode) with - * animation. This is triggered when the user taps on the side of the screen that is not - * currently occupied by the security view. + * animation. This is triggered when the user double taps on the side of the screen that is + * not currently occupied by the security view. */ - private void updateSecurityViewLocation(boolean leftAlign, boolean animate) { + protected void updateSecurityViewLocation(boolean leftAlign, boolean animate) { if (mRunningOneHandedAnimator != null) { mRunningOneHandedAnimator.cancel(); mRunningOneHandedAnimator = null; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 19a2d9ed5b7b..61e262440607 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -116,12 +116,8 @@ 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.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) { - boolean isLeftAligned = mView.isOneHandedModeLeftAligned(); - if ((isLeftAligned && ev.getX() > mView.getWidth() / 2f) - || (!isLeftAligned && ev.getX() <= mView.getWidth() / 2f)) { - mFalsingCollector.avoidGesture(); - } + if (mView.isTouchOnTheOtherSideOfSecurity(ev)) { + mFalsingCollector.avoidGesture(); } if (mTouchDown != null) { @@ -169,8 +165,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 (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) { - bouncerSide = mView.isOneHandedModeLeftAligned() + if (mView.isSidedSecurityMode()) { + bouncerSide = mView.isSecurityLeftAligned() ? SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__LEFT : SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__RIGHT; } @@ -367,8 +363,8 @@ 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 (mView.getMode() == KeyguardSecurityContainer.MODE_ONE_HANDED) { - state = mView.isOneHandedModeLeftAligned() + if (mView.isSidedSecurityMode()) { + state = mView.isSecurityLeftAligned() ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_LEFT : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_RIGHT; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 6009eba24f5b..70773005d0b2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -1670,7 +1670,6 @@ public class NotificationPanelViewController extends PanelViewController { setQsExpansionEnabled(); } - @Override public void resetViews(boolean animate) { mIsLaunchTransitionFinished = false; mBlockTouches = false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index 9f0ecb9d4096..ed12b00cc644 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -1163,8 +1163,6 @@ public abstract class PanelViewController { mTouchDisabled ? "T" : "f")); } - public abstract void resetViews(boolean animate); - public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) { mHeadsUpManager = headsUpManager; } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index 7de4586e1901..bc351427310d 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -27,7 +27,6 @@ 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.verify; import static org.mockito.Mockito.when; @@ -68,8 +67,6 @@ 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(); @@ -141,7 +138,6 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { 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); @@ -212,49 +208,26 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mUserSwitcherController); } - private void touchDownLeftSide() { + private void touchDown() { 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, + /* x= */0, /* y= */0, /* metaState= */0)); } @Test - public void onInterceptTap_inhibitsFalsingInOneHandedMode() { - when(mView.getMode()).thenReturn(MODE_ONE_HANDED); - 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); + public void onInterceptTap_inhibitsFalsingInSidedSecurityMode() { - // On the right... - touchDownRightSide(); + when(mView.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(false); + touchDown(); verify(mFalsingCollector, never()).avoidGesture(); - touchDownLeftSide(); + when(mView.isTouchOnTheOtherSideOfSecurity(any())).thenReturn(true); + touchDown(); verify(mFalsingCollector).avoidGesture(); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java index d49f4d8172dc..1b9662ccae0c 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java @@ -16,6 +16,9 @@ package com.android.keyguard; +import static android.provider.Settings.Global.ONE_HANDED_KEYGUARD_SIDE; +import static android.provider.Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT; +import static android.provider.Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.systemBars; @@ -25,7 +28,9 @@ import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -34,10 +39,10 @@ import static org.mockito.Mockito.when; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Insets; -import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.Gravity; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; @@ -70,6 +75,9 @@ import java.util.ArrayList; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper() public class KeyguardSecurityContainerTest extends SysuiTestCase { + + private static final int VIEW_WIDTH = 1600; + private int mScreenWidth; private int mFakeMeasureSpec; @@ -212,14 +220,12 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { mKeyguardSecurityContainer.updatePositionByTouchX( mKeyguardSecurityContainer.getWidth() - 1f); - verify(mGlobalSettings).putInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE, - Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT); + verify(mGlobalSettings).putInt(ONE_HANDED_KEYGUARD_SIDE, ONE_HANDED_KEYGUARD_SIDE_RIGHT); verify(mSecurityViewFlipper).setTranslationX( mKeyguardSecurityContainer.getWidth() - mSecurityViewFlipper.getWidth()); mKeyguardSecurityContainer.updatePositionByTouchX(1f); - verify(mGlobalSettings).putInt(Settings.Global.ONE_HANDED_KEYGUARD_SIDE, - Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT); + verify(mGlobalSettings).putInt(ONE_HANDED_KEYGUARD_SIDE, ONE_HANDED_KEYGUARD_SIDE_LEFT); verify(mSecurityViewFlipper).setTranslationX(0.0f); } @@ -253,10 +259,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { // THEN views are oriented side by side verify(mSecurityViewFlipper).setLayoutParams(mLayoutCaptor.capture()); assertThat(mLayoutCaptor.getValue().gravity).isEqualTo(Gravity.RIGHT | Gravity.BOTTOM); - ViewGroup userSwitcher = mKeyguardSecurityContainer.findViewById( - R.id.keyguard_bouncer_user_switcher); - assertThat(((FrameLayout.LayoutParams) userSwitcher.getLayoutParams()).gravity) - .isEqualTo(Gravity.LEFT | Gravity.CENTER_VERTICAL); + assertUserSwitcherGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); } @Test @@ -276,10 +279,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { // THEN views are both centered horizontally verify(mSecurityViewFlipper).setLayoutParams(mLayoutCaptor.capture()); assertThat(mLayoutCaptor.getValue().gravity).isEqualTo(Gravity.CENTER_HORIZONTAL); - ViewGroup userSwitcher = mKeyguardSecurityContainer.findViewById( - R.id.keyguard_bouncer_user_switcher); - assertThat(((FrameLayout.LayoutParams) userSwitcher.getLayoutParams()).gravity) - .isEqualTo(Gravity.CENTER_HORIZONTAL); + assertUserSwitcherGravity(Gravity.CENTER_HORIZONTAL); } @Test @@ -310,7 +310,85 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { assertThat(anchor.isClickable()).isTrue(); } + @Test + public void testTouchesAreRecognizedAsBeingOnTheOtherSideOfSecurity() { + setupUserSwitcher(); + setViewWidth(VIEW_WIDTH); + + assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity( + touchEventLeftSide())).isTrue(); + assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity( + touchEventRightSide())).isFalse(); + + mKeyguardSecurityContainer.handleDoubleTap(touchEventLeftSide()); + // settings should be updated, we need to keep the mock updated as well + when(mGlobalSettings.getInt(any(), anyInt())).thenReturn(ONE_HANDED_KEYGUARD_SIDE_LEFT); + assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity( + touchEventLeftSide())).isFalse(); + assertThat(mKeyguardSecurityContainer.isTouchOnTheOtherSideOfSecurity( + touchEventRightSide())).isTrue(); + } + + @Test + public void testSecuritySwitchesSidesInLandscapeUserSwitcherMode() { + Configuration config = new Configuration(); + config.orientation = Configuration.ORIENTATION_LANDSCAPE; + when(getContext().getResources().getConfiguration()).thenReturn(config); + setupUserSwitcher(); + // check default position + assertSecurityGravity(Gravity.RIGHT | Gravity.BOTTOM); + assertUserSwitcherGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); + + reset(mSecurityViewFlipper); + when(mSecurityViewFlipper.getLayoutParams()).thenReturn(mSecurityViewFlipperLayoutParams); + // change setting so configuration change triggers position change + when(mGlobalSettings.getInt(any(), anyInt())).thenReturn(ONE_HANDED_KEYGUARD_SIDE_LEFT); + mKeyguardSecurityContainer.onConfigurationChanged(new Configuration()); + + // check position after switching + assertSecurityGravity(Gravity.LEFT | Gravity.BOTTOM); + assertUserSwitcherGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL); + } + + private void assertUserSwitcherGravity(@Gravity.GravityFlags int gravity) { + ViewGroup userSwitcher = mKeyguardSecurityContainer.findViewById( + R.id.keyguard_bouncer_user_switcher); + assertThat(((FrameLayout.LayoutParams) userSwitcher.getLayoutParams()).gravity) + .isEqualTo(gravity); + } + + private void assertSecurityGravity(@Gravity.GravityFlags int gravity) { + verify(mSecurityViewFlipper, atLeastOnce()).setLayoutParams(mLayoutCaptor.capture()); + assertThat(mLayoutCaptor.getValue().gravity).isEqualTo(gravity); + } + + private void setViewWidth(int width) { + mKeyguardSecurityContainer.setRight(width); + mKeyguardSecurityContainer.setLeft(0); + } + + private MotionEvent touchEventLeftSide() { + return MotionEvent.obtain( + /* downTime= */0, + /* eventTime= */0, + MotionEvent.ACTION_DOWN, + /* x= */VIEW_WIDTH / 3f, + /* y= */0, + /* metaState= */0); + } + + private MotionEvent touchEventRightSide() { + return MotionEvent.obtain( + /* downTime= */0, + /* eventTime= */0, + MotionEvent.ACTION_DOWN, + /* x= */(VIEW_WIDTH / 3f) * 2, + /* y= */0, + /* metaState= */0); + } + private void setupUserSwitcher() { + when(mGlobalSettings.getInt(any(), anyInt())).thenReturn(ONE_HANDED_KEYGUARD_SIDE_RIGHT); mKeyguardSecurityContainer.initMode(KeyguardSecurityContainer.MODE_USER_SWITCHER, mGlobalSettings, mFalsingManager, mUserSwitcherController); } |