summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/ViewRootImpl.java14
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java4
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java70
-rw-r--r--core/java/com/android/internal/view/IInputConnectionWrapper.java59
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java5
5 files changed, 69 insertions, 83 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ffebf711e43e..7c0657795f51 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3287,6 +3287,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
+ private final static int MSG_FINISH_INPUT_CONNECTION = 12;
private final static int MSG_CHECK_FOCUS = 13;
private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14;
private final static int MSG_DISPATCH_DRAG_EVENT = 15;
@@ -3326,6 +3327,8 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_DISPATCH_GET_NEW_SURFACE";
case MSG_DISPATCH_KEY_FROM_IME:
return "MSG_DISPATCH_KEY_FROM_IME";
+ case MSG_FINISH_INPUT_CONNECTION:
+ return "MSG_FINISH_INPUT_CONNECTION";
case MSG_CHECK_FOCUS:
return "MSG_CHECK_FOCUS";
case MSG_CLOSE_SYSTEM_DIALOGS:
@@ -3546,6 +3549,12 @@ public final class ViewRootImpl implements ViewParent,
}
enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
} break;
+ case MSG_FINISH_INPUT_CONNECTION: {
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ imm.reportFinishInputConnection((InputConnection)msg.obj);
+ }
+ } break;
case MSG_CHECK_FOCUS: {
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) {
@@ -5856,6 +5865,11 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ public void dispatchFinishInputConnection(InputConnection connection) {
+ Message msg = mHandler.obtainMessage(MSG_FINISH_INPUT_CONNECTION, connection);
+ mHandler.sendMessage(msg);
+ }
+
public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig, Rect backDropFrame, boolean forceLayout,
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index a3c49c5a8457..6a830f87de1f 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -158,8 +158,8 @@ public class BaseInputConnection implements InputConnection {
*
* @hide
*/
- public void reportFinish() {
- // Intentionally empty
+ protected void reportFinish() {
+ // Intentionaly empty
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 4bb0c3cbb5ee..cf5cc3e0510a 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -317,6 +317,7 @@ public final class InputMethodManager {
/**
* The InputConnection that was last retrieved from the served view.
*/
+ InputConnection mServedInputConnection;
ControlledInputConnectionWrapper mServedInputConnectionWrapper;
/**
* The completions that were last provided by the served view.
@@ -497,7 +498,7 @@ public final class InputMethodManager {
// from a thread that created mServedView. That could happen
// the current activity is running in the system process.
// In that case, we really should not call
- // mServedInputConnectionWrapper.finishComposingText().
+ // mServedInputConnection.finishComposingText.
if (checkFocusNoStartInput(mHasBeenInactive, false)) {
final int reason = active ?
InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS :
@@ -531,25 +532,22 @@ public final class InputMethodManager {
private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
private final InputMethodManager mParentInputMethodManager;
+ private boolean mActive;
public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn,
final InputMethodManager inputMethodManager) {
super(mainLooper, conn);
mParentInputMethodManager = inputMethodManager;
+ mActive = true;
}
@Override
public boolean isActive() {
- return mParentInputMethodManager.mActive && !isFinished();
+ return mParentInputMethodManager.mActive && mActive;
}
void deactivate() {
- if (isFinished()) {
- // This is a small performance optimization. Still only the 1st call of
- // reportFinish() will take effect.
- return;
- }
- reportFinish();
+ mActive = false;
}
@Override
@@ -564,9 +562,7 @@ public final class InputMethodManager {
@Override
public String toString() {
- return "ControlledInputConnectionWrapper{"
- + "connection=" + getInputConnection()
- + " finished=" + isFinished()
+ return "ControlledInputConnectionWrapper{mActive=" + mActive
+ " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
+ "}";
}
@@ -784,8 +780,7 @@ public final class InputMethodManager {
*/
public boolean isAcceptingText() {
checkFocus();
- return mServedInputConnectionWrapper != null &&
- mServedInputConnectionWrapper.getInputConnection() != null;
+ return mServedInputConnection != null;
}
/**
@@ -820,6 +815,7 @@ public final class InputMethodManager {
*/
void clearConnectionLocked() {
mCurrentTextBoxAttribute = null;
+ mServedInputConnection = null;
if (mServedInputConnectionWrapper != null) {
mServedInputConnectionWrapper.deactivate();
mServedInputConnectionWrapper = null;
@@ -840,6 +836,7 @@ public final class InputMethodManager {
throw e.rethrowFromSystemServer();
}
}
+ notifyInputConnectionFinished();
mServedView = null;
mCompletions = null;
mServedConnecting = false;
@@ -847,6 +844,37 @@ public final class InputMethodManager {
}
}
+ /**
+ * Notifies the served view that the current InputConnection will no longer be used.
+ */
+ private void notifyInputConnectionFinished() {
+ if (mServedView != null && mServedInputConnection != null) {
+ // We need to tell the previously served view that it is no
+ // longer the input target, so it can reset its state. Schedule
+ // this call on its window's Handler so it will be on the correct
+ // thread and outside of our lock.
+ ViewRootImpl viewRootImpl = mServedView.getViewRootImpl();
+ if (viewRootImpl != null) {
+ // This will result in a call to reportFinishInputConnection() below.
+ viewRootImpl.dispatchFinishInputConnection(mServedInputConnection);
+ }
+ }
+ }
+
+ /**
+ * Called from the FINISH_INPUT_CONNECTION message above.
+ * @hide
+ */
+ public void reportFinishInputConnection(InputConnection ic) {
+ if (mServedInputConnection != ic) {
+ ic.finishComposingText();
+ // To avoid modifying the public InputConnection interface
+ if (ic instanceof BaseInputConnection) {
+ ((BaseInputConnection) ic).reportFinish();
+ }
+ }
+ }
+
public void displayCompletions(View view, CompletionInfo[] completions) {
checkFocus();
synchronized (mH) {
@@ -1212,10 +1240,9 @@ public final class InputMethodManager {
// Hook 'em up and let 'er rip.
mCurrentTextBoxAttribute = tba;
mServedConnecting = false;
- if (mServedInputConnectionWrapper != null) {
- mServedInputConnectionWrapper.deactivate();
- mServedInputConnectionWrapper = null;
- }
+ // Notify the served view that its previous input connection is finished
+ notifyInputConnectionFinished();
+ mServedInputConnection = ic;
ControlledInputConnectionWrapper servedContext;
final int missingMethodFlags;
if (ic != null) {
@@ -1240,6 +1267,9 @@ public final class InputMethodManager {
servedContext = null;
missingMethodFlags = 0;
}
+ if (mServedInputConnectionWrapper != null) {
+ mServedInputConnectionWrapper.deactivate();
+ }
mServedInputConnectionWrapper = servedContext;
try {
@@ -1383,7 +1413,7 @@ public final class InputMethodManager {
return false;
}
- final ControlledInputConnectionWrapper ic;
+ InputConnection ic = null;
synchronized (mH) {
if (mServedView == mNextServedView && !forceNewFocus) {
return false;
@@ -1403,7 +1433,7 @@ public final class InputMethodManager {
return false;
}
- ic = mServedInputConnectionWrapper;
+ ic = mServedInputConnection;
mServedView = mNextServedView;
mCurrentTextBoxAttribute = null;
@@ -2252,7 +2282,7 @@ public final class InputMethodManager {
} else {
p.println(" mCurrentTextBoxAttribute: null");
}
- p.println(" mServedInputConnectionWrapper=" + mServedInputConnectionWrapper);
+ p.println(" mServedInputConnection=" + mServedInputConnection);
p.println(" mCompletions=" + Arrays.toString(mCompletions));
p.println(" mCursorRect=" + mCursorRect);
p.println(" mCursorSelStart=" + mCursorSelStart
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index 02b9db347f1a..3be15f3998ec 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -16,10 +16,6 @@
package com.android.internal.view;
-import com.android.internal.annotations.GuardedBy;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -27,7 +23,6 @@ import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.KeyEvent;
-import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.ExtractedTextRequest;
@@ -61,16 +56,11 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
private static final int DO_CLEAR_META_KEY_STATES = 130;
private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
- private static final int DO_REPORT_FINISH = 150;
- @NonNull
- private final WeakReference<InputConnection> mInputConnection;
+ private WeakReference<InputConnection> mInputConnection;
private Looper mMainLooper;
private Handler mH;
- private Object mLock = new Object();
- @GuardedBy("mLock")
- private boolean mFinished = false;
static class SomeArgs {
Object arg1;
@@ -96,17 +86,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
mH = new MyHandler(mMainLooper);
}
- @Nullable
- public InputConnection getInputConnection() {
- return mInputConnection.get();
- }
-
- protected boolean isFinished() {
- synchronized (mLock) {
- return mFinished;
- }
- }
-
abstract protected boolean isActive();
/**
@@ -219,10 +198,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
seq, callback));
}
- public void reportFinish() {
- dispatchMessage(obtainMessage(DO_REPORT_FINISH));
- }
-
void dispatchMessage(Message msg) {
// If we are calling this from the main thread, then we can call
// right through. Otherwise, we need to send the message to the
@@ -235,7 +210,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
mH.sendMessage(msg);
}
-
+
void executeMessage(Message msg) {
switch (msg.what) {
case DO_GET_TEXT_AFTER_CURSOR: {
@@ -498,36 +473,6 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
}
return;
}
- case DO_REPORT_FINISH: {
- // Note that we do not need to worry about race condition here, because 1) mFinished
- // is updated only inside this block, and 2) the code here is running on a Handler
- // hence we assume multiple DO_REPORT_FINISH messages will not be handled at the
- // same time.
- if (isFinished()) {
- return;
- }
- try {
- InputConnection ic = mInputConnection.get();
- // Note we do NOT check isActive() here, because this is safe
- // for an IME to call at any time, and we need to allow it
- // through to clean up our state after the IME has switched to
- // another client.
- if (ic == null) {
- return;
- }
- ic.finishComposingText();
- // TODO: Make reportFinish() public method of InputConnection to remove this
- // check.
- if (ic instanceof BaseInputConnection) {
- ((BaseInputConnection) ic).reportFinish();
- }
- } finally {
- synchronized (mLock) {
- mFinished = true;
- }
- }
- return;
- }
}
Log.w(TAG, "Unhandled message code: " + msg.what);
}
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index a96b5a0d6ab1..f211ff269339 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -83,11 +83,8 @@ public class EditableInputConnection extends BaseInputConnection {
return false;
}
- /**
- * @hide
- */
@Override
- public void reportFinish() {
+ protected void reportFinish() {
super.reportFinish();
synchronized(this) {