Merge "Ensure ArrowPopup alpha is set to 1 at the end of the opening animation." into ub-launcher3-master
diff --git a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
index af1b353..76abe8d 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
@@ -263,7 +263,9 @@
*/
public Bitmap createIconBitmap(Drawable icon, float scale, int size) {
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
-
+ if (icon == null) {
+ return bitmap;
+ }
mCanvas.setBitmap(bitmap);
mOldBounds.set(icon.getBounds());
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
index 2966cb1..d84633d 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
@@ -505,7 +505,7 @@
}
static final class IconDB extends SQLiteCacheHelper {
- private final static int RELEASE_VERSION = 25;
+ private final static int RELEASE_VERSION = 26;
public final static String TABLE_NAME = "icons";
public final static String COLUMN_ROWID = "rowid";
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 9ccd477..16d2b67 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java
index b37c2e0..a41362f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/FlingAndHoldTouchController.java
@@ -91,5 +91,6 @@
} else {
super.onDragEnd(velocity, fling);
}
+ mMotionPauseDetector.clear();
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
index 51e9495..027fd91 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -120,13 +120,11 @@
*/
public static void onLauncherStateOrResumeChanged(Launcher launcher) {
LauncherState state = launcher.getStateManager().getState();
- if (!OverviewInteractionState.INSTANCE.get(launcher).swipeGestureInitializing()) {
- DeviceProfile profile = launcher.getDeviceProfile();
- boolean visible = (state == NORMAL || state == OVERVIEW) && launcher.isUserActive()
- && !profile.isVerticalBarLayout();
- UiThreadHelper.runAsyncCommand(launcher, SET_SHELF_HEIGHT_CMD,
- visible ? 1 : 0, profile.hotseatBarSizePx);
- }
+ DeviceProfile profile = launcher.getDeviceProfile();
+ boolean visible = (state == NORMAL || state == OVERVIEW) && launcher.isUserActive()
+ && !profile.isVerticalBarLayout();
+ UiThreadHelper.runAsyncCommand(launcher, SET_SHELF_HEIGHT_CMD,
+ visible ? 1 : 0, profile.hotseatBarSizePx);
if (state == NORMAL) {
launcher.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(false);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index af25355..a3c942e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -39,6 +39,8 @@
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.Region;
+import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -411,6 +413,11 @@
}
@Override
+ public boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
+ return activeNavBarRegion.contains((int) ev.getX(), (int) ev.getY());
+ }
+
+ @Override
public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target) {
return homeBounds;
}
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 0bdb578..fd60cb8 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -22,8 +22,10 @@
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.Region;
import android.os.Build;
import android.os.Handler;
+import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -103,6 +105,10 @@
*/
boolean deferStartingActivity(int downHitTarget);
+ default boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
+ return true;
+ }
+
boolean supportsLongSwipe(T activity);
AlphaProperty getAlphaProperty(T activity);
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
index 3664c97..3e2e9a6 100644
--- a/quickstep/src/com/android/quickstep/MotionEventQueue.java
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -52,8 +52,6 @@
ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_SHOW_OVERVIEW_FROM_ALT_TAB =
ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
- private static final int ACTION_QUICK_STEP =
- ACTION_VIRTUAL | (6 << ACTION_POINTER_INDEX_SHIFT);
private final InputEventDispatcher mDispatcher;
private final InputEventReceiver mReceiver;
@@ -98,9 +96,6 @@
mConsumer.onShowOverviewFromAltTab();
mConsumer.onQuickScrubStart();
break;
- case ACTION_QUICK_STEP:
- mConsumer.onQuickStep(event);
- break;
default:
Log.e(TAG, "Invalid virtual event: " + event.getAction());
}
@@ -139,11 +134,6 @@
queueVirtualAction(ACTION_QUICK_SCRUB_END, 0);
}
- public void onQuickStep(MotionEvent event) {
- event.setAction(ACTION_QUICK_STEP);
- queue(event);
- }
-
public void onNewGesture(@HitTarget int downHitTarget) {
queueVirtualAction(ACTION_NEW_GESTURE, downHitTarget);
}
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 84f16cb..63349ed 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -55,9 +55,10 @@
import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.NavigationBarCompat;
-import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import java.util.function.Consumer;
+
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -80,27 +81,37 @@
private final InputConsumerController mInputConsumer;
private final SwipeSharedState mSwipeSharedState;
- private final MotionEventQueue mEventQueue;
+ private final int mDisplayRotation;
+ private final Rect mStableInsets = new Rect();
+
+ private final Consumer<OtherActivityTouchConsumer> mOnCompleteCallback;
private final MotionPauseDetector mMotionPauseDetector;
private VelocityTracker mVelocityTracker;
+ private WindowTransformSwipeHandler mInteractionHandler;
+
private final boolean mIsDeferredDownTarget;
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
private int mActivePointerId = INVALID_POINTER_ID;
- private boolean mPassedInitialSlop;
- // Used for non-deferred gestures to determine when to start dragging
- private int mQuickStepDragSlop;
+
+ private final float mDragSlop;
+ private final float mTouchSlop;
+
+ // Slop used to check when we start moving window.
+ private boolean mPassedDragSlop;
+ // Slop used to determine when we say that the gesture has started.
+ private boolean mPassedTouchSlop;
+
+ // TODO: Start displacement should have both x and y
private float mStartDisplacement;
- private WindowTransformSwipeHandler mInteractionHandler;
- private int mDisplayRotation;
- private Rect mStableInsets = new Rect();
public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
- @HitTarget int downHitTarget, OverviewCallbacks overviewCallbacks,
+ boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
TaskOverlayFactory taskOverlayFactory, InputConsumerController inputConsumer,
- TouchInteractionLog touchInteractionLog, MotionEventQueue eventQueue,
+ TouchInteractionLog touchInteractionLog,
+ Consumer<OtherActivityTouchConsumer> onCompleteCallback,
SwipeSharedState swipeSharedState) {
super(base);
@@ -109,17 +120,26 @@
mHomeIntent = homeIntent;
mMotionPauseDetector = new MotionPauseDetector(base);
- mEventQueue = eventQueue;
+ mOnCompleteCallback = onCompleteCallback;
mVelocityTracker = VelocityTracker.obtain();
mActivityControlHelper = activityControl;
- mIsDeferredDownTarget = activityControl.deferStartingActivity(downHitTarget);
+ mIsDeferredDownTarget = isDeferredDownTarget;
mOverviewCallbacks = overviewCallbacks;
mTaskOverlayFactory = taskOverlayFactory;
mTouchInteractionLog = touchInteractionLog;
mTouchInteractionLog.setTouchConsumer(this);
mInputConsumer = inputConsumer;
mSwipeSharedState = swipeSharedState;
+
+ Display display = getSystemService(WindowManager.class).getDefaultDisplay();
+ mDisplayRotation = display.getRotation();
+ WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
+
+ mDragSlop = NavigationBarCompat.getQuickStepDragSlopPx();
+ mTouchSlop = NavigationBarCompat.getQuickStepTouchSlopPx();
+ // If active listener isn't null, we are continuing the previous gesture.
+ mPassedTouchSlop = mPassedDragSlop = mSwipeSharedState.getActiveListener() != null;
}
@Override
@@ -146,9 +166,6 @@
mActivePointerId = ev.getPointerId(0);
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
- // If active listener isn't null, we are continuing the previous gesture.
- mPassedInitialSlop = mSwipeSharedState.getActiveListener() != null;
- mQuickStepDragSlop = NavigationBarCompat.getQuickStepDragSlopPx();
// Start the window animation on down to give more time for launcher to draw if the
// user didn't start the gesture over the back button
@@ -156,9 +173,6 @@
startTouchTrackingForWindowAnimation(ev.getEventTime());
}
- Display display = getSystemService(WindowManager.class).getDefaultDisplay();
- mDisplayRotation = display.getRotation();
- WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
RaceConditionTracker.onEvent(DOWN_EVT, EXIT);
break;
}
@@ -182,18 +196,38 @@
}
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
float displacement = getDisplacement(ev);
- if (!mPassedInitialSlop) {
+
+ if (!mPassedDragSlop) {
if (!mIsDeferredDownTarget) {
// Normal gesture, ensure we pass the drag slop before we start tracking
// the gesture
- if (Math.abs(displacement) > mQuickStepDragSlop) {
- mPassedInitialSlop = true;
+ if (Math.abs(displacement) > mDragSlop) {
+ mPassedDragSlop = true;
mStartDisplacement = displacement;
}
}
}
- if (mPassedInitialSlop && mInteractionHandler != null) {
+ if (!mPassedTouchSlop) {
+ if (Math.hypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y) >=
+ mTouchSlop) {
+ mPassedTouchSlop = true;
+
+ mTouchInteractionLog.startQuickStep();
+ if (mIsDeferredDownTarget) {
+ // Deferred gesture, start the animation and gesture tracking once
+ // we pass the actual touch slop
+ startTouchTrackingForWindowAnimation(ev.getEventTime());
+ }
+ if (!mPassedDragSlop) {
+ mPassedDragSlop = true;
+ mStartDisplacement = displacement;
+ }
+ notifyGestureStarted();
+ }
+ }
+
+ if (mPassedDragSlop && mInteractionHandler != null) {
// Move
dispatchMotion(ev, displacement - mStartDisplacement, null);
@@ -298,7 +332,7 @@
* the animation can still be running.
*/
private void finishTouchTracking(MotionEvent ev) {
- if (mPassedInitialSlop && mInteractionHandler != null) {
+ if (mPassedDragSlop && mInteractionHandler != null) {
mVelocityTracker.computeCurrentVelocity(1000,
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
@@ -323,6 +357,7 @@
}
mVelocityTracker.recycle();
mVelocityTracker = null;
+ mMotionPauseDetector.clear();
}
@Override
@@ -348,7 +383,7 @@
Preconditions.assertUIThread();
removeListener();
mInteractionHandler = null;
- mEventQueue.onConsumerInactive(this);
+ mOnCompleteCallback.accept(this);
}
private void removeListener() {
@@ -360,11 +395,11 @@
@Override
public void onQuickScrubStart() {
- if (!mPassedInitialSlop && mIsDeferredDownTarget && mInteractionHandler == null) {
+ if (!mPassedDragSlop && mIsDeferredDownTarget && mInteractionHandler == null) {
// If we deferred starting the window animation on touch down, then
// start tracking now
startTouchTrackingForWindowAnimation(SystemClock.uptimeMillis());
- mPassedInitialSlop = true;
+ mPassedDragSlop = true;
}
mTouchInteractionLog.startQuickScrub();
@@ -390,21 +425,6 @@
}
}
- @Override
- public void onQuickStep(MotionEvent ev) {
- mTouchInteractionLog.startQuickStep();
- if (mIsDeferredDownTarget) {
- // Deferred gesture, start the animation and gesture tracking once we pass the actual
- // touch slop
- startTouchTrackingForWindowAnimation(ev.getEventTime());
- }
- if (!mPassedInitialSlop) {
- mPassedInitialSlop = true;
- mStartDisplacement = getDisplacement(ev);
- }
- notifyGestureStarted();
- }
-
private float getDisplacement(MotionEvent ev) {
float eventX = ev.getX();
float eventY = ev.getY();
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 27f1399..411e593 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -64,8 +64,6 @@
private final Handler mUiHandler;
private final Handler mBgHandler;
- private boolean mSwipeGestureInitializing = false;
-
// These are updated on the background thread
private ISystemUiProxy mISystemUiProxy;
private boolean mSwipeUpEnabled = true;
@@ -154,7 +152,7 @@
return;
}
- int flags = 0;
+ int flags = FLAG_DISABLE_QUICK_SCRUB;
if (!mSwipeUpEnabled) {
flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON;
}
@@ -177,15 +175,6 @@
}
}
- @WorkerThread
- public void setSwipeGestureInitializing(boolean swipeGestureInitializing) {
- mSwipeGestureInitializing = swipeGestureInitializing;
- }
-
- public boolean swipeGestureInitializing() {
- return mSwipeGestureInitializing;
- }
-
public void notifySwipeUpSettingChanged(boolean swipeUpEnabled) {
mUiHandler.removeMessages(MSG_SET_SWIPE_UP_ENABLED);
mUiHandler.obtainMessage(MSG_SET_SWIPE_UP_ENABLED, swipeUpEnabled ? 1 : 0, 0).
diff --git a/quickstep/src/com/android/quickstep/OverviewTouchConsumer.java b/quickstep/src/com/android/quickstep/OverviewTouchConsumer.java
new file mode 100644
index 0000000..2638f23
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/OverviewTouchConsumer.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_POINTER_DOWN;
+import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+import static android.view.MotionEvent.ACTION_UP;
+
+import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+
+import android.graphics.PointF;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+
+/**
+ * Touch consumer for handling touch on the recents/Launcher activity.
+ */
+public class OverviewTouchConsumer<T extends BaseDraggingActivity>
+ implements TouchConsumer {
+
+ private static final String TAG = "OverviewTouchConsumer";
+
+ private final ActivityControlHelper<T> mActivityHelper;
+ private final T mActivity;
+ private final BaseDragLayer mTarget;
+ private final int[] mLocationOnScreen = new int[2];
+ private final PointF mDownPos = new PointF();
+ private final int mTouchSlop;
+ private final QuickScrubController mQuickScrubController;
+ private final TouchInteractionLog mTouchInteractionLog;
+
+ private final boolean mStartingInActivityBounds;
+
+ private boolean mTrackingStarted = false;
+ private boolean mInvalidated = false;
+
+ private float mLastProgress = 0;
+ private boolean mStartPending = false;
+ private boolean mEndPending = false;
+ private boolean mWaitForWindowAvailable;
+
+ OverviewTouchConsumer(ActivityControlHelper<T> activityHelper, T activity,
+ boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
+ boolean waitForWindowAvailable) {
+ mActivityHelper = activityHelper;
+ mActivity = activity;
+ mTarget = activity.getDragLayer();
+ mTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
+ mStartingInActivityBounds = startingInActivityBounds;
+
+ mQuickScrubController = mActivity.<RecentsView>getOverviewPanel()
+ .getQuickScrubController();
+ mTouchInteractionLog = touchInteractionLog;
+ mTouchInteractionLog.setTouchConsumer(this);
+
+ mWaitForWindowAvailable = waitForWindowAvailable;
+ }
+
+ @Override
+ public void accept(MotionEvent ev) {
+ if (mInvalidated) {
+ return;
+ }
+ mTouchInteractionLog.addMotionEvent(ev);
+ int action = ev.getActionMasked();
+ if (action == ACTION_DOWN) {
+ if (mStartingInActivityBounds) {
+ startTouchTracking(ev, false /* updateLocationOffset */,
+ false /* closeActiveWindows */);
+ return;
+ }
+ mTrackingStarted = false;
+ mDownPos.set(ev.getX(), ev.getY());
+ } else if (!mTrackingStarted) {
+ switch (action) {
+ case ACTION_CANCEL:
+ case ACTION_UP:
+ startTouchTracking(ev, true /* updateLocationOffset */,
+ false /* closeActiveWindows */);
+ break;
+ case ACTION_MOVE: {
+ float displacement = mActivity.getDeviceProfile().isLandscape ?
+ ev.getX() - mDownPos.x : ev.getY() - mDownPos.y;
+ if (Math.abs(displacement) >= mTouchSlop) {
+ // Start tracking only when mTouchSlop is crossed.
+ startTouchTracking(ev, true /* updateLocationOffset */,
+ true /* closeActiveWindows */);
+ }
+ }
+ }
+ }
+
+ if (mTrackingStarted) {
+ sendEvent(ev);
+ }
+
+ if (action == ACTION_UP || action == ACTION_CANCEL) {
+ mInvalidated = true;
+ }
+ }
+
+ private void startTouchTracking(MotionEvent ev, boolean updateLocationOffset,
+ boolean closeActiveWindows) {
+ if (updateLocationOffset) {
+ mTarget.getLocationOnScreen(mLocationOnScreen);
+ }
+
+ // Send down touch event
+ MotionEvent down = MotionEvent.obtainNoHistory(ev);
+ down.setAction(ACTION_DOWN);
+ sendEvent(down);
+
+ mTrackingStarted = true;
+ // Send pointer down for remaining pointers.
+ int pointerCount = ev.getPointerCount();
+ for (int i = 1; i < pointerCount; i++) {
+ down.setAction(ACTION_POINTER_DOWN | (i << ACTION_POINTER_INDEX_SHIFT));
+ sendEvent(down);
+ }
+
+ down.recycle();
+
+ if (closeActiveWindows) {
+ OverviewCallbacks.get(mActivity).closeAllWindows();
+ ActivityManagerWrapper.getInstance()
+ .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ mTouchInteractionLog.startQuickStep();
+ }
+ }
+
+ private void sendEvent(MotionEvent ev) {
+ if (!mTarget.verifyTouchDispatch(this, ev)) {
+ mInvalidated = true;
+ return;
+ }
+ int flags = ev.getEdgeFlags();
+ ev.setEdgeFlags(flags | TouchInteractionService.EDGE_NAV_BAR);
+ ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
+ if (!mTrackingStarted) {
+ mTarget.onInterceptTouchEvent(ev);
+ }
+ mTarget.onTouchEvent(ev);
+ ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
+ ev.setEdgeFlags(flags);
+ }
+
+ @Override
+ public void onQuickScrubStart() {
+ if (mInvalidated) {
+ return;
+ }
+ mTouchInteractionLog.startQuickScrub();
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mInvalidated = true;
+ mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
+ return;
+ }
+ OverviewCallbacks.get(mActivity).closeAllWindows();
+ ActivityManagerWrapper.getInstance()
+ .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+
+ mStartPending = true;
+ Runnable action = () -> {
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mInvalidated = true;
+ mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
+ return;
+ }
+ mActivityHelper.onQuickInteractionStart(mActivity, null, true,
+ mTouchInteractionLog);
+ mQuickScrubController.onQuickScrubProgress(mLastProgress);
+ mStartPending = false;
+
+ if (mEndPending) {
+ mQuickScrubController.onQuickScrubEnd();
+ mEndPending = false;
+ }
+ };
+
+ if (mWaitForWindowAvailable) {
+ mActivityHelper.executeOnWindowAvailable(mActivity, action);
+ } else {
+ action.run();
+ }
+ }
+
+ @Override
+ public void onQuickScrubEnd() {
+ mTouchInteractionLog.endQuickScrub("onQuickScrubEnd");
+ if (mInvalidated) {
+ return;
+ }
+ if (mStartPending) {
+ mEndPending = true;
+ } else {
+ mQuickScrubController.onQuickScrubEnd();
+ }
+ }
+
+ @Override
+ public void onQuickScrubProgress(float progress) {
+ mTouchInteractionLog.setQuickScrubProgress(progress);
+ mLastProgress = progress;
+ if (mInvalidated || mStartPending) {
+ return;
+ }
+ mQuickScrubController.onQuickScrubProgress(progress);
+ }
+
+ public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
+ boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog) {
+ return newInstance(activityHelper, startingInActivityBounds, touchInteractionLog,
+ true /* waitForWindowAvailable */);
+ }
+
+ public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
+ boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
+ boolean waitForWindowAvailable) {
+ BaseDraggingActivity activity = activityHelper.getCreatedActivity();
+ if (activity == null) {
+ return TouchConsumer.NO_OP;
+ }
+ return new OverviewTouchConsumer(activityHelper, activity, startingInActivityBounds,
+ touchInteractionLog, waitForWindowAvailable);
+ }
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index db0150e..ab5fce1 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -267,6 +267,10 @@
return mWaitingForTaskLaunch;
}
+ public boolean hasFinishedTransitionToQuickScrub() {
+ return mFinishedTransitionToQuickScrub;
+ }
+
/**
* Attempts to go to normal overview or back to home, so UI doesn't prevent user interaction.
*/
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index 026f715..d9b1fcf 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -46,8 +46,6 @@
default void onQuickScrubProgress(float progress) { }
- default void onQuickStep(MotionEvent ev) { }
-
default void onShowOverviewFromAltTab() {}
default boolean isActive() {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 97e797b..6bbcd65 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -17,37 +17,35 @@
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_MOVE;
-import static android.view.MotionEvent.ACTION_POINTER_DOWN;
-import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_CHANNEL;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.content.Intent;
-import android.graphics.PointF;
+import android.graphics.Region;
import android.os.Build;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.util.SparseArray;
import android.view.Choreographer;
+import android.view.InputEvent;
import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.util.TraceHelper;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputChannelCompat;
+import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
@@ -77,8 +75,29 @@
private final IBinder mMyBinder = new IOverviewProxy.Stub() {
- @Override
+ public void onActiveNavBarRegionChanges(Region region) {
+ mActiveNavBarRegion = region;
+ }
+
+ public void onInitialize(Bundle bundle) {
+ mISystemUiProxy = ISystemUiProxy.Stub
+ .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
+ mRecentsModel.setSystemUiProxy(mISystemUiProxy);
+ mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
+
+ if (mInputEventReceiver != null) {
+ mInputEventReceiver.dispose();
+ }
+ mInputEventReceiver = InputChannelCompat.fromBundle(bundle, KEY_EXTRA_INPUT_CHANNEL,
+ Looper.getMainLooper(), mMainChoreographer,
+ TouchInteractionService.this::onInputEvent);
+ }
+
public void onPreMotionEvent(@HitTarget int downHitTarget) {
+ // If ev are using the new dispatching system, skip the old logic
+ if (mInputEventReceiver != null) {
+ return;
+ }
mTouchInteractionLog.prepareForNewGesture();
TraceHelper.beginSection("SysUiBinder");
@@ -86,44 +105,49 @@
TraceHelper.partitionSection("SysUiBinder", "Down target " + downHitTarget);
}
- @Override
public void onMotionEvent(MotionEvent ev) {
+ // If ev are using the new dispatching system, skip the old logic
+ if (mInputEventReceiver != null) {
+ ev.recycle();
+ return;
+ }
mEventQueue.queue(ev);
int action = ev.getActionMasked();
- if (action == ACTION_DOWN) {
- mOverviewInteractionState.setSwipeGestureInitializing(true);
- } else if (action == ACTION_UP || action == ACTION_CANCEL) {
- mOverviewInteractionState.setSwipeGestureInitializing(false);
- }
-
String name = sMotionEventNames.get(action);
if (name != null){
TraceHelper.partitionSection("SysUiBinder", name);
}
}
- @Override
public void onBind(ISystemUiProxy iSystemUiProxy) {
mISystemUiProxy = iSystemUiProxy;
mRecentsModel.setSystemUiProxy(mISystemUiProxy);
mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
}
- @Override
public void onQuickScrubStart() {
+ // If ev are using the new dispatching system, skip the old logic
+ if (mInputEventReceiver != null) {
+ return;
+ }
mEventQueue.onQuickScrubStart();
- mOverviewInteractionState.setSwipeGestureInitializing(false);
TraceHelper.partitionSection("SysUiBinder", "onQuickScrubStart");
}
- @Override
public void onQuickScrubProgress(float progress) {
+ // If ev are using the new dispatching system, skip the old logic
+ if (mInputEventReceiver != null) {
+ return;
+ }
mEventQueue.onQuickScrubProgress(progress);
}
- @Override
public void onQuickScrubEnd() {
+ // If ev are using the new dispatching system, skip the old logic
+ if (mInputEventReceiver != null) {
+ return;
+ }
mEventQueue.onQuickScrubEnd();
TraceHelper.endSection("SysUiBinder", "onQuickScrubEnd");
}
@@ -135,6 +159,11 @@
@Override
public void onOverviewShown(boolean triggeredFromAltTab) {
+ // If ev are using the new dispatching system, skip the old logic
+ if (mInputEventReceiver != null) {
+ mOverviewCommandHelper.onOverviewShown();
+ return;
+ }
if (triggeredFromAltTab) {
mEventQueue.onNewGesture(HIT_TARGET_NONE);
mEventQueue.onOverviewShownFromAltTab();
@@ -145,18 +174,17 @@
@Override
public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ // If ev are using the new dispatching system, skip the old logic
+ if (mInputEventReceiver != null) {
+ return;
+ }
if (triggeredFromAltTab && !triggeredFromHomeKey) {
// onOverviewShownFromAltTab initiates quick scrub. Ending it here.
mEventQueue.onQuickScrubEnd();
}
}
- @Override
- public void onQuickStep(MotionEvent motionEvent) {
- mEventQueue.onQuickStep(motionEvent);
- mOverviewInteractionState.setSwipeGestureInitializing(false);
- TraceHelper.endSection("SysUiBinder", "onQuickStep");
- }
+ public void onQuickStep(MotionEvent motionEvent) { }
@Override
public void onTip(int actionType, int viewType) {
@@ -183,12 +211,19 @@
private InputConsumerController mInputConsumer;
private SwipeSharedState mSwipeSharedState;
+ private TouchConsumer mConsumer = TouchConsumer.NO_OP;
+ private Choreographer mMainChoreographer;
+ private InputEventReceiver mInputEventReceiver;
+ private Region mActiveNavBarRegion = new Region();
+
@Override
public void onCreate() {
super.onCreate();
mAM = ActivityManagerWrapper.getInstance();
mRecentsModel = RecentsModel.INSTANCE.get(this);
mOverviewComponentObserver = new OverviewComponentObserver(this);
+ mMainChoreographer = Choreographer.getInstance();
+
mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
mEventQueue = new MotionEventQueue(Looper.myLooper(), Choreographer.getInstance(),
this::newConsumer);
@@ -211,6 +246,9 @@
mInputConsumer.unregisterInputConsumer();
mOverviewComponentObserver.onDestroy();
mEventQueue.dispose();
+ if (mInputEventReceiver != null) {
+ mInputEventReceiver.dispose();
+ }
sConnected = false;
super.onDestroy();
}
@@ -221,6 +259,22 @@
return mMyBinder;
}
+ private void onInputEvent(InputEvent ev) {
+ if (!(ev instanceof MotionEvent)) {
+ Log.e(TAG, "Unknown event " + ev);
+ return;
+ }
+ MotionEvent event = (MotionEvent) ev;
+ if (event.getAction() == ACTION_DOWN) {
+ mTouchInteractionLog.prepareForNewGesture();
+ boolean useSharedState = mConsumer.isActive();
+ mConsumer.onConsumerAboutToBeSwitched();
+ mConsumer = newConsumer(useSharedState, event);
+ }
+
+ mConsumer.accept(event);
+ }
+
private TouchConsumer newConsumer(@HitTarget int downHitTarget, boolean useSharedState) {
RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
if (!useSharedState) {
@@ -240,12 +294,54 @@
mOverviewComponentObserver.getActivityControlHelper(), false,
mTouchInteractionLog, false /* waitForWindowAvailable */);
} else {
+ ActivityControlHelper activityControl =
+ mOverviewComponentObserver.getActivityControlHelper();
return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
mOverviewComponentObserver.getOverviewIntent(),
mOverviewComponentObserver.getActivityControlHelper(),
- downHitTarget, mOverviewCallbacks,
- mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog, mEventQueue,
- mSwipeSharedState);
+ activityControl.deferStartingActivity(downHitTarget), mOverviewCallbacks,
+ mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog,
+ mEventQueue::onConsumerInactive, mSwipeSharedState);
+ }
+ }
+
+ private TouchConsumer newConsumer(boolean useSharedState, MotionEvent event) {
+ RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
+ if (!useSharedState) {
+ mSwipeSharedState.clearAllState();
+ }
+
+ if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher) {
+ return TouchConsumer.NO_OP;
+ } else if (mSwipeSharedState.goingToLauncher ||
+ mOverviewComponentObserver.getActivityControlHelper().isResumed()) {
+ return OverviewTouchConsumer.newInstance(
+ mOverviewComponentObserver.getActivityControlHelper(), false,
+ mTouchInteractionLog);
+ } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
+ mOverviewComponentObserver.getActivityControlHelper().isInLiveTileMode()) {
+ return OverviewTouchConsumer.newInstance(
+ mOverviewComponentObserver.getActivityControlHelper(), false,
+ mTouchInteractionLog, false /* waitForWindowAvailable */);
+ } else {
+ ActivityControlHelper activityControl =
+ mOverviewComponentObserver.getActivityControlHelper();
+ boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
+ return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
+ mOverviewComponentObserver.getOverviewIntent(),
+ mOverviewComponentObserver.getActivityControlHelper(),
+ shouldDefer, mOverviewCallbacks,
+ mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog,
+ this::onConsumerInactive, mSwipeSharedState);
+ }
+ }
+
+ /**
+ * To be called by the consumer when it's no longer active.
+ */
+ private void onConsumerInactive(TouchConsumer caller) {
+ if (mConsumer == caller) {
+ mConsumer = TouchConsumer.NO_OP;
}
}
@@ -253,212 +349,4 @@
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mTouchInteractionLog.dump(pw);
}
-
- public static class OverviewTouchConsumer<T extends BaseDraggingActivity>
- implements TouchConsumer {
-
- private final ActivityControlHelper<T> mActivityHelper;
- private final T mActivity;
- private final BaseDragLayer mTarget;
- private final int[] mLocationOnScreen = new int[2];
- private final PointF mDownPos = new PointF();
- private final int mTouchSlop;
- private final QuickScrubController mQuickScrubController;
- private final TouchInteractionLog mTouchInteractionLog;
-
- private final boolean mStartingInActivityBounds;
-
- private boolean mTrackingStarted = false;
- private boolean mInvalidated = false;
-
- private float mLastProgress = 0;
- private boolean mStartPending = false;
- private boolean mEndPending = false;
- private boolean mWaitForWindowAvailable;
-
- OverviewTouchConsumer(ActivityControlHelper<T> activityHelper, T activity,
- boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
- boolean waitForWindowAvailable) {
- mActivityHelper = activityHelper;
- mActivity = activity;
- mTarget = activity.getDragLayer();
- mTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
- mStartingInActivityBounds = startingInActivityBounds;
-
- mQuickScrubController = mActivity.<RecentsView>getOverviewPanel()
- .getQuickScrubController();
- mTouchInteractionLog = touchInteractionLog;
- mTouchInteractionLog.setTouchConsumer(this);
-
- mWaitForWindowAvailable = waitForWindowAvailable;
- }
-
- @Override
- public void accept(MotionEvent ev) {
- if (mInvalidated) {
- return;
- }
- mTouchInteractionLog.addMotionEvent(ev);
- int action = ev.getActionMasked();
- if (action == ACTION_DOWN) {
- if (mStartingInActivityBounds) {
- startTouchTracking(ev, false /* updateLocationOffset */);
- return;
- }
- mTrackingStarted = false;
- mDownPos.set(ev.getX(), ev.getY());
- } else if (!mTrackingStarted) {
- switch (action) {
- case ACTION_CANCEL:
- case ACTION_UP:
- startTouchTracking(ev, true /* updateLocationOffset */);
- break;
- case ACTION_MOVE: {
- float displacement = mActivity.getDeviceProfile().isLandscape ?
- ev.getX() - mDownPos.x : ev.getY() - mDownPos.y;
- if (Math.abs(displacement) >= mTouchSlop) {
- // Start tracking only when mTouchSlop is crossed.
- startTouchTracking(ev, true /* updateLocationOffset */);
- }
- }
- }
- }
-
- if (mTrackingStarted) {
- sendEvent(ev);
- }
-
- if (action == ACTION_UP || action == ACTION_CANCEL) {
- mInvalidated = true;
- }
- }
-
- private void startTouchTracking(MotionEvent ev, boolean updateLocationOffset) {
- if (updateLocationOffset) {
- mTarget.getLocationOnScreen(mLocationOnScreen);
- }
-
- // Send down touch event
- MotionEvent down = MotionEvent.obtainNoHistory(ev);
- down.setAction(ACTION_DOWN);
- sendEvent(down);
-
- mTrackingStarted = true;
- // Send pointer down for remaining pointers.
- int pointerCount = ev.getPointerCount();
- for (int i = 1; i < pointerCount; i++) {
- down.setAction(ACTION_POINTER_DOWN | (i << ACTION_POINTER_INDEX_SHIFT));
- sendEvent(down);
- }
-
- down.recycle();
- }
-
- private void sendEvent(MotionEvent ev) {
- if (!mTarget.verifyTouchDispatch(this, ev)) {
- mInvalidated = true;
- return;
- }
- int flags = ev.getEdgeFlags();
- ev.setEdgeFlags(flags | TouchInteractionService.EDGE_NAV_BAR);
- ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
- if (!mTrackingStarted) {
- mTarget.onInterceptTouchEvent(ev);
- }
- mTarget.onTouchEvent(ev);
- ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
- ev.setEdgeFlags(flags);
- }
-
- @Override
- public void onQuickStep(MotionEvent ev) {
- if (mInvalidated) {
- return;
- }
- OverviewCallbacks.get(mActivity).closeAllWindows();
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- mTouchInteractionLog.startQuickStep();
- }
-
- @Override
- public void onQuickScrubStart() {
- if (mInvalidated) {
- return;
- }
- mTouchInteractionLog.startQuickScrub();
- if (!mQuickScrubController.prepareQuickScrub(TAG)) {
- mInvalidated = true;
- mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
- return;
- }
- OverviewCallbacks.get(mActivity).closeAllWindows();
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
-
- mStartPending = true;
- Runnable action = () -> {
- if (!mQuickScrubController.prepareQuickScrub(TAG)) {
- mInvalidated = true;
- mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
- return;
- }
- mActivityHelper.onQuickInteractionStart(mActivity, null, true,
- mTouchInteractionLog);
- mQuickScrubController.onQuickScrubProgress(mLastProgress);
- mStartPending = false;
-
- if (mEndPending) {
- mQuickScrubController.onQuickScrubEnd();
- mEndPending = false;
- }
- };
-
- if (mWaitForWindowAvailable) {
- mActivityHelper.executeOnWindowAvailable(mActivity, action);
- } else {
- action.run();
- }
- }
-
- @Override
- public void onQuickScrubEnd() {
- mTouchInteractionLog.endQuickScrub("onQuickScrubEnd");
- if (mInvalidated) {
- return;
- }
- if (mStartPending) {
- mEndPending = true;
- } else {
- mQuickScrubController.onQuickScrubEnd();
- }
- }
-
- @Override
- public void onQuickScrubProgress(float progress) {
- mTouchInteractionLog.setQuickScrubProgress(progress);
- mLastProgress = progress;
- if (mInvalidated || mStartPending) {
- return;
- }
- mQuickScrubController.onQuickScrubProgress(progress);
- }
-
- public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
- boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog) {
- return newInstance(activityHelper, startingInActivityBounds, touchInteractionLog,
- true /* waitForWindowAvailable */);
- }
-
- public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
- boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
- boolean waitForWindowAvailable) {
- BaseDraggingActivity activity = activityHelper.getCreatedActivity();
- if (activity == null) {
- return TouchConsumer.NO_OP;
- }
- return new OverviewTouchConsumer(activityHelper, activity, startingInActivityBounds,
- touchInteractionLog, waitForWindowAvailable);
- }
- }
}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index bc4e094..b0f055c 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -95,7 +95,6 @@
import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState;
import com.android.quickstep.ActivityControlHelper.LayoutListener;
import com.android.quickstep.TouchConsumer.InteractionType;
-import com.android.quickstep.TouchInteractionService.OverviewTouchConsumer;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.util.SwipeAnimationTargetSet;
@@ -700,7 +699,9 @@
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- if (mRecentsAnimationWrapper.getController() != null && mLayoutListener != null) {
+ if (mRecentsAnimationWrapper.getController() != null && mLayoutListener != null &&
+ (mInteractionType == INTERACTION_NORMAL
+ || !mQuickScrubController.hasFinishedTransitionToQuickScrub())) {
mLayoutListener.open();
mLayoutListener.update(mCurrentShift.value > 1, mLongSwipeMode,
mClipAnimationHelper.getCurrentRectWithInsets(),
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index 1156b87..21d8144 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -20,6 +20,7 @@
import android.os.SystemClock;
import android.view.MotionEvent;
+import com.android.launcher3.Alarm;
import com.android.launcher3.R;
/**
@@ -32,11 +33,15 @@
// The bigger this number, the easier it is to trigger the first pause.
private static final float RAPID_DECELERATION_FACTOR = 0.6f;
+ /** If no motion is added for this amount of time, assume the motion has paused. */
+ private static final long FORCE_PAUSE_TIMEOUT = 300;
+
private final float mSpeedVerySlow;
private final float mSpeedSomewhatFast;
private final float mSpeedFast;
private final float mMinDisplacementForPause;
private final float mMaxOrthogonalDisplacementForPause;
+ private final Alarm mForcePauseTimeout;
private Long mPreviousTime = null;
private Float mPreviousPosition = null;
@@ -59,6 +64,8 @@
mMinDisplacementForPause = res.getDimension(R.dimen.motion_pause_detector_min_displacement);
mMaxOrthogonalDisplacementForPause = res.getDimension(
R.dimen.motion_pause_detector_max_orthogonal_displacement);
+ mForcePauseTimeout = new Alarm();
+ mForcePauseTimeout.setOnAlarmListener(alarm -> updatePaused(true /* isPaused */));
}
/**
@@ -70,6 +77,7 @@
if (mOnMotionPauseListener != null) {
mOnMotionPauseListener.onMotionPauseChanged(mIsPaused);
}
+ mForcePauseTimeout.setAlarm(FORCE_PAUSE_TIMEOUT);
}
/**
@@ -100,6 +108,7 @@
}
mPreviousTime = time;
mPreviousPosition = position;
+ mForcePauseTimeout.setAlarm(FORCE_PAUSE_TIMEOUT);
}
private void checkMotionPaused(float velocity, float prevVelocity,
@@ -129,6 +138,10 @@
boolean passedMaxOrthogonalDisplacement =
totalDisplacement.orthogonal >= mMaxOrthogonalDisplacementForPause;
isPaused &= passedMinDisplacement && !passedMaxOrthogonalDisplacement;
+ updatePaused(isPaused);
+ }
+
+ private void updatePaused(boolean isPaused) {
if (mIsPaused != isPaused) {
mIsPaused = isPaused;
if (mIsPaused) {
@@ -149,6 +162,7 @@
mTotalDisplacement.set(0, 0);
setOnMotionPauseListener(null);
mIsPaused = mHasEverBeenPaused = false;
+ mForcePauseTimeout.cancelAlarm();
}
public boolean isPaused() {
diff --git a/quickstep/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
index 3e49568..686e74d 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsAnimationListenerSet.java
@@ -58,7 +58,7 @@
SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, targets,
homeContentInsets, minimizedHomeBounds);
Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
- for (SwipeAnimationListener listener : mListeners) {
+ for (SwipeAnimationListener listener : getListeners()) {
listener.onRecentsAnimationStart(targetSet);
}
});
@@ -67,9 +67,13 @@
@Override
public final void onAnimationCanceled() {
Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> {
- for (SwipeAnimationListener listener : mListeners) {
+ for (SwipeAnimationListener listener : getListeners()) {
listener.onRecentsAnimationCanceled();
}
});
}
+
+ private SwipeAnimationListener[] getListeners() {
+ return mListeners.toArray(new SwipeAnimationListener[mListeners.size()]);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index bbcd425..cbd6b2f 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -78,6 +78,12 @@
public void initialize(Task task, InitializeCallback callback) {
mTask = task;
+
+ if (task.key.userId != UserHandle.myUserId()) {
+ callback.call(1, task.titleDescription);
+ return;
+ }
+
Utilities.THREAD_POOL_EXECUTOR.execute(() -> {
long appUsageLimitTimeMs = -1;
long appRemainingTimeMs = -1;
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 5c8f53c..1ee5110 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -16,8 +16,10 @@
package com.android.quickstep.views;
import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
+import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
@@ -111,7 +113,10 @@
mTranslationYFactor = translationFactor;
setTranslationY(computeTranslationYForFactor(mTranslationYFactor));
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- redrawLiveTile(false);
+ LauncherState state = mActivity.getStateManager().getState();
+ if (state == OVERVIEW || state == ALL_APPS) {
+ redrawLiveTile(false);
+ }
}
}
@@ -216,7 +221,11 @@
int offsetY = (int) (mTaskHeight * taskView.getScaleY() * getScaleY()
- mTempRect.height());
if (((mCurrentPage != 0) || mightNeedToRefill) && offsetX > 0) {
- mTempRect.right += offsetX;
+ if (mTempRect.left - offsetX < 0) {
+ mTempRect.left -= offsetX;
+ } else {
+ mTempRect.right += offsetX;
+ }
}
if (mightNeedToRefill && offsetY > 0) {
mTempRect.top -= offsetY;
diff --git a/quickstep/tests/src/com/android/quickstep/QuickStepOnOffRule.java b/quickstep/tests/src/com/android/quickstep/QuickStepOnOffRule.java
index b801b4f..7274090 100644
--- a/quickstep/tests/src/com/android/quickstep/QuickStepOnOffRule.java
+++ b/quickstep/tests/src/com/android/quickstep/QuickStepOnOffRule.java
@@ -90,11 +90,16 @@
base.evaluate();
}
- private void overrideSwipeUpEnabled(Boolean swipeUpEnabledOverride) {
+ private void overrideSwipeUpEnabled(Boolean swipeUpEnabledOverride)
+ throws Throwable {
mLauncher.overrideSwipeUpEnabled(swipeUpEnabledOverride);
mMainThreadExecutor.execute(() -> OverviewInteractionState.INSTANCE.get(
InstrumentationRegistry.getInstrumentation().getTargetContext()).
notifySwipeUpSettingChanged(mLauncher.isSwipeUpEnabled()));
+ // TODO(b/124236673): avoid using sleep().
+ mLauncher.getDevice().waitForIdle();
+ Thread.sleep(2000);
+ mLauncher.getDevice().waitForIdle();
}
};
} else {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 245e470..cf16759 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -259,7 +259,7 @@
private final Handler mHandler = new Handler();
- private final Runnable mLogOnDelayedResume = this::logOnDelayedResume;
+ private final Runnable mHandleDeferredResume = this::handleDeferredResume;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -782,11 +782,13 @@
RaceConditionTracker.onEvent(ON_START_EVT, EXIT);
}
- private void logOnDelayedResume() {
+ private void handleDeferredResume() {
if (hasBeenResumed()) {
getUserEventDispatcher().logActionCommand(Action.Command.RESUME,
mStateManager.getState().containerType, -1);
getUserEventDispatcher().startSession();
+
+ UiFactory.onLauncherStateOrResumeChanged(this);
}
}
@@ -797,8 +799,8 @@
super.onResume();
TraceHelper.partitionSection("ON_RESUME", "superCall");
- mHandler.removeCallbacks(mLogOnDelayedResume);
- Utilities.postAsyncCallback(mHandler, mLogOnDelayedResume);
+ mHandler.removeCallbacks(mHandleDeferredResume);
+ Utilities.postAsyncCallback(mHandler, mHandleDeferredResume);
setOnResumeCallback(null);
// Process any items that were added while Launcher was away.
@@ -812,7 +814,6 @@
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onResume();
}
- UiFactory.onLauncherStateOrResumeChanged(this);
TraceHelper.endSection("ON_RESUME");
RaceConditionTracker.onEvent(ON_RESUME_EVT, EXIT);
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 7e2c966..481281a 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -74,8 +74,11 @@
*/
public Workspace dragToWorkspace() {
final UiDevice device = mLauncher.getDevice();
- mObject.drag(new Point(
- device.getDisplayWidth() / 2, device.getDisplayHeight() / 2), DRAG_SPEED);
+ Workspace.dragIconToWorkspace(
+ mLauncher,
+ this,
+ new Point(device.getDisplayWidth() / 2, device.getDisplayHeight() / 2),
+ DRAG_SPEED);
return new Workspace(mLauncher);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 466bc5e..6b76012 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -266,6 +266,16 @@
event -> true,
"Pressing Home didn't produce any events");
mDevice.waitForIdle();
+
+ // Temporarily press home twice as the first click sometimes gets ignored (b/124239413)
+ executeAndWaitForEvent(
+ () -> {
+ log("LauncherInstrumentation.pressHome before clicking");
+ getSystemUiObject("home").click();
+ },
+ event -> true,
+ "Pressing Home didn't produce any events");
+ mDevice.waitForIdle();
return getWorkspace();
}
@@ -402,7 +412,7 @@
}
@NonNull
- UiDevice getDevice() {
+ public UiDevice getDevice() {
return mDevice;
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 587c712..e10c4fb 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -96,7 +96,13 @@
public void ensureWorkspaceIsScrollable() {
final UiObject2 workspace = verifyActiveContainer();
if (!isWorkspaceScrollable(workspace)) {
- dragIconToNextScreen(getHotseatAppIcon("Messages"), workspace);
+ dragIconToWorkspace(
+ mLauncher,
+ getHotseatAppIcon("Messages"),
+ new Point(mLauncher.getDevice().getDisplayWidth(),
+ workspace.getVisibleBounds().centerY()),
+ ICON_DRAG_SPEED);
+ verifyActiveContainer();
}
assertTrue("Home screen workspace didn't become scrollable",
isWorkspaceScrollable(workspace));
@@ -112,12 +118,10 @@
mHotseat, AppIcon.getAppIconSelector(appName, mLauncher)));
}
- private void dragIconToNextScreen(AppIcon app, UiObject2 workspace) {
- final Point dest = new Point(
- mLauncher.getDevice().getDisplayWidth(), workspace.getVisibleBounds().centerY());
- app.getObject().drag(dest, ICON_DRAG_SPEED);
- mLauncher.waitUntilGone("drop_target_bar");
- verifyActiveContainer();
+ static void dragIconToWorkspace(LauncherInstrumentation launcher, Launchable launchable,
+ Point dest, int icon_drag_speed) {
+ launchable.getObject().drag(dest, icon_drag_speed);
+ launcher.waitUntilGone("drop_target_bar");
}
/**