(1/n) Disabling OHM gesture in NavigationBar 3 Button mode

1) UX mentioned the swipe gesture in 3-Button NavgationBar area
may confuse user from taping NavBar buttons(Back, Home, Recents).
They decide to disable the swipe gesture and allow user to trigger
One Handed Mode(3 Button Mode) through A11y shortcut.
However, user can still use OHM by enabled shortcut button on
both Gesture Navigation & 3-Button mode.

2) OHM gestural handler consume the touch event while window
Magnification overlap with NavigationBar area in 3-button mode,
this result Magnification function can no long obtain the control.

Bug: 184903678
Bug: 179648683

Test: manual
Test: atest WMShellUnitTests
Change-Id: Ib9a06e19d749707e6f5e08c3ef803c1681f86bbc
This commit is contained in:
Jason Chang
2021-04-14 17:16:48 +08:00
committed by Bill Lin
parent a0e43e71e7
commit 1d1ea541f0
10 changed files with 2 additions and 568 deletions

View File

@@ -19,7 +19,6 @@ package com.android.wm.shell.onehanded;
import android.content.res.Configuration;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback;
/**
* Interface to engage one handed feature.
@@ -59,11 +58,6 @@ public interface OneHanded {
*/
void stopOneHanded(int uiEvent);
/**
* Sets navigation 3 button mode enabled or disabled by users.
*/
void setThreeButtonModeEnabled(boolean enabled);
/**
* Sets one handed feature temporary locked in enabled or disabled state, this won't change
* settings configuration.
@@ -79,12 +73,6 @@ public interface OneHanded {
*/
void registerTransitionCallback(OneHandedTransitionCallback callback);
/**
* Registers callback for one handed gesture, this gesture callback will be activated on
* 3 button navigation mode only
*/
void registerGestureCallback(OneHandedGestureEventCallback callback);
/**
* Receive onConfigurationChanged() events
*/

View File

@@ -41,7 +41,6 @@ import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Slog;
import android.view.Surface;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -59,7 +58,6 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback;
import java.io.PrintWriter;
@@ -101,7 +99,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
private final OneHandedImpl mImpl = new OneHandedImpl();
private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
private OneHandedGestureHandler mGestureHandler;
private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer;
/**
@@ -113,7 +110,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
return;
}
mDisplayAreaOrganizer.onRotateDisplay(mContext, toRotation, wct);
mGestureHandler.onRotateDisplay(mDisplayAreaOrganizer.getDisplayLayout());
};
private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener =
@@ -196,7 +192,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
private boolean isInitialized() {
if (mDisplayAreaOrganizer == null || mDisplayController == null
|| mGestureHandler == null || mOneHandedSettingsUtil == null) {
|| mOneHandedSettingsUtil == null) {
Slog.w(TAG, "Components may not initialized yet!");
return false;
}
@@ -226,8 +222,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
new OneHandedAnimationController(context);
OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler,
mainExecutor);
OneHandedGestureHandler gestureHandler = new OneHandedGestureHandler(
context, displayLayout, ViewConfiguration.get(context), mainExecutor);
OneHandedBackgroundPanelOrganizer oneHandedBackgroundPanelOrganizer =
new OneHandedBackgroundPanelOrganizer(context, displayLayout, mainExecutor);
OneHandedDisplayAreaOrganizer organizer = new OneHandedDisplayAreaOrganizer(
@@ -238,7 +232,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
ServiceManager.getService(Context.OVERLAY_SERVICE));
return new OneHandedController(context, displayController,
oneHandedBackgroundPanelOrganizer, organizer, touchHandler, tutorialHandler,
gestureHandler, settingsUtil, accessibilityUtil, timeoutHandler, transitionState,
settingsUtil, accessibilityUtil, timeoutHandler, transitionState,
oneHandedUiEventsLogger, overlayManager, taskStackListener, mainExecutor,
mainHandler);
}
@@ -250,7 +244,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
OneHandedDisplayAreaOrganizer displayAreaOrganizer,
OneHandedTouchHandler touchHandler,
OneHandedTutorialHandler tutorialHandler,
OneHandedGestureHandler gestureHandler,
OneHandedSettingsUtil settingsUtil,
OneHandedAccessibilityUtil oneHandedAccessibilityUtil,
OneHandedTimeoutHandler timeoutHandler,
@@ -269,7 +262,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mTouchHandler = touchHandler;
mState = state;
mTutorialHandler = tutorialHandler;
mGestureHandler = gestureHandler;
mOverlayManager = overlayManager;
mMainExecutor = mainExecutor;
mMainHandler = mainHandler;
@@ -399,24 +391,15 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mOneHandedUiEventLogger.writeEvent(uiEvent);
}
private void setThreeButtonModeEnabled(boolean enabled) {
mGestureHandler.onThreeButtonModeEnabled(enabled);
}
@VisibleForTesting
void registerTransitionCallback(OneHandedTransitionCallback callback) {
mDisplayAreaOrganizer.registerTransitionCallback(callback);
}
private void registerGestureCallback(OneHandedGestureEventCallback callback) {
mGestureHandler.setGestureEventListener(callback);
}
private void setupCallback() {
mTouchHandler.registerTouchEventListener(() ->
stopOneHanded(OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_OVERSPACE_OUT));
mDisplayAreaOrganizer.registerTransitionCallback(mTouchHandler);
mDisplayAreaOrganizer.registerTransitionCallback(mGestureHandler);
mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler);
mDisplayAreaOrganizer.registerTransitionCallback(mBackgroundPanelOrganizer);
mDisplayAreaOrganizer.registerTransitionCallback(mTransitionCallBack);
@@ -465,7 +448,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
private void updateDisplayLayout(int displayId) {
final DisplayLayout newDisplayLayout = mDisplayController.getDisplayLayout(displayId);
mDisplayAreaOrganizer.setDisplayLayout(newDisplayLayout);
mGestureHandler.onDisplayChanged(newDisplayLayout);
mTutorialHandler.onDisplayChanged(newDisplayLayout);
}
@@ -588,7 +570,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
}
mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
mGestureHandler.onGestureEnabled(mIsOneHandedEnabled || mIsSwipeToNotificationEnabled);
if (!mIsOneHandedEnabled) {
mDisplayAreaOrganizer.unregisterOrganizer();
@@ -643,9 +624,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
return;
}
mLockedDisabled = locked && !enabled;
// Disabled gesture when keyguard ON
mGestureHandler.onGestureEnabled(!mLockedDisabled && isFeatureEnabled);
}
private void onConfigChanged(Configuration newConfig) {
@@ -685,10 +663,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
mDisplayAreaOrganizer.dump(pw);
}
if (mGestureHandler != null) {
mGestureHandler.dump(pw);
}
if (mTouchHandler != null) {
mTouchHandler.dump(pw);
}
@@ -774,13 +748,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
});
}
@Override
public void setThreeButtonModeEnabled(boolean enabled) {
mMainExecutor.execute(() -> {
OneHandedController.this.setThreeButtonModeEnabled(enabled);
});
}
@Override
public void setLockedDisabled(boolean locked, boolean enabled) {
mMainExecutor.execute(() -> {
@@ -795,13 +762,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
});
}
@Override
public void registerGestureCallback(OneHandedGestureEventCallback callback) {
mMainExecutor.execute(() -> {
OneHandedController.this.registerGestureCallback(callback);
});
}
@Override
public void onConfigChanged(Configuration newConfig) {
mMainExecutor.execute(() -> {

View File

@@ -1,308 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.onehanded;
import static android.view.Display.DEFAULT_DISPLAY;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.os.Looper;
import android.view.Display;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.InputMonitor;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import java.io.PrintWriter;
/**
* The class manage swipe up and down gesture for 3-Button mode navigation, others(e.g, 2-button,
* full gesture mode) are handled by Launcher quick steps. TODO(b/160934654) Migrate to Launcher
* quick steps
*/
public class OneHandedGestureHandler implements OneHandedTransitionCallback {
private static final String TAG = "OneHandedGestureHandler";
private static final int ANGLE_MAX = 150;
private static final int ANGLE_MIN = 30;
private final float mDragDistThreshold;
private final float mSquaredSlop;
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
private final PointF mStartDragPos = new PointF();
private boolean mPassedSlop;
private boolean mAllowGesture;
private boolean mIsEnabled;
private int mNavGestureHeight;
private boolean mIsThreeButtonModeEnabled;
private int mRotation = Surface.ROTATION_0;
@VisibleForTesting
InputMonitor mInputMonitor;
@VisibleForTesting
InputEventReceiver mInputEventReceiver;
private final ShellExecutor mMainExecutor;
@VisibleForTesting
@Nullable
OneHandedGestureEventCallback mGestureEventCallback;
private Rect mGestureRegion = new Rect();
private boolean mIsStopGesture;
/**
* Constructor of OneHandedGestureHandler, we only handle the gesture of {@link
* Display#DEFAULT_DISPLAY}
*
* @param context Any context
* @param displayLayout Current {@link DisplayLayout} from controller
* @param viewConfig {@link ViewConfiguration} to obtain touch slop
* @param mainExecutor The wm-shell main executor
*/
public OneHandedGestureHandler(Context context,
DisplayLayout displayLayout,
ViewConfiguration viewConfig,
ShellExecutor mainExecutor) {
mMainExecutor = mainExecutor;
mDragDistThreshold = context.getResources().getDimensionPixelSize(
R.dimen.gestures_onehanded_drag_threshold);
final float slop = viewConfig.getScaledTouchSlop();
mSquaredSlop = slop * slop;
onDisplayChanged(displayLayout);
updateIsEnabled();
}
/**
* Notifies by {@link OneHandedController}, when swipe down gesture is enabled on 3 button
* navigation bar mode.
*
* @param isEnabled Either one handed mode or swipe for notification function enabled or not
*/
public void onGestureEnabled(boolean isEnabled) {
mIsEnabled = isEnabled;
updateIsEnabled();
}
void onThreeButtonModeEnabled(boolean isEnabled) {
mIsThreeButtonModeEnabled = isEnabled;
updateIsEnabled();
}
/**
* Registers {@link OneHandedGestureEventCallback} to receive onStart(), onStop() callback
*/
public void setGestureEventListener(OneHandedGestureEventCallback callback) {
mGestureEventCallback = callback;
}
/**
* Called when onDisplayAdded() or onDisplayRemoved() callback
* @param displayLayout The latest {@link DisplayLayout} representing current displayId
*/
public void onDisplayChanged(DisplayLayout displayLayout) {
mNavGestureHeight = getNavBarSize(displayLayout);
mGestureRegion.set(0, displayLayout.height() - mNavGestureHeight, displayLayout.width(),
displayLayout.height());
mRotation = displayLayout.rotation();
}
private void onMotionEvent(MotionEvent ev) {
int action = ev.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
mAllowGesture = isWithinTouchRegion(ev.getX(), ev.getY()) && isGestureAvailable();
if (mAllowGesture) {
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
}
} else if (mAllowGesture) {
switch (action) {
case MotionEvent.ACTION_MOVE:
mLastPos.set(ev.getX(), ev.getY());
if (!mPassedSlop) {
if (squaredHypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y)
> mSquaredSlop) {
mStartDragPos.set(mLastPos.x, mLastPos.y);
if (isValidStartAngle(
mDownPos.x - mLastPos.x, mDownPos.y - mLastPos.y)
|| isValidExitAngle(
mDownPos.x - mLastPos.x, mDownPos.y - mLastPos.y)) {
mPassedSlop = true;
mInputMonitor.pilferPointers();
}
}
} else {
float distance = (float) Math.hypot(mLastPos.x - mDownPos.x,
mLastPos.y - mDownPos.y);
if (distance > mDragDistThreshold) {
mIsStopGesture = true;
}
}
break;
case MotionEvent.ACTION_UP:
if (mLastPos.y >= mDownPos.y && mPassedSlop) {
mGestureEventCallback.onStart();
} else if (mIsStopGesture) {
mGestureEventCallback.onStop();
}
clearState();
break;
case MotionEvent.ACTION_CANCEL:
clearState();
break;
default:
break;
}
}
}
private void clearState() {
mPassedSlop = false;
mIsStopGesture = false;
}
private void disposeInputChannel() {
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
}
if (mInputMonitor != null) {
mInputMonitor.dispose();
mInputMonitor = null;
}
}
private boolean isWithinTouchRegion(float x, float y) {
return mGestureRegion.contains(Math.round(x), Math.round(y));
}
private int getNavBarSize(@NonNull DisplayLayout displayLayout) {
return isGestureAvailable() ? displayLayout.navBarFrameHeight() : 0 /* In landscape */;
}
private void updateIsEnabled() {
disposeInputChannel();
if (mIsEnabled && mIsThreeButtonModeEnabled && isGestureAvailable()) {
mInputMonitor = InputManager.getInstance().monitorGestureInput(
"onehanded-gesture-offset", DEFAULT_DISPLAY);
try {
mMainExecutor.executeBlocking(() -> {
mInputEventReceiver = new EventReceiver(
mInputMonitor.getInputChannel(), Looper.myLooper());
});
} catch (InterruptedException e) {
throw new RuntimeException("Failed to create input event receiver", e);
}
}
}
private void onInputEvent(InputEvent ev) {
if (ev instanceof MotionEvent) {
onMotionEvent((MotionEvent) ev);
}
}
/**
* Handler for display rotation changes by {@link DisplayLayout}
*
* @param displayLayout The rotated displayLayout
*/
public void onRotateDisplay(DisplayLayout displayLayout) {
mRotation = displayLayout.rotation();
mNavGestureHeight = getNavBarSize(displayLayout);
mGestureRegion.set(0, displayLayout.height() - mNavGestureHeight, displayLayout.width(),
displayLayout.height());
updateIsEnabled();
}
// TODO: Use BatchedInputEventReceiver
private class EventReceiver extends InputEventReceiver {
EventReceiver(InputChannel channel, Looper looper) {
super(channel, looper);
}
public void onInputEvent(InputEvent event) {
OneHandedGestureHandler.this.onInputEvent(event);
finishInputEvent(event, true);
}
}
private boolean isGestureAvailable() {
// Either OHM or swipe notification shade can activate in portrait mode only
return mRotation == Surface.ROTATION_0 || mRotation == Surface.ROTATION_180;
}
private boolean isValidStartAngle(float deltaX, float deltaY) {
final float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX));
return angle > -(ANGLE_MAX) && angle < -(ANGLE_MIN);
}
private boolean isValidExitAngle(float deltaX, float deltaY) {
final float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX));
return angle > ANGLE_MIN && angle < ANGLE_MAX;
}
private float squaredHypot(float x, float y) {
return x * x + y * y;
}
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG);
pw.print(innerPrefix + "mAllowGesture=");
pw.println(mAllowGesture);
pw.print(innerPrefix + "mIsEnabled=");
pw.println(mIsEnabled);
pw.print(innerPrefix + "mGestureRegion=");
pw.println(mGestureRegion);
pw.print(innerPrefix + "mNavGestureHeight=");
pw.println(mNavGestureHeight);
pw.print(innerPrefix + "mIsThreeButtonModeEnabled=");
pw.println(mIsThreeButtonModeEnabled);
pw.print(innerPrefix + "mRotation=");
pw.println(mRotation);
}
/**
* The touch(gesture) events to notify {@link OneHandedController} start or stop one handed
*/
public interface OneHandedGestureEventCallback {
/**
* Handles the start gesture.
*/
void onStart();
/**
* Handles the exit gesture.
*/
void onStop();
}
}

View File

@@ -37,7 +37,6 @@ import java.io.PrintWriter;
/**
* Manages all the touch handling for One Handed on the Phone, including user tap outside region
* to exit, reset timer when user is in one-handed mode.
* Refer {@link OneHandedGestureHandler} to see start and stop one handed gesture
*/
public class OneHandedTouchHandler implements OneHandedTransitionCallback {
private static final String TAG = "OneHandedTouchHandler";

View File

@@ -28,7 +28,6 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
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.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -79,8 +78,6 @@ public class OneHandedControllerTest extends OneHandedTestCase {
@Mock
OneHandedTutorialHandler mMockTutorialHandler;
@Mock
OneHandedGestureHandler mMockGestureHandler;
@Mock
OneHandedSettingsUtil mMockSettingsUitl;
@Mock
OneHandedUiEventLogger mMockUiEventLogger;
@@ -131,7 +128,6 @@ public class OneHandedControllerTest extends OneHandedTestCase {
mMockDisplayAreaOrganizer,
mMockTouchHandler,
mMockTutorialHandler,
mMockGestureHandler,
mMockSettingsUitl,
mOneHandedAccessibilityUtil,
mSpiedTimeoutHandler,
@@ -179,7 +175,6 @@ public class OneHandedControllerTest extends OneHandedTestCase {
@Test
public void testRegisterTransitionCallbackAfterInit() {
verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockTouchHandler);
verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockGestureHandler);
verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mMockTutorialHandler);
}
@@ -205,7 +200,6 @@ public class OneHandedControllerTest extends OneHandedTestCase {
mSpiedOneHandedController.setOneHandedEnabled(true);
verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(anyBoolean());
verify(mMockGestureHandler, atLeastOnce()).onGestureEnabled(anyBoolean());
}
@Test
@@ -213,7 +207,6 @@ public class OneHandedControllerTest extends OneHandedTestCase {
mSpiedOneHandedController.setSwipeToNotificationEnabled(mDefaultSwipeToNotificationEnabled);
verify(mMockTouchHandler, atLeastOnce()).onOneHandedEnabled(anyBoolean());
verify(mMockGestureHandler, atLeastOnce()).onGestureEnabled(anyBoolean());
}
@Test
@@ -339,30 +332,6 @@ public class OneHandedControllerTest extends OneHandedTestCase {
verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt());
}
@Test
public void testDisabled3ButtonGestureWhenKeyguardOn() {
final boolean isOneHandedEnabled = true;
final boolean isLockWhenKeyguardOn = true;
final boolean isEnabledWhenKeyguardOn = false;
mSpiedOneHandedController.setOneHandedEnabled(isOneHandedEnabled);
mSpiedOneHandedController.setLockedDisabled(isLockWhenKeyguardOn, isEnabledWhenKeyguardOn);
verify(mMockGestureHandler).onGestureEnabled(isEnabledWhenKeyguardOn);
}
@Test
public void testEnabled3ButtonGestureWhenKeyguardGoingAway() {
final boolean isOneHandedEnabled = true;
final boolean isLockWhenKeyguardOn = false;
final boolean isEnabledWhenKeyguardOn = false;
mSpiedOneHandedController.setOneHandedEnabled(isOneHandedEnabled);
reset(mMockGestureHandler);
mSpiedOneHandedController.setLockedDisabled(isLockWhenKeyguardOn, isEnabledWhenKeyguardOn);
verify(mMockGestureHandler).onGestureEnabled(isOneHandedEnabled);
}
@Test
public void testStateActive_shortcutRequestActivate_skipActions() {
when(mSpiedTransitionState.getState()).thenReturn(STATE_ACTIVE);

View File

@@ -1,129 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.onehanded;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.view.Surface;
import android.view.ViewConfiguration;
import androidx.test.filters.SmallTest;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class OneHandedGestureHandlerTest extends OneHandedTestCase {
OneHandedGestureHandler mGestureHandler;
DisplayLayout mDisplayLayout;
@Mock
DisplayLayout mMockDisplayLayout;
@Mock
ShellExecutor mMockShellMainExecutor;
@Before
public void setUp() {
final int mockNavBarHeight = 100;
MockitoAnnotations.initMocks(this);
mDisplayLayout = new DisplayLayout(mContext, mContext.getDisplay());
mGestureHandler = new OneHandedGestureHandler(mContext, mDisplayLayout,
ViewConfiguration.get(mTestContext), mMockShellMainExecutor);
when(mMockDisplayLayout.navBarFrameHeight()).thenReturn(mockNavBarHeight);
}
@Test
public void testSetGestureEventListener() {
OneHandedGestureHandler.OneHandedGestureEventCallback callback =
new OneHandedGestureHandler.OneHandedGestureEventCallback() {
@Override
public void onStart() {}
@Override
public void onStop() {}
};
mGestureHandler.setGestureEventListener(callback);
assertThat(mGestureHandler.mGestureEventCallback).isEqualTo(callback);
}
@Test
public void testOneHandedDisabled_shouldDisposeInputChannel() {
mGestureHandler.onGestureEnabled(false);
assertThat(mGestureHandler.mInputMonitor).isNull();
assertThat(mGestureHandler.mInputEventReceiver).isNull();
}
@Test
public void testChangeNavBarToNon3Button_shouldDisposeInputChannel() {
mGestureHandler.onGestureEnabled(true);
mGestureHandler.onThreeButtonModeEnabled(false);
assertThat(mGestureHandler.mInputMonitor).isNull();
assertThat(mGestureHandler.mInputEventReceiver).isNull();
}
@Test
public void testOnlyHandleGestureInPortraitMode() {
mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
mGestureHandler.onGestureEnabled(true);
mGestureHandler.onRotateDisplay(mDisplayLayout);
assertThat(mGestureHandler.mInputMonitor).isNull();
assertThat(mGestureHandler.mInputEventReceiver).isNull();
}
@Test
public void testRotation90ShouldNotRegisterEventReceiver() throws InterruptedException {
mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90);
mGestureHandler.onGestureEnabled(true);
mGestureHandler.onRotateDisplay(mDisplayLayout);
verify(mMockShellMainExecutor, never()).executeBlocking(any());
}
@Test
public void testRotation180ShouldNotRegisterEventReceiver() throws InterruptedException {
mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
mGestureHandler.onGestureEnabled(true);
mGestureHandler.onRotateDisplay(mDisplayLayout);
verify(mMockShellMainExecutor, never()).executeBlocking(any());
}
@Test
public void testRotation270ShouldNotRegisterEventReceiver() throws InterruptedException {
mDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270);
mGestureHandler.onGestureEnabled(true);
mGestureHandler.onRotateDisplay(mDisplayLayout);
verify(mMockShellMainExecutor, never()).executeBlocking(any());
}
}

View File

@@ -74,8 +74,6 @@ public class OneHandedStateTest extends OneHandedTestCase {
@Mock
OneHandedTutorialHandler mMockTutorialHandler;
@Mock
OneHandedGestureHandler mMockGestureHandler;
@Mock
OneHandedSettingsUtil mMockSettingsUitl;
@Mock
OneHandedUiEventLogger mMockUiEventLogger;
@@ -126,7 +124,6 @@ public class OneHandedStateTest extends OneHandedTestCase {
mMockDisplayAreaOrganizer,
mMockTouchHandler,
mMockTutorialHandler,
mMockGestureHandler,
mMockSettingsUitl,
mOneHandedAccessibilityUtil,
mSpiedTimeoutHandler,

View File

@@ -43,8 +43,6 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
OneHandedController mOneHandedController;
OneHandedState mSpiedTransitionState;
@Mock
OneHandedGestureHandler mMockGestureHandler;
@Mock
OneHandedTouchHandler mMockTouchHandler;
@Mock
@@ -84,7 +82,6 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
mMockDisplayAreaOrganizer,
mMockTouchHandler,
mMockTutorialHandler,
mMockGestureHandler,
mMockSettingsUtil,
mMockAccessibilityUtil,
mTimeoutHandler,

View File

@@ -17,7 +17,6 @@
package com.android.systemui.wmshell;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
@@ -35,7 +34,6 @@ import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.view.KeyEvent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -59,7 +57,6 @@ import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.nano.WmShellTraceProto;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedGestureHandler.OneHandedGestureEventCallback;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
import com.android.wm.shell.pip.Pip;
@@ -230,10 +227,6 @@ public final class WMShell extends SystemUI
@VisibleForTesting
void initOneHanded(OneHanded oneHanded) {
int currentMode = mNavigationModeController.addListener(mode ->
oneHanded.setThreeButtonModeEnabled(mode == NAV_BAR_MODE_3BUTTON));
oneHanded.setThreeButtonModeEnabled(currentMode == NAV_BAR_MODE_3BUTTON);
oneHanded.registerTransitionCallback(new OneHandedTransitionCallback() {
@Override
public void onStartTransition(boolean isEntering) {
@@ -260,32 +253,6 @@ public final class WMShell extends SystemUI
}
});
oneHanded.registerGestureCallback(new OneHandedGestureEventCallback() {
@Override
public void onStart() {
mSysUiMainExecutor.execute(() -> {
if (oneHanded.isOneHandedEnabled()) {
oneHanded.startOneHanded();
} else if (oneHanded.isSwipeToNotificationEnabled()) {
mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN);
}
});
}
@Override
public void onStop() {
mSysUiMainExecutor.execute(() -> {
if (oneHanded.isOneHandedEnabled()) {
// Log metrics for 3-button navigation mode.
oneHanded.stopOneHanded(
OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_OUT);
} else if (oneHanded.isSwipeToNotificationEnabled()) {
mCommandQueue.handleSystemKey(KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP);
}
});
}
});
mOneHandedKeyguardCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onKeyguardBouncerChanged(boolean bouncer) {

View File

@@ -37,7 +37,6 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.onehanded.OneHandedGestureHandler;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.pip.Pip;
@@ -106,11 +105,6 @@ public class WMShellTest extends SysuiTestCase {
verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class));
verify(mNavigationModeController).addListener(
any(NavigationModeController.ModeChangedListener.class));
verify(mOneHanded).registerGestureCallback(any(
OneHandedGestureHandler.OneHandedGestureEventCallback.class));
verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
}