Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(583)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java

Issue 2777223004: Migrate IME state update flow (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 6cae0306e6b02cee2884e9b011fe82d609bb6d30..a96b77de2873c5f90dc7099bd7d9387aeeb20632 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
@@ -17,8 +17,6 @@ import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.ResultReceiver;
import android.os.SystemClock;
import android.util.Pair;
import android.view.ActionMode;
@@ -37,7 +35,6 @@ import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeL
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputMethodManager;
import org.chromium.base.ObserverList;
import org.chromium.base.ObserverList.RewindableIterator;
@@ -61,6 +58,7 @@ import org.chromium.content_public.browser.AccessibilitySnapshotCallback;
import org.chromium.content_public.browser.AccessibilitySnapshotNode;
import org.chromium.content_public.browser.ActionModeCallbackHelper;
import org.chromium.content_public.browser.GestureStateListener;
+import org.chromium.content_public.browser.ImeEventObserver;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.device.gamepad.GamepadList;
@@ -68,7 +66,6 @@ import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.base.EventForwarder;
import org.chromium.ui.base.ViewAndroidDelegate;
import org.chromium.ui.base.WindowAndroid;
-import org.chromium.ui.base.ime.TextInputType;
import org.chromium.ui.display.DisplayAndroid;
import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver;
@@ -92,7 +89,7 @@ import java.util.Map;
public class ContentViewCore
implements AccessibilityStateChangeListener, DisplayAndroidObserver,
SystemCaptioningBridge.SystemCaptioningBridgeListener, WindowAndroidProvider,
- JoystickZoomProvider.PinchZoomHandler {
+ JoystickZoomProvider.PinchZoomHandler, ImeEventObserver {
private static final String TAG = "cr_ContentViewCore";
// Used to avoid enabling zooming in / out if resulting zooming will
@@ -174,32 +171,6 @@ public class ContentViewCore
}
/**
- * {@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.
- */
- // TODO(crbug.com/635567): Fix this properly.
- @SuppressLint("ParcelCreator")
- private static class ShowKeyboardResultReceiver extends ResultReceiver {
-
- // Unfortunately, the memory life cycle of ResultReceiver object, once passed in
- // showSoftInput(), is in the control of Android's input method framework and IME app,
- // so we use a weakref to avoid tying CVC's lifetime to that of ResultReceiver 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.
*
@@ -322,10 +293,6 @@ public class ContentViewCore
// WebView.
private boolean mShouldSetAccessibilityFocusOnPageLoad;
- // Temporary notification to tell onSizeChanged to focus a form element,
- // because the OSK was just brought up.
- private final Rect mFocusPreOSKViewportRect = new Rect();
-
// Whether a touch scroll sequence is active, used to hide text selection
// handles. Note that a scroll sequence will *always* bound a pinch
// sequence, so this will also be true for the duration of a pinch gesture.
@@ -356,10 +323,6 @@ public class ContentViewCore
// A ViewAndroidDelegate that delegates to the current container view.
private ViewAndroidDelegate mViewAndroidDelegate;
- // 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;
-
private Boolean mHasViewFocus;
// The list of observers that are notified when ContentViewCore changes its WindowAndroid.
@@ -474,6 +437,10 @@ public class ContentViewCore
if (mNativeContentViewCore != 0) nativeWasResized(mNativeContentViewCore);
}
+ public void addImeEventObserver(ImeEventObserver imeEventObserver) {
+ mImeAdapter.addEventObserver(imeEventObserver);
+ }
+
@VisibleForTesting
public void setImeAdapterForTest(ImeAdapter imeAdapter) {
mImeAdapter = imeAdapter;
@@ -484,55 +451,6 @@ public class ContentViewCore
return mImeAdapter;
}
- private ImeAdapter createImeAdapter() {
- return new ImeAdapter(mWebContents, new InputMethodManagerWrapper(mContext),
- new ImeAdapter.ImeAdapterDelegate() {
- @Override
- public void onImeEvent() {
- mPopupZoomer.hide(true);
- getContentViewClient().onImeEvent();
- if (isFocusedNodeEditable()) mWebContents.dismissTextHandles();
- }
-
- @Override
- public void onKeyboardBoundsUnchanged() {
- assert mWebContents != null;
- mWebContents.scrollFocusedEditableNodeIntoView();
- }
-
- @Override
- public boolean performContextMenuAction(int id) {
- assert mWebContents != null;
- switch (id) {
- case android.R.id.selectAll:
- mWebContents.selectAll();
- return true;
- case android.R.id.cut:
- mWebContents.cut();
- return true;
- case android.R.id.copy:
- mWebContents.copy();
- return true;
- case android.R.id.paste:
- mWebContents.paste();
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public View getAttachedView() {
- return mContainerView;
- }
-
- @Override
- public ResultReceiver getNewShowKeyboardReceiver() {
- return ContentViewCore.this.getNewShowKeyboardReceiver();
- }
- });
- }
-
/**
*
* @param viewDelegate Delegate to add/remove anchor views.
@@ -570,12 +488,14 @@ public class ContentViewCore
setContainerViewInternals(internalDispatcher);
initPopupZoomer(mContext);
- mImeAdapter = createImeAdapter();
+ mImeAdapter = new ImeAdapter(
+ mWebContents, mContainerView, new InputMethodManagerWrapper(mContext));
+ mImeAdapter.addEventObserver(this);
- mSelectionPopupController = new SelectionPopupController(mContext, windowAndroid,
- webContents, viewDelegate.getContainerView(), mRenderCoordinates);
+ mSelectionPopupController = new SelectionPopupController(
+ mContext, windowAndroid, webContents, mContainerView, mRenderCoordinates);
mSelectionPopupController.setCallback(ActionModeCallbackHelper.EMPTY_CALLBACK);
- mSelectionPopupController.setContainerView(getContainerView());
+ mSelectionPopupController.setContainerView(mContainerView);
mWebContentsObserver = new ContentViewWebContentsObserver(this);
@@ -663,6 +583,7 @@ public class ContentViewCore
if (mContainerView != null) {
hideSelectPopupWithCancelMessage();
mPopupZoomer.hide(false);
+ mImeAdapter.setContainerView(containerView);
}
mContainerView = containerView;
@@ -1295,12 +1216,13 @@ public class ContentViewCore
// Execute a delayed form focus operation because the OSK was brought
// up earlier.
- if (!mFocusPreOSKViewportRect.isEmpty()) {
+ Rect focusPreOSKViewportRect = mImeAdapter.getFocusPreOSKViewportRect();
+ if (!focusPreOSKViewportRect.isEmpty()) {
Rect rect = new Rect();
getContainerView().getWindowVisibleDisplayFrame(rect);
- if (!rect.equals(mFocusPreOSKViewportRect)) {
+ if (!rect.equals(focusPreOSKViewportRect)) {
// Only assume the OSK triggered the onSizeChanged if width was preserved.
- if (rect.width() == mFocusPreOSKViewportRect.width()) {
+ if (rect.width() == focusPreOSKViewportRect.width()) {
assert mWebContents != null;
mWebContents.scrollFocusedEditableNodeIntoView();
}
@@ -1312,7 +1234,7 @@ public class ContentViewCore
private void cancelRequestToScrollFocusedEditableNodeIntoView() {
// Zero-ing the rect will prevent |updateAfterSizeChanged()| from
// issuing the delayed form focus event.
- mFocusPreOSKViewportRect.setEmpty();
+ mImeAdapter.getFocusPreOSKViewportRect().setEmpty();
}
/**
@@ -1791,31 +1713,17 @@ public class ContentViewCore
TraceEvent.end("ContentViewCore:updateFrameInfo");
}
- @CalledByNative
- private void updateImeAdapter(int textInputType, int textInputFlags, int textInputMode,
- String text, int selectionStart, int selectionEnd, int compositionStart,
- int compositionEnd, boolean showImeIfNeeded, boolean replyToRequest) {
- try {
- TraceEvent.begin("ContentViewCore.updateImeAdapter");
- boolean focusedNodeEditable = (textInputType != TextInputType.NONE);
- boolean focusedNodeIsPassword = (textInputType == TextInputType.PASSWORD);
-
- mImeAdapter.updateState(textInputType, textInputFlags, textInputMode, showImeIfNeeded,
- text, selectionStart, selectionEnd, compositionStart, compositionEnd,
- replyToRequest);
-
- boolean editableToggled = (focusedNodeEditable != isFocusedNodeEditable());
- mSelectionPopupController.updateSelectionState(focusedNodeEditable,
- focusedNodeIsPassword);
- if (editableToggled) {
- if (mJoystickScrollProvider != null) {
- mJoystickScrollProvider.setEnabled(!focusedNodeEditable);
- }
- getContentViewClient().onFocusedNodeEditabilityChanged(focusedNodeEditable);
- }
- } finally {
- TraceEvent.end("ContentViewCore.updateImeAdapter");
- }
+ // ImeEventObserver
+
+ @Override
+ public void onImeEvent() {
+ mPopupZoomer.hide(true);
+ }
+
+ @Override
+ public void onNodeAttributeUpdated(boolean editable, boolean password) {
+ if (mJoystickScrollProvider != null) mJoystickScrollProvider.setEnabled(!editable);
+ mSelectionPopupController.updateSelectionState(editable, password);
}
/**
@@ -1937,10 +1845,7 @@ public class ContentViewCore
*/
@CalledByNative
private boolean hasFocus() {
- // If the container view is not focusable, we consider it always focused from
- // Chromium's point of view.
- if (!mContainerView.isFocusable()) return true;
- return mContainerView.hasFocus();
+ return ViewUtils.hasFocus(mContainerView);
}
/**
@@ -2564,35 +2469,6 @@ public class ContentViewCore
mSelectionPopupController.setSelectionClient(selectionClient);
}
- /**
- * 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, float dipScale, HashSet<Object> retainedObjectSet);
private static native ContentViewCore nativeFromWebContentsAndroid(WebContents webContents);
« no previous file with comments | « content/public/android/BUILD.gn ('k') | content/public/android/java/src/org/chromium/content/browser/ViewUtils.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698