summaryrefslogtreecommitdiff
path: root/core/java/android/inputmethodservice/InputMethodService.java
diff options
context:
space:
mode:
authorYohei Yukawa <yukawa@google.com>2015-09-14 16:48:15 -0700
committerYohei Yukawa <yukawa@google.com>2015-09-14 16:48:15 -0700
commit6fcbb5629019489a88a9748f278d40d554cc5cdc (patch)
tree0169cc3aa62dce8e3adc5ee0cf059b6b1e04e25b /core/java/android/inputmethodservice/InputMethodService.java
parent0f07424dc5b0a9d87c5f14c995447c77c9a636f2 (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.java21
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;
}