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

Commit 2a9e1e73 authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Android (Google) Code Review
Browse files

Merge "Fixed some bugs with main/side stage splits"

parents 413a382b f84a471b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -360,6 +360,11 @@ public final class WindowContainerTransaction implements Parcelable {
        }
    }

    /** @hide */
    public boolean isEmpty() {
        return mChanges.isEmpty() && mHierarchyOps.isEmpty();
    }

    /** @hide */
    public Map<IBinder, Change> getChanges() {
        return mChanges;
+3 −1
Original line number Diff line number Diff line
@@ -42,7 +42,9 @@ public class WindowOrganizer {
    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
    public void applyTransaction(@NonNull WindowContainerTransaction t) {
        try {
            if (!t.isEmpty()) {
                getWindowOrganizerController().applyTransaction(t);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+10 −6
Original line number Diff line number Diff line
@@ -51,8 +51,7 @@ class MainStage extends StageTaskListener {
        if (mIsActive) return;

        final WindowContainerToken rootToken = mRootTaskInfo.token;
        wct.setHidden(rootToken, false)
                .setBounds(rootToken, rootBounds)
        wct.setBounds(rootToken, rootBounds)
                .setLaunchRoot(
                        rootToken,
                        CONTROLLED_WINDOWING_MODES,
@@ -63,7 +62,7 @@ class MainStage extends StageTaskListener {
                        CONTROLLED_WINDOWING_MODES,
                        CONTROLLED_ACTIVITY_TYPES,
                        true /* onTop */)
                // Moving the root task to top after the child tasks were repareted , or the root
                // Moving the root task to top after the child tasks were re-parented , or the root
                // task cannot be visible and focused.
                .reorder(rootToken, true /* onTop */);

@@ -71,13 +70,16 @@ class MainStage extends StageTaskListener {
    }

    void deactivate(WindowContainerTransaction wct) {
        deactivate(wct, false /* toTop */);
    }

    void deactivate(WindowContainerTransaction wct, boolean toTop) {
        if (!mIsActive) return;
        mIsActive = false;

        if (mRootTaskInfo == null) return;
        final WindowContainerToken rootToken = mRootTaskInfo.token;
        wct.setHidden(rootToken, true)
                .setLaunchRoot(
        wct.setLaunchRoot(
                        rootToken,
                        null,
                        null)
@@ -86,7 +88,9 @@ class MainStage extends StageTaskListener {
                        null /* newParent */,
                        CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
                        CONTROLLED_ACTIVITY_TYPES,
                        false /* onTop */)
                        toTop)
                // We want this re-order to the bottom regardless since we are re-parenting
                // all its tasks.
                .reorder(rootToken, false /* onTop */);
    }

+2 −12
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.wm.shell.splitscreen;

import static android.app.ActivityTaskManager.INVALID_TASK_ID;

import android.app.ActivityManager;
import android.graphics.Rect;
import android.window.WindowContainerToken;
@@ -50,14 +48,14 @@ class SideStage extends StageTaskListener {
                .reorder(rootToken, true);
    }

    boolean removeAllTasks(WindowContainerTransaction wct) {
    boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
        if (mChildrenTaskInfo.size() == 0) return false;
        wct.reparentTasks(
                mRootTaskInfo.token,
                null /* newParent */,
                CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE,
                CONTROLLED_ACTIVITY_TYPES,
                false /* onTop */);
                toTop);
        return true;
    }

@@ -70,12 +68,4 @@ class SideStage extends StageTaskListener {
                .reparent(task.token, newParent, false /* onTop */);
        return true;
    }

    int getTopVisibleTaskId() {
        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
            final ActivityManager.RunningTaskInfo task = mChildrenTaskInfo.valueAt(i);
            if (task.isVisible) return task.taskId;
        }
        return INVALID_TASK_ID;
    }
}
+24 −30
Original line number Diff line number Diff line
@@ -146,10 +146,16 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
    }

    void exitSplitScreen() {
        exitSplitScreen(null /* childrenToTop */);
    }

    private void exitSplitScreen(StageTaskListener childrenToTop) {
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        mSideStage.removeAllTasks(wct);
        mMainStage.deactivate(wct);
        mSideStage.removeAllTasks(wct, childrenToTop == mSideStage);
        mMainStage.deactivate(wct, childrenToTop == mMainStage);
        mTaskOrganizer.applyTransaction(wct);
        // Reset divider position.
        mSplitLayout.resetDividerPosition();
    }

    void getStageBounds(Rect outTopOrLeftBounds, Rect outBottomOrRightBounds) {
@@ -272,41 +278,29 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
    }

    private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
        if (stageListener == mSideStageListener) {
        final boolean hasChildren = stageListener.mHasChildren;
        final boolean isSideStage = stageListener == mSideStageListener;
        if (!hasChildren) {
            if (isSideStage && mMainStageListener.mVisible) {
                // Exit to main stage if side stage no longer has children.
                exitSplitScreen(mMainStage);
            } else if (!isSideStage && mSideStageListener.mVisible) {
                // Exit to side stage if main stage no longer has children.
                exitSplitScreen(mSideStage);
            }
        } else if (isSideStage) {
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            if (mSideStageListener.mHasChildren) {
            // Make sure the main stage is active.
            mMainStage.activate(getMainStageBounds(), wct);
            } else {
                // The side stage no long has children so we can deactivate the main stage.
                mMainStage.deactivate(wct);
            }
            mTaskOrganizer.applyTransaction(wct);
        }
    }

    @Override
    public void onSnappedToDismiss(boolean bottomOrRight) {
        if (mSideStagePosition == SIDE_STAGE_POSITION_BOTTOM_OR_RIGHT && bottomOrRight) {
            // Main stage was fully expanded...Just side side-stage.
            setSideStageVisibility(false);
        } else {
            // Side stage was fully expanded...Move its top task to the main stage
            // and hide side-stage.
            // TODO: Would UX prefer the side-stage go into fullscreen mode here?
            final int taskId = mSideStage.getTopVisibleTaskId();
            if (taskId == INVALID_TASK_ID) {
                throw new IllegalStateException("Side stage doesn't have visible task? "
                        + mSideStage);
            }
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            mSideStage.removeTask(taskId, mMainStage.mRootTaskInfo.getToken(), wct);
            mSideStage.setVisibility(false, wct);
            mTaskOrganizer.applyTransaction(wct);
        }

        // Reset divider position.
        mSplitLayout.resetDividerPosition();
        final boolean mainStageToTop = bottomOrRight
                && mSideStagePosition == SIDE_STAGE_POSITION_BOTTOM_OR_RIGHT;
        exitSplitScreen(mainStageToTop ? mMainStage : mSideStage);
    }

    @Override
Loading