Merge "Run HOVER_EXIT event only if there's no BUTTON_PRESS event after." into rvc-dev am: e01198edec am: a9914ea6df

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12049437

Change-Id: If04f0dd88f7ea62d6ef2a4d684c23c171d1456fe
This commit is contained in:
Ben Lin
2020-07-06 21:46:48 +00:00
committed by Automerger Merge Worker
3 changed files with 55 additions and 3 deletions

View File

@@ -242,7 +242,8 @@ public class PipTouchHandler {
this::updateMovementBounds, sysUiState); this::updateMovementBounds, sysUiState);
mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler, mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler,
() -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(), () -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(),
true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle())); true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle()),
menuController::hideMenu);
Resources res = context.getResources(); Resources res = context.getResources();
mEnableDismissDragToEdge = res.getBoolean(R.bool.config_pipEnableDismissDragToEdge); mEnableDismissDragToEdge = res.getBoolean(R.bool.config_pipEnableDismissDragToEdge);
@@ -708,6 +709,7 @@ public class PipTouchHandler {
// on and changing MotionEvents into HoverEvents. // on and changing MotionEvents into HoverEvents.
// Let's not enable menu show/hide for a11y services. // Let's not enable menu show/hide for a11y services.
if (!mAccessibilityManager.isTouchExplorationEnabled()) { if (!mAccessibilityManager.isTouchExplorationEnabled()) {
mTouchState.removeHoverExitTimeoutCallback();
mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
false /* allowMenuTimeout */, false /* willResizeMenu */, false /* allowMenuTimeout */, false /* willResizeMenu */,
shouldShowResizeHandle()); shouldShowResizeHandle());
@@ -725,7 +727,7 @@ public class PipTouchHandler {
// Let's not enable menu show/hide for a11y services. // Let's not enable menu show/hide for a11y services.
if (!mAccessibilityManager.isTouchExplorationEnabled()) { if (!mAccessibilityManager.isTouchExplorationEnabled()) {
mHideMenuAfterShown = true; mHideMenuAfterShown = true;
mMenuController.hideMenu(); mTouchState.scheduleHoverExitTimeoutCallback();
} }
if (!shouldDeliverToMenu && mSendingHoverAccessibilityEvents) { if (!shouldDeliverToMenu && mSendingHoverAccessibilityEvents) {
sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT); sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);

View File

@@ -36,10 +36,12 @@ public class PipTouchState {
@VisibleForTesting @VisibleForTesting
static final long DOUBLE_TAP_TIMEOUT = 200; static final long DOUBLE_TAP_TIMEOUT = 200;
static final long HOVER_EXIT_TIMEOUT = 50;
private final Handler mHandler; private final Handler mHandler;
private final ViewConfiguration mViewConfig; private final ViewConfiguration mViewConfig;
private final Runnable mDoubleTapTimeoutCallback; private final Runnable mDoubleTapTimeoutCallback;
private final Runnable mHoverExitTimeoutCallback;
private VelocityTracker mVelocityTracker; private VelocityTracker mVelocityTracker;
private long mDownTouchTime = 0; private long mDownTouchTime = 0;
@@ -64,10 +66,11 @@ public class PipTouchState {
private int mActivePointerId; private int mActivePointerId;
public PipTouchState(ViewConfiguration viewConfig, Handler handler, public PipTouchState(ViewConfiguration viewConfig, Handler handler,
Runnable doubleTapTimeoutCallback) { Runnable doubleTapTimeoutCallback, Runnable hoverExitTimeoutCallback) {
mViewConfig = viewConfig; mViewConfig = viewConfig;
mHandler = handler; mHandler = handler;
mDoubleTapTimeoutCallback = doubleTapTimeoutCallback; mDoubleTapTimeoutCallback = doubleTapTimeoutCallback;
mHoverExitTimeoutCallback = hoverExitTimeoutCallback;
} }
/** /**
@@ -197,6 +200,10 @@ public class PipTouchState {
recycleVelocityTracker(); recycleVelocityTracker();
break; break;
} }
case MotionEvent.ACTION_BUTTON_PRESS: {
removeHoverExitTimeoutCallback();
break;
}
} }
} }
@@ -326,6 +333,15 @@ public class PipTouchState {
mHandler.removeCallbacks(mDoubleTapTimeoutCallback); mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
} }
void scheduleHoverExitTimeoutCallback() {
mHandler.removeCallbacks(mHoverExitTimeoutCallback);
mHandler.postDelayed(mHoverExitTimeoutCallback, HOVER_EXIT_TIMEOUT);
}
void removeHoverExitTimeoutCallback() {
mHandler.removeCallbacks(mHoverExitTimeoutCallback);
}
void addMovementToVelocityTracker(MotionEvent event) { void addMovementToVelocityTracker(MotionEvent event) {
if (mVelocityTracker == null) { if (mVelocityTracker == null) {
return; return;

View File

@@ -16,6 +16,7 @@
package com.android.systemui.pip.phone; package com.android.systemui.pip.phone;
import static android.view.MotionEvent.ACTION_BUTTON_PRESS;
import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.ACTION_UP;
@@ -49,13 +50,17 @@ public class PipTouchStateTest extends SysuiTestCase {
private PipTouchState mTouchState; private PipTouchState mTouchState;
private CountDownLatch mDoubleTapCallbackTriggeredLatch; private CountDownLatch mDoubleTapCallbackTriggeredLatch;
private CountDownLatch mHoverExitCallbackTriggeredLatch;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mDoubleTapCallbackTriggeredLatch = new CountDownLatch(1); mDoubleTapCallbackTriggeredLatch = new CountDownLatch(1);
mHoverExitCallbackTriggeredLatch = new CountDownLatch(1);
mTouchState = new PipTouchState(ViewConfiguration.get(getContext()), mTouchState = new PipTouchState(ViewConfiguration.get(getContext()),
Handler.createAsync(Looper.myLooper()), () -> { Handler.createAsync(Looper.myLooper()), () -> {
mDoubleTapCallbackTriggeredLatch.countDown(); mDoubleTapCallbackTriggeredLatch.countDown();
}, () -> {
mHoverExitCallbackTriggeredLatch.countDown();
}); });
assertFalse(mTouchState.isDoubleTap()); assertFalse(mTouchState.isDoubleTap());
assertFalse(mTouchState.isWaitingForDoubleTap()); assertFalse(mTouchState.isWaitingForDoubleTap());
@@ -120,6 +125,35 @@ public class PipTouchStateTest extends SysuiTestCase {
assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1); assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1);
} }
@Test
public void testHoverExitTimeout_timeoutCallbackCalled() throws Exception {
mTouchState.scheduleHoverExitTimeoutCallback();
// TODO: Remove this sleep. Its only being added because it speeds up this test a bit.
Thread.sleep(50);
TestableLooper.get(this).processAllMessages();
assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 0);
}
@Test
public void testHoverExitTimeout_timeoutCallbackNotCalled() throws Exception {
mTouchState.scheduleHoverExitTimeoutCallback();
TestableLooper.get(this).processAllMessages();
assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 1);
}
@Test
public void testHoverExitTimeout_timeoutCallbackNotCalled_ifButtonPress() throws Exception {
mTouchState.scheduleHoverExitTimeoutCallback();
mTouchState.onTouchEvent(createMotionEvent(ACTION_BUTTON_PRESS, SystemClock.uptimeMillis(),
0, 0));
// TODO: Remove this sleep. Its only being added because it speeds up this test a bit.
Thread.sleep(50);
TestableLooper.get(this).processAllMessages();
assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 1);
}
private MotionEvent createMotionEvent(int action, long eventTime, float x, float y) { private MotionEvent createMotionEvent(int action, long eventTime, float x, float y) {
return MotionEvent.obtain(0, eventTime, action, x, y, 0); return MotionEvent.obtain(0, eventTime, action, x, y, 0);
} }