Merge "Reset floating split task view after remote animation finished" into sc-v2-dev am: e9fbcc4aeb

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/15809021

Change-Id: I7596c805d44815084f888675308f99a5a0488c8f
This commit is contained in:
Vinit Nayak
2021-09-24 01:29:17 +00:00
committed by Automerger Merge Worker
5 changed files with 83 additions and 40 deletions
@@ -349,7 +349,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
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));
@@ -122,7 +122,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
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);
}
@@ -35,6 +35,7 @@ import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLAT
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.Animator;
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.InteractionJankMonitorWrapper;
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 @@ public final class TaskViewUtils {
@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,
@@ -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 @@ import java.util.function.Consumer;
*/
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 @@ public class SplitSelectStateController {
/**
* 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 class SplitSelectStateController {
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();
}
}
@@ -3836,10 +3836,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
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();