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
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 867e168..d8458c9 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -166,5 +166,6 @@
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 9795670..da4d468 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.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 @@
ActiveGestureLog.INSTANCE.addLog("Unexpected task appeared"
+ " id=" + taskInfo.taskId
+ " pkg=" + taskInfo.baseIntent.getComponent().getPackageName());
- finishRecentsAnimationOnTasksAppeared();
+ finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
} else if (handleTaskAppeared(appearedTaskTargets)) {
Optional<RemoteAnimationTarget> taskTargetOptional =
Arrays.stream(appearedTaskTargets)
@@ -2176,17 +2177,22 @@
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 @@
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 @@
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 f0d0bdb..499a260 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -243,7 +243,17 @@
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 cecf58d..b5c582a 100644
--- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java
+++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
@@ -74,6 +74,10 @@
// 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 @@
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 @@
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 7ab285d..441f88d 100644
--- a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java
+++ b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java
@@ -106,6 +106,15 @@
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 cf6ee2d..f0afa69 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1192,6 +1192,17 @@
.setMatrix(matrix);
surfaceApplier.scheduleApply(transaction);
});
+ appAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ final SurfaceTransaction showTransaction = new SurfaceTransaction();
+ for (int i = apps.length - 1; i >= 0; --i) {
+ showTransaction.getTransaction().show(apps[i].leash);
+ }
+ surfaceApplier.scheduleApply(showTransaction);
+ }
+ });
anim.play(appAnimator);
anim.addListener(new AnimatorListenerAdapter() {
@Override