From f5b13525100ea66b112dcd01abc00c485e1082c8 Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Thu, 17 Feb 2022 21:47:33 +0800 Subject: [PATCH] Fix a redundant assignRelativeLayerForIme case Somehow in FlickerTest#CloseAppBackButtonTest with enabling shell-transition flag will see a weird case is that first launcher be set relativeZ to above IME container during closing the IME actiivty, which is understandable since home activity is not IME target during transient launch, but soonly in assignRelativeLayerForIme will set IME container's relativeZ to be above launcher after recents animation finish. This action will confuse SurfaceFlinger side while invoking Layer::isHiddenByPolicy() to traverse all layers using relativeZ and cause stack-overflow due to circulated relativeZ relationship in between launcher and IME container. As we don't need to set relative layer if the IME target in non-multi-window mode is the activity main window since updateImeParent will ensure the IME surface be attached on the fullscreen activity. Add a check in assignRelativeLayerForIme to not set RelativeZ if the IME target is the full screen activity, to break out circulated RelativeZ in between ImeContainer & Launcher window layer. Fix: 219774897 Test: atest ZOrderingTest Test: atest FlickerTests#CloseAppBackButtonTest --iterations 20 Change-Id: I5abff1980328dc47ee193429a76a5d39a8625899 --- services/core/java/com/android/server/wm/DisplayContent.java | 4 ++++ .../wmtests/src/com/android/server/wm/ZOrderingTests.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 4c5c7054e9a0a..bd9f130e16189 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5009,6 +5009,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final boolean canImeTargetSetRelativeLayer = imeTarget.getSurfaceControl() != null && imeTarget.mToken == imeControlTargetToken && !imeTarget.inMultiWindowMode() + // We don't need to set relative layer if the IME target in non-multi-window + // mode is the activity main window since updateImeParent will ensure the IME + // surface be attached on the fullscreen activity. + && imeTarget.mAttrs.type != TYPE_BASE_APPLICATION && imeTarget.mToken.getActivity(app -> app.isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_ALL & ~ANIMATION_TYPE_RECENTS)) == null; if (canImeTargetSetRelativeLayer) { diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java index 0f223ca037ee4..eea3f844b40ff 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java @@ -293,7 +293,8 @@ public class ZOrderingTests extends WindowTestsBase { public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() { final WindowState appBelowImeTarget = createWindow("appBelowImeTarget"); final WindowState imeAppTarget = createWindow("imeAppTarget"); - final WindowState appAboveImeTarget = createWindow("appAboveImeTarget"); + final WindowState appAboveImeTarget = createWindow(imeAppTarget, TYPE_APPLICATION, + "appAboveImeTarget"); mDisplayContent.setImeLayeringTarget(imeAppTarget); mDisplayContent.setImeControlTarget(imeAppTarget);