From 141ab952e77a179661cac5d01c8e33863f47a482 Mon Sep 17 00:00:00 2001 From: Kevin Date: Mon, 6 May 2019 13:13:27 -0700 Subject: Ensure Recents Go layout finishes before remote anim begins We would like to assume a correct up-to-date layout for Go recents before the remote animation begins to ensure correctness of the app to overview transition and allow for animating all the newly laid out task views in sync. We do this by checking if recents is the remote target we are animating to and if so, checking if the view is ready. If it is not, then we delay the remote animation until the layout is finished and everything is attached. Bug: 132112131 Fix: 132108983 Test: Run Recents Go, have no tasks in recents, open app, press overview to go to recents Test: Test on AOSP and NexusLauncher that animations to Launcher work as before (both to recents and to home) Change-Id: Id74d90cffc9fe5db1dbb5fe63b8819c7436fef21 --- .../GoLauncherAppTransitionManagerImpl.java | 42 +++++++++++++++++++++- .../android/quickstep/views/IconRecentsView.java | 38 ++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) (limited to 'go/quickstep/src') diff --git a/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java b/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java index d189c504c..bcb1f5c3b 100644 --- a/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java +++ b/go/quickstep/src/com/android/launcher3/GoLauncherAppTransitionManagerImpl.java @@ -1,16 +1,20 @@ package com.android.launcher3; +import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.quickstep.TaskUtils.taskIsATargetWithMode; import static com.android.quickstep.views.IconRecentsView.CONTENT_ALPHA; +import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.app.ActivityOptions; import android.content.Context; +import android.os.Handler; import android.view.View; import com.android.quickstep.views.IconRecentsView; +import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; /** @@ -28,6 +32,12 @@ public final class GoLauncherAppTransitionManagerImpl extends QuickstepAppTransi return mLauncher.getStateManager().getState().overviewUi; } + @Override + RemoteAnimationRunnerCompat getWallpaperOpenRunner(boolean fromUnlock) { + return new GoWallpaperOpenLauncherAnimationRunner(mHandler, + false /* startAtFrontOfQueue */, fromUnlock); + } + @Override protected void composeRecentsLaunchAnimator(AnimatorSet anim, View v, RemoteAnimationTargetCompat[] targets, boolean launcherClosing) { @@ -51,4 +61,34 @@ public final class GoLauncherAppTransitionManagerImpl extends QuickstepAppTransi return mLauncher.getStateManager()::reapplyState; } + + /** + * Remote animation runner for animation from app to Launcher. For Go, when going to recents, + * we need to ensure that the recents view is ready for remote animation before starting. + */ + private final class GoWallpaperOpenLauncherAnimationRunner extends + WallpaperOpenLauncherAnimationRunner { + public GoWallpaperOpenLauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue, + boolean fromUnlock) { + super(handler, startAtFrontOfQueue, fromUnlock); + } + + @Override + public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats, + AnimationResult result) { + boolean isGoingToRecents = + taskIsATargetWithMode(targetCompats, mLauncher.getTaskId(), MODE_OPENING) + && (mLauncher.getStateManager().getState() == LauncherState.OVERVIEW); + if (isGoingToRecents) { + IconRecentsView recentsView = mLauncher.getOverviewPanel(); + if (!recentsView.isReadyForRemoteAnim()) { + recentsView.setOnReadyForRemoteAnimCallback(() -> + postAsyncCallback(mHandler, () -> onCreateAnimation(targetCompats, result)) + ); + return; + } + } + super.onCreateAnimation(targetCompats, result); + } + } } diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java index 7225e572b..07faa4bbd 100644 --- a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java +++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java @@ -378,6 +378,36 @@ public final class IconRecentsView extends FrameLayout implements Insettable { return view.getThumbnailView(); } + /** + * Whether this view has processed all data changes and is ready to animate from the app to + * the overview. + * + * @return true if ready to animate app to overview, false otherwise + */ + public boolean isReadyForRemoteAnim() { + return !mTaskRecyclerView.hasPendingAdapterUpdates(); + } + + /** + * Set a callback for whenever this view is ready to do a remote animation from the app to + * overview. See {@link #isReadyForRemoteAnim()}. + * + * @param callback callback to run when view is ready to animate + */ + public void setOnReadyForRemoteAnimCallback(onReadyForRemoteAnimCallback callback) { + mTaskRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (isReadyForRemoteAnim()) { + callback.onReadyForRemoteAnim(); + mTaskRecyclerView.getViewTreeObserver(). + removeOnGlobalLayoutListener(this); + } + } + }); + } + /** * Clear all tasks and animate out. */ @@ -557,4 +587,12 @@ public final class IconRecentsView extends FrameLayout implements Insettable { mTaskRecyclerView.setPadding(insets.left, insets.top, insets.right, insets.bottom); mTaskRecyclerView.invalidateItemDecorations(); } + + /** + * Callback for when this view is ready for a remote animation from app to overview. + */ + public interface onReadyForRemoteAnimCallback { + + void onReadyForRemoteAnim(); + } } -- cgit v1.2.3