Merge "Fixed some bugs with main/side stage splits"
This commit is contained in:
committed by
Android (Google) Code Review
commit
2a9e1e73ac
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user