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

Commit 4f590a93 authored by Jerry Chang's avatar Jerry Chang Committed by Automerger Merge Worker
Browse files

Merge "Support moving task to an activated split stage in a specific position"...

Merge "Support moving task to an activated split stage in a specific position" into sc-v2-dev am: dcab1387 am: 18827d25

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16279912

Change-Id: Idef77f54ad7fc3f983a3f6247e08dbba07590780
parents 80be8cc5 18827d25
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
@@ -61,6 +62,8 @@ import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;

import java.io.PrintWriter;

/**
 * Records and handles layout of splits. Helps to calculate proper bounds when configuration or
 * divide position changes.
@@ -415,6 +418,19 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        return bounds.width() > bounds.height();
    }

    /** Reverse the split position. */
    @SplitPosition
    public static int reversePosition(@SplitPosition int position) {
        switch (position) {
            case SPLIT_POSITION_TOP_OR_LEFT:
                return SPLIT_POSITION_BOTTOM_OR_RIGHT;
            case SPLIT_POSITION_BOTTOM_OR_RIGHT:
                return SPLIT_POSITION_TOP_OR_LEFT;
            default:
                return SPLIT_POSITION_UNDEFINED;
        }
    }

    /**
     * Return if this layout is landscape.
     */
@@ -502,6 +518,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        }
    }

    /** Dumps the current split bounds recorded in this layout. */
    public void dump(@NonNull PrintWriter pw, String prefix) {
        pw.println(prefix + "bounds1=" + mBounds1.toShortString());
        pw.println(prefix + "dividerBounds=" + mDividerBounds.toShortString());
        pw.println(prefix + "bounds2=" + mBounds2.toShortString());
    }

    /** Handles layout change event. */
    public interface SplitLayoutHandler {

+0 −4
Original line number Diff line number Diff line
@@ -50,10 +50,6 @@ class SideStage extends StageTaskListener {
        wct.setBounds(rootToken, rootBounds).reorder(rootToken, true /* onTop */);
    }

    void addTask(ActivityManager.RunningTaskInfo task, WindowContainerTransaction wct) {
        wct.reparent(task.token, mRootTaskInfo.token, true /* onTop*/);
    }

    boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
        // No matter if the root task is empty or not, moving the root to bottom because it no
        // longer preserves visible child task.
+12 −22
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;

import android.app.ActivityManager;
import android.app.ActivityTaskManager;
@@ -182,30 +184,17 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    }

    public boolean moveToSideStage(int taskId, @SplitPosition int sideStagePosition) {
        final ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
        if (task == null) {
            throw new IllegalArgumentException("Unknown taskId" + taskId);
        }
        return moveToSideStage(task, sideStagePosition);
        return moveToStage(taskId, STAGE_TYPE_SIDE, sideStagePosition,
                new WindowContainerTransaction());
    }

    public boolean moveToSideStage(int taskId, @SplitPosition int sideStagePosition,
            WindowContainerTransaction wct) {
    private boolean moveToStage(int taskId, @SplitScreen.StageType int stageType,
            @SplitPosition int stagePosition, WindowContainerTransaction wct) {
        final ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
        if (task == null) {
            throw new IllegalArgumentException("Unknown taskId" + taskId);
        }
        return moveToSideStage(task, sideStagePosition, wct);
    }

    public boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
            @SplitPosition int sideStagePosition) {
        return mStageCoordinator.moveToSideStage(task, sideStagePosition);
    }

    public boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
            @SplitPosition int sideStagePosition, WindowContainerTransaction wct) {
        return mStageCoordinator.moveToSideStage(task, sideStagePosition, wct);
        return mStageCoordinator.moveToStage(task, stageType, stagePosition, wct);
    }

    public boolean removeFromSideStage(int taskId) {
@@ -221,13 +210,14 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    }

    public void enterSplitScreen(int taskId, boolean leftOrTop) {
        moveToSideStage(taskId,
                leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
        enterSplitScreen(taskId, leftOrTop, new WindowContainerTransaction());
    }

    public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) {
        moveToSideStage(taskId,
                leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
        final int stageType = isSplitScreenVisible() ? STAGE_TYPE_UNDEFINED : STAGE_TYPE_SIDE;
        final int stagePosition =
                leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT;
        moveToStage(taskId, stageType, stagePosition, wct);
    }

    public void exitSplitScreen(int toTopTaskId, @ExitReason int exitReason) {
+32 −18
Original line number Diff line number Diff line
@@ -273,18 +273,31 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        return mSideStageListener.mVisible && mMainStageListener.mVisible;
    }

    boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
            @SplitPosition int sideStagePosition) {
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        return moveToSideStage(task, sideStagePosition, wct);
    boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitScreen.StageType int stageType,
            @SplitPosition int stagePosition, WindowContainerTransaction wct) {
        StageTaskListener targetStage;
        int sideStagePosition;
        if (stageType == STAGE_TYPE_MAIN) {
            targetStage = mMainStage;
            sideStagePosition = SplitLayout.reversePosition(stagePosition);
        } else if (stageType == STAGE_TYPE_SIDE) {
            targetStage = mSideStage;
            sideStagePosition = stagePosition;
        } else {
            if (mMainStage.isActive()) {
                // If the split screen is activated, retrieves target stage based on position.
                targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
                sideStagePosition = mSideStagePosition;
            } else {
                targetStage = mSideStage;
                sideStagePosition = stagePosition;
            }
        }

    boolean moveToSideStage(ActivityManager.RunningTaskInfo task,
            @SplitPosition int sideStagePosition, WindowContainerTransaction wct) {
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        setSideStagePosition(sideStagePosition, wct);
        mSideStage.evictAllChildren(evictWct);
        mSideStage.addTask(task, wct);
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        targetStage.evictAllChildren(evictWct);
        targetStage.addTask(task, wct);
        if (!evictWct.isEmpty()) {
            wct.merge(evictWct, true /* transfer */);
        }
@@ -463,9 +476,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            case STAGE_TYPE_MAIN: {
                if (position != SPLIT_POSITION_UNDEFINED) {
                    // Set the side stage opposite of what we want to the main stage.
                    final int sideStagePosition = position == SPLIT_POSITION_TOP_OR_LEFT
                            ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT;
                    setSideStagePosition(sideStagePosition, wct);
                    setSideStagePosition(SplitLayout.reversePosition(position), wct);
                } else {
                    position = getMainStagePosition();
                }
@@ -489,8 +500,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    @SplitLayout.SplitPosition
    int getMainStagePosition() {
        return mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
                ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT;
        return SplitLayout.reversePosition(mSideStagePosition);
    }

    void setSideStagePosition(@SplitPosition int sideStagePosition,
@@ -870,8 +880,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    @Override
    public void onDoubleTappedDivider() {
        setSideStagePosition(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT
                ? SPLIT_POSITION_BOTTOM_OR_RIGHT : SPLIT_POSITION_TOP_OR_LEFT, null /* wct */);
        setSideStagePosition(SplitLayout.reversePosition(mSideStagePosition), null /* wct */);
        mLogger.logSwap(getMainStagePosition(), mMainStage.getTopChildTaskUid(),
                getSideStagePosition(), mSideStage.getTopChildTaskUid(),
                mSplitLayout.isLandscape());
@@ -1296,11 +1305,16 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        pw.println(prefix + TAG + " mDisplayId=" + mDisplayId);
        pw.println(innerPrefix + "mDividerVisible=" + mDividerVisible);
        pw.println(innerPrefix + "MainStage");
        pw.println(childPrefix + "stagePosition=" + getMainStagePosition());
        pw.println(childPrefix + "isActive=" + mMainStage.isActive());
        mMainStageListener.dump(pw, childPrefix);
        pw.println(innerPrefix + "SideStage");
        pw.println(childPrefix + "stagePosition=" + getSideStagePosition());
        mSideStageListener.dump(pw, childPrefix);
        pw.println(innerPrefix + "mSplitLayout=" + mSplitLayout);
        if (mMainStage.isActive()) {
            pw.println(innerPrefix + "SplitLayout");
            mSplitLayout.dump(pw, childPrefix);
        }
    }

    /**
+4 −0
Original line number Diff line number Diff line
@@ -293,6 +293,10 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
        }
    }

    void addTask(ActivityManager.RunningTaskInfo task, WindowContainerTransaction wct) {
        wct.reparent(task.token, mRootTaskInfo.token, true /* onTop*/);
    }

    void setBounds(Rect bounds, WindowContainerTransaction wct) {
        wct.setBounds(mRootTaskInfo.token, bounds);
    }
Loading