Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92366490 authored by Jeff Chang's avatar Jeff Chang
Browse files

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
parent effcf277
Loading
Loading
Loading
Loading
+29 −7
Original line number Diff line number Diff line
@@ -337,17 +337,39 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    }

    public void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
        options = mStageCoordinator.resolveStartStage(STAGE_TYPE_UNDEFINED, position, options,
                null /* wct */);

        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.prepareEvictChildTasks(position, evictWct);
            final int result =
                    ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
            if (result == START_SUCCESS || result == START_TASK_TO_FRONT) {
                    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 {
            result[0] = ActivityTaskManager.getService().startActivityFromRecents(taskId,
                    activityOptions.toBundle());
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to launch task", e);
        }
+11 −5
Original line number Diff line number Diff line
@@ -451,11 +451,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                    IRemoteAnimationFinishedCallback finishedCallback,
                    SurfaceControl.Transaction t) {
                if (apps == null || apps.length == 0) {
                    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.
                    t.apply();
@@ -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