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

View File

@@ -52,9 +52,10 @@ interface ISplitScreen {
oneway void removeFromSideStage(int taskId) = 4; 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. * @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); leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT);
} }
public void exitSplitScreen(int exitReason) { public void exitSplitScreen(int toTopTaskId, int exitReason) {
mStageCoordinator.exitSplitScreen(exitReason); mStageCoordinator.exitSplitScreen(toTopTaskId, exitReason);
} }
public void onKeyguardOccludedChanged(boolean occluded) { public void onKeyguardOccludedChanged(boolean occluded) {
@@ -499,11 +499,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
} }
@Override @Override
public void exitSplitScreen() { public void exitSplitScreen(int toTopTaskId) {
executeRemoteCallWithTaskPermission(mController, "exitSplitScreen", executeRemoteCallWithTaskPermission(mController, "exitSplitScreen",
(controller) -> { (controller) -> {
controller.exitSplitScreen( controller.exitSplitScreen(toTopTaskId,
FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME); 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) { void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
mExitSplitScreenOnHide = 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) { private void exitSplitScreen(StageTaskListener childrenToTop, int exitReason) {
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
applyExitSplitScreen(childrenToTop, wct, exitReason);
}
private void applyExitSplitScreen(StageTaskListener childrenToTop,
WindowContainerTransaction wct, int exitReason) {
mSideStage.removeAllTasks(wct, childrenToTop == mSideStage); mSideStage.removeAllTasks(wct, childrenToTop == mSideStage);
mMainStage.deactivate(wct, childrenToTop == mMainStage); mMainStage.deactivate(wct, childrenToTop == mMainStage);
mTaskOrganizer.applyTransaction(wct); 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, // Don't dismiss staged split when both stages are not visible due to sleeping display,
// like the cases keyguard showing or screen off. // like the cases keyguard showing or screen off.
|| (!mMainStage.mRootTaskInfo.isSleeping && !mSideStage.mRootTaskInfo.isSleeping)) { || (!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) { } else if (mKeyguardOccluded) {
// At least one of the stages is visible while keyguard occluded. Dismiss split because // At least one of the stages is visible while keyguard occluded. Dismiss split because
@@ -1249,7 +1266,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Override @Override
public void onNoLongerSupportMultiWindow() { public void onNoLongerSupportMultiWindow() {
if (mMainStage.isActive()) { if (mMainStage.isActive()) {
StageCoordinator.this.exitSplitScreen( StageCoordinator.this.exitSplitScreen(null /* childrenToTop */,
SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW); 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); 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) { void setVisibility(boolean visible, WindowContainerTransaction wct) {
wct.reorder(mRootTaskInfo.token, visible /* onTop */); wct.reorder(mRootTaskInfo.token, visible /* onTop */);
} }

View File

@@ -16,14 +16,17 @@
package com.android.wm.shell.splitscreen; package com.android.wm.shell.splitscreen;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.view.Display.DEFAULT_DISPLAY; 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 com.android.wm.shell.common.split.SplitLayout.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.graphics.Rect; import android.graphics.Rect;
@@ -94,4 +97,38 @@ public class StageCoordinatorTests extends ShellTestCase {
verify(mSideStage).removeTask( verify(mSideStage).removeTask(
eq(task.taskId), any(), any(WindowContainerTransaction.class)); 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));
}
} }