From 096919c66454f7592737a8f77f3b518b966f6925 Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Mon, 27 Dec 2021 17:39:43 +0800 Subject: [PATCH] Fix IME layering target above IME surface CL[1] fixed the IME flickering issue when switching recents tasks with specifying to set IME relative layer until the layering target is not animated and be IME control target. However, it didn't consider the case that the IME layering target could be the drop down box window that not same as the IME control target, so that the issue happens when we didn't set IME above this window, the app drop down box will be above IME and cosumed the input to hide the keyboard. Fix this regression by checking the token of the layering target to set IME relative layer if the target isn't transitioning and same as the token of the control target. [1]: Iae65d6047c02dae241f2df21c666a03cca58fd0b Fix: 209722479 Test: manual as test steps Test: atest ZOrderingTests#\ testAssignWindowLayers_ForImeOnPopupImeLayeringTarget Change-Id: Id2e700c20b964e296576c49391853b680418bf57 --- .../com/android/server/wm/DisplayContent.java | 5 ++++- .../com/android/server/wm/ZOrderingTests.java | 19 +++++++++++++++++++ 2 files changed, 23 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 d1e9d6b600384..21369c693d9bd 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -5009,8 +5009,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // exists so it get's layered above the starting window. if (imeTarget != null && !(imeTarget.mActivityRecord != null && imeTarget.mActivityRecord.hasStartingWindow())) { + final WindowToken imeControlTargetToken = + mImeControlTarget != null && mImeControlTarget.getWindow() != null + ? mImeControlTarget.getWindow().mToken : null; final boolean canImeTargetSetRelativeLayer = imeTarget.getSurfaceControl() != null - && imeTarget == mImeControlTarget + && imeTarget.mToken == imeControlTargetToken && !imeTarget.inMultiWindowMode() && imeTarget.mToken.getActivity(app -> app.isAnimating(TRANSITION | PARENTS, ANIMATION_TYPE_ALL & ~ANIMATION_TYPE_RECENTS)) == null; 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 049966c7310d8..4dffe7e8345ba 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java @@ -428,6 +428,25 @@ public class ZOrderingTests extends WindowTestsBase { assertWindowHigher(mImeWindow, imeAppTarget); } + @Test + public void testAssignWindowLayers_ForImeOnPopupImeLayeringTarget() { + final WindowState imeAppTarget = createWindow(null, TYPE_APPLICATION, + mAppWindow.mActivityRecord, "imeAppTarget"); + mDisplayContent.setImeInputTarget(imeAppTarget); + mDisplayContent.setImeLayeringTarget(imeAppTarget); + mDisplayContent.setImeControlTarget(imeAppTarget); + + // Set a popup IME layering target and keeps the original IME control target behinds it. + final WindowState popupImeTargetWin = createWindow(imeAppTarget, + TYPE_APPLICATION_SUB_PANEL, mAppWindow.mActivityRecord, "popupImeTargetWin"); + mDisplayContent.setImeLayeringTarget(popupImeTargetWin); + mDisplayContent.updateImeParent(); + + // Ime should on top of the popup IME layering target window. + mDisplayContent.assignChildLayers(mTransaction); + assertWindowHigher(mImeWindow, popupImeTargetWin); + } + @Test public void testAssignWindowLayers_ForNegativelyZOrderedSubtype() {