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 |