From e7fc4b1f63c3add5ce6e7a72a22b09d8c3eab517 Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Wed, 7 Sep 2022 17:35:01 +0100 Subject: [PATCH] Use wm shell splash screen animation to reveal app after tasks have appeared. Bug: 202826469 Test: manual Change-Id: I6a9e8a932849c30f7b572119a7f607178b5a6437 --- quickstep/res/values/dimens.xml | 5 ++ .../android/quickstep/AbsSwipeUpHandler.java | 73 +++++++++++++++++-- .../quickstep/views/TaskThumbnailView.java | 2 +- .../com/android/quickstep/views/TaskView.java | 5 +- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index c85e71cebc..d2d1f52116 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -283,4 +283,9 @@ 47dp 47dp 47dp + + + + + 20dp diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index f3630c187b..d68db579cc 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -76,6 +76,7 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; +import android.view.ViewGroup; import android.view.ViewTreeObserver.OnDrawListener; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowInsets; @@ -128,12 +129,17 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; +import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.startingsurface.SplashScreenExitAnimationUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Optional; import java.util.function.Consumer; /** @@ -249,6 +255,13 @@ public abstract class AbsSwipeUpHandler, private static final float MAX_QUICK_SWITCH_RECENTS_SCALE_PROGRESS = 0.07f; + // Controls task thumbnail splash's reveal animation after landing on a task from quickswitch. + // These values match WindowManager/Shell starting_window_app_reveal_* config values. + private static final int SPLASH_FADE_OUT_DURATION = 133; + private static final int SPLASH_APP_REVEAL_DELAY = 83; + private static final int SPLASH_APP_REVEAL_DURATION = 266; + private static final int SPLASH_ANIMATION_DURATION = 349; + /** * Used as the page index for logging when we return to the last task at the end of the gesture. */ @@ -286,6 +299,8 @@ public abstract class AbsSwipeUpHandler, private final long mTouchTimeMs; private long mLauncherFrameDrawnTime; + private final int mSplashMainWindowShiftLength; + private final Runnable mOnDeferredActivityLaunch = this::onDeferredActivityLaunch; private SwipePipToHomeAnimator mSwipePipToHomeAnimator; @@ -321,6 +336,9 @@ public abstract class AbsSwipeUpHandler, mQuickSwitchScaleScrollThreshold = context.getResources().getDimension( R.dimen.quick_switch_scaling_scroll_threshold); + mSplashMainWindowShiftLength = -context.getResources().getDimensionPixelSize( + R.dimen.starting_surface_exit_animation_window_shift_length); + initAfterSubclassConstructor(); initStateCallbacks(); } @@ -2061,16 +2079,59 @@ public abstract class AbsSwipeUpHandler, public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) { if (mRecentsAnimationController != null) { if (handleTaskAppeared(appearedTaskTargets)) { - mRecentsAnimationController.finish(false /* toRecents */, - null /* onFinishComplete */); - ActiveGestureLog.INSTANCE.addLog( - /* event= */ "finishRecentsAnimation", - /* extras= */ false, - /* gestureEvent= */ FINISH_RECENTS_ANIMATION); + Optional taskTargetOptional = + Arrays.stream(appearedTaskTargets) + .filter(targetCompat -> + targetCompat.taskId == mGestureState.getLastStartedTaskId()) + .findFirst(); + if (!taskTargetOptional.isPresent()) { + finishRecentsAnimationOnTasksAppeared(); + return; + } + RemoteAnimationTargetCompat taskTarget = taskTargetOptional.get(); + TaskView taskView = mRecentsView.getTaskViewByTaskId(taskTarget.taskId); + if (taskView == null || !taskView.getThumbnail().shouldShowSplashView()) { + finishRecentsAnimationOnTasksAppeared(); + return; + } + + ViewGroup splashView = mActivity.getDragLayer(); + + // When revealing the app with launcher splash screen, make the app visible + // and behind the splash view before the splash is animated away. + SyncRtSurfaceTransactionApplierCompat surfaceApplier = + new SyncRtSurfaceTransactionApplierCompat(splashView); + ArrayList params = new ArrayList<>(); + for (RemoteAnimationTargetCompat target : appearedTaskTargets) { + SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash); + builder.withAlpha(1); + builder.withLayer(-1); + params.add(builder.build()); + } + surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[0])); + + SplashScreenExitAnimationUtils.startAnimations(splashView, taskTarget.leash, + mSplashMainWindowShiftLength, new TransactionPool(), new Rect(), + SPLASH_ANIMATION_DURATION, SPLASH_FADE_OUT_DURATION, + /* iconStartAlpha= */ 0, /* brandingStartAlpha= */ 0, + SPLASH_APP_REVEAL_DELAY, SPLASH_APP_REVEAL_DURATION, + new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + finishRecentsAnimationOnTasksAppeared(); + } + }); } } } + private void finishRecentsAnimationOnTasksAppeared() { + if (mRecentsAnimationController != null) { + mRecentsAnimationController.finish(false /* toRecents */, null /* onFinishComplete */); + } + ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false); + } + /** * @return The index of the TaskView in RecentsView whose taskId matches the task that will * resume if we finish the controller. diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index d7a8599eae..1e044dbc7d 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -373,7 +373,7 @@ public class TaskThumbnailView extends View { *

We want to show the splash if the aspect ratio or rotation of the thumbnail would be * different from the task. */ - boolean shouldShowSplashView() { + public boolean shouldShowSplashView() { return isThumbnailAspectRatioDifferentFromThumbnailData() || isThumbnailRotationDifferentFromTask(); } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index a81f95f3ac..25cc28fd50 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -18,7 +18,6 @@ package com.android.quickstep.views; import static android.view.Display.DEFAULT_DISPLAY; import static android.widget.Toast.LENGTH_SHORT; -import static android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR; import static com.android.launcher3.Utilities.comp; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; @@ -667,9 +666,7 @@ public class TaskView extends FrameLayout implements Reusable { if (freezeTaskList) { opts.setFreezeRecentTasksReordering(); } - // TODO(b/202826469): Replace setSplashScreenStyle with setDisableStartingWindow. - opts.setSplashScreenStyle(mSnapshotView.shouldShowSplashView() - ? SPLASH_SCREEN_STYLE_SOLID_COLOR : opts.getSplashScreenStyle()); + opts.setDisableStartingWindow(mSnapshotView.shouldShowSplashView()); Task.TaskKey key = mTask.key; UI_HELPER_EXECUTOR.execute(() -> { if (!ActivityManagerWrapper.getInstance().startActivityFromRecents(key, opts)) {