Merge "Fix crash due to null leash on transition" into udc-dev
This commit is contained in:
@@ -23,8 +23,6 @@ import static android.view.WindowManager.TRANSIT_TO_BACK;
|
|||||||
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||||
|
|
||||||
import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
|
import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
|
||||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
|
|
||||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
|
|
||||||
import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
|
import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
|
||||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
|
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
|
||||||
import static com.android.wm.shell.splitscreen.SplitScreenController.exitReasonToString;
|
import static com.android.wm.shell.splitscreen.SplitScreenController.exitReasonToString;
|
||||||
@@ -183,33 +181,6 @@ class SplitScreenTransitions {
|
|||||||
onFinish(null /* wct */, null /* wctCB */);
|
onFinish(null /* wct */, null /* wctCB */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyDismissTransition(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
|
||||||
@NonNull SurfaceControl.Transaction startTransaction,
|
|
||||||
@NonNull SurfaceControl.Transaction finishTransaction,
|
|
||||||
@NonNull Transitions.TransitionFinishCallback finishCallback,
|
|
||||||
@NonNull WindowContainerToken topRoot,
|
|
||||||
@NonNull WindowContainerToken mainRoot, @NonNull WindowContainerToken sideRoot,
|
|
||||||
@NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) {
|
|
||||||
if (mPendingDismiss.mDismissTop != STAGE_TYPE_UNDEFINED) {
|
|
||||||
mFinishCallback = finishCallback;
|
|
||||||
mAnimatingTransition = transition;
|
|
||||||
mFinishTransaction = finishTransaction;
|
|
||||||
|
|
||||||
startTransaction.apply();
|
|
||||||
|
|
||||||
final SplitDecorManager topDecor = mPendingDismiss.mDismissTop == STAGE_TYPE_MAIN
|
|
||||||
? mainDecor : sideDecor;
|
|
||||||
topDecor.fadeOutDecor(() -> {
|
|
||||||
mTransitions.getMainExecutor().execute(() -> {
|
|
||||||
onFinish(null /* wct */, null /* wctCB */);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
playAnimation(transition, info, startTransaction, finishTransaction,
|
|
||||||
finishCallback, mainRoot, sideRoot, topRoot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void playResizeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
void playResizeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
||||||
@NonNull SurfaceControl.Transaction startTransaction,
|
@NonNull SurfaceControl.Transaction startTransaction,
|
||||||
@NonNull SurfaceControl.Transaction finishTransaction,
|
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||||
|
|||||||
@@ -311,6 +311,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
transitions.addHandler(this);
|
transitions.addHandler(this);
|
||||||
mSplitUnsupportedToast = Toast.makeText(mContext,
|
mSplitUnsupportedToast = Toast.makeText(mContext,
|
||||||
R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
|
R.string.dock_non_resizeble_failed_to_dock_text, Toast.LENGTH_SHORT);
|
||||||
|
// With shell transition, we should update recents tile each callback so set this to true by
|
||||||
|
// default.
|
||||||
|
mShouldUpdateRecents = ENABLE_SHELL_TRANSITIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -1464,18 +1467,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
private void prepareExitSplitScreen(@StageType int stageToTop,
|
private void prepareExitSplitScreen(@StageType int stageToTop,
|
||||||
@NonNull WindowContainerTransaction wct) {
|
@NonNull WindowContainerTransaction wct) {
|
||||||
if (!mMainStage.isActive()) return;
|
if (!mMainStage.isActive()) return;
|
||||||
// Set the dismiss-to-top side to fullscreen for dismiss transition.
|
mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
|
||||||
// Reparent the non-dismiss-to-top side to properly update its visibility.
|
mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
|
||||||
if (stageToTop == STAGE_TYPE_MAIN) {
|
|
||||||
wct.setBounds(mMainStage.mRootTaskInfo.token, null /* bounds */);
|
|
||||||
mSideStage.removeAllTasks(wct, false /* toTop */);
|
|
||||||
} else if (stageToTop == STAGE_TYPE_SIDE) {
|
|
||||||
wct.setBounds(mSideStage.mRootTaskInfo.token, null /* bounds */);
|
|
||||||
mMainStage.deactivate(wct, false /* toTop */);
|
|
||||||
} else {
|
|
||||||
mSideStage.removeAllTasks(wct, false /* toTop */);
|
|
||||||
mMainStage.deactivate(wct, false /* toTop */);
|
|
||||||
}
|
|
||||||
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
|
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
|
||||||
false /* reparentLeafTaskIfRelaunch */);
|
false /* reparentLeafTaskIfRelaunch */);
|
||||||
}
|
}
|
||||||
@@ -1554,7 +1547,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
|
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
|
||||||
t.show(mRootTaskLeash);
|
t.show(mRootTaskLeash);
|
||||||
setSplitsVisible(true);
|
setSplitsVisible(true);
|
||||||
mShouldUpdateRecents = true;
|
|
||||||
updateRecentTasksSplitPair();
|
updateRecentTasksSplitPair();
|
||||||
if (!mLogger.hasStartedSession()) {
|
if (!mLogger.hasStartedSession()) {
|
||||||
mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
|
mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
|
||||||
@@ -2565,13 +2557,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
} else if (mSplitTransitions.isPendingDismiss(transition)) {
|
} else if (mSplitTransitions.isPendingDismiss(transition)) {
|
||||||
shouldAnimate = startPendingDismissAnimation(
|
shouldAnimate = startPendingDismissAnimation(
|
||||||
mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
|
mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
|
||||||
if (shouldAnimate) {
|
|
||||||
mSplitTransitions.applyDismissTransition(transition, info,
|
|
||||||
startTransaction, finishTransaction, finishCallback, mRootTaskInfo.token,
|
|
||||||
mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token,
|
|
||||||
mMainStage.getSplitDecorManager(), mSideStage.getSplitDecorManager());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (mSplitTransitions.isPendingResize(transition)) {
|
} else if (mSplitTransitions.isPendingResize(transition)) {
|
||||||
mSplitTransitions.playResizeAnimation(transition, info, startTransaction,
|
mSplitTransitions.playResizeAnimation(transition, info, startTransaction,
|
||||||
finishTransaction, finishCallback, mMainStage.mRootTaskInfo.token,
|
finishTransaction, finishCallback, mMainStage.mRootTaskInfo.token,
|
||||||
@@ -2760,8 +2745,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
mRecentTasks.ifPresent(recentTasks -> {
|
mRecentTasks.ifPresent(recentTasks -> {
|
||||||
// Notify recents if we are exiting in a way that breaks the pair, and disable further
|
// 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
|
// updates to splits in the recents until we enter split again
|
||||||
if (shouldBreakPairedTaskInRecents(dismissReason) && mShouldUpdateRecents) {
|
if (shouldBreakPairedTaskInRecents(dismissReason)) {
|
||||||
if (toStage == STAGE_TYPE_UNDEFINED) {
|
|
||||||
for (TransitionInfo.Change change : info.getChanges()) {
|
for (TransitionInfo.Change change : info.getChanges()) {
|
||||||
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
|
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
|
||||||
if (taskInfo != null
|
if (taskInfo != null
|
||||||
@@ -2769,13 +2753,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
recentTasks.removeSplitPair(taskInfo.taskId);
|
recentTasks.removeSplitPair(taskInfo.taskId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
recentTasks.removeSplitPair(mMainStage.getTopVisibleChildTaskId());
|
|
||||||
recentTasks.removeSplitPair(mSideStage.getTopVisibleChildTaskId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mShouldUpdateRecents = false;
|
|
||||||
mSplitRequest = null;
|
mSplitRequest = null;
|
||||||
|
|
||||||
// Update local states.
|
// Update local states.
|
||||||
@@ -2817,18 +2796,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
mSplitLayout.release(t);
|
mSplitLayout.release(t);
|
||||||
mSplitTransitions.mPendingDismiss = null;
|
mSplitTransitions.mPendingDismiss = null;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
final @SplitScreen.StageType int dismissTop = dismissTransition.mDismissTop;
|
|
||||||
// Reparent all tasks after dismiss transition finished.
|
|
||||||
dismissTransition.setFinishedCallback(
|
|
||||||
new SplitScreenTransitions.TransitionFinishedCallback() {
|
|
||||||
@Override
|
|
||||||
public void onFinished(WindowContainerTransaction wct,
|
|
||||||
SurfaceControl.Transaction t) {
|
|
||||||
mSideStage.removeAllTasks(wct, dismissTop == STAGE_TYPE_SIDE);
|
|
||||||
mMainStage.deactivate(wct, dismissTop == STAGE_TYPE_MAIN);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addDividerBarToTransition(info, false /* show */);
|
addDividerBarToTransition(info, false /* show */);
|
||||||
@@ -2868,6 +2835,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
|
|
||||||
private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
|
private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
|
||||||
final SurfaceControl leash = mSplitLayout.getDividerLeash();
|
final SurfaceControl leash = mSplitLayout.getDividerLeash();
|
||||||
|
if (leash == null || !leash.isValid()) {
|
||||||
|
Slog.w(TAG, "addDividerBarToTransition but leash was released or not be created");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final TransitionInfo.Change barChange = new TransitionInfo.Change(null /* token */, leash);
|
final TransitionInfo.Change barChange = new TransitionInfo.Change(null /* token */, leash);
|
||||||
mSplitLayout.getRefDividerBounds(mTempRect1);
|
mSplitLayout.getRefDividerBounds(mTempRect1);
|
||||||
barChange.setParent(mRootTaskInfo.token);
|
barChange.setParent(mRootTaskInfo.token);
|
||||||
|
|||||||
@@ -81,13 +81,9 @@ class DismissSplitScreenByDivider(override val flicker: FlickerTest) :
|
|||||||
@Presubmit
|
@Presubmit
|
||||||
@Test
|
@Test
|
||||||
fun secondaryAppBoundsIsFullscreenAtEnd() {
|
fun secondaryAppBoundsIsFullscreenAtEnd() {
|
||||||
flicker.assertLayers {
|
flicker.assertLayersEnd {
|
||||||
this.isVisible(secondaryApp).then().isInvisible(secondaryApp).then().invoke(
|
val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
|
||||||
"secondaryAppBoundsIsFullscreenAtEnd"
|
visibleRegion(secondaryApp).coversExactly(displayBounds)
|
||||||
) {
|
|
||||||
val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
|
|
||||||
it.visibleRegion(secondaryApp).coversExactly(displayBounds)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -376,8 +376,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
|||||||
IBinder transition = mock(IBinder.class);
|
IBinder transition = mock(IBinder.class);
|
||||||
WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
|
WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
|
||||||
|
|
||||||
// Don't reparent tasks until the animation is complete.
|
assertTrue(containsSplitExit(result));
|
||||||
assertFalse(containsSplitExit(result));
|
|
||||||
|
|
||||||
// make sure we haven't made any local changes yet (need to wait until transition is ready)
|
// make sure we haven't made any local changes yet (need to wait until transition is ready)
|
||||||
assertTrue(mStageCoordinator.isSplitScreenVisible());
|
assertTrue(mStageCoordinator.isSplitScreenVisible());
|
||||||
|
|||||||
Reference in New Issue
Block a user