Fix InputConnection creation callback

As noted in the linked bug, in certain scenarios IC established callback
is not always called. As a fix, we make sure we don't return early when
MSG_BIND callback is received from IME

Fix: 228105257
Bug: 217971553

Test: atest StylusHandwritingTest#testHandwritingEndToEnd

Change-Id: I780327003f7145c4f9b9df4dc5243227d7e67d92
This commit is contained in:
Taran Singh
2022-04-21 21:44:02 +00:00
parent c37d317e0c
commit fc6d5e91b7
2 changed files with 29 additions and 6 deletions

View File

@@ -33,6 +33,7 @@ import static android.view.inputmethod.InputMethodManagerProto.CUR_ID;
import static android.view.inputmethod.InputMethodManagerProto.FULLSCREEN_MODE;
import static android.view.inputmethod.InputMethodManagerProto.SERVED_CONNECTING;
import static com.android.internal.inputmethod.StartInputReason.BOUND_TO_IMMS;
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITHOUT_CONNECTION;
import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_CONNECTION;
@@ -449,6 +450,11 @@ public final class InputMethodManager {
int mInitialSelStart;
int mInitialSelEnd;
/**
* Handler for {@link RemoteInputConnectionImpl#getInputConnection()}.
*/
private Handler mServedInputConnectionHandler;
/**
* The instance that has previously been sent to the input method.
*/
@@ -1658,6 +1664,7 @@ public final class InputMethodManager {
if (mServedInputConnection != null) {
mServedInputConnection.deactivate();
mServedInputConnection = null;
mServedInputConnectionHandler = null;
}
}
@@ -2289,6 +2296,13 @@ public final class InputMethodManager {
"Starting input: finished by someone else. view=" + dumpViewInfo(view)
+ " servedView=" + dumpViewInfo(servedView)
+ " mServedConnecting=" + mServedConnecting);
if (mServedInputConnection != null && startInputReason == BOUND_TO_IMMS) {
// This is not an error. Once IME binds (MSG_BIND), InputConnection is fully
// established. So we report this to interested recipients.
reportInputConnectionOpened(
mServedInputConnection.getInputConnection(), mCurrentTextBoxAttribute,
mServedInputConnectionHandler, view);
}
return false;
}
@@ -2305,6 +2319,7 @@ public final class InputMethodManager {
if (mServedInputConnection != null) {
mServedInputConnection.deactivate();
mServedInputConnection = null;
mServedInputConnectionHandler = null;
}
RemoteInputConnectionImpl servedInputConnection;
if (ic != null) {
@@ -2323,11 +2338,13 @@ public final class InputMethodManager {
// TODO(b/199934664): See if we can remove this by providing a default impl.
}
icHandler = handler;
mServedInputConnectionHandler = icHandler;
servedInputConnection = new RemoteInputConnectionImpl(
icHandler != null ? icHandler.getLooper() : vh.getLooper(), ic, this, view);
} else {
servedInputConnection = null;
icHandler = null;
mServedInputConnectionHandler = null;
}
mServedInputConnection = servedInputConnection;
@@ -2397,16 +2414,21 @@ public final class InputMethodManager {
Log.v(TAG, "Calling View.onInputConnectionOpened: view= " + view
+ ", ic=" + ic + ", tba=" + tba + ", handler=" + icHandler);
}
view.onInputConnectionOpenedInternal(ic, tba, icHandler);
final ViewRootImpl viewRoot = view.getViewRootImpl();
if (viewRoot != null) {
viewRoot.getHandwritingInitiator().onInputConnectionCreated(view);
}
reportInputConnectionOpened(ic, tba, icHandler, view);
}
return true;
}
private void reportInputConnectionOpened(
InputConnection ic, EditorInfo tba, Handler icHandler, View view) {
view.onInputConnectionOpenedInternal(ic, tba, icHandler);
final ViewRootImpl viewRoot = view.getViewRootImpl();
if (viewRoot != null) {
viewRoot.getHandwritingInitiator().onInputConnectionCreated(view);
}
}
/**
* An empty method only to avoid crashes of apps that call this method via reflection and do not
* handle {@link NoSuchMethodException} in a graceful manner.
@@ -3550,6 +3572,7 @@ public final class InputMethodManager {
p.println(" mCurrentTextBoxAttribute: null");
}
p.println(" mServedInputConnection=" + mServedInputConnection);
p.println(" mServedInputConnectionHandler=" + mServedInputConnectionHandler);
p.println(" mCompletions=" + Arrays.toString(mCompletions));
p.println(" mCursorRect=" + mCursorRect);
p.println(" mCursorSelStart=" + mCursorSelStart

View File

@@ -191,7 +191,7 @@ public final class RemoteInputConnectionImpl extends IInputContext.Stub {
* @return {@link InputConnection} to which incoming IPCs will be dispatched.
*/
@Nullable
private InputConnection getInputConnection() {
public InputConnection getInputConnection() {
synchronized (mLock) {
return mInputConnection;
}