From 817d5f7d3ce051184959f9adfac317f31d39d6fe Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Wed, 4 Jan 2017 20:15:02 -0800 Subject: [PATCH] Refresh IMMS#mBoundToMethod when IMS is disconnected It turns out that InputMethodManagerService#mBoundToMethod is not correctly reset to false when the current InputMethodService is killed by the system before IMMS explicitly terminates the connection. As a result, InputMethodService#onBindInput() is not called when the same IMS is reconnected to the IMMS. This also means that IMS#mInputBinding and IMS#mInputConnection remain to be null unexpectedly. Crashes of IMEs and APK replacement of IMEs can trigger such a situation. With this CL, IMMS#onServiceDisconnected() eventually calls IMMS#unbindCurrentClientLocked(). It not only resets IMMS#mBoundToMethod but also updates NavBar icons and closes the IME switcher dialog, but it is probably an acceptable and reasonable behavior change because we have done so when switching the IME. Bug: b.android.com/225029 Bug: 32102706 Test: `adb shell dumpsys input_method | grep "mBoundToMethod"` becomes "false" after the current IME crashes Change-Id: Id87252a1a50029481d08b70afb12f38830bcd1d9 --- .../android/server/InputMethodManagerService.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 372e9a6409947..f718fa11598e2 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -1666,6 +1666,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @Override public void onServiceDisconnected(ComponentName name) { + // Note that mContext.unbindService(this) does not trigger this. Hence if we are here the + // disconnection is not intended by IMMS (e.g. triggered because the current IMS crashed), + // which is irregular but can eventually happen for everyone just by continuing using the + // device. Thus it is important to make sure that all the internal states are properly + // refreshed when this method is called back. Running + // adb install -r + // would be a good way to trigger such a situation. synchronized (mMethodMap) { if (DEBUG) Slog.v(TAG, "Service disconnected: " + name + " mCurIntent=" + mCurIntent); @@ -1677,11 +1684,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mLastBindTime = SystemClock.uptimeMillis(); mShowRequested = mInputShown; mInputShown = false; - if (mCurClient != null) { - executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO( - MSG_UNBIND_CLIENT, InputMethodClient.UNBIND_REASON_DISCONNECT_IME, - mCurSeq, mCurClient.client)); - } + unbindCurrentClientLocked(InputMethodClient.UNBIND_REASON_DISCONNECT_IME); } } }