summaryrefslogtreecommitdiff
path: root/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java')
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java132
1 files changed, 111 insertions, 21 deletions
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index f824210bd8..0a558e2a98 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -15,16 +15,23 @@
*/
package com.android.quickstep.inputconsumers;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DEEP_PRESS_NAVBAR;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_NAVBAR;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.InputConsumer;
+import com.android.quickstep.RecentsAnimationDeviceState;
+import com.android.quickstep.TopTaskTracker;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
@@ -32,33 +39,36 @@ import com.android.systemui.shared.system.InputMonitorCompat;
*/
public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
- private final GestureDetector mLongPressDetector;
private final NavHandleLongPressHandler mNavHandleLongPressHandler;
private final float mNavHandleWidth;
private final float mScreenWidth;
+ private final Runnable mTriggerLongPress = this::triggerLongPress;
+ private final float mTouchSlopSquared;
+ private final int mLongPressTimeout;
+ private final boolean mDeepPressEnabled;
+ private final StatsLogManager mStatsLogManager;
+ private final TopTaskTracker mTopTaskTracker;
+
+ private MotionEvent mCurrentDownEvent;
+ private boolean mDeepPressLogged; // Whether deep press has been logged for the current touch.
+
public NavHandleLongPressInputConsumer(Context context, InputConsumer delegate,
- InputMonitorCompat inputMonitor) {
+ InputMonitorCompat inputMonitor, RecentsAnimationDeviceState deviceState) {
super(delegate, inputMonitor);
mNavHandleWidth = context.getResources().getDimensionPixelSize(
R.dimen.navigation_home_handle_width);
mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
-
+ mDeepPressEnabled = FeatureFlags.ENABLE_LPNH_DEEP_PRESS.get();
+ if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
+ mLongPressTimeout = LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
+ } else {
+ mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
+ }
+ mTouchSlopSquared = deviceState.getSquaredTouchSlop();
mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
-
- mLongPressDetector = new GestureDetector(context, new SimpleOnGestureListener() {
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- if (isInArea(motionEvent.getRawX())) {
- Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable();
- if (longPressRunnable != null) {
- setActive(motionEvent);
-
- MAIN_EXECUTOR.getHandler().postDelayed(longPressRunnable, 50);
- }
- }
- }
- });
+ mStatsLogManager = StatsLogManager.newInstance(context);
+ mTopTaskTracker = TopTaskTracker.INSTANCE.get(context);
}
@Override
@@ -68,13 +78,93 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
@Override
public void onMotionEvent(MotionEvent ev) {
- mLongPressDetector.onTouchEvent(ev);
+ if (mDelegate.allowInterceptByParent()) {
+ handleMotionEvent(ev);
+ } else if (MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
+ cancelLongPress("intercept disallowed by child input consumer");
+ }
+
if (mState != STATE_ACTIVE) {
mDelegate.onMotionEvent(ev);
}
}
- protected boolean isInArea(float x) {
+ private void handleMotionEvent(MotionEvent ev) {
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN -> {
+ if (mCurrentDownEvent != null) {
+ mCurrentDownEvent.recycle();
+ }
+ mCurrentDownEvent = MotionEvent.obtain(ev);
+ mDeepPressLogged = false;
+ if (isInNavBarHorizontalArea(ev.getRawX())) {
+ mNavHandleLongPressHandler.onTouchStarted();
+ MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress,
+ mLongPressTimeout);
+ }
+ }
+ case MotionEvent.ACTION_MOVE -> {
+ if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
+ break;
+ }
+
+ float touchSlopSquared = mTouchSlopSquared;
+ float dx = ev.getX() - mCurrentDownEvent.getX();
+ float dy = ev.getY() - mCurrentDownEvent.getY();
+ double distanceSquared = (dx * dx) + (dy * dy);
+ if (distanceSquared > touchSlopSquared) {
+ cancelLongPress("touch slop passed");
+ }
+ }
+ case MotionEvent.ACTION_UP -> cancelLongPress("touch action up");
+ case MotionEvent.ACTION_CANCEL -> cancelLongPress("touch action cancel");
+ }
+
+ // If the gesture is deep press then trigger long press asap
+ if (MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)
+ && ev.getClassification() == MotionEvent.CLASSIFICATION_DEEP_PRESS
+ && !mDeepPressLogged) {
+ // Log deep press even if feature is disabled.
+ String runningPackage = mTopTaskTracker.getCachedTopTask(
+ /* filterOnlyVisibleRecents */ true).getPackageName();
+ mStatsLogManager.logger().withPackageName(runningPackage)
+ .log(LAUNCHER_DEEP_PRESS_NAVBAR);
+ mDeepPressLogged = true;
+
+ // But only trigger if the feature is enabled.
+ if (mDeepPressEnabled) {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+ MAIN_EXECUTOR.getHandler().post(mTriggerLongPress);
+ }
+ }
+ }
+
+ private void triggerLongPress() {
+ String runningPackage = mTopTaskTracker.getCachedTopTask(
+ /* filterOnlyVisibleRecents */ true).getPackageName();
+ mStatsLogManager.logger().withPackageName(runningPackage).log(LAUNCHER_LONG_PRESS_NAVBAR);
+
+ Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable();
+ if (longPressRunnable == null) {
+ return;
+ }
+
+ OtherActivityInputConsumer oaic = getInputConsumerOfClass(OtherActivityInputConsumer.class);
+ if (oaic != null && oaic.hasStartedTouchTracking()) {
+ oaic.setForceFinishRecentsTransitionCallback(longPressRunnable);
+ setActive(mCurrentDownEvent);
+ } else {
+ setActive(mCurrentDownEvent);
+ MAIN_EXECUTOR.post(longPressRunnable);
+ }
+ }
+
+ private void cancelLongPress(String reason) {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+ mNavHandleLongPressHandler.onTouchFinished(reason);
+ }
+
+ private boolean isInNavBarHorizontalArea(float x) {
float areaFromMiddle = mNavHandleWidth / 2.0f;
float distFromMiddle = Math.abs(mScreenWidth / 2.0f - x);