Loading core/java/android/view/ViewRootImpl.java +0 −14 Original line number Diff line number Diff line Loading @@ -3287,7 +3287,6 @@ 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; Loading Loading @@ -3327,8 +3326,6 @@ 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: Loading Loading @@ -3549,12 +3546,6 @@ 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) { Loading Loading @@ -5864,11 +5855,6 @@ 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, Loading core/java/android/view/inputmethod/BaseInputConnection.java +2 −2 Original line number Diff line number Diff line Loading @@ -158,8 +158,8 @@ public class BaseInputConnection implements InputConnection { * * @hide */ protected void reportFinish() { // Intentionaly empty public void reportFinish() { // Intentionally empty } /** Loading core/java/android/view/inputmethod/InputMethodManager.java +12 −53 Original line number Diff line number Diff line Loading @@ -531,22 +531,25 @@ 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 && mActive; return mParentInputMethodManager.mActive && !isFinished(); } void deactivate() { mActive = false; if (isFinished()) { // This is a small performance optimization. Still only the 1st call of // reportFinish() will take effect. return; } reportFinish(); } @Override Loading @@ -563,7 +566,7 @@ public final class InputMethodManager { public String toString() { return "ControlledInputConnectionWrapper{" + "connection=" + getInputConnection() + " mActive=" + mActive + " finished=" + isFinished() + " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive + "}"; } Loading Loading @@ -837,7 +840,6 @@ public final class InputMethodManager { throw e.rethrowFromSystemServer(); } } notifyInputConnectionFinished(); mServedView = null; mCompletions = null; mServedConnecting = false; Loading @@ -845,48 +847,6 @@ public final class InputMethodManager { } } /** * Notifies the served view that the current InputConnection will no longer be used. */ private void notifyInputConnectionFinished() { if (mServedView == null || mServedInputConnectionWrapper == null) { return; } final InputConnection inputConnection = mServedInputConnectionWrapper.getInputConnection(); if (inputConnection == null) { return; } // 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(inputConnection); } } /** * Called from the FINISH_INPUT_CONNECTION message above. * @hide */ public void reportFinishInputConnection(InputConnection ic) { final InputConnection currentConnection; if (mServedInputConnectionWrapper == null) { currentConnection = null; } else { currentConnection = mServedInputConnectionWrapper.getInputConnection(); } if (currentConnection != 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) { Loading Loading @@ -1252,8 +1212,10 @@ public final class InputMethodManager { // Hook 'em up and let 'er rip. mCurrentTextBoxAttribute = tba; mServedConnecting = false; // Notify the served view that its previous input connection is finished notifyInputConnectionFinished(); if (mServedInputConnectionWrapper != null) { mServedInputConnectionWrapper.deactivate(); mServedInputConnectionWrapper = null; } ControlledInputConnectionWrapper servedContext; final int missingMethodFlags; if (ic != null) { Loading @@ -1278,9 +1240,6 @@ public final class InputMethodManager { servedContext = null; missingMethodFlags = 0; } if (mServedInputConnectionWrapper != null) { mServedInputConnectionWrapper.deactivate(); } mServedInputConnectionWrapper = servedContext; try { Loading core/java/com/android/internal/view/IInputConnectionWrapper.java +48 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.view; import com.android.internal.annotations.GuardedBy; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; Loading @@ -25,6 +27,7 @@ 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; Loading Loading @@ -58,12 +61,16 @@ 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 Looper mMainLooper; private Handler mH; private Object mLock = new Object(); @GuardedBy("mLock") private boolean mFinished = false; static class SomeArgs { Object arg1; Loading Loading @@ -94,6 +101,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { return mInputConnection.get(); } protected boolean isFinished() { synchronized (mLock) { return mFinished; } } abstract protected boolean isActive(); /** Loading Loading @@ -206,6 +219,10 @@ 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 Loading Loading @@ -481,6 +498,36 @@ 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); } Loading core/java/com/android/internal/widget/EditableInputConnection.java +4 −1 Original line number Diff line number Diff line Loading @@ -83,8 +83,11 @@ public class EditableInputConnection extends BaseInputConnection { return false; } /** * @hide */ @Override protected void reportFinish() { public void reportFinish() { super.reportFinish(); synchronized(this) { Loading Loading
core/java/android/view/ViewRootImpl.java +0 −14 Original line number Diff line number Diff line Loading @@ -3287,7 +3287,6 @@ 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; Loading Loading @@ -3327,8 +3326,6 @@ 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: Loading Loading @@ -3549,12 +3546,6 @@ 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) { Loading Loading @@ -5864,11 +5855,6 @@ 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, Loading
core/java/android/view/inputmethod/BaseInputConnection.java +2 −2 Original line number Diff line number Diff line Loading @@ -158,8 +158,8 @@ public class BaseInputConnection implements InputConnection { * * @hide */ protected void reportFinish() { // Intentionaly empty public void reportFinish() { // Intentionally empty } /** Loading
core/java/android/view/inputmethod/InputMethodManager.java +12 −53 Original line number Diff line number Diff line Loading @@ -531,22 +531,25 @@ 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 && mActive; return mParentInputMethodManager.mActive && !isFinished(); } void deactivate() { mActive = false; if (isFinished()) { // This is a small performance optimization. Still only the 1st call of // reportFinish() will take effect. return; } reportFinish(); } @Override Loading @@ -563,7 +566,7 @@ public final class InputMethodManager { public String toString() { return "ControlledInputConnectionWrapper{" + "connection=" + getInputConnection() + " mActive=" + mActive + " finished=" + isFinished() + " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive + "}"; } Loading Loading @@ -837,7 +840,6 @@ public final class InputMethodManager { throw e.rethrowFromSystemServer(); } } notifyInputConnectionFinished(); mServedView = null; mCompletions = null; mServedConnecting = false; Loading @@ -845,48 +847,6 @@ public final class InputMethodManager { } } /** * Notifies the served view that the current InputConnection will no longer be used. */ private void notifyInputConnectionFinished() { if (mServedView == null || mServedInputConnectionWrapper == null) { return; } final InputConnection inputConnection = mServedInputConnectionWrapper.getInputConnection(); if (inputConnection == null) { return; } // 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(inputConnection); } } /** * Called from the FINISH_INPUT_CONNECTION message above. * @hide */ public void reportFinishInputConnection(InputConnection ic) { final InputConnection currentConnection; if (mServedInputConnectionWrapper == null) { currentConnection = null; } else { currentConnection = mServedInputConnectionWrapper.getInputConnection(); } if (currentConnection != 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) { Loading Loading @@ -1252,8 +1212,10 @@ public final class InputMethodManager { // Hook 'em up and let 'er rip. mCurrentTextBoxAttribute = tba; mServedConnecting = false; // Notify the served view that its previous input connection is finished notifyInputConnectionFinished(); if (mServedInputConnectionWrapper != null) { mServedInputConnectionWrapper.deactivate(); mServedInputConnectionWrapper = null; } ControlledInputConnectionWrapper servedContext; final int missingMethodFlags; if (ic != null) { Loading @@ -1278,9 +1240,6 @@ public final class InputMethodManager { servedContext = null; missingMethodFlags = 0; } if (mServedInputConnectionWrapper != null) { mServedInputConnectionWrapper.deactivate(); } mServedInputConnectionWrapper = servedContext; try { Loading
core/java/com/android/internal/view/IInputConnectionWrapper.java +48 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.view; import com.android.internal.annotations.GuardedBy; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Bundle; Loading @@ -25,6 +27,7 @@ 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; Loading Loading @@ -58,12 +61,16 @@ 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 Looper mMainLooper; private Handler mH; private Object mLock = new Object(); @GuardedBy("mLock") private boolean mFinished = false; static class SomeArgs { Object arg1; Loading Loading @@ -94,6 +101,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub { return mInputConnection.get(); } protected boolean isFinished() { synchronized (mLock) { return mFinished; } } abstract protected boolean isActive(); /** Loading Loading @@ -206,6 +219,10 @@ 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 Loading Loading @@ -481,6 +498,36 @@ 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); } Loading
core/java/com/android/internal/widget/EditableInputConnection.java +4 −1 Original line number Diff line number Diff line Loading @@ -83,8 +83,11 @@ public class EditableInputConnection extends BaseInputConnection { return false; } /** * @hide */ @Override protected void reportFinish() { public void reportFinish() { super.reportFinish(); synchronized(this) { Loading