diff options
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 1 | ||||
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/view/inputmethod/BaseInputConnection.java | 20 | ||||
| -rw-r--r-- | core/java/android/view/inputmethod/InputMethodManager.java | 44 | ||||
| -rw-r--r-- | core/java/com/android/internal/view/IInputConnectionWrapper.java | 29 |
6 files changed, 70 insertions, 26 deletions
diff --git a/api/current.txt b/api/current.txt index 20ca35663504..3c60b02fb9f7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -43646,6 +43646,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<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList(); diff --git a/api/system-current.txt b/api/system-current.txt index 5dc14d2d8932..d5b7a185509e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -46008,6 +46008,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<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList(); diff --git a/api/test-current.txt b/api/test-current.txt index 716a5a4e8a7c..4060b30c6a6a 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -43662,6 +43662,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<android.view.inputmethod.InputMethodInfo> getEnabledInputMethodList(); diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index 6e5e5915bb6f..bdf89e9f02bc 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -195,7 +195,6 @@ public class BaseInputConnection implements InputConnection { public boolean commitText(CharSequence text, int newCursorPosition) { if (DEBUG) Log.v(TAG, "commitText " + text); replaceText(text, newCursorPosition, false); - mIMM.notifyUserAction(); sendCurrentText(); return true; } @@ -450,7 +449,6 @@ public class BaseInputConnection implements InputConnection { public boolean setComposingText(CharSequence text, int newCursorPosition) { if (DEBUG) Log.v(TAG, "setComposingText " + text); replaceText(text, newCursorPosition, true); - mIMM.notifyUserAction(); return true; } @@ -523,29 +521,17 @@ public class BaseInputConnection implements InputConnection { * 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.notifyUserAction(); + mIMM.dispatchKeyEventFromInputMethod(mTargetView, event); return false; } - + /** * Updates InputMethodManager with the current fullscreen mode. */ public boolean reportFullscreenMode(boolean enabled) { - mIMM.setFullscreenMode(enabled); return true; } - + private void sendCurrentText() { if (!mDummyMode) { return; diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 5e0734742e36..9647345c986f 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.IInputMethodSession; 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; @@ -527,7 +529,7 @@ public final class InputMethodManager { } } } - + private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper { private final InputMethodManager mParentInputMethodManager; private boolean mActive; @@ -549,13 +551,23 @@ public final class InputMethodManager { } @Override + protected void onUserAction() { + mParentInputMethodManager.notifyUserAction(); + } + + @Override + protected void onReportFullscreenMode(boolean enabled) { + mParentInputMethodManager.setFullscreenMode(enabled); + } + + @Override public String toString() { return "ControlledInputConnectionWrapper{mActive=" + mActive + " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive + "}"; } } - + final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() { @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { @@ -1813,6 +1825,34 @@ public final class InputMethodManager { 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. + * + * <p>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.</p> + * + * @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; diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java index 85ec29c4634c..0e7f06bc77b9 100644 --- a/core/java/com/android/internal/view/IInputConnectionWrapper.java +++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java @@ -30,7 +30,7 @@ import android.view.inputmethod.InputConnection; import java.lang.ref.WeakReference; -public class IInputConnectionWrapper extends IInputContext.Stub { +public abstract class IInputConnectionWrapper extends IInputContext.Stub { static final String TAG = "IInputConnectionWrapper"; private static final int DO_GET_TEXT_AFTER_CURSOR = 10; @@ -80,15 +80,25 @@ public class IInputConnectionWrapper extends IInputContext.Stub { } public IInputConnectionWrapper(Looper mainLooper, InputConnection conn) { - mInputConnection = new WeakReference<InputConnection>(conn); + mInputConnection = new WeakReference<>(conn); mMainLooper = mainLooper; mH = new MyHandler(mMainLooper); } - public boolean isActive() { - return true; - } - + abstract protected boolean isActive(); + + /** + * Called when the user took some actions that should be taken into consideration to update the + * LRU list for input method rotation. + */ + abstract protected void onUserAction(); + + /** + * Called when the input method started or stopped full-screen mode. + * + */ + abstract protected void onReportFullscreenMode(boolean enabled); + public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) { dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback)); } @@ -284,6 +294,7 @@ public class IInputConnectionWrapper extends IInputContext.Stub { return; } ic.commitText((CharSequence)msg.obj, msg.arg1); + onUserAction(); return; } case DO_SET_SELECTION: { @@ -338,6 +349,7 @@ public class IInputConnectionWrapper extends IInputContext.Stub { return; } ic.setComposingText((CharSequence)msg.obj, msg.arg1); + onUserAction(); return; } case DO_SET_COMPOSING_REGION: { @@ -369,6 +381,7 @@ public class IInputConnectionWrapper extends IInputContext.Stub { return; } ic.sendKeyEvent((KeyEvent)msg.obj); + onUserAction(); return; } case DO_CLEAR_META_KEY_STATES: { @@ -413,7 +426,9 @@ public class IInputConnectionWrapper extends IInputContext.Stub { Log.w(TAG, "reportFullscreenMode on inexistent InputConnection"); return; } - ic.reportFullscreenMode(msg.arg1 == 1); + final boolean enabled = msg.arg1 == 1; + ic.reportFullscreenMode(enabled); + onReportFullscreenMode(enabled); return; } case DO_PERFORM_PRIVATE_COMMAND: { |