diff options
Diffstat (limited to 'quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java')
-rw-r--r-- | quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java | 132 |
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); |