Merge changes Ib5ea8131,I571d6cc9
* changes:
Add a new API IMM#dispatchKeyEventFromInputMethod().
BaseInputConnection shouldn't rely on @hide APIs.
diff --git a/api/current.txt b/api/current.txt
index 20ca356..3c60b02 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -43646,6 +43646,7 @@
}
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 5dc14d2..d5b7a18 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -46008,6 +46008,7 @@
}
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 716a5a4..4060b30 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -43662,6 +43662,7 @@
}
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 6e5e591..bdf89e9 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -195,7 +195,6 @@
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 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 @@
* 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 5e07347..9647345 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;
@@ -527,7 +529,7 @@
}
}
}
-
+
private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
private final InputMethodManager mParentInputMethodManager;
private boolean mActive;
@@ -549,13 +551,23 @@
}
@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 @@
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 85ec29c..0e7f06b 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -30,7 +30,7 @@
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 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 @@
return;
}
ic.commitText((CharSequence)msg.obj, msg.arg1);
+ onUserAction();
return;
}
case DO_SET_SELECTION: {
@@ -338,6 +349,7 @@
return;
}
ic.setComposingText((CharSequence)msg.obj, msg.arg1);
+ onUserAction();
return;
}
case DO_SET_COMPOSING_REGION: {
@@ -369,6 +381,7 @@
return;
}
ic.sendKeyEvent((KeyEvent)msg.obj);
+ onUserAction();
return;
}
case DO_CLEAR_META_KEY_STATES: {
@@ -413,7 +426,9 @@
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: {