Fix transition animations for launch-from-staged operation

This change makes it so that a smoother animation will play when the user cancels the splitscreen flow by tapping the staged app to launch the app in fullscreen.

Previously, we did not support the launch of a solo app into fullscreen during the splitscreen flow. When this feature was implemented in ag/20432050, the fade-in animation would subtly fail (and the solo task would pop in with no animation at all) because the single-app animation case was not fully supported yet. This change adds a single-app-launch case in startTasksWithLegacyTransition() and startIntentAndTaskWithLegacyTransition(), allowing the animation to be applied in the same way as in the splitscreen case.

Fixes: 257513449
Test: Manual
Change-Id: Ieadf8cecf39d36d4252152ba55c6d9f84634281a
This commit is contained in:
Jeremy Sim
2022-12-29 16:34:33 -08:00
parent fa71876cc0
commit 65514324d9

View File

@@ -605,9 +605,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (options1 == null) options1 = new Bundle();
if (taskId2 == INVALID_TASK_ID) {
// Launching a solo task.
ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
options1 = activityOptions.toBundle();
addActivityOptions(options1, null /* launchTarget */);
wct.startTask(taskId1, options1);
mSyncQueue.queue(wct);
return;
}
addActivityOptions(options1, mSideStage);
wct.startTask(taskId1, options1);
startWithLegacyTransition(wct, taskId2, options2, splitPosition, splitRatio, adapter,
instanceId);
}
@@ -632,9 +642,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
InstanceId instanceId) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (options1 == null) options1 = new Bundle();
if (taskId == INVALID_TASK_ID) {
// Launching a solo task.
ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
options1 = activityOptions.toBundle();
addActivityOptions(options1, null /* launchTarget */);
wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
mSyncQueue.queue(wct);
return;
}
addActivityOptions(options1, mSideStage);
wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
startWithLegacyTransition(wct, taskId, options2, splitPosition, splitRatio, adapter,
instanceId);
}
@@ -696,6 +716,34 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mShouldUpdateRecents = false;
mIsSplitEntering = true;
setSideStagePosition(sidePosition, wct);
if (!mMainStage.isActive()) {
mMainStage.activate(wct, false /* reparent */);
}
if (mainOptions == null) mainOptions = new Bundle();
addActivityOptions(mainOptions, mMainStage);
mainOptions = wrapAsSplitRemoteAnimation(adapter, mainOptions);
updateWindowBounds(mSplitLayout, wct);
if (mainTaskId == INVALID_TASK_ID) {
wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions);
} else {
wct.startTask(mainTaskId, mainOptions);
}
wct.reorder(mRootTaskInfo.token, true);
wct.setForceTranslucent(mRootTaskInfo.token, false);
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {
setDividerVisibility(true, t);
});
setEnterInstanceId(instanceId);
}
private Bundle wrapAsSplitRemoteAnimation(RemoteAnimationAdapter adapter, Bundle options) {
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
if (isSplitScreenVisible()) {
mMainStage.evictAllChildren(evictWct);
@@ -739,37 +787,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
};
RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(
wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay());
if (mainOptions == null) {
mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle();
} else {
ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions);
mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
mainOptions = mainActivityOptions.toBundle();
}
setSideStagePosition(sidePosition, wct);
if (!mMainStage.isActive()) {
mMainStage.activate(wct, false /* reparent */);
}
if (mainOptions == null) mainOptions = new Bundle();
addActivityOptions(mainOptions, mMainStage);
updateWindowBounds(mSplitLayout, wct);
if (mainTaskId == INVALID_TASK_ID) {
wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, mainOptions);
} else {
wct.startTask(mainTaskId, mainOptions);
}
wct.reorder(mRootTaskInfo.token, true);
wct.setForceTranslucent(mRootTaskInfo.token, false);
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {
setDividerVisibility(true, t);
});
setEnterInstanceId(instanceId);
ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
return activityOptions.toBundle();
}
private void setEnterInstanceId(InstanceId instanceId) {
@@ -1228,8 +1248,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
return SPLIT_POSITION_UNDEFINED;
}
private void addActivityOptions(Bundle opts, StageTaskListener stage) {
opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, stage.mRootTaskInfo.token);
private void addActivityOptions(Bundle opts, @Nullable StageTaskListener launchTarget) {
if (launchTarget != null) {
opts.putParcelable(KEY_LAUNCH_ROOT_TASK_TOKEN, launchTarget.mRootTaskInfo.token);
}
// Put BAL flags to avoid activity start aborted. Otherwise, flows like shortcut to split
// will be canceled.
opts.putBoolean(KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED, true);