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

This commit is contained in:
Wale Ogunwale
2021-01-25 23:46:26 +00:00
committed by Android (Google) Code Review
6 changed files with 52 additions and 50 deletions

View File

@@ -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;

View File

@@ -42,7 +42,9 @@ public class WindowOrganizer {
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
public void applyTransaction(@NonNull WindowContainerTransaction t) {
try {
getWindowOrganizerController().applyTransaction(t);
if (!t.isEmpty()) {
getWindowOrganizerController().applyTransaction(t);
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

View File

@@ -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 */);
}

View File

@@ -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;
}
}

View File

@@ -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 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);
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();
// Make sure the main stage is active.
mMainStage.activate(getMainStageBounds(), 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

View File

@@ -2522,6 +2522,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
final ActivityOptions activityOptions = options != null
? options.getOptions(this)
: null;
boolean moveHomeTaskForward = true;
if (activityOptions != null) {
activityType = activityOptions.getLaunchActivityType();
windowingMode = activityOptions.getLaunchWindowingMode();
@@ -2529,6 +2530,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
&& mRecentTasks.isCallerRecents(callingUid)) {
mRecentTasks.setFreezeTaskListReordering();
}
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
|| activityOptions.getLaunchRootTask() != null) {
// Don't move home activity forward if we are launching into primary split or there
// is a launch root set.
moveHomeTaskForward = false;
}
}
if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) {
throw new IllegalArgumentException("startActivityFromRecents: Task "
@@ -2545,7 +2552,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
"startActivityFromRecents: Task " + taskId + " not found.");
}
if (windowingMode != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
if (moveHomeTaskForward) {
// We always want to return to the home activity instead of the recents activity
// from whatever is started from the recents activity, so move the home stack
// forward.