mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 08:16:49 +00:00
Merge "Hook up split-launch to legacy transition system" into sc-v2-dev
This commit is contained in:
@@ -33,6 +33,7 @@ import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.RemoteAnimationAdapter;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||
@@ -562,6 +563,22 @@ public class SystemUiProxy implements ISystemUiProxy,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start multiple tasks in split-screen simultaneously.
|
||||
*/
|
||||
public void startTasksWithLegacyTransition(int mainTaskId, Bundle mainOptions, int sideTaskId,
|
||||
Bundle sideOptions, @SplitConfigurationOptions.StagePosition int sidePosition,
|
||||
RemoteAnimationAdapter adapter) {
|
||||
if (mSystemUiProxy != null) {
|
||||
try {
|
||||
mSplitScreen.startTasksWithLegacyTransition(mainTaskId, mainOptions, sideTaskId,
|
||||
sideOptions, sidePosition, adapter);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call startTasksWithLegacyTransition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startShortcut(String packageName, String shortcutId, int stage, int position,
|
||||
Bundle options, UserHandle user) {
|
||||
if (mSplitScreen != null) {
|
||||
|
||||
@@ -405,77 +405,39 @@ public final class TaskViewUtils {
|
||||
}
|
||||
|
||||
/** Legacy version (until shell transitions are enabled) */
|
||||
public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull AnimatorSet anim,
|
||||
public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull TaskView initialView,
|
||||
@NonNull TaskView v, @NonNull RemoteAnimationTargetCompat[] appTargets,
|
||||
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
@NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing,
|
||||
@NonNull StateManager stateManager, @NonNull DepthController depthController,
|
||||
int targetStage) {
|
||||
PendingAnimation out = new PendingAnimation(RECENTS_LAUNCH_DURATION);
|
||||
boolean isRunningTask = v.isRunningTask();
|
||||
TransformParams params = null;
|
||||
TaskViewSimulator tvs = null;
|
||||
RecentsView recentsView = v.getRecentsView();
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
|
||||
params = recentsView.getLiveTileParams();
|
||||
tvs = recentsView.getLiveTileTaskViewSimulator();
|
||||
@NonNull RemoteAnimationTargetCompat[] nonAppTargets,
|
||||
@NonNull Runnable finishCallback) {
|
||||
|
||||
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 == initialView.getTask().key.id || taskId == v.getTask().key.id) {
|
||||
if (mode != MODE_OPENING) {
|
||||
throw new IllegalStateException(
|
||||
"Expected task to be opening, but it is " + mode);
|
||||
}
|
||||
splitRoots[taskId == initialView.getTask().key.id ? 0 : 1] = i;
|
||||
}
|
||||
}
|
||||
|
||||
boolean inLiveTileMode =
|
||||
ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskIndex() != -1;
|
||||
final RemoteAnimationTargets targets =
|
||||
new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets,
|
||||
inLiveTileMode ? MODE_CLOSING : MODE_OPENING);
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
|
||||
if (params == null) {
|
||||
SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
|
||||
targets.addReleaseCheck(applier);
|
||||
|
||||
params = new TransformParams()
|
||||
.setSyncTransactionApplier(applier)
|
||||
.setTargetSet(targets);
|
||||
// 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);
|
||||
}
|
||||
|
||||
Rect crop = new Rect();
|
||||
Context context = v.getContext();
|
||||
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
|
||||
if (tvs == null && targets.apps.length > 0) {
|
||||
tvs = new TaskViewSimulator(recentsView.getContext(), recentsView.getSizeStrategy());
|
||||
tvs.setDp(dp);
|
||||
// This contains the initial state (before animation), so apply this at the beginning of
|
||||
// the animation.
|
||||
t.apply();
|
||||
|
||||
// RecentsView never updates the display rotation until swipe-up so the value may
|
||||
// be stale. Use the display value instead.
|
||||
int displayRotation = DisplayController.INSTANCE.get(recentsView.getContext())
|
||||
.getInfo().rotation;
|
||||
tvs.getOrientationState().update(displayRotation, displayRotation);
|
||||
|
||||
tvs.setPreview(targets.apps[targets.apps.length - 1]);
|
||||
tvs.fullScreenProgress.value = 0;
|
||||
tvs.recentsViewScale.value = 1;
|
||||
// tvs.setScroll(startScroll);
|
||||
|
||||
// Fade in the task during the initial 20% of the animation
|
||||
out.addFloat(params, TransformParams.TARGET_ALPHA, 0, 1,
|
||||
clampToProgress(LINEAR, 0, 0.2f));
|
||||
}
|
||||
|
||||
TaskViewSimulator topMostSimulator = null;
|
||||
|
||||
if (tvs != null) {
|
||||
out.setFloat(tvs.fullScreenProgress,
|
||||
AnimatedFloat.VALUE, 1, TOUCH_RESPONSE_INTERPOLATOR);
|
||||
out.setFloat(tvs.recentsViewScale,
|
||||
AnimatedFloat.VALUE, tvs.getFullScreenScale(), TOUCH_RESPONSE_INTERPOLATOR);
|
||||
out.setFloat(tvs.recentsViewScroll,
|
||||
AnimatedFloat.VALUE, 0, TOUCH_RESPONSE_INTERPOLATOR);
|
||||
|
||||
TaskViewSimulator finalTsv = tvs;
|
||||
TransformParams finalParams = params;
|
||||
out.addOnFrameCallback(() -> finalTsv.apply(finalParams));
|
||||
topMostSimulator = tvs;
|
||||
}
|
||||
|
||||
anim.play(out.buildAnim());
|
||||
// Once there is an animation, this should be called AFTER the animation completes.
|
||||
finishCallback.run();
|
||||
}
|
||||
|
||||
public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
|
||||
|
||||
@@ -22,33 +22,26 @@ 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.animation.AnimatorSet;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityThread;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.util.Pair;
|
||||
import android.view.Gravity;
|
||||
import android.view.RemoteAnimationAdapter;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.InsettableFrameLayout;
|
||||
import com.android.launcher3.LauncherAnimationRunner;
|
||||
import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskAnimationManager;
|
||||
import com.android.quickstep.TaskViewUtils;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
@@ -92,37 +85,27 @@ public class SplitSelectStateController {
|
||||
? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
|
||||
: new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
|
||||
|
||||
RemoteSplitLaunchAnimationRunner animationRunner =
|
||||
new RemoteSplitLaunchAnimationRunner(mInitialTaskView, taskView);
|
||||
RemoteSplitLaunchTransitionRunner animationRunner =
|
||||
new RemoteSplitLaunchTransitionRunner(mInitialTaskView, taskView);
|
||||
mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
|
||||
null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
|
||||
new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR));
|
||||
return;
|
||||
} else {
|
||||
// Assume initial task is for top/left part of screen
|
||||
final int[] taskIds = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT
|
||||
? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
|
||||
: new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
|
||||
|
||||
RemoteSplitLaunchAnimationRunner animationRunner =
|
||||
new RemoteSplitLaunchAnimationRunner(mInitialTaskView, taskView);
|
||||
final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
|
||||
RemoteAnimationAdapterCompat.wrapRemoteAnimationRunner(animationRunner),
|
||||
300, 150,
|
||||
ActivityThread.currentActivityThread().getApplicationThread());
|
||||
|
||||
mSystemUiProxy.startTasksWithLegacyTransition(taskIds[0], null /* mainOptions */,
|
||||
taskIds[1], null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, adapter);
|
||||
}
|
||||
// Assume initial mInitialTaskId is for top/left part of screen
|
||||
RemoteAnimationFactory initialSplitRunnerWrapped = new SplitLaunchAnimationRunner(
|
||||
mInitialTaskView, 0);
|
||||
RemoteAnimationFactory secondarySplitRunnerWrapped = new SplitLaunchAnimationRunner(
|
||||
taskView, 1);
|
||||
RemoteAnimationRunnerCompat initialSplitRunner = new LauncherAnimationRunner(
|
||||
new Handler(Looper.getMainLooper()), initialSplitRunnerWrapped,
|
||||
true /* startAtFrontOfQueue */);
|
||||
RemoteAnimationRunnerCompat secondarySplitRunner = new LauncherAnimationRunner(
|
||||
new Handler(Looper.getMainLooper()), secondarySplitRunnerWrapped,
|
||||
true /* startAtFrontOfQueue */);
|
||||
ActivityOptions initialOptions = ActivityOptionsCompat.makeRemoteAnimation(
|
||||
new RemoteAnimationAdapterCompat(initialSplitRunner, 300, 150));
|
||||
ActivityOptions secondaryOptions = ActivityOptionsCompat.makeRemoteAnimation(
|
||||
new RemoteAnimationAdapterCompat(secondarySplitRunner, 300, 150));
|
||||
mSystemUiProxy.startTask(mInitialTaskView.getTask().key.id, mInitialPosition.mStageType,
|
||||
mInitialPosition.mStagePosition,
|
||||
/*null*/ initialOptions.toBundle());
|
||||
Pair<Integer, Integer> compliment = getComplimentaryStageAndPosition(mInitialPosition);
|
||||
mSystemUiProxy.startTask(taskView.getTask().key.id, compliment.first,
|
||||
compliment.second,
|
||||
/*null*/ secondaryOptions.toBundle());
|
||||
// After successful launch, call resetState
|
||||
resetState();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,12 +136,12 @@ public class SplitSelectStateController {
|
||||
/**
|
||||
* Requires Shell Transitions
|
||||
*/
|
||||
private class RemoteSplitLaunchAnimationRunner implements RemoteTransitionRunner {
|
||||
private class RemoteSplitLaunchTransitionRunner implements RemoteTransitionRunner {
|
||||
|
||||
private final TaskView mInitialTaskView;
|
||||
private final TaskView mTaskView;
|
||||
|
||||
RemoteSplitLaunchAnimationRunner(TaskView initialTaskView, TaskView taskView) {
|
||||
RemoteSplitLaunchTransitionRunner(TaskView initialTaskView, TaskView taskView) {
|
||||
mInitialTaskView = initialTaskView;
|
||||
mTaskView = taskView;
|
||||
}
|
||||
@@ -173,50 +156,36 @@ public class SplitSelectStateController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LEGACY
|
||||
* @return the opposite stage and position from the {@param position} provided as first and
|
||||
* second object, respectively
|
||||
* Ex. If position is has stage = Main and position = Top/Left, this will return
|
||||
* Pair(stage=Side, position=Bottom/Left)
|
||||
*/
|
||||
private Pair<Integer, Integer> getComplimentaryStageAndPosition(SplitPositionOption position) {
|
||||
// Right now this is as simple as flipping between 0 and 1
|
||||
int complimentStageType = position.mStageType ^ 1;
|
||||
int complimentStagePosition = position.mStagePosition ^ 1;
|
||||
return new Pair<>(complimentStageType, complimentStagePosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* LEGACY
|
||||
* Remote animation runner for animation to launch an app.
|
||||
*/
|
||||
private class SplitLaunchAnimationRunner implements RemoteAnimationFactory {
|
||||
private class RemoteSplitLaunchAnimationRunner implements RemoteAnimationRunnerCompat {
|
||||
|
||||
private final TaskView mV;
|
||||
private final int mTargetState;
|
||||
private final TaskView mInitialTaskView;
|
||||
private final TaskView mTaskView;
|
||||
|
||||
SplitLaunchAnimationRunner(TaskView v, int targetState) {
|
||||
mV = v;
|
||||
mTargetState = targetState;
|
||||
RemoteSplitLaunchAnimationRunner(TaskView initialTaskView, TaskView taskView) {
|
||||
mInitialTaskView = initialTaskView;
|
||||
mTaskView = taskView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateAnimation(int transit,
|
||||
RemoteAnimationTargetCompat[] appTargets,
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
RemoteAnimationTargetCompat[] nonAppTargets,
|
||||
LauncherAnimationRunner.AnimationResult result) {
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
BaseQuickstepLauncher activity = BaseActivity.fromContext(mV.getContext());
|
||||
TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(anim, mV,
|
||||
appTargets, wallpaperTargets, nonAppTargets, true, activity.getStateManager(),
|
||||
activity.getDepthController(), mTargetState);
|
||||
result.setAnimation(anim, activity);
|
||||
public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps,
|
||||
RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
|
||||
Runnable finishedCallback) {
|
||||
TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTaskView, mTaskView, apps,
|
||||
wallpapers, nonApps, finishedCallback);
|
||||
// After successful launch, call resetState
|
||||
resetState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancelled() {
|
||||
resetState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* To be called if split select was cancelled
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user