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:
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user