| Index: content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java
|
| index 271a80ca27802436a21017676c5074feab90b638..7ccb69615126b5f4e5afd7504685bb32ec142e5f 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java
|
| @@ -15,6 +15,8 @@ import org.chromium.base.Log;
|
| import org.chromium.base.ThreadUtils;
|
|
|
| import java.util.concurrent.Callable;
|
| +import java.util.concurrent.atomic.AtomicBoolean;
|
| +import java.util.concurrent.atomic.AtomicReference;
|
|
|
| /**
|
| * This is a fake View that is only exposed to InputMethodManager.
|
| @@ -23,23 +25,58 @@ public class ThreadedInputConnectionProxyView extends View {
|
| private static final String TAG = "cr_Ime";
|
| private static final boolean DEBUG_LOGS = false;
|
|
|
| - private final Handler mHandler;
|
| + private final Handler mImeThreadHandler;
|
| private final View mContainerView;
|
| + private final AtomicBoolean mFocused = new AtomicBoolean();
|
| + private final AtomicBoolean mWindowFocused = new AtomicBoolean();
|
| + private final AtomicReference<IBinder> mWindowToken = new AtomicReference<>();
|
| + private final AtomicReference<View> mRootView = new AtomicReference<>();
|
|
|
| - ThreadedInputConnectionProxyView(Context context, Handler handler, View containerView) {
|
| + ThreadedInputConnectionProxyView(
|
| + Context context, Handler imeThreadHandler, View containerView) {
|
| super(context);
|
| - mHandler = handler;
|
| + mImeThreadHandler = imeThreadHandler;
|
| mContainerView = containerView;
|
| setFocusable(true);
|
| setFocusableInTouchMode(true);
|
| setVisibility(View.VISIBLE);
|
| if (DEBUG_LOGS) Log.w(TAG, "constructor");
|
| +
|
| + mFocused.set(mContainerView.hasFocus());
|
| + mWindowFocused.set(mContainerView.hasWindowFocus());
|
| + mWindowToken.set(mContainerView.getWindowToken());
|
| + mRootView.set(mContainerView.getRootView());
|
| + }
|
| +
|
| + public void onOriginalViewFocusChanged(boolean gainFocus) {
|
| + mFocused.set(gainFocus);
|
| + }
|
| +
|
| + public void onOriginalViewWindowFocusChanged(boolean gainFocus) {
|
| + mWindowFocused.set(gainFocus);
|
| + }
|
| +
|
| + public void onOriginalViewAttachedToWindow() {
|
| + mWindowToken.set(mContainerView.getWindowToken());
|
| + // Note: this is an approximation of the real behavior.
|
| + // Real root view may change upon addView / removeView, but this is good
|
| + // enough for IME purpose.
|
| + mRootView.set(mContainerView.getRootView());
|
| + }
|
| +
|
| + public void onOriginalViewDetachedFromWindow() {
|
| + mWindowToken.set(null);
|
| + // Note: we are not asking mContainerView.getRootView() here. We cannot get the correct
|
| + // root view here as ViewRootImpl's mParent is set to null *after* this call.
|
| + // In vanilla Android, getRootView() is never called when window is detaching or detached
|
| + // anyways.
|
| + mRootView.set(null);
|
| }
|
|
|
| @Override
|
| public Handler getHandler() {
|
| if (DEBUG_LOGS) Log.w(TAG, "getHandler");
|
| - return mHandler;
|
| + return mImeThreadHandler;
|
| }
|
|
|
| @Override
|
| @@ -60,69 +97,34 @@ public class ThreadedInputConnectionProxyView extends View {
|
| }
|
|
|
| @Override
|
| - public boolean hasFocus() {
|
| - if (DEBUG_LOGS) Log.w(TAG, "hasFocus");
|
| - return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
|
| - @Override
|
| - public Boolean call() throws Exception {
|
| - return mContainerView.hasFocus();
|
| - }
|
| - });
|
| - }
|
| -
|
| - @Override
|
| public boolean hasWindowFocus() {
|
| if (DEBUG_LOGS) Log.w(TAG, "hasWindowFocus");
|
| - return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
|
| - @Override
|
| - public Boolean call() throws Exception {
|
| - return mContainerView.hasWindowFocus();
|
| - }
|
| - });
|
| + return mWindowFocused.get();
|
| }
|
|
|
| @Override
|
| public View getRootView() {
|
| if (DEBUG_LOGS) Log.w(TAG, "getRootView");
|
| - return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<View>() {
|
| - @Override
|
| - public View call() throws Exception {
|
| - return mContainerView.getRootView();
|
| - }
|
| - });
|
| + return mRootView.get();
|
| }
|
|
|
| @Override
|
| public boolean onCheckIsTextEditor() {
|
| if (DEBUG_LOGS) Log.w(TAG, "onCheckIsTextEditor");
|
| - return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
|
| - @Override
|
| - public Boolean call() throws Exception {
|
| - return mContainerView.onCheckIsTextEditor();
|
| - }
|
| - });
|
| + // We do not allow Android apps to override WebView#onCheckIsTextEditor() for now.
|
| + return true;
|
| }
|
|
|
| @Override
|
| public boolean isFocused() {
|
| if (DEBUG_LOGS) Log.w(TAG, "isFocused");
|
| - return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<Boolean>() {
|
| - @Override
|
| - public Boolean call() throws Exception {
|
| - return mContainerView.isFocused();
|
| - }
|
| - });
|
| + return mFocused.get();
|
| }
|
|
|
| @Override
|
| public IBinder getWindowToken() {
|
| if (DEBUG_LOGS) Log.w(TAG, "getWindowToken");
|
| - return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<IBinder>() {
|
| - @Override
|
| - public IBinder call() throws Exception {
|
| - return mContainerView.getWindowToken();
|
| - }
|
| - });
|
| + return mWindowToken.get();
|
| }
|
|
|
| @Override
|
|
|