Merge "(1/n) Disabling OHM gesture in NavigationBar 3 Button mode" into sc-dev
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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(() -> {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user