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

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

Do not evict starting task when startShortcut

Split screen evicts the original pairing task after drag-n-drop a
shortcut into split. Launching a shortcut into the same task, it'll
dismiss the split due to one side of the split being empty.

This CL evicts the non-opening child tasks only to pevent one side of
the split being empty.

Bug: 235027308
Test: 1. Launch App1 and drag Settings' shortcut (Wi-Fi) to split
      2. Launch Settings' shortcut (Data usage) to split screen
Change-Id: I9f6ea82759a7f73f6f7f4b2617dd7b5dbb9eeb38
parent 22430618
Loading
Loading
Loading
Loading
+28 −6
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;

import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
@@ -46,6 +47,7 @@ import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
@@ -334,17 +336,37 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,

    public void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
            @Nullable Bundle options, UserHandle user) {
        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);
                }
                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 */);
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        mStageCoordinator.prepareEvictChildTasks(position, evictWct);
        RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(wrapper,
                0 /* duration */, 0 /* statusBarTransitionDelay */);
        ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
        activityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));

        try {
            LauncherApps launcherApps =
                    mContext.getSystemService(LauncherApps.class);
            LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
            launcherApps.startShortcut(packageName, shortcutId, null /* sourceBounds */,
                    options, user);
            mSyncQueue.queue(evictWct);
                    activityOptions.toBundle(), user);
        } catch (ActivityNotFoundException e) {
            Slog.e(TAG, "Failed to launch shortcut", e);
        }
+9 −0
Original line number Diff line number Diff line
@@ -617,6 +617,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }
    }

    void prepareEvictNonOpeningChildTasks(@SplitPosition int position, RemoteAnimationTarget[] apps,
            WindowContainerTransaction wct) {
        if (position == mSideStagePosition) {
            mSideStage.evictNonOpeningChildren(apps, wct);
        } else {
            mMainStage.evictNonOpeningChildren(apps, wct);
        }
    }

    void prepareEvictInvisibleChildTasks(WindowContainerTransaction wct) {
        mMainStage.evictInvisibleChildren(wct);
        mSideStage.evictInvisibleChildren(wct);
+15 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.RemoteAnimationTarget.MODE_OPENING;

import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE;
@@ -33,6 +34,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.util.SparseArray;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.window.WindowContainerToken;
@@ -334,6 +336,19 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        }
    }

    void evictNonOpeningChildren(RemoteAnimationTarget[] apps, WindowContainerTransaction wct) {
        final SparseArray<ActivityManager.RunningTaskInfo> toBeEvict = mChildrenTaskInfo.clone();
        for (int i = 0; i < apps.length; i++) {
            if (apps[i].mode == MODE_OPENING) {
                toBeEvict.remove(apps[i].taskId);
            }
        }
        for (int i = toBeEvict.size() - 1; i >= 0; i--) {
            final ActivityManager.RunningTaskInfo taskInfo = toBeEvict.valueAt(i);
            wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
        }
    }

    void evictInvisibleChildren(WindowContainerTransaction wct) {
        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
            final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);