Merge "Reset floating split task view after remote animation finished" into sc-v2-dev
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index c80818a..b8ce818 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -349,7 +349,7 @@
mActionsView = findViewById(R.id.overview_actions_view);
RecentsView overviewPanel = (RecentsView) getOverviewPanel();
SplitSelectStateController controller =
- new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this));
+ new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this));
overviewPanel.init(mActionsView, controller);
mActionsView.setDp(getDeviceProfile());
mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index cc6cfd7..03e2395 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -122,7 +122,7 @@
SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
SplitSelectStateController controller =
- new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this));
+ new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this));
mDragLayer.recreateControllers();
mFallbackRecentsView.init(mActionsView, controller);
}
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 23dc913..37d88ae 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -35,6 +35,7 @@
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -42,6 +43,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
@@ -79,6 +81,8 @@
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
+import java.util.ArrayList;
+
/**
* Utility class for helpful methods related to {@link TaskView} objects and their tasks.
*/
@@ -427,34 +431,64 @@
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
@NonNull RemoteAnimationTargetCompat[] nonAppTargets,
@NonNull Runnable finishCallback) {
+ final ArrayList<SurfaceControl> openingTargets = new ArrayList<>();
+ final ArrayList<SurfaceControl> closingTargets = new ArrayList<>();
- final int[] splitRoots = new int[2];
- for (int i = 0; i < appTargets.length; ++i) {
- final int taskId = appTargets[i].taskInfo != null ? appTargets[i].taskInfo.taskId : -1;
- final int mode = appTargets[i].mode;
- if (taskId == initialTask.key.id || taskId == secondTask.key.id) {
- if (mode != MODE_OPENING) {
- throw new IllegalStateException(
- "Expected task to be opening, but it is " + mode);
- }
- splitRoots[taskId == initialTask.key.id ? 0 : 1] = i;
+ for (RemoteAnimationTargetCompat appTarget : appTargets) {
+ final int taskId = appTarget.taskInfo != null ? appTarget.taskInfo.taskId : -1;
+ final int mode = appTarget.mode;
+ final SurfaceControl leash = appTarget.leash.getSurfaceControl();
+ if (leash == null) {
+ continue;
+ }
+
+ if (mode == MODE_OPENING) {
+ openingTargets.add(leash);
+ } else if (taskId == initialTask.key.id || taskId == secondTask.key.id) {
+ throw new IllegalStateException("Expected task to be opening, but it is " + mode);
+ } else if (mode == MODE_CLOSING) {
+ closingTargets.add(leash);
}
}
- SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-
- // This is where we should animate the split roots. For now, though, just make them visible.
- for (int i = 0; i < 2; ++i) {
- t.show(appTargets[splitRoots[i]].leash.getSurfaceControl());
- t.setAlpha(appTargets[splitRoots[i]].leash.getSurfaceControl(), 1.f);
+ for (int i = 0; i < nonAppTargets.length; ++i) {
+ final SurfaceControl leash = appTargets[i].leash.getSurfaceControl();
+ if (nonAppTargets[i].windowType == TYPE_DOCK_DIVIDER && leash != null) {
+ openingTargets.add(leash);
+ }
}
- // This contains the initial state (before animation), so apply this at the beginning of
- // the animation.
- t.apply();
+ final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
+ animator.addUpdateListener(valueAnimator -> {
+ float progress = valueAnimator.getAnimatedFraction();
+ for (SurfaceControl leash: openingTargets) {
+ t.setAlpha(leash, progress);
+ }
+ for (SurfaceControl leash: closingTargets) {
+ t.setAlpha(leash, 1 - progress);
+ }
+ t.apply();
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ for (SurfaceControl leash: openingTargets) {
+ t.show(leash).setAlpha(leash, 0.0f);
+ }
+ t.apply();
+ }
- // Once there is an animation, this should be called AFTER the animation completes.
- finishCallback.run();
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ for (SurfaceControl leash: closingTargets) {
+ t.hide(leash);
+ }
+ super.onAnimationEnd(animation);
+ finishCallback.run();
+ }
+ });
+ animator.start();
}
public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 3069504..e9a695d 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -16,17 +16,20 @@
package com.android.quickstep.util;
+import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import android.app.ActivityThread;
import android.graphics.Rect;
+import android.os.Handler;
import android.os.IBinder;
import android.view.RemoteAnimationAdapter;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.quickstep.SystemUiProxy;
@@ -47,13 +50,15 @@
*/
public class SplitSelectStateController {
+ private final Handler mHandler;
private final SystemUiProxy mSystemUiProxy;
private @StagePosition int mStagePosition;
private Task mInitialTask;
private Task mSecondTask;
private Rect mInitialBounds;
- public SplitSelectStateController(SystemUiProxy systemUiProxy) {
+ public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
+ mHandler = handler;
mSystemUiProxy = systemUiProxy;
}
@@ -70,9 +75,9 @@
/**
* To be called after second task selected
*/
- public void setSecondTaskId(Task taskView) {
+ public void setSecondTaskId(Task taskView, Consumer<Boolean> callback) {
mSecondTask = taskView;
- launchTasks(mInitialTask, mSecondTask, mStagePosition, null /*callback*/);
+ launchTasks(mInitialTask, mSecondTask, mStagePosition, callback);
}
/**
@@ -151,22 +156,27 @@
public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps,
RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
Runnable finishedCallback) {
- TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask,
- mSecondTask, apps, wallpapers, nonApps, () -> {
- finishedCallback.run();
- if (mSuccessCallback != null) {
- mSuccessCallback.accept(true);
- }
- });
+ postAsyncCallback(mHandler,
+ () -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask,
+ mSecondTask, apps, wallpapers, nonApps, () -> {
+ finishedCallback.run();
+ if (mSuccessCallback != null) {
+ mSuccessCallback.accept(true);
+ }
+ }));
+
// After successful launch, call resetState
resetState();
}
@Override
public void onAnimationCancelled() {
- if (mSuccessCallback != null) {
- mSuccessCallback.accept(false);
- }
+ postAsyncCallback(mHandler, () -> {
+ if (mSuccessCallback != null) {
+ mSuccessCallback.accept(false);
+ }
+ });
+
resetState();
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index cb8e7f7..5794396 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3836,10 +3836,9 @@
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
secondTaskEndingBounds, taskView.getThumbnail(),
true /*fadeWithThumbnail*/);
- pendingAnimation.addEndListener(aBoolean -> {
- mSplitSelectStateController.setSecondTaskId(taskView.getTask());
- resetFromSplitSelectionState();
- });
+ pendingAnimation.addEndListener(aBoolean ->
+ mSplitSelectStateController.setSecondTaskId(taskView.getTask(),
+ aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
mSecondSplitHiddenTaskView = taskView;
taskView.setVisibility(INVISIBLE);
pendingAnimation.buildAnim().start();