From a4f52ad5318969d0000a408ae3aa2222f18f4ef8 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Mon, 28 Mar 2016 17:21:55 -0700 Subject: [PATCH] Fix a remaining View leak in InputMethodManager. Basically there are two ways to clean up IMM#mNextServedView and IMM#mServedView: 1. Clean up them when the Window to which IMM#mServedView belongs is dismissed. 2. Clean up them when IMM#mServedView is detached from a Window. A previous commit [1] has taken care of the case 1, and my previous commit [2] aimed to take care of the case 2, which however had an edge case. Imagine the following code. package com.android.b.bug205171; import android.app.Activity; import android.os.Bundle; import android.widget.EditText; import android.widget.LinearLayout; public class MainActivity extends Activity { LinearLayout mLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLayout = new LinearLayout(this); mLayout.setOrientation(LinearLayout.VERTICAL); final EditText editText = new EditText(this); mLayout.addView(editText); setContentView(mLayout); } @Override protected void onDestroy() { super.onDestroy(); mLayout.removeAllViews(); // (*) mLayout = null; } } In this case, when the focused EditText is manually detached from the Window in MainActivity#onDestroy() at (*) the Window no longer has Window focus. Hence we should have cleaned up them regardless of Window focus in InputMethodManager#onViewDetachedFromWindow(). We have seen that not a small number of Fragment-based apps fall into this issue, probably because Activity#onDestroy() can indirectly trigger ViewGroup#removeView() after the app loses window focus by back key. [1]: Iad09cf5dbb7f6f156fd39ed243431432e00f8945 4478de3c02c1fb2f4f888e696ee1b13721e936d9 [2]: Iaf3fe2c065b5bf91e49a729ba46262114bb6da88 b13f015ab519b3e553c03eba971ada89b472fbbc Bug: b.android.com/205171 Bug: 5057608 Bug: 26348766 Bug: 27450392 Bug: 27858665 Change-Id: I9d8fe9ec5ea8ab5716bd189021899792d1206364 --- core/java/android/view/inputmethod/InputMethodManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 2eadad748616c..f6f88f2e39a42 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1353,7 +1353,7 @@ public final class InputMethodManager { synchronized (mH) { if (DEBUG) Log.v(TAG, "onViewDetachedFromWindow: view=" + dumpViewInfo(view) + " mServedView=" + dumpViewInfo(mServedView)); - if (mServedView == view && view.hasWindowFocus()) { + if (mServedView == view) { mNextServedView = null; scheduleCheckFocusLocked(view); }