Merge "Exit split when fold only if user interacted" into udc-qpr-dev
This commit is contained in:
@@ -219,6 +219,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
private boolean mIsDropEntering;
|
||||
private boolean mIsExiting;
|
||||
private boolean mIsRootTranslucent;
|
||||
@VisibleForTesting
|
||||
int mTopStageAfterFoldDismiss;
|
||||
|
||||
private DefaultMixedHandler mMixedHandler;
|
||||
private final Toast mSplitUnsupportedToast;
|
||||
@@ -1310,6 +1312,24 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
final StageTaskListener toTop = mainStageVisible ? mMainStage : mSideStage;
|
||||
exitSplitScreen(toTop, EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP);
|
||||
}
|
||||
|
||||
// Dismiss split if the flag record any side of stages.
|
||||
if (mTopStageAfterFoldDismiss != STAGE_TYPE_UNDEFINED) {
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
// Need manually clear here due to this transition might be aborted due to keyguard
|
||||
// on top and lead to no visible change.
|
||||
clearSplitPairedInRecents(EXIT_REASON_DEVICE_FOLDED);
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
prepareExitSplitScreen(mTopStageAfterFoldDismiss, wct);
|
||||
mSplitTransitions.startDismissTransition(wct, this,
|
||||
mTopStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
|
||||
} else {
|
||||
exitSplitScreen(
|
||||
mTopStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
|
||||
EXIT_REASON_DEVICE_FOLDED);
|
||||
}
|
||||
mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
|
||||
@@ -1346,15 +1366,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (!mMainStage.isActive() || mIsExiting) return;
|
||||
|
||||
onSplitScreenExit();
|
||||
clearSplitPairedInRecents(exitReason);
|
||||
|
||||
mRecentTasks.ifPresent(recentTasks -> {
|
||||
// Notify recents if we are exiting in a way that breaks the pair, and disable further
|
||||
// updates to splits in the recents until we enter split again
|
||||
if (shouldBreakPairedTaskInRecents(exitReason) && mShouldUpdateRecents) {
|
||||
recentTasks.removeSplitPair(mMainStage.getTopVisibleChildTaskId());
|
||||
recentTasks.removeSplitPair(mSideStage.getTopVisibleChildTaskId());
|
||||
}
|
||||
});
|
||||
mShouldUpdateRecents = false;
|
||||
mIsDividerRemoteAnimating = false;
|
||||
mSplitRequest = null;
|
||||
@@ -1481,6 +1494,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
private void clearSplitPairedInRecents(@ExitReason int exitReason) {
|
||||
if (!shouldBreakPairedTaskInRecents(exitReason) || !mShouldUpdateRecents) return;
|
||||
|
||||
mRecentTasks.ifPresent(recentTasks -> {
|
||||
// Notify recents if we are exiting in a way that breaks the pair, and disable further
|
||||
// updates to splits in the recents until we enter split again
|
||||
mMainStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
|
||||
mSideStage.doForAllChildTasks(taskId -> recentTasks.removeSplitPair(taskId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike exitSplitScreen, this takes a stagetype vs an actual stage-reference and populates
|
||||
* an existing WindowContainerTransaction (rather than applying immediately). This is intended
|
||||
@@ -2208,7 +2232,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
void updateSurfaces(SurfaceControl.Transaction transaction) {
|
||||
/**
|
||||
* Update surfaces of the split screen layout based on the current state
|
||||
* @param transaction to write the updates to
|
||||
*/
|
||||
public void updateSurfaces(SurfaceControl.Transaction transaction) {
|
||||
updateSurfaceBounds(mSplitLayout, transaction, /* applyResizingOffset */ false);
|
||||
mSplitLayout.update(transaction);
|
||||
}
|
||||
@@ -2227,26 +2255,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
@VisibleForTesting
|
||||
void onFoldedStateChanged(boolean folded) {
|
||||
int topStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
|
||||
mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
|
||||
if (!folded) return;
|
||||
|
||||
if (!mMainStage.isActive()) return;
|
||||
if (!isSplitActive() || !isSplitScreenVisible()) return;
|
||||
|
||||
// To avoid split dismiss when user fold the device and unfold to use later, we only
|
||||
// record the flag here and try to dismiss on wakeUp callback to ensure split dismiss
|
||||
// when user interact on phone folded.
|
||||
if (mMainStage.isFocused()) {
|
||||
topStageAfterFoldDismiss = STAGE_TYPE_MAIN;
|
||||
mTopStageAfterFoldDismiss = STAGE_TYPE_MAIN;
|
||||
} else if (mSideStage.isFocused()) {
|
||||
topStageAfterFoldDismiss = STAGE_TYPE_SIDE;
|
||||
}
|
||||
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
prepareExitSplitScreen(topStageAfterFoldDismiss, wct);
|
||||
mSplitTransitions.startDismissTransition(wct, this,
|
||||
topStageAfterFoldDismiss, EXIT_REASON_DEVICE_FOLDED);
|
||||
} else {
|
||||
exitSplitScreen(
|
||||
topStageAfterFoldDismiss == STAGE_TYPE_MAIN ? mMainStage : mSideStage,
|
||||
EXIT_REASON_DEVICE_FOLDED);
|
||||
mTopStageAfterFoldDismiss = STAGE_TYPE_SIDE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ import com.android.wm.shell.windowdecor.WindowDecorViewModel;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -347,6 +348,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
wct.reorder(mChildrenTaskInfo.get(taskId).token, onTop /* onTop */);
|
||||
}
|
||||
|
||||
void doForAllChildTasks(Consumer<Integer> consumer) {
|
||||
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
|
||||
final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
|
||||
consumer.accept(taskInfo.taskId);
|
||||
}
|
||||
}
|
||||
|
||||
/** Collects all the current child tasks and prepares transaction to evict them to display. */
|
||||
void evictAllChildren(WindowContainerTransaction wct) {
|
||||
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; i--) {
|
||||
|
||||
@@ -704,6 +704,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
if (mPipHandler != null) {
|
||||
mPipHandler.syncPipSurfaceState(info, startTransaction, finishTransaction);
|
||||
}
|
||||
if (mSplitHandler != null && mSplitHandler.isSplitActive()) {
|
||||
mSplitHandler.updateSurfaces(startTransaction);
|
||||
}
|
||||
return mUnfoldHandler.startAnimation(
|
||||
mixed.mTransition, info, startTransaction, finishTransaction, finishCB);
|
||||
}
|
||||
|
||||
@@ -270,7 +270,6 @@ public class SplitTaskUnfoldAnimator implements UnfoldTaskAnimator,
|
||||
@Override
|
||||
public void prepareStartTransaction(Transaction transaction) {
|
||||
mUnfoldBackgroundController.ensureBackground(transaction);
|
||||
mSplitScreenController.get().get().updateSplitScreenSurfaces(transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -347,13 +347,20 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExitSplitScreenAfterFolded() {
|
||||
when(mMainStage.isActive()).thenReturn(true);
|
||||
public void testExitSplitScreenAfterFoldedAndWakeUp() {
|
||||
when(mMainStage.isFocused()).thenReturn(true);
|
||||
when(mMainStage.getTopVisibleChildTaskId()).thenReturn(INVALID_TASK_ID);
|
||||
mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().setVisible(true).build();
|
||||
mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().setVisible(true).build();
|
||||
when(mStageCoordinator.isSplitActive()).thenReturn(true);
|
||||
when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);
|
||||
|
||||
mStageCoordinator.onFoldedStateChanged(true);
|
||||
|
||||
assertEquals(mStageCoordinator.mTopStageAfterFoldDismiss, STAGE_TYPE_MAIN);
|
||||
|
||||
mStageCoordinator.onFinishedWakingUp();
|
||||
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
verify(mTaskOrganizer).startNewTransition(eq(TRANSIT_SPLIT_DISMISS), notNull());
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user