Merge changes Id75611af,I1ead6501 into tm-qpr-dev
* changes: Support back to split Support back gesture to split pair in background
This commit is contained in:
@@ -240,7 +240,7 @@ public class DragAndDropPolicy {
|
||||
// Update launch options for the split side we are targeting.
|
||||
position = leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
// Add some data for logging splitscreen once it is invoked
|
||||
mSplitScreen.logOnDroppedToSplit(position, mLoggerSessionId);
|
||||
mSplitScreen.onDroppedToSplit(position, mLoggerSessionId);
|
||||
}
|
||||
|
||||
final ClipDescription description = data.getDescription();
|
||||
|
||||
@@ -16,9 +16,6 @@
|
||||
|
||||
package com.android.wm.shell.splitscreen;
|
||||
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.SurfaceSession;
|
||||
import android.window.WindowContainerToken;
|
||||
@@ -34,8 +31,6 @@ import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
* @see StageCoordinator
|
||||
*/
|
||||
class MainStage extends StageTaskListener {
|
||||
private static final String TAG = MainStage.class.getSimpleName();
|
||||
|
||||
private boolean mIsActive = false;
|
||||
|
||||
MainStage(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
|
||||
@@ -52,15 +47,8 @@ class MainStage extends StageTaskListener {
|
||||
void activate(WindowContainerTransaction wct, boolean includingTopTask) {
|
||||
if (mIsActive) return;
|
||||
|
||||
final WindowContainerToken rootToken = mRootTaskInfo.token;
|
||||
if (includingTopTask) {
|
||||
wct.reparentTasks(
|
||||
null /* currentParent */,
|
||||
rootToken,
|
||||
CONTROLLED_WINDOWING_MODES,
|
||||
CONTROLLED_ACTIVITY_TYPES,
|
||||
true /* onTop */,
|
||||
true /* reparentTopOnly */);
|
||||
reparentTopTask(wct);
|
||||
}
|
||||
|
||||
mIsActive = true;
|
||||
|
||||
@@ -121,7 +121,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
public static final int EXIT_REASON_SCREEN_LOCKED = 7;
|
||||
public static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
|
||||
public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9;
|
||||
public static final int EXIT_REASON_FULLSCREEN_SHORTCUT = 10;
|
||||
public static final int EXIT_REASON_RECREATE_SPLIT = 10;
|
||||
public static final int EXIT_REASON_FULLSCREEN_SHORTCUT = 11;
|
||||
@IntDef(value = {
|
||||
EXIT_REASON_UNKNOWN,
|
||||
EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW,
|
||||
@@ -133,6 +134,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
EXIT_REASON_SCREEN_LOCKED,
|
||||
EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP,
|
||||
EXIT_REASON_CHILD_TASK_ENTER_PIP,
|
||||
EXIT_REASON_RECREATE_SPLIT,
|
||||
EXIT_REASON_FULLSCREEN_SHORTCUT,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@@ -470,7 +472,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
*/
|
||||
public void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
|
||||
@Nullable Bundle options, UserHandle user, @NonNull InstanceId instanceId) {
|
||||
mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER);
|
||||
mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER);
|
||||
startShortcut(packageName, shortcutId, position, options, user);
|
||||
}
|
||||
|
||||
@@ -518,7 +520,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
*/
|
||||
public void startIntent(PendingIntent intent, @Nullable Intent fillInIntent,
|
||||
@SplitPosition int position, @Nullable Bundle options, @NonNull InstanceId instanceId) {
|
||||
mStageCoordinator.getLogger().enterRequested(instanceId, ENTER_REASON_LAUNCHER);
|
||||
mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER);
|
||||
startIntent(intent, fillInIntent, position, options);
|
||||
}
|
||||
|
||||
@@ -784,10 +786,10 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
return splitTasksLayer;
|
||||
}
|
||||
/**
|
||||
* Sets drag info to be logged when splitscreen is entered.
|
||||
* Drop callback when splitscreen is entered.
|
||||
*/
|
||||
public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
|
||||
mStageCoordinator.logOnDroppedToSplit(position, dragSessionId);
|
||||
public void onDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
|
||||
mStageCoordinator.onDroppedToSplit(position, dragSessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -815,6 +817,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
return "APP_DOES_NOT_SUPPORT_MULTIWINDOW";
|
||||
case EXIT_REASON_CHILD_TASK_ENTER_PIP:
|
||||
return "CHILD_TASK_ENTER_PIP";
|
||||
case EXIT_REASON_RECREATE_SPLIT:
|
||||
return "RECREATE_SPLIT";
|
||||
default:
|
||||
return "unknown reason, reason int = " + exitReason;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,11 @@ import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED_
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__ENTER_REASON__UNKNOWN_ENTER;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_DOES_NOT_SUPPORT_MULTIWINDOW;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__APP_FINISHED;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__CHILD_TASK_ENTER_PIP;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DEVICE_FOLDED;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__DRAG_DIVIDER;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RECREATE_SPLIT;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__RETURN_HOME;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__ROOT_TASK_VANISHED;
|
||||
import static com.android.internal.util.FrameworkStatsLog.SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED;
|
||||
@@ -37,9 +39,11 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASO
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_UNKNOWN;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ROOT_TASK_VANISHED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_SCREEN_LOCKED;
|
||||
@@ -182,6 +186,10 @@ public class SplitscreenEventLogger {
|
||||
return SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED;
|
||||
case EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP:
|
||||
return SPLITSCREEN_UICHANGED__EXIT_REASON__SCREEN_LOCKED_SHOW_ON_TOP;
|
||||
case EXIT_REASON_CHILD_TASK_ENTER_PIP:
|
||||
return SPLITSCREEN_UICHANGED__EXIT_REASON__CHILD_TASK_ENTER_PIP;
|
||||
case EXIT_REASON_RECREATE_SPLIT:
|
||||
return SPLITSCREEN_UICHANGED__EXIT_REASON__RECREATE_SPLIT;
|
||||
case EXIT_REASON_FULLSCREEN_SHORTCUT:
|
||||
return SPLITSCREEN_UICHANGED__EXIT_REASON__FULLSCREEN_SHORTCUT;
|
||||
case EXIT_REASON_UNKNOWN:
|
||||
|
||||
@@ -49,10 +49,11 @@ import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASO
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.ENTER_REASON_MULTI_INSTANCE;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_APP_FINISHED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ROOT_TASK_VANISHED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP;
|
||||
@@ -199,7 +200,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
// and exit, since exit itself can trigger a number of changes that update the stages.
|
||||
private boolean mShouldUpdateRecents;
|
||||
private boolean mExitSplitScreenOnHide;
|
||||
private boolean mIsDividerRemoteAnimating;
|
||||
private boolean mIsSplitEntering;
|
||||
private boolean mIsDropEntering;
|
||||
private boolean mIsExiting;
|
||||
|
||||
/** The target stage to dismiss to when unlock after folded. */
|
||||
@@ -347,10 +349,19 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
return mSplitTransitions;
|
||||
}
|
||||
|
||||
boolean isSplitScreenVisible() {
|
||||
public boolean isSplitScreenVisible() {
|
||||
return mSideStageListener.mVisible && mMainStageListener.mVisible;
|
||||
}
|
||||
|
||||
public boolean isSplitActive() {
|
||||
return mMainStage.isActive();
|
||||
}
|
||||
|
||||
boolean isSplitScreenRunningBackground() {
|
||||
return !isSplitScreenVisible() && mMainStageListener.mHasChildren
|
||||
&& mSideStageListener.mHasChildren;
|
||||
}
|
||||
|
||||
@StageType
|
||||
int getStageOfTask(int taskId) {
|
||||
if (mMainStage.containsTask(taskId)) {
|
||||
@@ -373,11 +384,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
targetStage = mSideStage;
|
||||
sideStagePosition = stagePosition;
|
||||
} else {
|
||||
if (mMainStage.isActive()) {
|
||||
if (isSplitScreenVisible()) {
|
||||
// If the split screen is activated, retrieves target stage based on position.
|
||||
targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
|
||||
sideStagePosition = mSideStagePosition;
|
||||
} else {
|
||||
exitSplitIfBackground();
|
||||
targetStage = mSideStage;
|
||||
sideStagePosition = stagePosition;
|
||||
}
|
||||
@@ -673,6 +685,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
@Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
|
||||
@Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio,
|
||||
RemoteAnimationAdapter adapter, InstanceId instanceId) {
|
||||
exitSplitIfBackground();
|
||||
// Init divider first to make divider leash for remote animation target.
|
||||
mSplitLayout.init();
|
||||
mSplitLayout.setDivideRatio(splitRatio);
|
||||
@@ -685,11 +698,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
// Set false to avoid record new bounds with old task still on top;
|
||||
mShouldUpdateRecents = false;
|
||||
mIsDividerRemoteAnimating = true;
|
||||
mIsSplitEntering = true;
|
||||
|
||||
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
|
||||
prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct);
|
||||
prepareEvictChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, evictWct);
|
||||
if (isSplitScreenVisible()) {
|
||||
mMainStage.evictAllChildren(evictWct);
|
||||
mSideStage.evictAllChildren(evictWct);
|
||||
}
|
||||
|
||||
IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
|
||||
@Override
|
||||
@@ -769,7 +784,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
private void onRemoteAnimationFinishedOrCancelled(boolean cancel,
|
||||
WindowContainerTransaction evictWct) {
|
||||
mIsDividerRemoteAnimating = false;
|
||||
mIsSplitEntering = false;
|
||||
mShouldUpdateRecents = true;
|
||||
// If any stage has no child after animation finished, it means that split will display
|
||||
// nothing, such status will happen if task and intent is same app but not support
|
||||
@@ -781,6 +796,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mSplitUnsupportedToast.show();
|
||||
} else {
|
||||
mSyncQueue.queue(evictWct);
|
||||
mSyncQueue.runInSync(t -> {
|
||||
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,7 +833,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
switch (stage) {
|
||||
case STAGE_TYPE_UNDEFINED: {
|
||||
if (position != SPLIT_POSITION_UNDEFINED) {
|
||||
if (mMainStage.isActive()) {
|
||||
if (isSplitScreenVisible()) {
|
||||
// Use the stage of the specified position
|
||||
options = resolveStartStage(
|
||||
position == mSideStagePosition ? STAGE_TYPE_SIDE : STAGE_TYPE_MAIN,
|
||||
@@ -1045,7 +1063,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
});
|
||||
mShouldUpdateRecents = false;
|
||||
mIsDividerRemoteAnimating = false;
|
||||
mIsSplitEntering = false;
|
||||
|
||||
mSplitLayout.getInvisibleBounds(mTempRect1);
|
||||
if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) {
|
||||
@@ -1064,6 +1082,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
wct.setSmallestScreenWidthDp(childrenToTop.mRootTaskInfo.token,
|
||||
SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
|
||||
}
|
||||
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
|
||||
false /* reparentLeafTaskIfRelaunch */);
|
||||
mSyncQueue.queue(wct);
|
||||
mSyncQueue.runInSync(t -> {
|
||||
t.setWindowCrop(mMainStage.mRootLeash, null)
|
||||
@@ -1102,6 +1122,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
/** Exit split screen if it still running background */
|
||||
public void exitSplitIfBackground() {
|
||||
if (!isSplitScreenRunningBackground()) return;
|
||||
|
||||
exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden by child classes.
|
||||
*/
|
||||
@@ -1374,7 +1401,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
&& !ENABLE_SHELL_TRANSITIONS) {
|
||||
// Clear the divider remote animating flag as the divider will be re-rendered to apply
|
||||
// the new rotation config.
|
||||
mIsDividerRemoteAnimating = false;
|
||||
mIsSplitEntering = false;
|
||||
mSplitLayout.update(null /* t */);
|
||||
onLayoutSizeChanged(mSplitLayout);
|
||||
}
|
||||
@@ -1423,6 +1450,33 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
});
|
||||
}
|
||||
|
||||
void onChildTaskAppeared(StageListenerImpl stageListener, int taskId) {
|
||||
if (stageListener == mSideStageListener && isSplitScreenRunningBackground()) {
|
||||
// Handle entring split case here if split already running background.
|
||||
if (mIsDropEntering) {
|
||||
mSplitLayout.resetDividerPosition();
|
||||
} else {
|
||||
mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
|
||||
}
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
mMainStage.evictAllChildren(wct);
|
||||
mSideStage.evictOtherChildren(wct, taskId);
|
||||
mMainStage.reparentTopTask(wct);
|
||||
updateWindowBounds(mSplitLayout, wct);
|
||||
wct.reorder(mRootTaskInfo.token, true);
|
||||
|
||||
mSyncQueue.queue(wct);
|
||||
mSyncQueue.runInSync(t -> {
|
||||
if (mIsDropEntering) {
|
||||
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
|
||||
mIsDropEntering = false;
|
||||
} else {
|
||||
mSplitLayout.flingDividerToCenter();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void onRootTaskVanished() {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
if (mRootTaskInfo != null) {
|
||||
@@ -1441,20 +1495,20 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
return;
|
||||
}
|
||||
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
if (!mainStageVisible) {
|
||||
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
|
||||
true /* setReparentLeafTaskIfRelaunch */);
|
||||
// Both stages are not visible, check if it needs to dismiss split screen.
|
||||
if (mExitSplitScreenOnHide
|
||||
// Don't dismiss split screen when both stages are not visible due to sleeping
|
||||
// display.
|
||||
|| (!mMainStage.mRootTaskInfo.isSleeping
|
||||
&& !mSideStage.mRootTaskInfo.isSleeping)) {
|
||||
if (mExitSplitScreenOnHide) {
|
||||
exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RETURN_HOME);
|
||||
}
|
||||
} else {
|
||||
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
|
||||
false /* setReparentLeafTaskIfRelaunch */);
|
||||
}
|
||||
|
||||
mSyncQueue.queue(wct);
|
||||
mSyncQueue.runInSync(t -> {
|
||||
t.setVisibility(mSideStage.mRootLeash, sideStageVisible)
|
||||
.setVisibility(mMainStage.mRootLeash, mainStageVisible);
|
||||
setDividerVisibility(mainStageVisible, t);
|
||||
});
|
||||
}
|
||||
@@ -1479,7 +1533,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
mDividerVisible = visible;
|
||||
sendSplitVisibilityChanged();
|
||||
|
||||
if (mIsDividerRemoteAnimating) {
|
||||
if (mIsSplitEntering) {
|
||||
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
|
||||
" Skip animating divider bar due to it's remote animating.");
|
||||
return;
|
||||
@@ -1499,7 +1553,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
" Skip animating divider bar due to divider leash not ready.");
|
||||
return;
|
||||
}
|
||||
if (mIsDividerRemoteAnimating) {
|
||||
if (mIsSplitEntering) {
|
||||
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
|
||||
" Skip animating divider bar due to it's remote animating.");
|
||||
return;
|
||||
@@ -1555,26 +1609,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (!hasChildren && !mIsExiting && mMainStage.isActive()) {
|
||||
if (isSideStage && mMainStageListener.mVisible) {
|
||||
// Exit to main stage if side stage no longer has children.
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED);
|
||||
} else {
|
||||
mSplitLayout.flingDividerToDismiss(
|
||||
mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT,
|
||||
EXIT_REASON_APP_FINISHED);
|
||||
}
|
||||
mSplitLayout.flingDividerToDismiss(
|
||||
mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT,
|
||||
EXIT_REASON_APP_FINISHED);
|
||||
} else if (!isSideStage && mSideStageListener.mVisible) {
|
||||
// Exit to side stage if main stage no longer has children.
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
|
||||
} else {
|
||||
mSplitLayout.flingDividerToDismiss(
|
||||
mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT,
|
||||
EXIT_REASON_APP_FINISHED);
|
||||
}
|
||||
mSplitLayout.flingDividerToDismiss(
|
||||
mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT,
|
||||
EXIT_REASON_APP_FINISHED);
|
||||
} else if (isSplitScreenRunningBackground()) {
|
||||
// Do not exit to any stage due to running background.
|
||||
exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED);
|
||||
}
|
||||
} else if (isSideStage && hasChildren && !mMainStage.isActive()) {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
mSplitLayout.init();
|
||||
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
if (mLogger.isEnterRequestedByDrag()) {
|
||||
prepareEnterSplitScreen(wct);
|
||||
} else {
|
||||
@@ -1589,8 +1639,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
mSyncQueue.queue(wct);
|
||||
mSyncQueue.runInSync(t -> {
|
||||
if (mLogger.isEnterRequestedByDrag()) {
|
||||
if (mIsDropEntering) {
|
||||
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
|
||||
mIsDropEntering = false;
|
||||
} else {
|
||||
mShowDecorImmediately = true;
|
||||
mSplitLayout.flingDividerToCenter();
|
||||
@@ -1945,10 +1996,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSplitActive() {
|
||||
return mMainStage.isActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mergeAnimation(IBinder transition, TransitionInfo info,
|
||||
SurfaceControl.Transaction t, IBinder mergeTarget,
|
||||
@@ -2304,10 +2351,28 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
/**
|
||||
* Sets drag info to be logged when splitscreen is next entered.
|
||||
*/
|
||||
public void logOnDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
|
||||
public void onDroppedToSplit(@SplitPosition int position, InstanceId dragSessionId) {
|
||||
if (!isSplitScreenVisible()) {
|
||||
mIsDropEntering = true;
|
||||
}
|
||||
if (isSplitScreenRunningBackground()) {
|
||||
// Split running background, log exit first and start new enter request.
|
||||
logExit(EXIT_REASON_RECREATE_SPLIT);
|
||||
}
|
||||
mLogger.enterRequestedByDrag(position, dragSessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets info to be logged when splitscreen is next entered.
|
||||
*/
|
||||
public void onRequestToSplit(InstanceId sessionId, int enterReason) {
|
||||
if (isSplitScreenRunningBackground()) {
|
||||
// Split running background, log exit first and start new enter request.
|
||||
logExit(EXIT_REASON_RECREATE_SPLIT);
|
||||
}
|
||||
mLogger.enterRequested(sessionId, enterReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the exit of splitscreen.
|
||||
*/
|
||||
@@ -2342,6 +2407,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
StageCoordinator.this.onRootTaskAppeared();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChildTaskAppeared(int taskId) {
|
||||
StageCoordinator.this.onChildTaskAppeared(this, taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(boolean visible, boolean hasChildren) {
|
||||
if (!mHasRootTask) return;
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES_WHEN_ACTIVE;
|
||||
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
|
||||
|
||||
@@ -69,6 +70,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
public interface StageListenerCallbacks {
|
||||
void onRootTaskAppeared();
|
||||
|
||||
void onChildTaskAppeared(int taskId);
|
||||
|
||||
void onStatusChanged(boolean visible, boolean hasChildren);
|
||||
|
||||
void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
|
||||
@@ -185,6 +188,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
// Status is managed/synchronized by the transition lifecycle.
|
||||
return;
|
||||
}
|
||||
mCallbacks.onChildTaskAppeared(taskId);
|
||||
sendStatusChanged();
|
||||
} else {
|
||||
throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
|
||||
@@ -338,6 +342,14 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
}
|
||||
}
|
||||
|
||||
void evictOtherChildren(WindowContainerTransaction wct, int taskId) {
|
||||
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
|
||||
final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
|
||||
if (taskId == taskInfo.taskId) continue;
|
||||
wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
|
||||
}
|
||||
}
|
||||
|
||||
void evictNonOpeningChildren(RemoteAnimationTarget[] apps, WindowContainerTransaction wct) {
|
||||
final SparseArray<ActivityManager.RunningTaskInfo> toBeEvict = mChildrenTaskInfo.clone();
|
||||
for (int i = 0; i < apps.length; i++) {
|
||||
@@ -360,6 +372,12 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
}
|
||||
}
|
||||
|
||||
void reparentTopTask(WindowContainerTransaction wct) {
|
||||
wct.reparentTasks(null /* currentParent */, mRootTaskInfo.token,
|
||||
CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES,
|
||||
true /* onTop */, true /* reparentTopOnly */);
|
||||
}
|
||||
|
||||
void resetBounds(WindowContainerTransaction wct) {
|
||||
wct.setBounds(mRootTaskInfo.token, null);
|
||||
wct.setAppBounds(mRootTaskInfo.token, null);
|
||||
|
||||
@@ -111,7 +111,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler {
|
||||
@Override
|
||||
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
|
||||
@NonNull TransitionRequestInfo request) {
|
||||
if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitActive()) {
|
||||
if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitScreenVisible()) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a PiP-enter request while "
|
||||
+ "Split-Screen is active, so treat it as Mixed.");
|
||||
if (request.getRemoteTransition() != null) {
|
||||
|
||||
Reference in New Issue
Block a user