diff --git a/api/current.txt b/api/current.txt index 2417493190e33..6bc0757ccd5d6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -43492,6 +43492,7 @@ package android.view.inputmethod { } public final class InputMethodManager { + method public void dispatchKeyEventFromInputMethod(android.view.View, android.view.KeyEvent); method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]); method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype(); method public java.util.List getEnabledInputMethodList(); diff --git a/api/system-current.txt b/api/system-current.txt index 15fc680b75b05..a4e6fa889f900 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -45842,6 +45842,7 @@ package android.view.inputmethod { } public final class InputMethodManager { + method public void dispatchKeyEventFromInputMethod(android.view.View, android.view.KeyEvent); method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]); method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype(); method public java.util.List getEnabledInputMethodList(); diff --git a/api/test-current.txt b/api/test-current.txt index 4a2641f59daa3..fb94d3bbef415 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -43508,6 +43508,7 @@ package android.view.inputmethod { } public final class InputMethodManager { + method public void dispatchKeyEventFromInputMethod(android.view.View, android.view.KeyEvent); method public void displayCompletions(android.view.View, android.view.inputmethod.CompletionInfo[]); method public android.view.inputmethod.InputMethodSubtype getCurrentInputMethodSubtype(); method public java.util.List getEnabledInputMethodList(); diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index 8cfb1eeb5d71f..52f1a5915a47a 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -514,17 +514,7 @@ public boolean setSelection(int start, int end) { * attached to the input connection's view. */ public boolean sendKeyEvent(KeyEvent event) { - synchronized (mIMM.mH) { - ViewRootImpl viewRootImpl = mTargetView != null ? mTargetView.getViewRootImpl() : null; - if (viewRootImpl == null) { - if (mIMM.mServedView != null) { - viewRootImpl = mIMM.mServedView.getViewRootImpl(); - } - } - if (viewRootImpl != null) { - viewRootImpl.dispatchKeyFromIme(event); - } - } + mIMM.dispatchKeyEventFromInputMethod(mTargetView, event); return false; } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 15a5d20463493..9647345c986f4 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -25,6 +25,8 @@ import com.android.internal.view.InputBindResult; import com.android.internal.view.InputMethodClient; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.content.Context; import android.graphics.Rect; @@ -1823,6 +1825,34 @@ public int dispatchInputEvent(InputEvent event, Object token, return DISPATCH_NOT_HANDLED; } + /** + * Provides the default implementation of {@link InputConnection#sendKeyEvent(KeyEvent)}, which + * is expected to dispatch an keyboard event sent from the IME to an appropriate event target + * depending on the given {@link View} and the current focus state. + * + *

CAUTION: This method is provided only for the situation where + * {@link InputConnection#sendKeyEvent(KeyEvent)} needs to be implemented without relying on + * {@link BaseInputConnection}. Do not use this API for anything else.

+ * + * @param targetView the default target view. If {@code null} is specified, then this method + * tries to find a good event target based on the current focus state. + * @param event the key event to be dispatched. + */ + public void dispatchKeyEventFromInputMethod(@Nullable View targetView, + @NonNull KeyEvent event) { + synchronized (mH) { + ViewRootImpl viewRootImpl = targetView != null ? targetView.getViewRootImpl() : null; + if (viewRootImpl == null) { + if (mServedView != null) { + viewRootImpl = mServedView.getViewRootImpl(); + } + } + if (viewRootImpl != null) { + viewRootImpl.dispatchKeyFromIme(event); + } + } + } + // Must be called on the main looper void sendInputEventAndReportResultOnMainLooper(PendingEvent p) { final boolean handled;