Loading core/java/android/inputmethodservice/InputMethodService.java +8 −24 Original line number Diff line number Diff line Loading @@ -370,19 +370,6 @@ public class InputMethodService extends AbstractInputMethodService { InputConnection mStartedInputConnection; EditorInfo mInputEditorInfo; /** * A token to keep tracking the last IPC that triggered * {@link #doStartInput(InputConnection, EditorInfo, boolean)}. If * {@link #doStartInput(InputConnection, EditorInfo, boolean)} was not caused by IPCs from * {@link com.android.server.InputMethodManagerService}, this needs to remain unchanged. * * <p>Some IPCs to {@link com.android.server.InputMethodManagerService} require this token to * disentangle event flows for various purposes such as better window animation and providing * fine-grained debugging information.</p> */ @Nullable private IBinder mStartInputToken; int mShowInputFlags; boolean mShowInputRequested; boolean mLastShowInputRequested; Loading Loading @@ -528,7 +515,7 @@ public class InputMethodService extends AbstractInputMethodService { public void dispatchStartInputWithToken(@Nullable InputConnection inputConnection, @NonNull EditorInfo editorInfo, boolean restarting, @NonNull IBinder startInputToken) { mStartInputToken = startInputToken; mImm.reportStartInput(mToken, startInputToken); // This needs to be dispatched to interface methods rather than doStartInput(). // Otherwise IME developers who have overridden those interface methods will lose Loading Loading @@ -579,8 +566,8 @@ public class InputMethodService extends AbstractInputMethodService { } clearInsetOfPreviousIme(); // If user uses hard keyboard, IME button should always be shown. mImm.setImeWindowStatus(mToken, mStartInputToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); mImm.setImeWindowStatus(mToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); if (resultReceiver != null) { resultReceiver.send(wasVis != isInputViewShown() ? InputMethodManager.RESULT_SHOWN Loading Loading @@ -1059,8 +1046,8 @@ public class InputMethodService extends AbstractInputMethodService { } // If user uses hard keyboard, IME button should always be shown. boolean showing = onEvaluateInputViewShown(); mImm.setImeWindowStatus(mToken, mStartInputToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0), mBackDisposition); mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0), mBackDisposition); } } Loading Loading @@ -1110,8 +1097,7 @@ public class InputMethodService extends AbstractInputMethodService { return; } mBackDisposition = disposition; mImm.setImeWindowStatus(mToken, mStartInputToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); mImm.setImeWindowStatus(mToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); } /** Loading Loading @@ -1861,8 +1847,7 @@ public class InputMethodService extends AbstractInputMethodService { final int nextImeWindowStatus = mapToImeWindowStatus(isInputViewShown()); if (previousImeWindowStatus != nextImeWindowStatus) { mImm.setImeWindowStatus(mToken, mStartInputToken, nextImeWindowStatus, mBackDisposition); mImm.setImeWindowStatus(mToken, nextImeWindowStatus, mBackDisposition); } if ((previousImeWindowStatus & IME_ACTIVE) == 0) { if (DEBUG) Log.v(TAG, "showWindow: showing!"); Loading @@ -1887,7 +1872,7 @@ public class InputMethodService extends AbstractInputMethodService { } private void doHideWindow() { mImm.setImeWindowStatus(mToken, mStartInputToken, 0, mBackDisposition); mImm.setImeWindowStatus(mToken, 0, mBackDisposition); hideWindow(); } Loading Loading @@ -2869,7 +2854,6 @@ public class InputMethodService extends AbstractInputMethodService { p.println(" mInputStarted=" + mInputStarted + " mInputViewStarted=" + mInputViewStarted + " mCandidatesViewStarted=" + mCandidatesViewStarted); p.println(" mStartInputToken=" + mStartInputToken); if (mInputEditorInfo != null) { p.println(" mInputEditorInfo:"); Loading core/java/android/view/inputmethod/InputMethodManager.java +11 −3 Original line number Diff line number Diff line Loading @@ -798,10 +798,18 @@ public final class InputMethodManager { } /** @hide */ public void setImeWindowStatus(IBinder imeToken, IBinder startInputToken, int vis, int backDisposition) { public void setImeWindowStatus(IBinder imeToken, int vis, int backDisposition) { try { mService.setImeWindowStatus(imeToken, startInputToken, vis, backDisposition); mService.setImeWindowStatus(imeToken, vis, backDisposition); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** @hide */ public void reportStartInput(IBinder imeToken, IBinder startInputToken) { try { mService.reportStartInput(imeToken, startInputToken); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading core/java/com/android/internal/view/IInputMethodManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -74,8 +74,8 @@ interface IInputMethodManager { void hideMySoftInput(in IBinder token, int flags); void showMySoftInput(in IBinder token, int flags); void updateStatusIcon(in IBinder token, String packageName, int iconId); void setImeWindowStatus(in IBinder token, in IBinder startInputToken, int vis, int backDisposition); void setImeWindowStatus(in IBinder token, int vis, int backDisposition); void reportStartInput(in IBinder token, in IBinder startInputToken); void registerSuggestionSpansForNotification(in SuggestionSpan[] spans); boolean notifySuggestionPicked(in SuggestionSpan span, String originalString, int index); InputMethodSubtype getCurrentInputMethodSubtype(); Loading services/core/java/com/android/server/InputMethodManagerService.java +27 −8 Original line number Diff line number Diff line Loading @@ -467,6 +467,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ IBinder mCurFocusedWindow; /** * The last window token that we confirmed that IME started talking to. This is always updated * upon reports from the input method. If the window state is already changed before the report * is handled, this field just keeps the last value. */ IBinder mLastImeTargetWindow; /** * {@link WindowManager.LayoutParams#softInputMode} of {@link #mCurFocusedWindow}. * Loading Loading @@ -688,7 +695,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @GuardedBy("mMethodMap") private final WeakHashMap<IBinder, StartInputInfo> mStartInputMap = new WeakHashMap<>(); private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>(); /** * A ring buffer to store the history of {@link StartInputInfo}. Loading Loading @@ -1809,7 +1816,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final StartInputInfo info = new StartInputInfo(mCurToken, mCurId, startInputReason, !initial, mCurFocusedWindow, mCurAttribute, mCurFocusedWindowSoftInputMode, mCurSeq); mStartInputMap.put(startInputToken, info); mImeTargetWindowMap.put(startInputToken, mCurFocusedWindow); mStartInputHistory.addEntry(info); final SessionState session = mCurClient.curSession; Loading Loading @@ -2219,15 +2226,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @BinderThread @SuppressWarnings("deprecation") @Override public void setImeWindowStatus(IBinder token, IBinder startInputToken, int vis, int backDisposition) { public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { if (!calledWithValidToken(token)) { return; } final StartInputInfo info; synchronized (mMethodMap) { info = mStartInputMap.get(startInputToken); mImeWindowVis = vis; mBackDisposition = backDisposition; updateSystemUiLocked(token, vis, backDisposition); Loading @@ -2247,8 +2251,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub break; } mWindowManagerInternal.updateInputMethodWindowStatus(token, (vis & InputMethodService.IME_VISIBLE) != 0, dismissImeOnBackKeyPressed, info != null ? info.mTargetWindow : null); (vis & InputMethodService.IME_VISIBLE) != 0, dismissImeOnBackKeyPressed); } private void updateSystemUi(IBinder token, int vis, int backDisposition) { Loading @@ -2257,6 +2260,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } @BinderThread @Override public void reportStartInput(IBinder token, IBinder startInputToken) { if (!calledWithValidToken(token)) { return; } synchronized (mMethodMap) { final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken); if (targetWindow != null && mLastImeTargetWindow != targetWindow) { mWindowManagerInternal.updateInputMethodTargetWindow(token, targetWindow); } mLastImeTargetWindow = targetWindow; } } // Caution! This method is called in this class. Handle multi-user carefully private void updateSystemUiLocked(IBinder token, int vis, int backDisposition) { if (!calledWithValidToken(token)) { Loading services/core/java/com/android/server/wm/WindowManagerInternal.java +17 −6 Original line number Diff line number Diff line Loading @@ -368,14 +368,25 @@ public abstract class WindowManagerInternal { * to be synchronized with state in WindowManagerService. * @param dismissImeOnBackKeyPressed {@code true} if the software keyboard is shown and the back * key is expected to dismiss the software keyboard. * @param targetWindowToken token to identify the target window that the IME is associated with. * {@code null} when application, system, or the IME itself decided to * change its window visibility before being associated with any target * window. */ public abstract void updateInputMethodWindowStatus(@NonNull IBinder imeToken, boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed, @Nullable IBinder targetWindowToken); boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed); /** * Notifies WindowManagerService that the current IME window status is being changed. * * <p>Only {@link com.android.server.InputMethodManagerService} is the expected and tested * caller of this method.</p> * * @param imeToken token to track the active input method. Corresponding IME windows can be * identified by checking {@link android.view.WindowManager.LayoutParams#token}. * Note that there is no guarantee that the corresponding window is already * created * @param imeTargetWindowToken token to identify the target window that the IME is associated * with */ public abstract void updateInputMethodTargetWindow(@NonNull IBinder imeToken, @NonNull IBinder imeTargetWindowToken); /** * Returns true when the hardware keyboard is available. Loading Loading
core/java/android/inputmethodservice/InputMethodService.java +8 −24 Original line number Diff line number Diff line Loading @@ -370,19 +370,6 @@ public class InputMethodService extends AbstractInputMethodService { InputConnection mStartedInputConnection; EditorInfo mInputEditorInfo; /** * A token to keep tracking the last IPC that triggered * {@link #doStartInput(InputConnection, EditorInfo, boolean)}. If * {@link #doStartInput(InputConnection, EditorInfo, boolean)} was not caused by IPCs from * {@link com.android.server.InputMethodManagerService}, this needs to remain unchanged. * * <p>Some IPCs to {@link com.android.server.InputMethodManagerService} require this token to * disentangle event flows for various purposes such as better window animation and providing * fine-grained debugging information.</p> */ @Nullable private IBinder mStartInputToken; int mShowInputFlags; boolean mShowInputRequested; boolean mLastShowInputRequested; Loading Loading @@ -528,7 +515,7 @@ public class InputMethodService extends AbstractInputMethodService { public void dispatchStartInputWithToken(@Nullable InputConnection inputConnection, @NonNull EditorInfo editorInfo, boolean restarting, @NonNull IBinder startInputToken) { mStartInputToken = startInputToken; mImm.reportStartInput(mToken, startInputToken); // This needs to be dispatched to interface methods rather than doStartInput(). // Otherwise IME developers who have overridden those interface methods will lose Loading Loading @@ -579,8 +566,8 @@ public class InputMethodService extends AbstractInputMethodService { } clearInsetOfPreviousIme(); // If user uses hard keyboard, IME button should always be shown. mImm.setImeWindowStatus(mToken, mStartInputToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); mImm.setImeWindowStatus(mToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); if (resultReceiver != null) { resultReceiver.send(wasVis != isInputViewShown() ? InputMethodManager.RESULT_SHOWN Loading Loading @@ -1059,8 +1046,8 @@ public class InputMethodService extends AbstractInputMethodService { } // If user uses hard keyboard, IME button should always be shown. boolean showing = onEvaluateInputViewShown(); mImm.setImeWindowStatus(mToken, mStartInputToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0), mBackDisposition); mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0), mBackDisposition); } } Loading Loading @@ -1110,8 +1097,7 @@ public class InputMethodService extends AbstractInputMethodService { return; } mBackDisposition = disposition; mImm.setImeWindowStatus(mToken, mStartInputToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); mImm.setImeWindowStatus(mToken, mapToImeWindowStatus(isInputViewShown()), mBackDisposition); } /** Loading Loading @@ -1861,8 +1847,7 @@ public class InputMethodService extends AbstractInputMethodService { final int nextImeWindowStatus = mapToImeWindowStatus(isInputViewShown()); if (previousImeWindowStatus != nextImeWindowStatus) { mImm.setImeWindowStatus(mToken, mStartInputToken, nextImeWindowStatus, mBackDisposition); mImm.setImeWindowStatus(mToken, nextImeWindowStatus, mBackDisposition); } if ((previousImeWindowStatus & IME_ACTIVE) == 0) { if (DEBUG) Log.v(TAG, "showWindow: showing!"); Loading @@ -1887,7 +1872,7 @@ public class InputMethodService extends AbstractInputMethodService { } private void doHideWindow() { mImm.setImeWindowStatus(mToken, mStartInputToken, 0, mBackDisposition); mImm.setImeWindowStatus(mToken, 0, mBackDisposition); hideWindow(); } Loading Loading @@ -2869,7 +2854,6 @@ public class InputMethodService extends AbstractInputMethodService { p.println(" mInputStarted=" + mInputStarted + " mInputViewStarted=" + mInputViewStarted + " mCandidatesViewStarted=" + mCandidatesViewStarted); p.println(" mStartInputToken=" + mStartInputToken); if (mInputEditorInfo != null) { p.println(" mInputEditorInfo:"); Loading
core/java/android/view/inputmethod/InputMethodManager.java +11 −3 Original line number Diff line number Diff line Loading @@ -798,10 +798,18 @@ public final class InputMethodManager { } /** @hide */ public void setImeWindowStatus(IBinder imeToken, IBinder startInputToken, int vis, int backDisposition) { public void setImeWindowStatus(IBinder imeToken, int vis, int backDisposition) { try { mService.setImeWindowStatus(imeToken, startInputToken, vis, backDisposition); mService.setImeWindowStatus(imeToken, vis, backDisposition); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** @hide */ public void reportStartInput(IBinder imeToken, IBinder startInputToken) { try { mService.reportStartInput(imeToken, startInputToken); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
core/java/com/android/internal/view/IInputMethodManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -74,8 +74,8 @@ interface IInputMethodManager { void hideMySoftInput(in IBinder token, int flags); void showMySoftInput(in IBinder token, int flags); void updateStatusIcon(in IBinder token, String packageName, int iconId); void setImeWindowStatus(in IBinder token, in IBinder startInputToken, int vis, int backDisposition); void setImeWindowStatus(in IBinder token, int vis, int backDisposition); void reportStartInput(in IBinder token, in IBinder startInputToken); void registerSuggestionSpansForNotification(in SuggestionSpan[] spans); boolean notifySuggestionPicked(in SuggestionSpan span, String originalString, int index); InputMethodSubtype getCurrentInputMethodSubtype(); Loading
services/core/java/com/android/server/InputMethodManagerService.java +27 −8 Original line number Diff line number Diff line Loading @@ -467,6 +467,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ IBinder mCurFocusedWindow; /** * The last window token that we confirmed that IME started talking to. This is always updated * upon reports from the input method. If the window state is already changed before the report * is handled, this field just keeps the last value. */ IBinder mLastImeTargetWindow; /** * {@link WindowManager.LayoutParams#softInputMode} of {@link #mCurFocusedWindow}. * Loading Loading @@ -688,7 +695,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } @GuardedBy("mMethodMap") private final WeakHashMap<IBinder, StartInputInfo> mStartInputMap = new WeakHashMap<>(); private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>(); /** * A ring buffer to store the history of {@link StartInputInfo}. Loading Loading @@ -1809,7 +1816,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final StartInputInfo info = new StartInputInfo(mCurToken, mCurId, startInputReason, !initial, mCurFocusedWindow, mCurAttribute, mCurFocusedWindowSoftInputMode, mCurSeq); mStartInputMap.put(startInputToken, info); mImeTargetWindowMap.put(startInputToken, mCurFocusedWindow); mStartInputHistory.addEntry(info); final SessionState session = mCurClient.curSession; Loading Loading @@ -2219,15 +2226,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub @BinderThread @SuppressWarnings("deprecation") @Override public void setImeWindowStatus(IBinder token, IBinder startInputToken, int vis, int backDisposition) { public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { if (!calledWithValidToken(token)) { return; } final StartInputInfo info; synchronized (mMethodMap) { info = mStartInputMap.get(startInputToken); mImeWindowVis = vis; mBackDisposition = backDisposition; updateSystemUiLocked(token, vis, backDisposition); Loading @@ -2247,8 +2251,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub break; } mWindowManagerInternal.updateInputMethodWindowStatus(token, (vis & InputMethodService.IME_VISIBLE) != 0, dismissImeOnBackKeyPressed, info != null ? info.mTargetWindow : null); (vis & InputMethodService.IME_VISIBLE) != 0, dismissImeOnBackKeyPressed); } private void updateSystemUi(IBinder token, int vis, int backDisposition) { Loading @@ -2257,6 +2260,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } @BinderThread @Override public void reportStartInput(IBinder token, IBinder startInputToken) { if (!calledWithValidToken(token)) { return; } synchronized (mMethodMap) { final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken); if (targetWindow != null && mLastImeTargetWindow != targetWindow) { mWindowManagerInternal.updateInputMethodTargetWindow(token, targetWindow); } mLastImeTargetWindow = targetWindow; } } // Caution! This method is called in this class. Handle multi-user carefully private void updateSystemUiLocked(IBinder token, int vis, int backDisposition) { if (!calledWithValidToken(token)) { Loading
services/core/java/com/android/server/wm/WindowManagerInternal.java +17 −6 Original line number Diff line number Diff line Loading @@ -368,14 +368,25 @@ public abstract class WindowManagerInternal { * to be synchronized with state in WindowManagerService. * @param dismissImeOnBackKeyPressed {@code true} if the software keyboard is shown and the back * key is expected to dismiss the software keyboard. * @param targetWindowToken token to identify the target window that the IME is associated with. * {@code null} when application, system, or the IME itself decided to * change its window visibility before being associated with any target * window. */ public abstract void updateInputMethodWindowStatus(@NonNull IBinder imeToken, boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed, @Nullable IBinder targetWindowToken); boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed); /** * Notifies WindowManagerService that the current IME window status is being changed. * * <p>Only {@link com.android.server.InputMethodManagerService} is the expected and tested * caller of this method.</p> * * @param imeToken token to track the active input method. Corresponding IME windows can be * identified by checking {@link android.view.WindowManager.LayoutParams#token}. * Note that there is no guarantee that the corresponding window is already * created * @param imeTargetWindowToken token to identify the target window that the IME is associated * with */ public abstract void updateInputMethodTargetWindow(@NonNull IBinder imeToken, @NonNull IBinder imeTargetWindowToken); /** * Returns true when the hardware keyboard is available. Loading