Loading libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java +12 −3 Original line number Diff line number Diff line Loading @@ -52,18 +52,27 @@ public interface OneHanded { void stopOneHanded(int uiEvent); /** * Set navigation 3 button mode enabled or disabled by users. * Sets navigation 3 button mode enabled or disabled by users. */ void setThreeButtonModeEnabled(boolean enabled); /** * Register callback to be notified after {@link OneHandedDisplayAreaOrganizer} * Sets one handed feature temporary locked in enabled or disabled state, this won't change * settings configuration. * * @param locked locked function in disabled(can not trigger) or enabled state. * @param enabled function in disabled(can not trigger) or enabled state. */ void setLockedDisabled(boolean locked, boolean enabled); /** * Registers callback to be notified after {@link OneHandedDisplayAreaOrganizer} * transition start or finish */ void registerTransitionCallback(OneHandedTransitionCallback callback); /** * Register callback for one handed gesture, this gesture callbcak will be activated on * Registers callback for one handed gesture, this gesture callback will be activated on * 3 button navigation mode only */ void registerGestureCallback(OneHandedGestureEventCallback callback); Loading libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +27 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class OneHandedController { private volatile boolean mIsOneHandedEnabled; private volatile boolean mIsSwipeToNotificationEnabled; private boolean mTaskChangeToExit; private boolean mLockedDisabled; private float mOffSetFraction; private final Context mContext; Loading Loading @@ -263,6 +264,10 @@ public class OneHandedController { @VisibleForTesting void startOneHanded() { if (isLockedDisabled()) { Slog.d(TAG, "Temporary lock disabled"); return; } if (!mDisplayAreaOrganizer.isInOneHanded()) { final int yOffSet = Math.round(getDisplaySize().y * mOffSetFraction); mDisplayAreaOrganizer.scheduleOffset(0, yOffSet); Loading Loading @@ -433,6 +438,11 @@ public class OneHandedController { return displaySize; } @VisibleForTesting boolean isLockedDisabled() { return mLockedDisabled; } private void updateOneHandedEnabled() { if (mDisplayAreaOrganizer.isInOneHanded()) { stopOneHanded(); Loading Loading @@ -485,6 +495,14 @@ public class OneHandedController { } } @VisibleForTesting void setLockedDisabled(boolean locked, boolean enabled) { if (enabled == mIsOneHandedEnabled) { return; } mLockedDisabled = locked && !enabled; } private void onConfigChanged(Configuration newConfig) { if (mTutorialHandler != null) { if (!mIsOneHandedEnabled Loading @@ -500,6 +518,8 @@ public class OneHandedController { pw.println(TAG + "states: "); pw.print(innerPrefix + "mOffSetFraction="); pw.println(mOffSetFraction); pw.print(innerPrefix + "mLockedDisabled="); pw.println(mLockedDisabled); if (mDisplayAreaOrganizer != null) { mDisplayAreaOrganizer.dump(pw); Loading Loading @@ -575,6 +595,13 @@ public class OneHandedController { }); } @Override public void setLockedDisabled(boolean locked, boolean enabled) { mMainExecutor.execute(() -> { OneHandedController.this.setLockedDisabled(locked, enabled); }); } @Override public void registerTransitionCallback(OneHandedTransitionCallback callback) { mMainExecutor.execute(() -> { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +70 −13 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ public class OneHandedControllerTest extends OneHandedTestCase { final boolean mDefaultSwipeToNotificationEnabled = OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled( getTestContext().getContentResolver()); final boolean mDefaultTapAppToExitEnabled = OneHandedSettingsUtil.getSettingsTapsAppToExit( getTestContext().getContentResolver()); @Before public void setUp() { Loading Loading @@ -176,7 +178,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test public void testStopOneHanded_shouldRemoveTimer() { public void testStopOneHandedShouldRemoveTimer() { when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(true); mSpiedOneHandedController.stopOneHanded(); Loading @@ -193,27 +195,29 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test public void testUpdateSwipeToNotificationEnabled() { final boolean swipeToNotificationEnabled = true; mSpiedOneHandedController.setSwipeToNotificationEnabled(swipeToNotificationEnabled); public void testUpdateSwipeToNotification() { mSpiedOneHandedController.setSwipeToNotificationEnabled(mDefaultSwipeToNotificationEnabled); verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(mDefaultEnabled); verify(mMockGestureHandler, atLeastOnce()).onOneHandedEnabled( mDefaultEnabled || swipeToNotificationEnabled); mDefaultEnabled || mDefaultSwipeToNotificationEnabled); } @Test public void testUpdateTapAppToExitUpdate() { public void testSettingsObserverUpdateTapAppToExit() { mSpiedOneHandedController.onTaskChangeExitSettingChanged(); if (mDefaultTapAppToExitEnabled) { verify(mMockTaskStackListener, atLeastOnce()).addListener(any()); } else { verify(mMockTaskStackListener, atLeastOnce()).removeListener(any()); } } @Test public void tesSettingsObserverUpdateEnabled() { public void testSettingsObserverUpdateEnabled() { mSpiedOneHandedController.onEnabledSettingChanged(); verify(mSpiedOneHandedController, atLeastOnce()).setOneHandedEnabled(mDefaultEnabled); verify(mSpiedOneHandedController).setOneHandedEnabled(mDefaultEnabled); } @Test Loading @@ -224,10 +228,63 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test public void tesSettingsObserverUpdateSwipeToNotification() { public void testSettingsObserverUpdateSwipeToNotification() { mSpiedOneHandedController.onSwipeToNotificationEnabledSettingChanged(); verify(mSpiedOneHandedController, atLeastOnce()).setSwipeToNotificationEnabled( !mDefaultEnabled); // Swipe to notification function is opposite with one handed mode function if (mDefaultSwipeToNotificationEnabled) { verify(mSpiedOneHandedController).setSwipeToNotificationEnabled( mDefaultSwipeToNotificationEnabled); } else { verify(mSpiedOneHandedController, never()).setSwipeToNotificationEnabled( mDefaultSwipeToNotificationEnabled); } } @Test public void testLockedOneHandedDisabled() { // Default mLockDisabled is false assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, true /* enabled */); // If mOneHandedEnabled == enabled, then keep unlocked assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); // If prefer locked enabled state and 'mOneHandedEnabled == enabled', then unlocked mSpiedOneHandedController.setLockedDisabled(true /* locked */, true /* enabled */); assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); // If prefer locked disabled state and 'mOneHandedEnabled != enabled', then locked disabled mSpiedOneHandedController.setLockedDisabled(true /* locked */, false /* enabled */); assertThat(mSpiedOneHandedController.isLockedDisabled()).isTrue(); // If prefer unlock disabled state and 'mOneHandedEnabled != enabled', then unlocked mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); } @Test public void testKeyguardShowingLockOneHandedDisabled() { when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(true /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); } @Test public void testResetKeyguardShowingLockOneHandedDisabled() { when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); verify(mMockDisplayAreaOrganizer).scheduleOffset(anyInt(), anyInt()); } } packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +7 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,13 @@ public final class WMShell extends SystemUI @Override public void onKeyguardVisibilityChanged(boolean showing) { if (showing) { // When keyguard shown, temperory lock OHM disabled to avoid mis-trigger. oneHanded.setLockedDisabled(true /* locked */, false /* enabled */); } else { // Reset locked. oneHanded.setLockedDisabled(false /* locked */, false /* enabled */); } oneHanded.stopOneHanded(); } }; Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHanded.java +12 −3 Original line number Diff line number Diff line Loading @@ -52,18 +52,27 @@ public interface OneHanded { void stopOneHanded(int uiEvent); /** * Set navigation 3 button mode enabled or disabled by users. * Sets navigation 3 button mode enabled or disabled by users. */ void setThreeButtonModeEnabled(boolean enabled); /** * Register callback to be notified after {@link OneHandedDisplayAreaOrganizer} * Sets one handed feature temporary locked in enabled or disabled state, this won't change * settings configuration. * * @param locked locked function in disabled(can not trigger) or enabled state. * @param enabled function in disabled(can not trigger) or enabled state. */ void setLockedDisabled(boolean locked, boolean enabled); /** * Registers callback to be notified after {@link OneHandedDisplayAreaOrganizer} * transition start or finish */ void registerTransitionCallback(OneHandedTransitionCallback callback); /** * Register callback for one handed gesture, this gesture callbcak will be activated on * Registers callback for one handed gesture, this gesture callback will be activated on * 3 button navigation mode only */ void registerGestureCallback(OneHandedGestureEventCallback callback); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +27 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class OneHandedController { private volatile boolean mIsOneHandedEnabled; private volatile boolean mIsSwipeToNotificationEnabled; private boolean mTaskChangeToExit; private boolean mLockedDisabled; private float mOffSetFraction; private final Context mContext; Loading Loading @@ -263,6 +264,10 @@ public class OneHandedController { @VisibleForTesting void startOneHanded() { if (isLockedDisabled()) { Slog.d(TAG, "Temporary lock disabled"); return; } if (!mDisplayAreaOrganizer.isInOneHanded()) { final int yOffSet = Math.round(getDisplaySize().y * mOffSetFraction); mDisplayAreaOrganizer.scheduleOffset(0, yOffSet); Loading Loading @@ -433,6 +438,11 @@ public class OneHandedController { return displaySize; } @VisibleForTesting boolean isLockedDisabled() { return mLockedDisabled; } private void updateOneHandedEnabled() { if (mDisplayAreaOrganizer.isInOneHanded()) { stopOneHanded(); Loading Loading @@ -485,6 +495,14 @@ public class OneHandedController { } } @VisibleForTesting void setLockedDisabled(boolean locked, boolean enabled) { if (enabled == mIsOneHandedEnabled) { return; } mLockedDisabled = locked && !enabled; } private void onConfigChanged(Configuration newConfig) { if (mTutorialHandler != null) { if (!mIsOneHandedEnabled Loading @@ -500,6 +518,8 @@ public class OneHandedController { pw.println(TAG + "states: "); pw.print(innerPrefix + "mOffSetFraction="); pw.println(mOffSetFraction); pw.print(innerPrefix + "mLockedDisabled="); pw.println(mLockedDisabled); if (mDisplayAreaOrganizer != null) { mDisplayAreaOrganizer.dump(pw); Loading Loading @@ -575,6 +595,13 @@ public class OneHandedController { }); } @Override public void setLockedDisabled(boolean locked, boolean enabled) { mMainExecutor.execute(() -> { OneHandedController.this.setLockedDisabled(locked, enabled); }); } @Override public void registerTransitionCallback(OneHandedTransitionCallback callback) { mMainExecutor.execute(() -> { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +70 −13 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ public class OneHandedControllerTest extends OneHandedTestCase { final boolean mDefaultSwipeToNotificationEnabled = OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled( getTestContext().getContentResolver()); final boolean mDefaultTapAppToExitEnabled = OneHandedSettingsUtil.getSettingsTapsAppToExit( getTestContext().getContentResolver()); @Before public void setUp() { Loading Loading @@ -176,7 +178,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test public void testStopOneHanded_shouldRemoveTimer() { public void testStopOneHandedShouldRemoveTimer() { when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(true); mSpiedOneHandedController.stopOneHanded(); Loading @@ -193,27 +195,29 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test public void testUpdateSwipeToNotificationEnabled() { final boolean swipeToNotificationEnabled = true; mSpiedOneHandedController.setSwipeToNotificationEnabled(swipeToNotificationEnabled); public void testUpdateSwipeToNotification() { mSpiedOneHandedController.setSwipeToNotificationEnabled(mDefaultSwipeToNotificationEnabled); verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(mDefaultEnabled); verify(mMockGestureHandler, atLeastOnce()).onOneHandedEnabled( mDefaultEnabled || swipeToNotificationEnabled); mDefaultEnabled || mDefaultSwipeToNotificationEnabled); } @Test public void testUpdateTapAppToExitUpdate() { public void testSettingsObserverUpdateTapAppToExit() { mSpiedOneHandedController.onTaskChangeExitSettingChanged(); if (mDefaultTapAppToExitEnabled) { verify(mMockTaskStackListener, atLeastOnce()).addListener(any()); } else { verify(mMockTaskStackListener, atLeastOnce()).removeListener(any()); } } @Test public void tesSettingsObserverUpdateEnabled() { public void testSettingsObserverUpdateEnabled() { mSpiedOneHandedController.onEnabledSettingChanged(); verify(mSpiedOneHandedController, atLeastOnce()).setOneHandedEnabled(mDefaultEnabled); verify(mSpiedOneHandedController).setOneHandedEnabled(mDefaultEnabled); } @Test Loading @@ -224,10 +228,63 @@ public class OneHandedControllerTest extends OneHandedTestCase { } @Test public void tesSettingsObserverUpdateSwipeToNotification() { public void testSettingsObserverUpdateSwipeToNotification() { mSpiedOneHandedController.onSwipeToNotificationEnabledSettingChanged(); verify(mSpiedOneHandedController, atLeastOnce()).setSwipeToNotificationEnabled( !mDefaultEnabled); // Swipe to notification function is opposite with one handed mode function if (mDefaultSwipeToNotificationEnabled) { verify(mSpiedOneHandedController).setSwipeToNotificationEnabled( mDefaultSwipeToNotificationEnabled); } else { verify(mSpiedOneHandedController, never()).setSwipeToNotificationEnabled( mDefaultSwipeToNotificationEnabled); } } @Test public void testLockedOneHandedDisabled() { // Default mLockDisabled is false assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, true /* enabled */); // If mOneHandedEnabled == enabled, then keep unlocked assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); // If prefer locked enabled state and 'mOneHandedEnabled == enabled', then unlocked mSpiedOneHandedController.setLockedDisabled(true /* locked */, true /* enabled */); assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); // If prefer locked disabled state and 'mOneHandedEnabled != enabled', then locked disabled mSpiedOneHandedController.setLockedDisabled(true /* locked */, false /* enabled */); assertThat(mSpiedOneHandedController.isLockedDisabled()).isTrue(); // If prefer unlock disabled state and 'mOneHandedEnabled != enabled', then unlocked mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); assertThat(mSpiedOneHandedController.isLockedDisabled()).isFalse(); } @Test public void testKeyguardShowingLockOneHandedDisabled() { when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(true /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); } @Test public void testResetKeyguardShowingLockOneHandedDisabled() { when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); verify(mMockDisplayAreaOrganizer).scheduleOffset(anyInt(), anyInt()); } }
packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +7 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,13 @@ public final class WMShell extends SystemUI @Override public void onKeyguardVisibilityChanged(boolean showing) { if (showing) { // When keyguard shown, temperory lock OHM disabled to avoid mis-trigger. oneHanded.setLockedDisabled(true /* locked */, false /* enabled */); } else { // Reset locked. oneHanded.setLockedDisabled(false /* locked */, false /* enabled */); } oneHanded.stopOneHanded(); } }; Loading