From faa8799621144e2ea2bda6a0cb7656a34e21da76 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Wed, 29 May 2019 09:12:18 -0700 Subject: Use unbatched inputeventreceiver, reduce touchslop To ensure gesture navigation has sufficient time to intercept gestures, use unbatched inputreceiver, meaning that input events will be processed immediately rather than on vsync boundaries. Also, reduce touch slop to ensure that interception happens before the app starts to react to the gesture. Fix provided by michaelwr@. Note: if the device is slow (for example, still executing first-boot instructions), then the symptom can still be reproduced. However, once the performance is good, then the issue is no longer observed. Bug: 130352502 Test: open google maps and swipe from right and left. observe that the map doesn't start moving before the back gesture icon appears. Change-Id: I0696509c7f1cb0a0d2450080e0b61e2218a01140 --- .../systemui/shared/system/InputChannelCompat.java | 14 ----------- .../statusbar/phone/EdgeBackGestureHandler.java | 28 +++++++++++++++------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java index 6567b6ad1171..2b1fce8a4cf5 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputChannelCompat.java @@ -18,7 +18,6 @@ package com.android.systemui.shared.system; import android.os.Bundle; import android.os.Looper; -import android.util.Pair; import android.view.BatchedInputEventReceiver; import android.view.Choreographer; import android.view.InputChannel; @@ -41,19 +40,6 @@ public class InputChannelCompat { void onInputEvent(InputEvent ev); } - /** - * Creates a dispatcher and receiver pair to better handle events across threads. - */ - public static Pair createPair(String name, - Looper looper, Choreographer choreographer, InputEventListener listener) { - InputChannel[] channels = InputChannel.openInputChannelPair(name); - - InputEventDispatcher dispatcher = new InputEventDispatcher(channels[0], looper); - InputEventReceiver receiver = new InputEventReceiver(channels[1], looper, choreographer, - listener); - return Pair.create(dispatcher, receiver); - } - /** * Creates a dispatcher from the extras received as part on onInitialize */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index f2218651d7c7..05a86fa9d7ea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -33,13 +33,14 @@ import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import android.util.MathUtils; -import android.view.Choreographer; import android.view.Gravity; import android.view.IPinnedStackController; import android.view.IPinnedStackListener; import android.view.ISystemGestureExclusionListener; +import android.view.InputChannel; import android.view.InputDevice; import android.view.InputEvent; +import android.view.InputEventReceiver; import android.view.InputMonitor; import android.view.KeyCharacterMap; import android.view.KeyEvent; @@ -53,7 +54,6 @@ import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.recents.OverviewProxyService; -import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.WindowManagerWrapper; @@ -165,12 +165,14 @@ public class EdgeBackGestureHandler implements DisplayListener { mEdgeWidth = res.getDimensionPixelSize( com.android.internal.R.dimen.config_backGestureInset); - mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + // Reduce the default touch slop to ensure that we can intercept the gesture + // before the app starts to react to it. + // TODO(b/130352502) Tune this value and extract into a constant + mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 0.75f; mLongPressTimeout = ViewConfiguration.getLongPressTimeout(); mNavBarHeight = res.getDimensionPixelSize(R.dimen.navigation_bar_frame_height); - mMinArrowPosition = res.getDimensionPixelSize( - R.dimen.navigation_edge_arrow_min_y); + mMinArrowPosition = res.getDimensionPixelSize(R.dimen.navigation_edge_arrow_min_y); mFingerOffset = res.getDimensionPixelSize(R.dimen.navigation_edge_finger_offset); } @@ -250,9 +252,8 @@ public class EdgeBackGestureHandler implements DisplayListener { // Register input event receiver mInputMonitor = InputManager.getInstance().monitorGestureInput( "edge-swipe", mDisplayId); - mInputEventReceiver = new InputEventReceiver(mInputMonitor.getInputChannel(), - Looper.getMainLooper(), Choreographer.getMainThreadInstance(), - this::onInputEvent); + mInputEventReceiver = new SysUiInputEventReceiver( + mInputMonitor.getInputChannel(), Looper.getMainLooper()); // Add a nav bar panel window mEdgePanel = new NavigationBarEdgePanel(mContext); @@ -440,4 +441,15 @@ public class EdgeBackGestureHandler implements DisplayListener { } InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); } + + class SysUiInputEventReceiver extends InputEventReceiver { + SysUiInputEventReceiver(InputChannel channel, Looper looper) { + super(channel, looper); + } + + public void onInputEvent(InputEvent event) { + EdgeBackGestureHandler.this.onInputEvent(event); + finishInputEvent(event, true); + } + } } -- cgit v1.2.3-59-g8ed1b