diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 923be5e06582b..4799773d9ed69 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -1714,18 +1714,9 @@ public class InputMethodService extends AbstractInputMethodService { private void clearInsetOfPreviousIme() { if (DEBUG) Log.v(TAG, "clearInsetOfPreviousIme() " + " mShouldClearInsetOfPreviousIme=" + mShouldClearInsetOfPreviousIme); - if (!mShouldClearInsetOfPreviousIme || mWindow == null) return; - try { - // We do not call onWindowShown() and onWindowHidden() so as not to make the IME author - // confused. - // TODO: Find out a better way which has less side-effect. - mWindow.show(); - mWindow.hide(); - } catch (WindowManager.BadTokenException e) { - if (DEBUG) Log.v(TAG, "clearInsetOfPreviousIme: BadTokenException: IME is done."); - mWindowVisible = false; - mWindowAdded = false; - } + if (!mShouldClearInsetOfPreviousIme) return; + + mImm.clearLastInputMethodWindowForTransition(mToken); mShouldClearInsetOfPreviousIme = false; } diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java index 4b188c4e35c1b..610dff8c8bab6 100644 --- a/core/java/android/view/WindowManagerInternal.java +++ b/core/java/android/view/WindowManagerInternal.java @@ -260,6 +260,13 @@ public abstract class WindowManagerInternal { */ public abstract void saveLastInputMethodWindowForTransition(); + /** + * Clears last input method window for transition. + * + * Note that it is assumed that this method is called only by InputMethodManagerService. + */ + public abstract void clearLastInputMethodWindowForTransition(); + /** * Returns true when the hardware keyboard is available. */ diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 5a9a212538b68..1618758929ef1 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -2139,6 +2139,28 @@ public final class InputMethodManager { } } + /** + * Tells the system that the IME decided to not show a window and the system no longer needs to + * use the previous IME's inset. + * + *
Caveat: {@link android.inputmethodservice.InputMethodService#clearInsetOfPreviousIme()} + * is the only expected caller of this method. Do not depend on this anywhere else.
+ * + *TODO: We probably need to reconsider how IME should be handled.
+ * @hide + * @param token Supplies the identifying token given to an input method when it was started, + * which allows it to perform this operation on itself. + */ + public void clearLastInputMethodWindowForTransition(final IBinder token) { + synchronized (mH) { + try { + mService.clearLastInputMethodWindowForTransition(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + /** * Force switch to the last used input method and subtype. If the last input method didn't have * any subtypes, the framework will simply switch to the last input method with no subtype diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 94c94c190e6b8..cb7c3bfecc89b 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -79,5 +79,7 @@ interface IInputMethodManager { boolean setInputMethodEnabled(String id, boolean enabled); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); int getInputMethodWindowVisibleHeight(); + void clearLastInputMethodWindowForTransition(in IBinder token); + oneway void notifyUserAction(int sequenceNumber); } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index a584f707f9a9d..b0a00e654b804 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -2642,6 +2642,27 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mWindowManagerInternal.getInputMethodWindowVisibleHeight(); } + @Override + public void clearLastInputMethodWindowForTransition(IBinder token) { + if (!calledFromValidUser()) { + return; + } + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mMethodMap) { + if (!calledWithValidToken(token)) { + final int uid = Binder.getCallingUid(); + Slog.e(TAG, "Ignoring clearLastInputMethodWindowForTransition due to an " + + "invalid token. uid:" + uid + " token:" + token); + return; + } + } + mWindowManagerInternal.clearLastInputMethodWindowForTransition(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + @Override public void notifyUserAction(int sequenceNumber) { if (DEBUG) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 11327582a481d..239cc8eaae8cd 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -11293,6 +11293,13 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override + public void clearLastInputMethodWindowForTransition() { + synchronized (mWindowMap) { + mPolicy.setLastInputMethodWindowLw(null, null); + } + } + @Override public boolean isHardKeyboardAvailable() { synchronized (mWindowMap) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java index 0cf51a46f63f4..3f276c9375ba6 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java @@ -218,6 +218,11 @@ public class BridgeIInputMethodManager implements IInputMethodManager { } + @Override + public void clearLastInputMethodWindowForTransition(IBinder arg0) throws RemoteException { + // TODO Auto-generated method stub + } + @Override public InputBindResult startInputOrWindowGainedFocus( /* @InputMethodClient.StartInputReason */ int startInputReason,