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

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

Issue 2103243002: Factor out ContentViewAndroidDelegate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments chrome/webview Created 4 years, 5 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 be34d7dcd57cad827f55dae5c70fc4d44f7cdb6f..31647c351fddb9a9b5469e00827981f6d6e2cb20 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
@@ -46,10 +46,7 @@ import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.CommandLine;
import org.chromium.base.Log;
import org.chromium.base.ObserverList;
@@ -89,7 +86,6 @@ import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.base.ViewAndroidDelegate;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.base.ime.TextInputType;
-import org.chromium.ui.gfx.DeviceDisplayInfo;
import org.chromium.ui.touch_selection.SelectionEventType;
import java.lang.annotation.Annotation;
@@ -97,10 +93,8 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
/**
* Provides a Java-side 'wrapper' around a WebContent (native) instance.
@@ -150,176 +144,6 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
private final HashSet<Object> mRetainedJavaScriptObjects = new HashSet<Object>();
/**
- * A {@link ViewAndroidDelegate} that delegates to the current container view.
- *
- * <p>This delegate handles the replacement of container views transparently so
- * that clients can safely hold to instances of this class.
- */
- private static class ContentViewAndroidDelegate implements ViewAndroidDelegate {
- // TODO(hush): use View#DRAG_FLAG_GLOBAL when Chromium starts to build with API 24.
- private static final int DRAG_FLAG_GLOBAL = 1 << 8;
- /**
- * Represents the position of an anchor view.
- */
- @VisibleForTesting
- private static class Position {
- private final float mX;
- private final float mY;
- private final float mWidth;
- private final float mHeight;
-
- public Position(float x, float y, float width, float height) {
- mX = x;
- mY = y;
- mWidth = width;
- mHeight = height;
- }
- }
-
- private final RenderCoordinates mRenderCoordinates;
-
- /**
- * The current container view. This view can be updated with
- * {@link #updateCurrentContainerView()}. This needs to be a WeakReference
- * because ViewAndroidDelegate is held strongly native side, which otherwise
- * indefinitely prevents Android WebView from being garbage collected.
- */
- private WeakReference<ViewGroup> mCurrentContainerView;
-
- /**
- * List of anchor views stored in the order in which they were acquired mapped
- * to their position.
- */
- private final Map<View, Position> mAnchorViews = new LinkedHashMap<View, Position>();
-
- ContentViewAndroidDelegate(ViewGroup containerView, RenderCoordinates renderCoordinates) {
- mRenderCoordinates = renderCoordinates;
- mCurrentContainerView = new WeakReference<>(containerView);
- }
-
- @Override
- public View acquireAnchorView() {
- ViewGroup containerView = mCurrentContainerView.get();
- if (containerView == null) return null;
- View anchorView = new View(containerView.getContext());
- mAnchorViews.put(anchorView, null);
- containerView.addView(anchorView);
- return anchorView;
- }
-
- @Override
- public void setAnchorViewPosition(
- View view, float x, float y, float width, float height) {
- mAnchorViews.put(view, new Position(x, y, width, height));
- doSetAnchorViewPosition(view, x, y, width, height);
- }
-
- @SuppressWarnings("deprecation") // AbsoluteLayout
- private void doSetAnchorViewPosition(
- View view, float x, float y, float width, float height) {
- if (view.getParent() == null) {
- // Ignore. setAnchorViewPosition has been called after the anchor view has
- // already been released.
- return;
- }
- ViewGroup containerView = mCurrentContainerView.get();
- if (containerView == null) {
- return;
- }
- assert view.getParent() == containerView;
-
- float scale =
- (float) DeviceDisplayInfo.create(containerView.getContext()).getDIPScale();
-
- // The anchor view should not go outside the bounds of the ContainerView.
- int leftMargin = Math.round(x * scale);
- int topMargin = Math.round(mRenderCoordinates.getContentOffsetYPix() + y * scale);
- int scaledWidth = Math.round(width * scale);
- // ContentViewCore currently only supports these two container view types.
- if (containerView instanceof FrameLayout) {
- int startMargin;
- if (ApiCompatibilityUtils.isLayoutRtl(containerView)) {
- startMargin =
- containerView.getMeasuredWidth() - Math.round((width + x) * scale);
- } else {
- startMargin = leftMargin;
- }
- if (scaledWidth + startMargin > containerView.getWidth()) {
- scaledWidth = containerView.getWidth() - startMargin;
- }
- FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
- scaledWidth, Math.round(height * scale));
- ApiCompatibilityUtils.setMarginStart(lp, startMargin);
- lp.topMargin = topMargin;
- view.setLayoutParams(lp);
- } else if (containerView instanceof android.widget.AbsoluteLayout) {
- // This fixes the offset due to a difference in
- // scrolling model of WebView vs. Chrome.
- // TODO(sgurun) fix this to use mContainerViewAtCreation.getScroll[X/Y]()
- // as it naturally accounts for scroll differences between
- // these models.
- leftMargin += mRenderCoordinates.getScrollXPixInt();
- topMargin += mRenderCoordinates.getScrollYPixInt();
-
- android.widget.AbsoluteLayout.LayoutParams lp =
- new android.widget.AbsoluteLayout.LayoutParams(
- scaledWidth, (int) (height * scale), leftMargin, topMargin);
- view.setLayoutParams(lp);
- } else {
- Log.e(TAG, "Unknown layout %s", containerView.getClass().getName());
- }
- }
-
- @Override
- public void releaseAnchorView(View anchorView) {
- mAnchorViews.remove(anchorView);
- ViewGroup containerView = mCurrentContainerView.get();
- if (containerView != null) {
- containerView.removeView(anchorView);
- }
- }
-
- /**
- * Updates (or sets for the first time) the current container view to which
- * this class delegates. Existing anchor views are transferred from the old to
- * the new container view.
- */
- void updateCurrentContainerView(ViewGroup containerView) {
- ViewGroup oldContainerView = mCurrentContainerView.get();
- mCurrentContainerView = new WeakReference<>(containerView);
- for (Entry<View, Position> entry : mAnchorViews.entrySet()) {
- View anchorView = entry.getKey();
- Position position = entry.getValue();
- if (oldContainerView != null) {
- oldContainerView.removeView(anchorView);
- }
- containerView.addView(anchorView);
- if (position != null) {
- doSetAnchorViewPosition(anchorView,
- position.mX, position.mY, position.mWidth, position.mHeight);
- }
- }
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public void startDragAndDrop(String text, Bitmap shadowImage) {
- ClipData data = ClipData.newPlainText(null, text);
-
- ViewGroup containerView = mCurrentContainerView.get();
- if (containerView == null) return;
-
- ImageView imageView = new ImageView(containerView.getContext());
- imageView.setImageBitmap(shadowImage);
- imageView.layout(0, 0, shadowImage.getWidth(), shadowImage.getHeight());
-
- // TODO(hush): use View#startDragAndDrop when Chromium starts to build with API 24.
- containerView.startDrag(
- data, new View.DragShadowBuilder(imageView), null, DRAG_FLAG_GLOBAL);
- }
- }
-
- /**
* A {@link WebContentsObserver} that listens to frame navigation events.
*/
private static class ContentViewWebContentsObserver extends WebContentsObserver {
@@ -625,7 +449,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
private boolean mFullscreenRequiredForOrientationLock = true;
// A ViewAndroidDelegate that delegates to the current container view.
- private ContentViewAndroidDelegate mViewAndroidDelegate;
+ private ViewAndroidDelegate mViewAndroidDelegate;
// A flag to determine if we enable hover feature or not.
private Boolean mEnableTouchHover;
@@ -733,7 +557,10 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
*
* @return A ViewAndroidDelegate that can be used to add and remove views.
*/
+ @VisibleForTesting
public ViewAndroidDelegate getViewAndroidDelegate() {
+ // TODO(jinsukkim): Remove this method since it is only used by tests that don't
+ // necessarily require the delegate.
return mViewAndroidDelegate;
}
@@ -813,17 +640,17 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
// to set the private browsing mode at a later point for the WebView implementation.
// Note that the caller remains the owner of the nativeWebContents and is responsible for
// deleting it after destroying the ContentViewCore.
- public void initialize(ViewGroup containerView, InternalAccessDelegate internalDispatcher,
- WebContents webContents, WindowAndroid windowAndroid) {
- createContentViewAndroidDelegate();
- setContainerView(containerView);
+ public void initialize(ViewAndroidDelegate viewDelegate,
+ InternalAccessDelegate internalDispatcher, WebContents webContents,
+ WindowAndroid windowAndroid) {
+ mViewAndroidDelegate = viewDelegate;
+ setContainerView(viewDelegate.getContainerView());
long windowNativePointer = windowAndroid.getNativePointer();
assert windowNativePointer != 0;
mZoomControlsDelegate = NO_OP_ZOOM_CONTROLS_DELEGATE;
-
- mNativeContentViewCore = nativeInit(
- webContents, mViewAndroidDelegate, windowNativePointer, mRetainedJavaScriptObjects);
+ mNativeContentViewCore = nativeInit(webContents, mViewAndroidDelegate, windowNativePointer,
+ mRetainedJavaScriptObjects);
mWebContents = nativeGetWebContentsAndroid(mNativeContentViewCore);
setContainerViewInternals(internalDispatcher);
@@ -850,11 +677,6 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
mPastePopupMenu = null;
}
- @VisibleForTesting
- public void createContentViewAndroidDelegate() {
- mViewAndroidDelegate = new ContentViewAndroidDelegate(mContainerView, mRenderCoordinates);
- }
-
/**
* Sets a new container view for this {@link ContentViewCore}.
*
@@ -884,7 +706,6 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
mContainerView = containerView;
mContainerView.setClickable(true);
- mViewAndroidDelegate.updateCurrentContainerView(mContainerView);
for (ContainerViewObserver observer : mContainerViewObservers) {
observer.onContainerViewChanged(mContainerView);
}
@@ -2526,6 +2347,8 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
/**
* Called (from native) when the <select> popup needs to be shown.
+ * @param anchorView View anchored for popup.
+ * @param anchorWidth Width of the anchor view without dip scale applied.
* @param nativeSelectPopupSourceFrame The native RenderFrameHost that owns the popup.
* @param items Items to show.
* @param enabled POPUP_ITEM_TYPEs for items.
@@ -2534,8 +2357,9 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
*/
@SuppressWarnings("unused")
@CalledByNative
- private void showSelectPopup(long nativeSelectPopupSourceFrame, Rect bounds, String[] items,
- int[] enabled, boolean multiple, int[] selectedIndices, boolean rightAligned) {
+ private void showSelectPopup(View anchorView, float anchorWidth,
+ long nativeSelectPopupSourceFrame, String[] items, int[] enabled, boolean multiple,
+ int[] selectedIndices, boolean rightAligned) {
if (mContainerView.getParent() == null || mContainerView.getVisibility() != View.VISIBLE) {
mNativeSelectPopupSourceFrame = nativeSelectPopupSourceFrame;
selectPopupMenuItems(null);
@@ -2552,7 +2376,7 @@ public class ContentViewCore implements AccessibilityStateChangeListener, Screen
}
if (DeviceFormFactor.isTablet(mContext) && !multiple && !isTouchExplorationEnabled()) {
mSelectPopup = new SelectPopupDropdown(
- this, popupItems, bounds, selectedIndices, rightAligned);
+ this, anchorView, anchorWidth, popupItems, selectedIndices, rightAligned);
} else {
if (getWindowAndroid() == null) return;
Context windowContext = getWindowAndroid().getContext().get();

Powered by Google App Engine
This is Rietveld 408576698