From 9236649034be568252d876869d9fa2060367be6d Mon Sep 17 00:00:00 2001 From: Jeff Chang Date: Thu, 4 Aug 2022 15:02:17 +0800 Subject: 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 --- .../shell/splitscreen/SplitScreenController.java | 36 +++++++++++++++++----- .../wm/shell/splitscreen/StageCoordinator.java | 16 +++++++--- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index de7e7bd1c506..5cbc3177256f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -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); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index f2340d531168..2a32b68b4009 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -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 -- cgit v1.2.3-59-g8ed1b