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

Commit d0cda70d authored by Jerry Chang's avatar Jerry Chang
Browse files

Fix drop to enter split not working

Sometimes when dropping app icon to enter split screen, it'll exit split
screen immediatlly because it evicts newly launched task before the task
considered to be visible. Update to collect child tasks to evict before
launching activity.

Fix: 203610931
Fix: 203636251
Test: atest WMShellUnitTests
Change-Id: If070fb5b3eb0b3fc178122d38b2dce3072621449
parent 430944ce
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -215,10 +215,12 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */);

        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) {
                mStageCoordinator.evictOccludedChildren(position);
                mSyncQueue.queue(evictWct);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to launch task", e);
@@ -229,13 +231,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
            @SplitScreen.StageType int stage, @SplitPosition int position,
            @Nullable Bundle options, UserHandle user) {
        options = mStageCoordinator.resolveStartStage(stage, position, options, null /* wct */);
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        mStageCoordinator.prepareEvictChildTasks(position, evictWct);

        try {
            LauncherApps launcherApps =
                    mContext.getSystemService(LauncherApps.class);
            launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
                    options, user);
            mStageCoordinator.evictOccludedChildren(position);
            mSyncQueue.queue(evictWct);
        } catch (ActivityNotFoundException e) {
            Slog.e(TAG, "Failed to launch shortcut", e);
        }
@@ -255,6 +259,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    private void startIntentLegacy(PendingIntent intent, Intent fillInIntent,
            @SplitScreen.StageType int stage, @SplitPosition int position,
            @Nullable Bundle options) {
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        mStageCoordinator.prepareEvictChildTasks(position, evictWct);

        LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
            @Override
            public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
@@ -280,12 +287,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
                    }
                }

                // Launching a new app into a specific split evicts tasks previously in the same
                // split.
                mStageCoordinator.evictOccludedChildren(position);
                mSyncQueue.queue(evictWct);
            }
        };
        WindowContainerTransaction wct = new WindowContainerTransaction();

        final WindowContainerTransaction wct = new WindowContainerTransaction();
        options = mStageCoordinator.resolveStartStage(stage, position, options, wct);
        wct.sendPendingIntent(intent, fillInIntent, options);
        mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
+10 −4
Original line number Diff line number Diff line
@@ -394,10 +394,16 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct, remoteTransition, this);
    }

    void evictOccludedChildren(@SplitPosition int position) {
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        (position == mSideStagePosition ? mSideStage : mMainStage).evictOccludedChildren(wct);
        mTaskOrganizer.applyTransaction(wct);
    /**
     * Collects all the current child tasks of a specific split and prepares transaction to evict
     * them to display.
     */
    void prepareEvictChildTasks(@SplitPosition int position, WindowContainerTransaction wct) {
        if (position == mSideStagePosition) {
            mSideStage.evictAllChildren(wct);
        } else {
            mMainStage.evictAllChildren(wct);
        }
    }

    Bundle resolveStartStage(@SplitScreen.StageType int stage,
+3 −4
Original line number Diff line number Diff line
@@ -248,14 +248,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
    }

    void evictOccludedChildren(WindowContainerTransaction wct) {
    /** Collects all the current child tasks and prepares transaction to evict them to display. */
    void evictAllChildren(WindowContainerTransaction wct) {
        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
            final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
            if (!taskInfo.isVisible) {
            wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
        }
    }
    }

    void setVisibility(boolean visible, WindowContainerTransaction wct) {
        wct.reorder(mRootTaskInfo.token, visible /* onTop */);
+28 −6
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import static android.view.Display.DEFAULT_DISPLAY;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
@@ -31,6 +33,7 @@ import android.app.ActivityManager;
import android.os.SystemProperties;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.WindowContainerTransaction;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -58,11 +61,16 @@ public final class StageTaskListenerTests {
    private static final boolean ENABLE_SHELL_TRANSITIONS =
            SystemProperties.getBoolean("persist.debug.shell_transit", false);

    @Mock private ShellTaskOrganizer mTaskOrganizer;
    @Mock private StageTaskListener.StageListenerCallbacks mCallbacks;
    @Mock private SyncTransactionQueue mSyncQueue;
    @Mock private StageTaskUnfoldController mStageTaskUnfoldController;
    @Captor private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
    @Mock
    private ShellTaskOrganizer mTaskOrganizer;
    @Mock
    private StageTaskListener.StageListenerCallbacks mCallbacks;
    @Mock
    private SyncTransactionQueue mSyncQueue;
    @Mock
    private StageTaskUnfoldController mStageTaskUnfoldController;
    @Captor
    private ArgumentCaptor<SyncTransactionQueue.TransactionRunnable> mRunnableCaptor;
    private SurfaceSession mSurfaceSession = new SurfaceSession();
    private SurfaceControl mSurfaceControl;
    private ActivityManager.RunningTaskInfo mRootTask;
@@ -167,4 +175,18 @@ public final class StageTaskListenerTests {
        mStageTaskListener.onTaskInfoChanged(childTask);
        verify(mCallbacks).onNoLongerSupportMultiWindow();
    }

    @Test
    public void testEvictAllChildren() {
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        mStageTaskListener.evictAllChildren(wct);
        assertTrue(wct.isEmpty());

        final ActivityManager.RunningTaskInfo childTask =
                new TestRunningTaskInfoBuilder().setParentTaskId(mRootTask.taskId).build();
        mStageTaskListener.onTaskAppeared(childTask, mSurfaceControl);

        mStageTaskListener.evictAllChildren(wct);
        assertFalse(wct.isEmpty());
    }
}