From a6beec8e60daf023d4d853e85480b63117ff6b42 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Fri, 17 Jul 2020 13:52:03 +0200 Subject: [PATCH] Fix stuck IME when IME dialog is focused Only the currently focused window will invoke startInput, and thus control the IME. However, if the IME puts up a focusable dialog, and the requesting activity restarts, its new window won't regain focus - because the IME dialog still has it. Thus, IMMS never receives a startInput, and never tells WMS about a new mInputMethodInputTarget. To address this, we clear mInputMethodInputTarget if it refers to a no longer existing window, then the empty IME control target will take over, and hide the IME, which will hide its dialog and let the newly launched WindowState obtain focus and ultimately control of the IME. Fixes: 160672060 Test: atest 'DisplayContentTests#testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved' Change-Id: I138ac7198013635e7fb620921305ed1eb224d4de --- .../java/com/android/server/wm/WindowState.java | 3 +++ .../android/server/wm/DisplayContentTests.java | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 26bcf3b285ec4..1cf9aeb1e4c7b 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2170,6 +2170,9 @@ class WindowState extends WindowContainer implements WindowManagerP if (isInputMethodTarget()) { dc.computeImeTarget(true /* updateImeTarget */); } + if (dc.mInputMethodInputTarget == this) { + dc.setInputMethodInputTarget(null); + } if (dc.mInputMethodControlTarget == this) { dc.updateImeControlTarget(); } 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 94acd776fcb30..d6e038d8d027d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -889,6 +889,21 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent()); } + @Test + public void testInputMethodInputTarget_isClearedWhenWindowStateIsRemoved() throws Exception { + final DisplayContent dc = createNewDisplay(); + + WindowState app = createWindow(null, TYPE_BASE_APPLICATION, dc, "app"); + + dc.mInputMethodInputTarget = app; + assertEquals(app, dc.computeImeControlTarget()); + + app.removeImmediately(); + + assertNull(dc.mInputMethodInputTarget); + assertNull(dc.computeImeControlTarget()); + } + @Test public void testComputeImeControlTarget() throws Exception { final DisplayContent dc = createNewDisplay();