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:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user