diff options
Diffstat (limited to 'content/public')
-rw-r--r-- | content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java | 78 |
1 files changed, 58 insertions, 20 deletions
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 0d9c2c5..c1792f6 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(); } }); } @@ -3307,6 +3315,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); |