Merge ControlledInputConnectionWrapper into parent class
Since ControlledInputConnectionWrapper is the only derived class of IInputConnectionWrapper hence it doesn't have a reason keep them separate. Bug: 167948374 Bug: 163450598 Test: atest CtsInputMethodTestCases Change-Id: Ice1ea23dcb2351b56ef03b507d8aec8f8fb7b30a
This commit is contained in:
@@ -106,7 +106,6 @@ import com.android.internal.view.InputBindResult;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -413,7 +412,7 @@ public final class InputMethodManager {
|
||||
* The InputConnection that was last retrieved from the served view.
|
||||
*/
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
ControlledInputConnectionWrapper mServedInputConnectionWrapper;
|
||||
IInputConnectionWrapper mServedInputConnectionWrapper;
|
||||
/**
|
||||
* The completions that were last provided by the served view.
|
||||
*/
|
||||
@@ -740,8 +739,7 @@ public final class InputMethodManager {
|
||||
/**
|
||||
* Checks whether the active input connection (if any) is for the given view.
|
||||
*
|
||||
* TODO(b/160968797): Remove this method and move mServedInputConnectionWrapper to
|
||||
* ImeFocusController.
|
||||
* TODO(b/182259171): Clean-up hasActiveConnection to simplify the logic.
|
||||
*
|
||||
* Note that this method is only intended for restarting input after focus gain
|
||||
* (e.g. b/160391516), DO NOT leverage this method to do another check.
|
||||
@@ -755,7 +753,7 @@ public final class InputMethodManager {
|
||||
|
||||
return mServedInputConnectionWrapper != null
|
||||
&& mServedInputConnectionWrapper.isActive()
|
||||
&& mServedInputConnectionWrapper.mServedView.get() == view;
|
||||
&& mServedInputConnectionWrapper.getServedView() == view;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1022,77 +1020,6 @@ public final class InputMethodManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper {
|
||||
private final InputMethodManager mParentInputMethodManager;
|
||||
private final WeakReference<View> mServedView;
|
||||
|
||||
ControlledInputConnectionWrapper(Looper icLooper, InputConnection conn,
|
||||
InputMethodManager inputMethodManager, View servedView) {
|
||||
super(icLooper, conn);
|
||||
mParentInputMethodManager = inputMethodManager;
|
||||
mServedView = new WeakReference<>(servedView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return mParentInputMethodManager.mActive && !isFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputMethodManager getIMM() {
|
||||
return mParentInputMethodManager;
|
||||
}
|
||||
|
||||
void deactivate() {
|
||||
if (isFinished()) {
|
||||
// This is a small performance optimization. Still only the 1st call of
|
||||
// reportFinish() will take effect.
|
||||
return;
|
||||
}
|
||||
closeConnection();
|
||||
|
||||
// Notify the app that the InputConnection was closed.
|
||||
final View servedView = mServedView.get();
|
||||
if (servedView != null) {
|
||||
final Handler handler = servedView.getHandler();
|
||||
// The handler is null if the view is already detached. When that's the case, for
|
||||
// now, we simply don't dispatch this callback.
|
||||
if (handler != null) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "Calling View.onInputConnectionClosed: view=" + servedView);
|
||||
}
|
||||
if (handler.getLooper().isCurrentThread()) {
|
||||
servedView.onInputConnectionClosedInternal();
|
||||
} else {
|
||||
handler.post(servedView::onInputConnectionClosedInternal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ControlledInputConnectionWrapper{"
|
||||
+ "connection=" + getInputConnection()
|
||||
+ " finished=" + isFinished()
|
||||
+ " mParentInputMethodManager.mActive=" + mParentInputMethodManager.mActive
|
||||
+ " mServedView=" + mServedView.get()
|
||||
+ "}";
|
||||
}
|
||||
|
||||
void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
// Check that the call is initiated in the main thread of the current InputConnection
|
||||
// {@link InputConnection#getHandler} since the messages to IInputConnectionWrapper are
|
||||
// executed on this thread. Otherwise the messages are dispatched to the correct thread
|
||||
// in IInputConnectionWrapper, but this is not wanted while dumpng, for performance
|
||||
// reasons.
|
||||
if (getInputConnection() instanceof DumpableInputConnection && Looper.myLooper()
|
||||
== getLooper()) {
|
||||
((DumpableInputConnection) getInputConnection()).dumpDebug(proto, fieldId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() {
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
|
||||
@@ -1256,8 +1183,7 @@ public final class InputMethodManager {
|
||||
mMainLooper = looper;
|
||||
mH = new H(looper);
|
||||
mDisplayId = displayId;
|
||||
mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this,
|
||||
null);
|
||||
mIInputContext = new IInputConnectionWrapper(looper, mDummyInputConnection, this, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2063,7 +1989,7 @@ public final class InputMethodManager {
|
||||
mServedInputConnectionWrapper.deactivate();
|
||||
mServedInputConnectionWrapper = null;
|
||||
}
|
||||
ControlledInputConnectionWrapper servedContext;
|
||||
IInputConnectionWrapper servedContext;
|
||||
final int missingMethodFlags;
|
||||
if (ic != null) {
|
||||
mCursorSelStart = tba.initialSelStart;
|
||||
@@ -2080,7 +2006,7 @@ public final class InputMethodManager {
|
||||
} else {
|
||||
icHandler = ic.getHandler();
|
||||
}
|
||||
servedContext = new ControlledInputConnectionWrapper(
|
||||
servedContext = new IInputConnectionWrapper(
|
||||
icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this, view);
|
||||
} else {
|
||||
servedContext = null;
|
||||
|
||||
@@ -31,8 +31,10 @@ import android.util.imetracing.ImeTracing;
|
||||
import android.util.imetracing.InputConnectionHelper;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.CorrectionInfo;
|
||||
import android.view.inputmethod.DumpableInputConnection;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
@@ -49,7 +51,9 @@ import com.android.internal.inputmethod.IIntResultCallback;
|
||||
import com.android.internal.inputmethod.ISurroundingTextResultCallback;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
|
||||
public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public final class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
private static final String TAG = "IInputConnectionWrapper";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
@@ -90,10 +94,13 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
private Looper mMainLooper;
|
||||
private Handler mH;
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||
private Object mLock = new Object();
|
||||
private final Object mLock = new Object();
|
||||
@GuardedBy("mLock")
|
||||
private boolean mFinished = false;
|
||||
|
||||
private final InputMethodManager mParentInputMethodManager;
|
||||
private final WeakReference<View> mServedView;
|
||||
|
||||
class MyHandler extends Handler {
|
||||
MyHandler(Looper looper) {
|
||||
super(looper);
|
||||
@@ -104,11 +111,15 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
executeMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
|
||||
|
||||
public IInputConnectionWrapper(@NonNull Looper mainLooper,
|
||||
@NonNull InputConnection inputConnection,
|
||||
@NonNull InputMethodManager inputMethodManager, @Nullable View servedView) {
|
||||
mInputConnection = inputConnection;
|
||||
mMainLooper = mainLooper;
|
||||
mH = new MyHandler(mMainLooper);
|
||||
mParentInputMethodManager = inputMethodManager;
|
||||
mServedView = new WeakReference<>(servedView);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -118,21 +129,70 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
protected Looper getLooper() {
|
||||
synchronized (mMainLooper) {
|
||||
return mMainLooper;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isFinished() {
|
||||
private boolean isFinished() {
|
||||
synchronized (mLock) {
|
||||
return mFinished;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isActive();
|
||||
public boolean isActive() {
|
||||
return mParentInputMethodManager.isActive() && !isFinished();
|
||||
}
|
||||
|
||||
protected abstract InputMethodManager getIMM();
|
||||
public View getServedView() {
|
||||
return mServedView.get();
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
if (isFinished()) {
|
||||
// This is a small performance optimization. Still only the 1st call of
|
||||
// reportFinish() will take effect.
|
||||
return;
|
||||
}
|
||||
closeConnection();
|
||||
|
||||
// Notify the app that the InputConnection was closed.
|
||||
final View servedView = mServedView.get();
|
||||
if (servedView != null) {
|
||||
final Handler handler = servedView.getHandler();
|
||||
// The handler is null if the view is already detached. When that's the case, for
|
||||
// now, we simply don't dispatch this callback.
|
||||
if (handler != null) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "Calling View.onInputConnectionClosed: view=" + servedView);
|
||||
}
|
||||
if (handler.getLooper().isCurrentThread()) {
|
||||
servedView.onInputConnectionClosedInternal();
|
||||
} else {
|
||||
handler.post(servedView::onInputConnectionClosedInternal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IInputConnectionWrapper{"
|
||||
+ "connection=" + getInputConnection()
|
||||
+ " finished=" + isFinished()
|
||||
+ " mParentInputMethodManager.isActive()=" + mParentInputMethodManager.isActive()
|
||||
+ " mServedView=" + mServedView.get()
|
||||
+ "}";
|
||||
}
|
||||
|
||||
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
synchronized (mLock) {
|
||||
// Check that the call is initiated in the main thread of the current InputConnection
|
||||
// {@link InputConnection#getHandler} since the messages to IInputConnectionWrapper are
|
||||
// executed on this thread. Otherwise the messages are dispatched to the correct thread
|
||||
// in IInputConnectionWrapper, but this is not wanted while dumpng, for performance
|
||||
// reasons.
|
||||
if ((mInputConnection instanceof DumpableInputConnection)
|
||||
&& Looper.myLooper() == mMainLooper) {
|
||||
((DumpableInputConnection) mInputConnection).dumpDebug(proto, fieldId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void getTextAfterCursor(int length, int flags, ICharSequenceResultCallback callback) {
|
||||
dispatchMessage(mH.obtainMessage(DO_GET_TEXT_AFTER_CURSOR, length, flags, callback));
|
||||
@@ -161,6 +221,10 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
dispatchMessage(mH.obtainMessage(DO_GET_SURROUNDING_TEXT, flags, 0 /* unused */, args));
|
||||
}
|
||||
|
||||
public void setImeTemporarilyConsumesInput(boolean imeTemporarilyConsumesInput) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
public void getCursorCapsMode(int reqModes, IIntResultCallback callback) {
|
||||
dispatchMessage(
|
||||
mH.obtainMessage(DO_GET_CURSOR_CAPS_MODE, reqModes, 0 /* unused */, callback));
|
||||
@@ -309,7 +373,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
icProto = InputConnectionHelper.buildGetTextAfterCursorProto(msg.arg1,
|
||||
msg.arg2, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getTextAfterCursor", getIMM(), icProto);
|
||||
TAG + "#getTextAfterCursor", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
@@ -339,7 +403,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
icProto = InputConnectionHelper.buildGetTextBeforeCursorProto(msg.arg1,
|
||||
msg.arg2, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getTextBeforeCursor", getIMM(), icProto);
|
||||
TAG + "#getTextBeforeCursor", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
@@ -368,7 +432,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
if (ImeTracing.getInstance().isEnabled()) {
|
||||
icProto = InputConnectionHelper.buildGetSelectedTextProto(msg.arg1, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getSelectedText", getIMM(), icProto);
|
||||
TAG + "#getSelectedText", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
@@ -402,7 +466,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
icProto = InputConnectionHelper.buildGetSurroundingTextProto(beforeLength,
|
||||
afterLength, flags, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getSurroundingText", getIMM(), icProto);
|
||||
TAG + "#getSurroundingText", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
@@ -432,7 +496,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
icProto = InputConnectionHelper.buildGetCursorCapsModeProto(msg.arg1,
|
||||
result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getCursorCapsMode", getIMM(), icProto);
|
||||
TAG + "#getCursorCapsMode", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
@@ -464,7 +528,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
icProto = InputConnectionHelper.buildGetExtractedTextProto(request,
|
||||
msg.arg1, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getExtractedText", getIMM(), icProto);
|
||||
TAG + "#getExtractedText", mParentInputMethodManager, icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
|
||||
Reference in New Issue
Block a user