Check shortcut enabled before auto trun on OHM

When device (factory)boot, controller regsiter settings
'one_handed_mode_activated' will receive callback, and
the shortcut do not enabled by default, the flow will
go to auto enable one-handed mode feature and leading
unexpedted UX(disabled by default) and testing issue.

Solution:
- Add additional check for shortcut enabled when
  onActivatedActionChanged() callback.
- When setting is pull screen, notify shortcut
  one_handed_mode_activated to reset and align current
  mState when function enabled.

Note:
The setting provider one_handed_mode_activated could set
2 different values when shortcut button pressed
 - "0" mapping to pull screen STATE_NONE
 - "1" mapping to pull screen STATE_ACTIVE
Since show notification do not have state, whenever
onChange callback, we trigger expand notification.

Test: atest WMShellUnitTests
Test: manual factory reset | reboot check Log should show \
      "Shortcut not enabled, skip onActivatedActionChanged()".
Test: manual disable both OHM & shortcut toggle in settings \
      '# adb shell settings --user 0 put secure \
      one_handed_mode_activated 1'
      should not auto enable OHM main toggle.
Bug: 191736174
Bug: 191831415
Bug: 191950195
Fixes: 191812697
Change-Id: Ib9d66fbbcc7e6a52a37bb47efebf90c9d2644508
This commit is contained in:
Bill Lin
2021-06-25 12:42:43 +08:00
parent 3245ab133d
commit 6061ddc2f7
3 changed files with 71 additions and 5 deletions

View File

@@ -498,6 +498,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
@VisibleForTesting
void onActivatedActionChanged() {
if (!isShortcutEnabled()) {
Slog.w(TAG, "Shortcut not enabled, skip onActivatedActionChanged()");
return;
}
if (!isOneHandedEnabled()) {
final boolean success = mOneHandedSettingsUtil.setOneHandedModeEnabled(
mContext.getContentResolver(), 1 /* Enabled for shortcut */, mUserId);
@@ -607,6 +612,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
return mIsOneHandedEnabled;
}
@VisibleForTesting
boolean isShortcutEnabled() {
return mOneHandedSettingsUtil.getShortcutEnabled(mContext.getContentResolver(), mUserId);
}
@VisibleForTesting
boolean isSwipeToNotificationEnabled() {
return mIsSwipeToNotificationEnabled;
@@ -617,8 +627,11 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mMainExecutor.execute(() -> stopOneHanded());
}
// Reset and align shortcut one_handed_mode_activated status with current mState
notifyShortcutState(mState.getState());
// If setting is pull screen, notify shortcut one_handed_mode_activated to reset
// and align status with current mState when function enabled.
if (isOneHandedEnabled() && !isSwipeToNotificationEnabled()) {
notifyShortcutState(mState.getState());
}
mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
@@ -717,6 +730,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
pw.println(mLockedDisabled);
pw.print(innerPrefix + "mUserId=");
pw.println(mUserId);
pw.print(innerPrefix + "isShortcutEnabled=");
pw.println(isShortcutEnabled());
if (mBackgroundPanelOrganizer != null) {
mBackgroundPanelOrganizer.dump(pw);

View File

@@ -16,6 +16,8 @@
package com.android.wm.shell.onehanded;
import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME;
import android.annotation.IntDef;
import android.content.ContentResolver;
import android.database.ContentObserver;
@@ -34,6 +36,9 @@ import java.lang.annotation.RetentionPolicy;
public final class OneHandedSettingsUtil {
private static final String TAG = "OneHandedSettingsUtil";
private static final String ONE_HANDED_MODE_TARGET_NAME =
ONE_HANDED_COMPONENT_NAME.getShortClassName();
@IntDef(prefix = {"ONE_HANDED_TIMEOUT_"}, value = {
ONE_HANDED_TIMEOUT_NEVER,
ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS,
@@ -157,6 +162,17 @@ public final class OneHandedSettingsUtil {
Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0, userId);
}
/**
* Queries one-handed mode shortcut enabled in settings or not.
*
* @return true if user enabled one-handed shortcut in settings, false otherwise.
*/
public boolean getShortcutEnabled(ContentResolver resolver, int userId) {
final String targets = Settings.Secure.getStringForUser(resolver,
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, userId);
return targets != null ? targets.contains(ONE_HANDED_MODE_TARGET_NAME) : false;
}
/**
* Sets tutorial shown counts.
*

View File

@@ -118,6 +118,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
mDefaultTapAppToExitEnabled);
when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn(
mDefaultSwipeToNotificationEnabled);
when(mMockSettingsUitl.getShortcutEnabled(any(), anyInt())).thenReturn(false);
when(mMockDisplayAreaOrganizer.getLastDisplayBounds()).thenReturn(
new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height()));
@@ -341,6 +342,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mSpiedTransitionState.getState()).thenReturn(STATE_ACTIVE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
verify(mSpiedOneHandedController, never()).startOneHanded();
@@ -352,6 +354,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(false);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
verify(mSpiedOneHandedController, never()).startOneHanded();
@@ -363,6 +366,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
verify(mSpiedOneHandedController).startOneHanded();
@@ -374,6 +378,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mSpiedTransitionState.getState()).thenReturn(STATE_ENTERING);
when(mSpiedTransitionState.isTransitioning()).thenReturn(true);
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
verify(mSpiedTransitionState, never()).setState(STATE_EXITING);
@@ -384,6 +389,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mSpiedTransitionState.getState()).thenReturn(STATE_EXITING);
when(mSpiedTransitionState.isTransitioning()).thenReturn(true);
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
verify(mSpiedTransitionState, never()).setState(STATE_ENTERING);
@@ -392,6 +398,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
@Test
public void testOneHandedDisabled_shortcutTrigger_thenAutoEnabled() {
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(false);
@@ -417,6 +424,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(true);
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true);
mSpiedOneHandedController.registerEventCallback(mMockEventCallback);
mSpiedOneHandedController.onActivatedActionChanged();
@@ -425,11 +433,11 @@ public class OneHandedControllerTest extends OneHandedTestCase {
}
@Test
public void testNotifyShortcutState_whenUpdateOneHandedEnabled() {
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
public void testNotifyShortcutState_whenSetOneHandedEnabled() {
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(true);
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true);
when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(false);
mSpiedOneHandedController.registerEventCallback(mMockEventCallback);
mSpiedOneHandedController.setOneHandedEnabled(true);
@@ -448,4 +456,31 @@ public class OneHandedControllerTest extends OneHandedTestCase {
// Verify no NPE crash and mMockShellMainExecutor never be execute.
verify(mMockShellMainExecutor, never()).execute(any());
}
@Test
public void testShortcutEnable_ableToAutoEnableOneHandedMode() {
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mSpiedOneHandedController.isShortcutEnabled()).thenReturn(true);
when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(false);
when(mMockSettingsUitl.setOneHandedModeEnabled(any(), anyInt(), anyInt())).thenReturn(
false /* To avoid test runner create Toast */);
mSpiedOneHandedController.onActivatedActionChanged();
verify(mSpiedOneHandedController).notifyUserConfigChanged(anyBoolean());
}
@Test
public void testShortcutDisable_shouldNotAutoEnableOneHandedMode() {
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(false);
when(mMockSettingsUitl.setOneHandedModeEnabled(any(), anyInt(), anyInt())).thenReturn(true);
mSpiedOneHandedController.onActivatedActionChanged();
verify(mMockSettingsUitl, never()).setOneHandedModeEnabled(any(), anyInt(), anyInt());
verify(mSpiedOneHandedController, never()).notifyUserConfigChanged(anyBoolean());
}
}