From ea95fa9df70fe4e26b9d9179a540300a83b9449d Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Sun, 25 Apr 2021 23:34:57 +0800 Subject: [PATCH] Don't attach IME screenshot when performing non-task transition As currently attaching IME screenshot is only valid during switching between app tasks with IME window for aligning with the IME window surface layer on the fullscreen activity. The issue happens when SettingsPanelActivity (non-fullscreen activity) launch another translucent activity and popup the wifi password dialog. When user dismiss the dialog, it makes WifiDialogActivity incidentally attachs the IME screenshot on SettingsPanelActivity while performing translucent activity closing transition. Since initially we only support IME screenshot when performing task level app transition or switching apps with recents animation, We won't support for the app activity with theming or popup the non-fullscreen dialog with editor in case wrong IME screenshot attaching as the above issue case during activity closing transition. Add more checks to consolidate the attaching rule that valid only when the task is IME layering target and performing task closing transition. Fix: 186080920 Test: atest DisplayContentTests#testAttachAndShowImeScreenshotOnTarget Test: atest DisplayContentTests#testShowImeScreenshot Test: manual as issue steps: 1) Open Internet connection from quick settings. 2) Choose a Wifi ssid which requires password. 3) Enter password and press Enter key. 4) Verify if the keyboard is still remain on the screen. Expected is not. Change-Id: I0a0a8322c5d1cd44e3a4520c7f5434b8bc5b8306 --- .../com/android/server/wm/AppTransition.java | 6 +++- .../android/server/wm/WindowContainer.java | 10 ++++++- .../server/wm/DisplayContentTests.java | 29 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 43326df1a1439..d5a76199f7b81 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -1691,7 +1691,11 @@ public class AppTransition implements Dump { static boolean isTaskTransitOld(@TransitionOldType int transit) { return isTaskOpenTransitOld(transit) - || transit == TRANSIT_OLD_TASK_CLOSE + || isTaskCloseTransitOld(transit); + } + + static boolean isTaskCloseTransitOld(@TransitionOldType int transit) { + return transit == TRANSIT_OLD_TASK_CLOSE || transit == TRANSIT_OLD_TASK_TO_BACK; } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index bea733b0267e7..b1c7e196b70c2 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -37,6 +37,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SYNC_ENGINE; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.AppTransition.MAX_APP_TRANSITION_DURATION; +import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.IdentifierProto.HASH_CODE; import static com.android.server.wm.IdentifierProto.TITLE; import static com.android.server.wm.IdentifierProto.USER_ID; @@ -2696,7 +2697,14 @@ class WindowContainer extends ConfigurationContainer< @Nullable ArrayList sources) { final Task task = asTask(); if (task != null && !enter && !task.isHomeOrRecentsRootTask()) { - mDisplayContent.showImeScreenshot(); + final InsetsControlTarget imeTarget = mDisplayContent.getImeTarget(IME_TARGET_LAYERING); + final boolean isImeLayeringTarget = imeTarget != null && imeTarget.getWindow() != null + && imeTarget.getWindow().getTask() == task; + // Attach and show the IME screenshot when the task is the IME target and performing + // task closing transition to the next task. + if (isImeLayeringTarget && AppTransition.isTaskCloseTransitOld(transit)) { + mDisplayContent.showImeScreenshot(); + } } final Pair adapters = getAnimationAdapter(lp, transit, enter, isVoiceInteraction); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index e1eef762059ee..e09606e3389f2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -54,6 +54,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import static android.view.WindowManager.TRANSIT_CLOSE; +import static android.view.WindowManager.TRANSIT_OLD_TASK_CLOSE; +import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE; import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; @@ -1909,6 +1912,32 @@ public class DisplayContentTests extends WindowTestsBase { verify(t).show(mDisplayContent.mImeScreenshot); } + @UseTestDisplay(addWindows = {W_INPUT_METHOD}, addAllCommonWindows = true) + @Test + public void testShowImeScreenshot() { + final Task rootTask = createTask(mDisplayContent); + final Task task = createTaskInRootTask(rootTask, 0 /* userId */); + final ActivityRecord activity = createActivityRecord(mDisplayContent, task); + final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win"); + task.getDisplayContent().prepareAppTransition(TRANSIT_CLOSE); + doReturn(true).when(task).okToAnimate(); + ArrayList sources = new ArrayList<>(); + sources.add(activity); + + mDisplayContent.setImeLayeringTarget(win); + spyOn(mDisplayContent); + + // Expecting the IME screenshot only be attached when performing task closing transition. + task.applyAnimation(null, TRANSIT_OLD_TASK_CLOSE, false /* enter */, + false /* isVoiceInteraction */, sources); + verify(mDisplayContent).showImeScreenshot(); + + clearInvocations(mDisplayContent); + activity.applyAnimation(null, TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE, false /* enter */, + false /* isVoiceInteraction */, sources); + verify(mDisplayContent, never()).showImeScreenshot(); + } + @Test public void testRotateBounds_keepSamePhysicalPosition() { final DisplayContent dc =