Exit split-screen if one of the splits is empty

Unusual use cases result in the split being empty.The case happens if
the intent is the same app but not support multi-instance, we should
exit split and expand that app as full screen.

Moreover, apply the same evicts logic from startShortCut to startTask
on this CL.

Bug: 235193477
Test: Launch Google calendar and drag the app to split screen
Change-Id: I1081aaa8303a551f140668c953cd2fd7c4dd3c54
This commit is contained in:
Jeff Chang
2022-08-04 15:02:17 +08:00
parent effcf27740
commit 9236649034
2 changed files with 40 additions and 12 deletions

View File

@@ -337,17 +337,39 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
public void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
final int[] result = new int[1];
IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
@Override
public void onAnimationStart(@WindowManager.TransitionOldType int transit,
RemoteAnimationTarget[] apps,
RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps,
final IRemoteAnimationFinishedCallback finishedCallback) {
try {
finishedCallback.onAnimationFinished();
} catch (RemoteException e) {
Slog.e(TAG, "Failed to invoke onAnimationFinished", e);
}
if (result[0] == START_SUCCESS || result[0] == START_TASK_TO_FRONT) {
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
mStageCoordinator.prepareEvictNonOpeningChildTasks(position, apps, evictWct);
mSyncQueue.queue(evictWct);
}
}
@Override
public void onAnimationCancelled(boolean isKeyguardOccluded) {
}
};
options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
null /* wct */);
RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper,
0 /* duration */, 0 /* statusBarTransitionDelay */);
ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
try {
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
mStageCoordinator.prepareEvictChildTasks(position, evictWct);
final int result =
ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
if (result == START_SUCCESS || result == START_TASK_TO_FRONT) {
mSyncQueue.queue(evictWct);
}
result[0] = ActivityTaskManager.getService().startActivityFromRecents(taskId,
activityOptions.toBundle());
} catch (RemoteException e) {
Slog.e(TAG, "Failed to launch task", e);
}

View File

@@ -451,10 +451,16 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
IRemoteAnimationFinishedCallback finishedCallback,
SurfaceControl.Transaction t) {
if (apps == null || apps.length == 0) {
// Switch the split position if launching as MULTIPLE_TASK failed.
if ((fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
setSideStagePosition(SplitLayout.reversePosition(
getSideStagePosition()), null);
if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
mMainExecutor.execute(() ->
exitSplitScreen(mMainStage.getChildCount() == 0
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
} else {
// Switch the split position if launching as MULTIPLE_TASK failed.
if ((fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
setSideStagePosition(SplitLayout.reversePosition(
getSideStagePosition()), null);
}
}
// Do nothing when the animation was cancelled.
@@ -650,7 +656,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mShouldUpdateRecents = true;
// If any stage has no child after animation finished, it means that split will display
// nothing, such status will happen if task and intent is same app but not support
// multi-instagce, we should exit split and expand that app as full screen.
// multi-instance, we should exit split and expand that app as full screen.
if (!cancel && (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
mMainExecutor.execute(() ->
exitSplitScreen(mMainStage.getChildCount() == 0