From 7905ab64bb81b7ed9f0fc9fbfe7c8c5fb54496e2 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Tue, 10 Jan 2023 16:27:07 +0800 Subject: [PATCH] Fix freeze when Chrome multi instance split This freeze should be a race caused by calling wct.setForceTranslucent every time in onStageVisibilityChanged so fix this by only doing it necessary. Fix: 264690550 Test: manaul Test: pass existing tests Change-Id: I9234fa5c427ef83c503313e53dd43fc712f93912 --- .../shell/splitscreen/StageCoordinator.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 8ddc3c04d991b..a37f9d47ce747 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -1052,6 +1052,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mSideStage.removeAllTasks(wct, false /* toTop */); mMainStage.deactivate(wct, false /* toTop */); wct.reorder(mRootTaskInfo.token, false /* onTop */); + wct.setForceTranslucent(mRootTaskInfo.token, true); wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1); onTransitionAnimationComplete(); } else { @@ -1083,6 +1084,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mMainStage.deactivate(finishedWCT, childrenToTop == mMainStage /* toTop */); mSideStage.removeAllTasks(finishedWCT, childrenToTop == mSideStage /* toTop */); finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */); + finishedWCT.setForceTranslucent(mRootTaskInfo.token, true); finishedWCT.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1); mSyncQueue.queue(finishedWCT); mSyncQueue.runInSync(at -> { @@ -1463,6 +1465,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } private void onStageVisibilityChanged(StageListenerImpl stageListener) { + // If split didn't active, just ignore this callback because we should already did these + // on #applyExitSplitScreen. + if (!isSplitActive()) { + return; + } + final boolean sideStageVisible = mSideStageListener.mVisible; final boolean mainStageVisible = mMainStageListener.mVisible; @@ -1471,20 +1479,23 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return; } + // Check if it needs to dismiss split screen when both stage invisible. + if (!mainStageVisible && mExitSplitScreenOnHide) { + exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RETURN_HOME); + return; + } + final WindowContainerTransaction wct = new WindowContainerTransaction(); if (!mainStageVisible) { + // Split entering background. wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, true /* setReparentLeafTaskIfRelaunch */); wct.setForceTranslucent(mRootTaskInfo.token, true); - // Both stages are not visible, check if it needs to dismiss split screen. - if (mExitSplitScreenOnHide) { - exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RETURN_HOME); - } } else { wct.setReparentLeafTaskIfRelaunch(mRootTaskInfo.token, false /* setReparentLeafTaskIfRelaunch */); - wct.setForceTranslucent(mRootTaskInfo.token, false); } + mSyncQueue.queue(wct); mSyncQueue.runInSync(t -> { setDividerVisibility(mainStageVisible, t);