Fix blocking issues re. window transitions and quick scrub
- Clean up the consumer when starting quickscrub/switch in addition to
motion up
- Defer invalidating the handler until after quickscrub ends
- Ensure that we always finish the remote animation
Bug: 67957962
Bug: 70180755
Change-Id: Id5af5dc9917638f1dfb8e4a04c358aadb19fd67a
diff --git a/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
index 21b032b..b3ebd77 100644
--- a/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
+++ b/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
@@ -38,8 +38,10 @@
public abstract void updateInteractionType(@InteractionType int interactionType);
+ @WorkerThread
public abstract void onQuickScrubEnd();
+ @WorkerThread
public abstract void onQuickScrubProgress(float progress);
@WorkerThread
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 61d4790..d8f7aaf 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -157,13 +157,7 @@
startTouchTrackingForScreenshotAnimation();
}
- // Notify the handler that the gesture has actually started
- mInteractionHandler.onGestureStarted();
-
- // Notify the system that we have started tracking the event
- if (mISystemUiProxy != null) {
- executeSafely(mISystemUiProxy::onRecentsAnimationStarted);
- }
+ notifyGestureStarted();
}
} else {
// Move
@@ -182,6 +176,16 @@
}
}
+ private void notifyGestureStarted() {
+ // Notify the handler that the gesture has actually started
+ mInteractionHandler.onGestureStarted();
+
+ // Notify the system that we have started tracking the event
+ if (mISystemUiProxy != null) {
+ executeSafely(mISystemUiProxy::onRecentsAnimationStarted);
+ }
+ }
+
private boolean isNavBarOnRight() {
return mDisplayRotation == Surface.ROTATION_90 && mStableInsets.right > 0;
}
@@ -263,7 +267,7 @@
handler.setLauncherOnDrawCallback(() -> {
drawWaitLock.countDown();
if (handler == mInteractionHandler) {
- switchToMainConsumer();
+ switchToMainChoreographer();
}
});
handler.initWhenReady(mMainThreadExecutor);
@@ -346,6 +350,8 @@
@Override
public void updateTouchTracking(int interactionType) {
+ notifyGestureStarted();
+
mMainThreadExecutor.execute(() -> {
if (mInteractionHandler != null) {
mInteractionHandler.updateInteractionType(interactionType);
@@ -378,7 +384,7 @@
public void onTouchTrackingComplete() { }
- public void switchToMainConsumer() { }
+ public void switchToMainChoreographer() { }
@Override
public void preProcessMotionEvent(MotionEvent ev) {
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index 3e65ffe..61684e0 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -62,6 +62,7 @@
int snapDuration = Math.abs(page - mRecentsView.getPageNearestToCenterOfScreen())
* QUICKSCRUB_END_SNAP_DURATION_PER_PAGE;
mRecentsView.snapToPage(page, snapDuration);
+ // TODO: Fix this to actually wait until page-settle
mRecentsView.postDelayed(() -> {
if (page < mRecentsView.getFirstTaskIndex()) {
mRecentsView.getPageAt(page).performClick();
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 6f3a8ff..5e89644 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -190,7 +190,7 @@
mHomeIntent, mISystemUiProxy, mMainThreadExecutor) {
@Override
- public void switchToMainConsumer() {
+ public void switchToMainChoreographer() {
if (mCurrentConsumer == this) {
mEventQueue.setInterimChoreographer(null);
}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 6082aea..17f0482 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -142,6 +142,7 @@
private @InteractionType int mInteractionType = INTERACTION_NORMAL;
private boolean mStartedQuickScrubFromHome;
+ private boolean mDeferredQuickScrubEnd;
private final RecentsAnimationWrapper mRecentsAnimationWrapper = new RecentsAnimationWrapper();
private Matrix mTmpMatrix = new Matrix();
@@ -352,6 +353,7 @@
private void updateUiForQuickScrub() {
mStartedQuickScrubFromHome = mWasLauncherAlreadyVisible;
+ mDeferredQuickScrubEnd = false;
mQuickScrubController = mRecentsView.getQuickScrubController();
mQuickScrubController.onQuickScrubStart(mStartedQuickScrubFromHome);
animateToProgress(1f, MAX_SWIPE_DURATION);
@@ -547,7 +549,11 @@
}
public void reset() {
- setStateOnUiThread(STATE_HANDLER_INVALIDATED);
+ if (mInteractionType != INTERACTION_QUICK_SCRUB) {
+ // Only invalidate the handler if we are not quick scrubbing, otherwise, it will be
+ // invalidated after the quick scrub ends
+ setStateOnUiThread(STATE_HANDLER_INVALIDATED);
+ }
}
private void invalidateHandler() {
@@ -573,6 +579,22 @@
}
private void switchToScreenshot() {
+ synchronized (mRecentsAnimationWrapper) {
+ if (mRecentsAnimationWrapper.controller != null) {
+ TransactionCompat transaction = new TransactionCompat();
+ for (RemoteAnimationTargetCompat app : mRecentsAnimationWrapper.targets) {
+ if (app.mode == MODE_CLOSING) {
+ // Update the screenshot of the task
+ final ThumbnailData thumbnail =
+ mRecentsAnimationWrapper.controller.screenshotTask(app.taskId);
+ mRecentsView.updateThumbnail(app.taskId, thumbnail);
+ }
+ }
+ transaction.apply();
+ }
+ }
+ mRecentsAnimationWrapper.finish(true /* toHome */);
+
if (mInteractionType == INTERACTION_QUICK_SWITCH) {
for (int i = mRecentsView.getFirstTaskIndex(); i < mRecentsView.getPageCount(); i++) {
TaskView taskView = (TaskView) mRecentsView.getPageAt(i);
@@ -585,24 +607,12 @@
}
} else if (mInteractionType == INTERACTION_QUICK_SCRUB) {
if (mQuickScrubController != null) {
- mQuickScrubController.snapToPageForCurrentQuickScrubSection();
- }
- } else {
- synchronized (mRecentsAnimationWrapper) {
- if (mRecentsAnimationWrapper.controller != null) {
- TransactionCompat transaction = new TransactionCompat();
- for (RemoteAnimationTargetCompat app : mRecentsAnimationWrapper.targets) {
- if (app.mode == MODE_CLOSING) {
- // Update the screenshot of the task
- final ThumbnailData thumbnail =
- mRecentsAnimationWrapper.controller.screenshotTask(app.taskId);
- mRecentsView.updateThumbnail(app.taskId, thumbnail);
- }
- }
- transaction.apply();
+ if (mDeferredQuickScrubEnd) {
+ onQuickScrubEnd();
+ } else {
+ mQuickScrubController.snapToPageForCurrentQuickScrubSection();
}
}
- mRecentsAnimationWrapper.finish(true /* toHome */);
}
}
@@ -610,7 +620,6 @@
// Re apply state in case we did something funky during the transition.
mLauncher.getStateManager().reapplyState();
-
// Animate ui the first icon.
View currentRecentsPage = mRecentsView.getPageAt(mRecentsView.getCurrentPage());
if (currentRecentsPage instanceof TaskView) {
@@ -619,11 +628,24 @@
}
public void onQuickScrubEnd() {
+ if ((mStateCallback.getState() & STATE_SCALED_CONTROLLER_RECENTS) == 0) {
+ // If we are still animating into recents, then defer until that has run to end
+ // quick scrub since we need to finish the window animation before launching the next
+ // task
+ mDeferredQuickScrubEnd = true;
+ return;
+ }
+
if (mQuickScrubController != null) {
mQuickScrubController.onQuickScrubEnd();
} else {
// TODO:
}
+
+ // Normally this is handled in reset(), but since we are still scrubbing after the
+ // transition into recents, we need to defer the handler invalidation for quick scrub until
+ // after the gesture ends
+ setStateOnUiThread(STATE_HANDLER_INVALIDATED);
}
public void onQuickScrubProgress(float progress) {