Commit f5feceb2 authored by changwan's avatar changwan Committed by Commit bot

Ignore reentrancy for ImeThread triggering

In the delayed activation of input connection, we call requestFocus()
on proxy view, and this triggers HwSecImmHelper.isPasswordInputType()
on Huawei phone, which in turn calls View#onCreateInputConnection() so
there is an infinite loop, which eventually causes stackoverflow.

Presumably isPasswordInputType() is only concerned about whether
onCreateInputConnection()'s outAttrs.inputType is password type or not,
so we fill out outAttrs.inputType and early out when there is a reentrance.

BUG=636197

Review-Url: https://codereview.chromium.org/2246833002
Cr-Commit-Position: refs/heads/master@{#415220}
parent 00f5b745
......@@ -13,7 +13,6 @@ import android.view.View;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
......@@ -106,15 +105,10 @@ public class ThreadedInputConnection extends BaseInputConnection
mHandler = handler;
}
void initializeOutAttrsOnUiThread(int inputType, int inputFlags, int selectionStart,
int selectionEnd, EditorInfo outAttrs) {
void resetOnUiThread() {
ImeUtils.checkOnUiThread();
mNumNestedBatchEdits = 0;
mPendingAccent = 0;
ImeUtils.computeEditorInfo(inputType, inputFlags, selectionStart, selectionEnd, outAttrs);
if (DEBUG_LOGS) {
Log.w(TAG, "initializeOutAttrs: " + ImeUtils.getEditorInfoDebugString(outAttrs));
}
}
@Override
......
......@@ -36,6 +36,7 @@ public class ThreadedInputConnectionFactory implements ChromiumBaseInputConnecti
private ThreadedInputConnectionProxyView mProxyView;
private ThreadedInputConnection mThreadedInputConnection;
private CheckInvalidator mCheckInvalidator;
private boolean mReentrantTriggering;
// A small class that can be updated to invalidate the check when there is an external event
// such as window focus loss or view focus loss.
......@@ -105,6 +106,14 @@ public class ThreadedInputConnectionFactory implements ChromiumBaseInputConnecti
int selectionEnd, EditorInfo outAttrs) {
ImeUtils.checkOnUiThread();
// Compute outAttrs early in case we early out to prevent reentrancy. (crbug.com/636197)
// TODO(changwan): move this up to ImeAdapter once ReplicaInputConnection is deprecated.
ImeUtils.computeEditorInfo(
inputType, inputFlags, selectionStart, selectionEnd, outAttrs);
if (DEBUG_LOGS) {
Log.w(TAG, "initializeAndGet. outAttr: " + ImeUtils.getEditorInfoDebugString(outAttrs));
}
// IMM can internally ignore subsequent activation requests, e.g., by checking
// mServedConnecting.
if (mCheckInvalidator != null) mCheckInvalidator.invalidate();
......@@ -118,14 +127,17 @@ public class ThreadedInputConnectionFactory implements ChromiumBaseInputConnecti
if (mThreadedInputConnection == null) {
if (DEBUG_LOGS) Log.w(TAG, "Creating ThreadedInputConnection...");
mThreadedInputConnection = new ThreadedInputConnection(view, imeAdapter, mHandler);
} else {
mThreadedInputConnection.resetOnUiThread();
}
mThreadedInputConnection.initializeOutAttrsOnUiThread(inputType, inputFlags,
selectionStart, selectionEnd, outAttrs);
return mThreadedInputConnection;
}
private void triggerDelayedOnCreateInputConnection(final View view) {
if (DEBUG_LOGS) Log.w(TAG, "triggerDelayedOnCreateInputConnection");
// Prevent infinite loop when View methods trigger onCreateInputConnection
// on some OEM phones. (crbug.com/636197)
if (mReentrantTriggering) return;
// We need to check this before creating invalidator.
if (!view.hasFocus() || !view.hasWindowFocus()) return;
......@@ -135,8 +147,10 @@ public class ThreadedInputConnectionFactory implements ChromiumBaseInputConnecti
if (mProxyView == null) {
mProxyView = createProxyView(mHandler, view);
}
mReentrantTriggering = true;
// This does not affect view focus of the real views.
mProxyView.requestFocus();
mReentrantTriggering = false;
view.getHandler().post(new Runnable() {
@Override
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment