Merge "Implements LAUNCHER_ITEM_DROP_FOLDER_CREATED event." into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 6b0d7a3..1f6c506 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -26,7 +26,6 @@
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.util.TraceHelper.FLAG_CHECK_FOR_RACE_CONDITIONS;
-import static com.android.quickstep.GestureState.STATE_OVERSCROLL_WINDOW_CREATED;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -431,6 +430,6 @@
@Override
public boolean allowInterceptByParent() {
- return !mPassedPilferInputSlop || mGestureState.hasState(STATE_OVERSCROLL_WINDOW_CREATED);
+ return !mPassedPilferInputSlop;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
index 1941830..c49b8f2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
@@ -24,11 +24,9 @@
import static com.android.launcher3.Utilities.squaredHypot;
-import static java.lang.Math.abs;
-
import android.content.Context;
import android.graphics.PointF;
-import android.util.Log;
+import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -46,31 +44,24 @@
* Input consumer for handling events to pass to an {@code OverscrollPlugin}.
*/
public class OverscrollInputConsumer extends DelegateInputConsumer {
+
private static final String TAG = "OverscrollInputConsumer";
- private static final boolean DEBUG_LOGS_ENABLED = false;
- private static void debugPrint(String log) {
- if (DEBUG_LOGS_ENABLED) {
- Log.v(TAG, log);
- }
- }
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
private final PointF mStartDragPos = new PointF();
private final int mAngleThreshold;
- private final int mFlingDistanceThresholdPx;
- private final int mFlingVelocityThresholdPx;
+ private final float mFlingThresholdPx;
private int mActivePointerId = -1;
private boolean mPassedSlop = false;
- // True if we set ourselves as active, meaning we no longer pass events to the delegate.
- private boolean mPassedActiveThreshold = false;
- private final float mSquaredActiveThreshold;
+
private final float mSquaredSlop;
private final GestureState mGestureState;
@Nullable
private final OverscrollPlugin mPlugin;
+ private final GestureDetector mGestureDetector;
@Nullable
private RecentsView mRecentsView;
@@ -81,19 +72,15 @@
mAngleThreshold = context.getResources()
.getInteger(R.integer.assistant_gesture_corner_deg_threshold);
- mFlingDistanceThresholdPx = (int) context.getResources()
- .getDimension(R.dimen.gestures_overscroll_fling_threshold);
- mFlingVelocityThresholdPx = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
+ mFlingThresholdPx = context.getResources()
+ .getDimension(R.dimen.gestures_overscroll_fling_threshold);
mGestureState = gestureState;
mPlugin = plugin;
float slop = ViewConfiguration.get(context).getScaledTouchSlop();
mSquaredSlop = slop * slop;
-
- float dragThreshold = (int) context.getResources()
- .getDimension(R.dimen.gestures_overscroll_drag_threshold);
- mSquaredActiveThreshold = dragThreshold * dragThreshold;
+ mGestureDetector = new GestureDetector(context, new FlingGestureListener());
}
@Override
@@ -103,27 +90,12 @@
@Override
public void onMotionEvent(MotionEvent ev) {
- if (mPlugin == null) {
- return;
- }
-
switch (ev.getActionMasked()) {
case ACTION_DOWN: {
- if (mPlugin.blockOtherGestures()) {
- // When an Activity is visible, blocking other gestures prevents the Activity
- // from disappearing upon ACTION_DOWN in the navigation bar. (it will reappear
- // on ACTION_MOVE or ACTION_UP)
- debugPrint("Becoming active on ACTION_DOWN");
- if (mState != STATE_ACTIVE) {
- setActive(ev);
- }
- }
mActivePointerId = ev.getPointerId(0);
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
- mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
- (int) Math.sqrt(mSquaredActiveThreshold), mFlingDistanceThresholdPx,
- mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+
break;
}
case ACTION_POINTER_DOWN: {
@@ -159,82 +131,53 @@
}
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
- float squaredDist = squaredHypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y);
-
-
-
if (!mPassedSlop) {
// Normal gesture, ensure we pass the slop before we start tracking the gesture
- if (squaredDist > mSquaredSlop) {
- debugPrint("passed slop");
+ if (squaredHypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y)
+ > mSquaredSlop) {
+
mPassedSlop = true;
mStartDragPos.set(mLastPos.x, mLastPos.y);
if (isOverscrolled()) {
- debugPrint("setting STATE_OVERSCROLL_WINDOW_CREATED");
- mGestureState.setState(GestureState.STATE_OVERSCROLL_WINDOW_CREATED);
- if (!mPlugin.allowsUnderlyingActivityOverscroll()
- && (mState != STATE_ACTIVE)) {
- debugPrint("setting active gesture handler to overscroll to "
- + "prevent losing active touch when Activity starts");
- setActive(ev);
- }
- }
- } else {
- debugPrint("Not past slop");
- }
- }
-
- if (mPassedSlop && !mPassedActiveThreshold && isOverscrolled()) {
- if ((squaredDist > mSquaredActiveThreshold)) {
- debugPrint("Past slop and past threshold, set active");
-
- mPassedActiveThreshold = true;
- if (mState != STATE_ACTIVE) {
setActive(ev);
+
+ if (mPlugin != null) {
+ mPlugin.onTouchStart(getDeviceState(), getUnderlyingActivity());
+ }
+ } else {
+ mState = STATE_DELEGATE_ACTIVE;
}
}
}
- if (mPassedSlop && mState != STATE_DELEGATE_ACTIVE && isOverscrolled()) {
- debugPrint("Relaying touch event");
- mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
- (int) Math.sqrt(mSquaredActiveThreshold), mFlingDistanceThresholdPx,
- mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+ if (mPassedSlop && mState != STATE_DELEGATE_ACTIVE && isOverscrolled()
+ && mPlugin != null) {
+ mPlugin.onTouchTraveled(getDistancePx());
}
break;
}
case ACTION_CANCEL:
case ACTION_UP:
- if (mPassedSlop && isOverscrolled()) {
- mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
- (int) Math.sqrt(mSquaredActiveThreshold), mFlingDistanceThresholdPx,
- mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+ if (mState != STATE_DELEGATE_ACTIVE && mPassedSlop && mPlugin != null) {
+ mPlugin.onTouchEnd(getDistancePx());
}
mPassedSlop = false;
- mPassedActiveThreshold = false;
mState = STATE_INACTIVE;
break;
}
+ if (mState != STATE_DELEGATE_ACTIVE) {
+ mGestureDetector.onTouchEvent(ev);
+ }
+
if (mState != STATE_ACTIVE) {
mDelegate.onMotionEvent(ev);
}
}
private boolean isOverscrolled() {
- if (mPlugin.blockOtherGestures()) {
- // When an Activity is visible, this `InputConsumer` immediately becomes
- // the active gesture handler to prevent the Activity from disappearing on TOUCH_DOWN
- // in the navbar.
- //
- // Returning `true` ensures that case will still result in touches being handled,
- // instead of dropping touches until the gesture reaches the thresholds calculated
- // below.
- return true;
- }
-
if (mRecentsView == null) {
BaseDraggingActivity activity = mGestureState.getActivityInterface()
.getCreatedActivity();
@@ -253,10 +196,9 @@
|| mRecentsView.getRunningTaskIndex() <= maxIndex);
// Check if the gesture is within our angle threshold of horizontal
- float deltaY = abs(mLastPos.y - mDownPos.y);
- float deltaX = abs(mDownPos.x - mLastPos.x);
-
- boolean angleInBounds = (Math.toDegrees(Math.atan2(deltaY, deltaX)) < mAngleThreshold);
+ float deltaY = Math.abs(mLastPos.y - mDownPos.y);
+ float deltaX = mDownPos.x - mLastPos.x; // Positive if this is a gesture to the left
+ boolean angleInBounds = Math.toDegrees(Math.atan2(deltaY, deltaX)) < mAngleThreshold;
return atRightMostApp && angleInBounds;
}
@@ -277,22 +219,35 @@
return deviceState;
}
- private int getHorizontalDistancePx() {
- return (int) (mLastPos.x - mDownPos.x);
- }
-
- private int getVerticalDistancePx() {
- return (int) (mLastPos.y - mDownPos.y);
+ private int getDistancePx() {
+ return (int) Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y);
}
private String getUnderlyingActivity() {
- // Overly defensive, got guidance on code review that something in the chain of
- // `mGestureState.getRunningTask().topActivity` can be null and thus cause a null pointer
- // exception to be thrown, but we aren't sure which part can be null.
- if ((mGestureState == null) || (mGestureState.getRunningTask() == null)
- || (mGestureState.getRunningTask().topActivity == null)) {
- return "";
- }
return mGestureState.getRunningTask().topActivity.flattenToString();
}
+
+ private class FlingGestureListener extends GestureDetector.SimpleOnGestureListener {
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ if (isValidAngle(velocityX, -velocityY)
+ && getDistancePx() >= mFlingThresholdPx
+ && mState != STATE_DELEGATE_ACTIVE) {
+
+ if (mPlugin != null) {
+ mPlugin.onFling(-velocityX);
+ }
+ }
+ return true;
+ }
+
+ private boolean isValidAngle(float deltaX, float deltaY) {
+ float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX));
+ // normalize so that angle is measured clockwise from horizontal in the bottom right
+ // corner and counterclockwise from horizontal in the bottom left corner
+
+ angle = angle > 90 ? 180 - angle : angle;
+ return (angle < mAngleThreshold);
+ }
+ }
}
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 6624ff9..b06dc6b 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -79,7 +79,6 @@
<!-- Overscroll Gesture -->
<dimen name="gestures_overscroll_fling_threshold">40dp</dimen>
- <dimen name="gestures_overscroll_drag_threshold">136dp</dimen>
<!-- Tips Gesture Tutorial -->
<dimen name="gesture_tutorial_title_margin_start_end">40dp</dimen>
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 209412a..544f420 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -106,10 +106,6 @@
public static final int STATE_RECENTS_ANIMATION_ENDED =
getFlagForIndex("STATE_RECENTS_ANIMATION_ENDED");
- // Called when we create an overscroll window when swiping right to left on the most recent app
- public static final int STATE_OVERSCROLL_WINDOW_CREATED =
- getFlagForIndex("STATE_OVERSCROLL_WINDOW_CREATED");
-
// Called when RecentsView stops scrolling and settles on a TaskView.
public static final int STATE_RECENTS_SCROLLING_FINISHED =
getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED");
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 6919339..78d194b 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -110,9 +110,6 @@
public static final BooleanFlag ENABLE_QUICK_CAPTURE_GESTURE = getDebugFlag(
"ENABLE_QUICK_CAPTURE_GESTURE", true, "Swipe from right to left to quick capture");
- public static final BooleanFlag ENABLE_QUICK_CAPTURE_WINDOW = getDebugFlag(
- "ENABLE_QUICK_CAPTURE_WINDOW", false, "Use window to host quick capture");
-
public static final BooleanFlag FORCE_LOCAL_OVERSCROLL_PLUGIN = getDebugFlag(
"FORCE_LOCAL_OVERSCROLL_PLUGIN", false,
"Use a launcher-provided OverscrollPlugin if available");
diff --git a/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java b/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
index a434d07..28a9193 100644
--- a/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
@@ -15,8 +15,6 @@
*/
package com.android.systemui.plugins;
-import android.view.MotionEvent;
-
import com.android.systemui.plugins.annotations.ProvidesInterface;
/**
@@ -30,7 +28,7 @@
public interface OverscrollPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_LAUNCHER_OVERSCROLL";
- int VERSION = 4;
+ int VERSION = 3;
String DEVICE_STATE_LOCKED = "Locked";
String DEVICE_STATE_LAUNCHER = "Launcher";
@@ -43,33 +41,33 @@
boolean isActive();
/**
- * Called when a touch has been recognized as an overscroll gesture.
- * @param horizontalDistancePx Horizontal distance from the last finger location to the finger
- * location when it first touched the screen.
- * @param verticalDistancePx Horizontal distance from the last finger location to the finger
- * location when it first touched the screen.
- * @param thresholdPx Minimum distance for gesture.
- * @param flingDistanceThresholdPx Minimum distance for gesture by fling.
- * @param flingVelocityThresholdPx Minimum velocity for gesture by fling.
+ * Called when a touch is down and has been recognized as an overscroll gesture.
+ * A call of this method will always result in `onTouchUp` being called, and possibly
+ * `onFling` as well.
+ *
* @param deviceState String representing the current device state
* @param underlyingActivity String representing the currently active Activity
*/
- void onTouchEvent(MotionEvent event,
- int horizontalDistancePx,
- int verticalDistancePx,
- int thresholdPx,
- int flingDistanceThresholdPx,
- int flingVelocityThresholdPx,
- String deviceState,
- String underlyingActivity);
+ void onTouchStart(String deviceState, String underlyingActivity);
/**
- * @return `true` if overscroll gesture handling should override all other gestures.
+ * Called when a touch that was previously recognized has moved.
+ *
+ * @param px distance between the position of touch on this update and the position of the
+ * touch when it was initially recognized.
*/
- boolean blockOtherGestures();
+ void onTouchTraveled(int px);
/**
- * @return `true` if the overscroll gesture can pan the underlying app.
+ * Called when a touch that was previously recognized has ended.
+ *
+ * @param px distance between the position of touch on this update and the position of the
+ * touch when it was initially recognized.
*/
- boolean allowsUnderlyingActivityOverscroll();
+ void onTouchEnd(int px);
+
+ /**
+ * Called when the user starts Compose with a fling. `onTouchUp` will also be called.
+ */
+ void onFling(float velocity);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index dd170c5..ce7d39d 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -622,6 +622,8 @@
* @return the Workspace object.
*/
public Workspace pressHome() {
+ mInstrumentation.getUiAutomation().setOnAccessibilityEventListener(
+ e -> Log.d("b/155926212", e.toString()));
try (LauncherInstrumentation.Closable e = eventsCheck()) {
// Click home, then wait for any accessibility event, then wait until accessibility
// events stop.
@@ -629,7 +631,9 @@
// otherwise waitForIdle may return immediately in case when there was a big enough
// pause in accessibility events prior to pressing Home.
final String action;
+ Log.d("b/155926212", "Before isLauncherVisible()");
final boolean launcherWasVisible = isLauncherVisible();
+ Log.d("b/155926212", "After isLauncherVisible(): " + launcherWasVisible);
if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
checkForAnomaly();
@@ -685,6 +689,8 @@
"performed action to switch to Home - " + action)) {
return getWorkspace();
}
+ } finally {
+ mInstrumentation.getUiAutomation().setOnAccessibilityEventListener(null);
}
}