Merge "Update split screen interface to indicate dismissing to top task" into sc-v2-dev am: 2d113fb2a3

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

Change-Id: I2e405515ad7e4db62fa67a2c63e2b486895f9e05
This commit is contained in:
Vinit Nayak
2021-09-09 20:36:42 +00:00
committed by Automerger Merge Worker
6 changed files with 77 additions and 15 deletions

View File

@@ -304,7 +304,7 @@ public class DragAndDropPolicy {
* Exits splitscreen, with an associated exit trigger from the SplitscreenUIChanged proto
* for logging.
*/
void exitSplitScreen(int exitTrigger);
void exitSplitScreen(int toTopTaskId, int exitTrigger);
}
/**
@@ -357,7 +357,7 @@ public class DragAndDropPolicy {
}
@Override
public void exitSplitScreen(int exitTrigger) {
public void exitSplitScreen(int toTopTaskId, int exitTrigger) {
throw new UnsupportedOperationException("exitSplitScreen not implemented by starter");
}
}

View File

@@ -52,9 +52,10 @@ interface ISplitScreen {
oneway void removeFromSideStage(int taskId) = 4;
/**
* Removes the split-screen stages.
* Removes the split-screen stages and leaving indicated task to top. Passing INVALID_TASK_ID
* to indicate leaving no top task after leaving split-screen.
*/
oneway void exitSplitScreen() = 5;
oneway void exitSplitScreen(int toTopTaskId) = 5;
/**
* @param exitSplitScreenOnHide if to exit split-screen if both stages are not visible.

View File

@@ -173,8 +173,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
}
public void exitSplitScreen(int exitReason) {
mStageCoordinator.exitSplitScreen(exitReason);
public void exitSplitScreen(int toTopTaskId, int exitReason) {
mStageCoordinator.exitSplitScreen(toTopTaskId, exitReason);
}
public void onKeyguardOccludedChanged(boolean occluded) {
@@ -499,11 +499,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
}
@Override
public void exitSplitScreen() {
public void exitSplitScreen(int toTopTaskId) {
executeRemoteCallWithTaskPermission(mController, "exitSplitScreen",
(controller) -> {
controller.exitSplitScreen(
FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
controller.exitSplitScreen(toTopTaskId,
FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__UNKNOWN_EXIT);
});
}

View File

@@ -472,16 +472,32 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
}
void exitSplitScreen(int exitReason) {
exitSplitScreen(null /* childrenToTop */, exitReason);
}
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
mExitSplitScreenOnHide = exitSplitScreenOnHide;
}
void exitSplitScreen(int toTopTaskId, int exitReason) {
StageTaskListener childrenToTop = null;
if (mMainStage.containsTask(toTopTaskId)) {
childrenToTop = mMainStage;
} else if (mSideStage.containsTask(toTopTaskId)) {
childrenToTop = mSideStage;
}
final WindowContainerTransaction wct = new WindowContainerTransaction();
if (childrenToTop != null) {
childrenToTop.reorderChild(toTopTaskId, true /* onTop */, wct);
}
applyExitSplitScreen(childrenToTop, wct, exitReason);
}
private void exitSplitScreen(StageTaskListener childrenToTop, int exitReason) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
applyExitSplitScreen(childrenToTop, wct, exitReason);
}
private void applyExitSplitScreen(StageTaskListener childrenToTop,
WindowContainerTransaction wct, int exitReason) {
mSideStage.removeAllTasks(wct, childrenToTop == mSideStage);
mMainStage.deactivate(wct, childrenToTop == mMainStage);
mTaskOrganizer.applyTransaction(wct);
@@ -627,7 +643,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Don't dismiss staged split when both stages are not visible due to sleeping display,
// like the cases keyguard showing or screen off.
|| (!mMainStage.mRootTaskInfo.isSleeping && !mSideStage.mRootTaskInfo.isSleeping)) {
exitSplitScreen(SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
exitSplitScreen(null /* childrenToTop */,
SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
}
} else if (mKeyguardOccluded) {
// At least one of the stages is visible while keyguard occluded. Dismiss split because
@@ -1249,7 +1266,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override
public void onNoLongerSupportMultiWindow() {
if (mMainStage.isActive()) {
StageCoordinator.this.exitSplitScreen(
StageCoordinator.this.exitSplitScreen(null /* childrenToTop */,
SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW);
}
}

View File

@@ -224,6 +224,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
wct.setBounds(mRootTaskInfo.token, bounds);
}
void reorderChild(int taskId, boolean onTop, WindowContainerTransaction wct) {
if (!containsTask(taskId)) {
return;
}
wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
}
void setVisibility(boolean visible, WindowContainerTransaction wct) {
wct.reorder(mRootTaskInfo.token, visible /* onTop */);
}

View File

@@ -16,14 +16,17 @@
package com.android.wm.shell.splitscreen;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME;
import static com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.graphics.Rect;
@@ -94,4 +97,38 @@ public class StageCoordinatorTests extends ShellTestCase {
verify(mSideStage).removeTask(
eq(task.taskId), any(), any(WindowContainerTransaction.class));
}
@Test
public void testExitSplitScreen() {
mStageCoordinator.exitSplitScreen(INVALID_TASK_ID,
SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(false));
verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
}
@Test
public void testExitSplitScreenToMainStage() {
final int testTaskId = 12345;
when(mMainStage.containsTask(eq(testTaskId))).thenReturn(true);
when(mSideStage.containsTask(eq(testTaskId))).thenReturn(false);
mStageCoordinator.exitSplitScreen(testTaskId,
SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
verify(mMainStage).reorderChild(eq(testTaskId), eq(true),
any(WindowContainerTransaction.class));
verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(false));
verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(true));
}
@Test
public void testExitSplitScreenToSideStage() {
final int testTaskId = 12345;
when(mMainStage.containsTask(eq(testTaskId))).thenReturn(false);
when(mSideStage.containsTask(eq(testTaskId))).thenReturn(true);
mStageCoordinator.exitSplitScreen(testTaskId,
SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME);
verify(mSideStage).reorderChild(eq(testTaskId), eq(true),
any(WindowContainerTransaction.class));
verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(true));
verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
}
}