| Index: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| index 4a50997b1341bd4a637c574dd7811ebf5a0c4cf8..14b389c52a52f90116996a5a0861323bd933ebd2 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
|
| @@ -362,6 +362,29 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
|
| }
|
|
|
| /**
|
| + * {@ResultReceiver} passed in InputMethodManager#showSoftInput}. We need this to scroll to the
|
| + * editable node at the right timing, which is after input method window shows up.
|
| + */
|
| + private static class ShowKeyboardResultReceiver extends ResultReceiver {
|
| +
|
| + // Unfortunately, ResultReceiver used in showSoftInput() will be leaked. We minimize
|
| + // the leak by weak referencing CVC and therefore WebView object.
|
| + private final WeakReference<ContentViewCore> mContentViewCore;
|
| +
|
| + public ShowKeyboardResultReceiver(ContentViewCore contentViewCore, Handler handler) {
|
| + super(handler);
|
| + mContentViewCore = new WeakReference<>(contentViewCore);
|
| + }
|
| +
|
| + @Override
|
| + public void onReceiveResult(int resultCode, Bundle resultData) {
|
| + ContentViewCore contentViewCore = mContentViewCore.get();
|
| + if (contentViewCore == null) return;
|
| + contentViewCore.onShowKeyboardReceiveResult(resultCode);
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Interface that consumers of {@link ContentViewCore} must implement to allow the proper
|
| * dispatching of view methods through the containing view.
|
| *
|
| @@ -585,6 +608,10 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
|
| // The client that implements Contextual Search functionality, or null if none exists.
|
| private ContextualSearchClient mContextualSearchClient;
|
|
|
| + // NOTE: This object will not be released by Android framework until the matching
|
| + // ResultReceiver in the InputMethodService (IME app) gets gc'ed.
|
| + private ShowKeyboardResultReceiver mShowKeyboardResultReceiver;
|
| +
|
| /**
|
| * @param webContents The {@link WebContents} to find a {@link ContentViewCore} of.
|
| * @return A {@link ContentViewCore} that is connected to {@code webContents} or
|
| @@ -739,26 +766,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
|
|
|
| @Override
|
| public ResultReceiver getNewShowKeyboardReceiver() {
|
| - return new ResultReceiver(new Handler()) {
|
| - @Override
|
| - public void onReceiveResult(int resultCode, Bundle resultData) {
|
| - if (resultCode == InputMethodManager.RESULT_SHOWN) {
|
| - // If OSK is newly shown, delay the form focus until
|
| - // the onSizeChanged (in order to adjust relative to the
|
| - // new size).
|
| - // TODO(jdduke): We should not assume that onSizeChanged will
|
| - // always be called, crbug.com/294908.
|
| - getContainerView().getWindowVisibleDisplayFrame(
|
| - mFocusPreOSKViewportRect);
|
| - } else if (hasFocus() && resultCode
|
| - == InputMethodManager.RESULT_UNCHANGED_SHOWN) {
|
| - // If the OSK was already there, focus the form immediately.
|
| - if (mWebContents != null) {
|
| - mWebContents.scrollFocusedEditableNodeIntoView();
|
| - }
|
| - }
|
| - }
|
| - };
|
| + return ContentViewCore.this.getNewShowKeyboardReceiver();
|
| }
|
| });
|
| }
|
| @@ -3283,6 +3291,36 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
|
| mContextualSearchClient = contextualSearchClient;
|
| }
|
|
|
| + /**
|
| + * Call this when we get result from ResultReceiver passed in calling showSoftInput().
|
| + * @param resultCode The result of showSoftInput() as defined in InputMethodManager.
|
| + */
|
| + public void onShowKeyboardReceiveResult(int resultCode) {
|
| + if (resultCode == InputMethodManager.RESULT_SHOWN) {
|
| + // If OSK is newly shown, delay the form focus until
|
| + // the onSizeChanged (in order to adjust relative to the
|
| + // new size).
|
| + // TODO(jdduke): We should not assume that onSizeChanged will
|
| + // always be called, crbug.com/294908.
|
| + getContainerView().getWindowVisibleDisplayFrame(
|
| + mFocusPreOSKViewportRect);
|
| + } else if (hasFocus() && resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN) {
|
| + // If the OSK was already there, focus the form immediately.
|
| + if (mWebContents != null) {
|
| + mWebContents.scrollFocusedEditableNodeIntoView();
|
| + }
|
| + }
|
| + }
|
| +
|
| + @VisibleForTesting
|
| + public ResultReceiver getNewShowKeyboardReceiver() {
|
| + if (mShowKeyboardResultReceiver == null) {
|
| + // Note: the returned object will get leaked by Android framework.
|
| + mShowKeyboardResultReceiver = new ShowKeyboardResultReceiver(this, new Handler());
|
| + }
|
| + return mShowKeyboardResultReceiver;
|
| + }
|
| +
|
| private native long nativeInit(WebContents webContents, ViewAndroidDelegate viewAndroidDelegate,
|
| long windowAndroidPtr, HashSet<Object> retainedObjectSet);
|
| private static native ContentViewCore nativeFromWebContentsAndroid(WebContents webContents);
|
|
|