From 146e81b8c20b9906d54405fa4c3234edebf2975d Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Thu, 13 Apr 2023 13:37:34 +0800 Subject: [PATCH] Polish reveal animation after onTasksAppeared. Showing the animation leash of appearedTaskTargets if there need to play the reveal animation behind splash screen view. Pausing applyDepthAndBlur while playing splash screen exit animation from launcher side, otherwise the app window would be blurred. Bug: 277704255 Test: manual, do quickswitch to start the app behind splash screen view, verify no flicker or blur happen when playing reveal animation. Change-Id: I83604ceeaeb54ab2100fdabf45a1624644b85e37 --- .../statehandlers/DepthController.java | 1 + .../android/quickstep/AbsSwipeUpHandler.java | 29 ++++++++++++++----- .../com/android/quickstep/TaskViewUtils.java | 12 +++++++- .../quickstep/util/BaseDepthController.java | 15 ++++++++-- .../quickstep/util/SurfaceTransaction.java | 9 ++++++ .../android/quickstep/views/RecentsView.java | 11 +++++++ 6 files changed, 67 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 867e168dd2..d8458c9991 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -166,5 +166,6 @@ public class DepthController extends BaseDepthController implements StateHandler writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp); writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation=" + mIgnoreStateChangesDuringMultiWindowAnimation); + writer.println(prefix + "\tmPauseBlurs=" + mPauseBlurs); } } diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 97956701ab..da4d4686d7 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -105,6 +105,7 @@ import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarUIController; import com.android.launcher3.tracing.InputConsumerProto; import com.android.launcher3.tracing.SwipeHandlerProto; +import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.TraceHelper; @@ -2168,7 +2169,7 @@ public abstract class AbsSwipeUpHandler, ActiveGestureLog.INSTANCE.addLog("Unexpected task appeared" + " id=" + taskInfo.taskId + " pkg=" + taskInfo.baseIntent.getComponent().getPackageName()); - finishRecentsAnimationOnTasksAppeared(); + finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */); } else if (handleTaskAppeared(appearedTaskTargets)) { Optional taskTargetOptional = Arrays.stream(appearedTaskTargets) @@ -2176,17 +2177,22 @@ public abstract class AbsSwipeUpHandler, targetCompat.taskId == mGestureState.getLastStartedTaskId()) .findFirst(); if (!taskTargetOptional.isPresent()) { - finishRecentsAnimationOnTasksAppeared(); + finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */); return; } RemoteAnimationTarget taskTarget = taskTargetOptional.get(); TaskView taskView = mRecentsView.getTaskViewByTaskId(taskTarget.taskId); if (taskView == null || !taskView.getThumbnail().shouldShowSplashView()) { - finishRecentsAnimationOnTasksAppeared(); + finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */); return; } ViewGroup splashView = mActivity.getDragLayer(); + final QuickstepLauncher quickstepLauncher = mActivity instanceof QuickstepLauncher + ? (QuickstepLauncher) mActivity : null; + if (quickstepLauncher != null) { + quickstepLauncher.getDepthController().pauseBlursOnWindows(true); + } // When revealing the app with launcher splash screen, make the app visible // and behind the splash view before the splash is animated away. @@ -2194,7 +2200,7 @@ public abstract class AbsSwipeUpHandler, new SurfaceTransactionApplier(splashView); SurfaceTransaction transaction = new SurfaceTransaction(); for (RemoteAnimationTarget target : appearedTaskTargets) { - transaction.forSurface(target.leash).setAlpha(1).setLayer(-1); + transaction.forSurface(target.leash).setAlpha(1).setLayer(-1).setShow(); } surfaceApplier.scheduleApply(transaction); @@ -2206,16 +2212,25 @@ public abstract class AbsSwipeUpHandler, new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - finishRecentsAnimationOnTasksAppeared(); + // Hiding launcher which shows the app surface behind, then + // finishing recents to the app. After transition finish, showing + // the views on launcher again, so it can be visible when next + // animation starts. + splashView.setAlpha(0); + if (quickstepLauncher != null) { + quickstepLauncher.getDepthController() + .pauseBlursOnWindows(false); + } + finishRecentsAnimationOnTasksAppeared(() -> splashView.setAlpha(1)); } }); } } } - private void finishRecentsAnimationOnTasksAppeared() { + private void finishRecentsAnimationOnTasksAppeared(Runnable onFinishComplete) { if (mRecentsAnimationController != null) { - mRecentsAnimationController.finish(false /* toRecents */, null /* onFinishComplete */); + mRecentsAnimationController.finish(false /* toRecents */, onFinishComplete); } ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimationOnTasksAppeared"); } diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index f0d0bdb0ed..499a2601a9 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -243,7 +243,17 @@ public final class TaskViewUtils { TOUCH_RESPONSE_INTERPOLATOR); out.setFloat(tvsLocal.recentsViewScroll, AnimatedFloat.VALUE, 0, TOUCH_RESPONSE_INTERPOLATOR); - + out.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + super.onAnimationStart(animation); + final SurfaceTransaction showTransaction = new SurfaceTransaction(); + for (int i = targets.apps.length - 1; i >= 0; --i) { + showTransaction.getTransaction().show(targets.apps[i].leash); + } + applier.scheduleApply(showTransaction); + } + }); out.addOnFrameCallback(() -> { for (RemoteTargetHandle handle : remoteTargetHandles) { handle.getTaskViewSimulator().apply(handle.getTransformParams()); diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java index cecf58d105..b5c582a3e0 100644 --- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java +++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java @@ -74,6 +74,10 @@ public class BaseDepthController { // Hints that there is potentially content behind Launcher and that we shouldn't optimize by // marking the launcher surface as opaque. Only used in certain Launcher states. private boolean mHasContentBehindLauncher; + + /** Pause applying depth and blur, can be used when something behind the Launcher. */ + protected boolean mPauseBlurs; + /** * Last blur value, in pixels, that was applied. * For debugging purposes. @@ -104,6 +108,13 @@ public class BaseDepthController { mHasContentBehindLauncher = hasContentBehindLauncher; } + public void pauseBlursOnWindows(boolean pause) { + if (pause != mPauseBlurs) { + mPauseBlurs = pause; + applyDepthAndBlur(); + } + } + protected void applyDepthAndBlur() { float depth = mDepth; IBinder windowToken = mLauncher.getRootView().getWindowToken(); @@ -121,9 +132,9 @@ public class BaseDepthController { return; } boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque(); - boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg; + boolean isSurfaceOpaque = mPauseBlurs || (!mHasContentBehindLauncher && hasOpaqueBg); - mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg + mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg || mPauseBlurs ? 0 : (int) (depth * mMaxBlurRadius); SurfaceControl.Transaction transaction = new SurfaceControl.Transaction() .setBackgroundBlurRadius(mSurface, mCurrentBlur) diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java index 7ab285dfa7..441f88d115 100644 --- a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java +++ b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java @@ -106,6 +106,15 @@ public class SurfaceTransaction { mTransaction.setShadowRadius(mSurface, radius); return this; } + + /** + * Requests to show the given surface. + * @return this Builder + */ + public SurfaceProperties setShow() { + mTransaction.show(mSurface); + return this; + } } /** diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index cf6ee2d2e5..f0afa69983 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1192,6 +1192,17 @@ public abstract class RecentsView= 0; --i) { + showTransaction.getTransaction().show(apps[i].leash); + } + surfaceApplier.scheduleApply(showTransaction); + } + }); anim.play(appAnimator); anim.addListener(new AnimatorListenerAdapter() { @Override