diff options
| author | Yohei Yukawa <yukawa@google.com> | 2015-09-14 16:48:15 -0700 |
|---|---|---|
| committer | Yohei Yukawa <yukawa@google.com> | 2015-09-14 16:48:15 -0700 |
| commit | 6fcbb5629019489a88a9748f278d40d554cc5cdc (patch) | |
| tree | 0169cc3aa62dce8e3adc5ee0cf059b6b1e04e25b /core/java/android/inputmethodservice/InputMethodService.java | |
| parent | 0f07424dc5b0a9d87c5f14c995447c77c9a636f2 (diff) | |
Handle BadTokenException exception more reliably.
This is a follow up for I2c21573cf972145ab08e66604cdb9344139a3f31, which
added BadTokenException handler so that we can deal with unavoidable
runtime exceptions. However, it turns out that CL does not work well
in a certain case.
One problem in I2c21573cf972145ab08e66604cdb9344139a3f31 that it added
the exception handler in the call site of
InputMethodService#showWindow(boolean) rather than callee side as
follows.
try {
showWindow(true);
} catch (BadTokenException e) {
if (DEBUG) Log.v(TAG, "BadTokenException: IME is done.");
mWindowVisible = false;
}
However, the above code fails to update #mWindowVisible if an IME
overrides InputMethodService#showWindow(boolean) but catch-and-ignore
BadTokenException as follows.
@Override
public void showWindow(boolean showInput) {
try {
super.showWindow(showInput);
// Do something if super.showWindow() succeeds.
} catch (BadTokenException ex) {
// Do something if super.showWindow() fails.
}
}
With this CL, InputMethodService#mWindowVisible is always updated in
the callee side whenever it should be.
Note that this CL does not change anything about which method can
throw BadTokenException and which method catch-and-ignores it so as
not to break existing IMEs unexpectedly.
Bug: 23798142
Change-Id: Id1e5f236f48c8ef01b7f157ba3f6e7ab2c26b135
Diffstat (limited to 'core/java/android/inputmethodservice/InputMethodService.java')
| -rw-r--r-- | core/java/android/inputmethodservice/InputMethodService.java | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 6e28982fe4f8..8ab8991c7a42 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -436,9 +436,12 @@ public class InputMethodService extends AbstractInputMethodService { try { showWindow(true); } catch (BadTokenException e) { - if (DEBUG) Log.v(TAG, "BadTokenException: IME is done."); - mWindowVisible = false; - mWindowAdded = false; + // We have ignored BadTokenException here since Jelly Bean MR-2 (API Level 18). + // We could ignore BadTokenException in InputMethodService#showWindow() instead, + // but it may break assumptions for those who override #showWindow() that we can + // detect errors in #showWindow() by checking BadTokenException. + // TODO: Investigate its feasibility. Update JavaDoc of #showWindow() of + // whether it's OK to override #showWindow() or not. } } clearInsetOfPreviousIme(); @@ -1445,7 +1448,19 @@ public class InputMethodService extends AbstractInputMethodService { mWindowWasVisible = mWindowVisible; mInShowWindow = true; showWindowInner(showInput); + } catch (BadTokenException e) { + // BadTokenException is a normal consequence in certain situations, e.g., swapping IMEs + // while there is a DO_SHOW_SOFT_INPUT message in the IIMethodWrapper queue. + if (DEBUG) Log.v(TAG, "BadTokenException: IME is done."); + mWindowVisible = false; + mWindowAdded = false; + // Rethrow the exception to preserve the existing behavior. Some IMEs may have directly + // called this method and relied on this exception for some clean-up tasks. + // TODO: Give developers a clear guideline of whether it's OK to call this method or + // InputMethodManager#showSoftInputFromInputMethod() should always be used instead. + throw e; } finally { + // TODO: Is it OK to set true when we get BadTokenException? mWindowWasVisible = true; mInShowWindow = false; } |
