Merge "Fix crash due to null leash on transition" into udc-dev

This commit is contained in:
Tony Huang
2023-05-11 09:10:37 +00:00
committed by Android (Google) Code Review
4 changed files with 15 additions and 77 deletions

View File

@@ -23,8 +23,6 @@ import static android.view.WindowManager.TRANSIT_TO_BACK;
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.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.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
import static com.android.wm.shell.splitscreen.SplitScreenController.exitReasonToString;
@@ -183,33 +181,6 @@ class SplitScreenTransitions {
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,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,

View File

@@ -311,6 +311,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
transitions.addHandler(this);
mSplitUnsupportedToast = Toast.makeText(mContext,
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
@@ -1464,18 +1467,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void prepareExitSplitScreen(@StageType int stageToTop,
@NonNull WindowContainerTransaction wct) {
if (!mMainStage.isActive()) return;
// Set the dismiss-to-top side to fullscreen for dismiss transition.
// Reparent the non-dismiss-to-top side to properly update its visibility.
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 */);
}
mSideStage.removeAllTasks(wct, stageToTop == STAGE_TYPE_SIDE);
mMainStage.deactivate(wct, stageToTop == STAGE_TYPE_MAIN);
wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token,
false /* reparentLeafTaskIfRelaunch */);
}
@@ -1554,7 +1547,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
t.show(mRootTaskLeash);
setSplitsVisible(true);
mShouldUpdateRecents = true;
updateRecentTasksSplitPair();
if (!mLogger.hasStartedSession()) {
mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
@@ -2565,13 +2557,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
} else if (mSplitTransitions.isPendingDismiss(transition)) {
shouldAnimate = startPendingDismissAnimation(
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)) {
mSplitTransitions.playResizeAnimation(transition, info, startTransaction,
finishTransaction, finishCallback, mMainStage.mRootTaskInfo.token,
@@ -2760,8 +2745,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
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(dismissReason) && mShouldUpdateRecents) {
if (toStage == STAGE_TYPE_UNDEFINED) {
if (shouldBreakPairedTaskInRecents(dismissReason)) {
for (TransitionInfo.Change change : info.getChanges()) {
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo != null
@@ -2769,13 +2753,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
recentTasks.removeSplitPair(taskInfo.taskId);
}
}
} else {
recentTasks.removeSplitPair(mMainStage.getTopVisibleChildTaskId());
recentTasks.removeSplitPair(mSideStage.getTopVisibleChildTaskId());
}
}
});
mShouldUpdateRecents = false;
mSplitRequest = null;
// Update local states.
@@ -2817,18 +2796,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.release(t);
mSplitTransitions.mPendingDismiss = null;
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 */);
@@ -2868,6 +2835,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
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);
mSplitLayout.getRefDividerBounds(mTempRect1);
barChange.setParent(mRootTaskInfo.token);

View File

@@ -81,13 +81,9 @@ class DismissSplitScreenByDivider(override val flicker: FlickerTest) :
@Presubmit
@Test
fun secondaryAppBoundsIsFullscreenAtEnd() {
flicker.assertLayers {
this.isVisible(secondaryApp).then().isInvisible(secondaryApp).then().invoke(
"secondaryAppBoundsIsFullscreenAtEnd"
) {
val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
it.visibleRegion(secondaryApp).coversExactly(displayBounds)
}
flicker.assertLayersEnd {
val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
visibleRegion(secondaryApp).coversExactly(displayBounds)
}
}

View File

@@ -376,8 +376,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder transition = mock(IBinder.class);
WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
// Don't reparent tasks until the animation is complete.
assertFalse(containsSplitExit(result));
assertTrue(containsSplitExit(result));
// make sure we haven't made any local changes yet (need to wait until transition is ready)
assertTrue(mStageCoordinator.isSplitScreenVisible());