| Index: android_webview/java/src/org/chromium/android_webview/AwContents.java
|
| diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
|
| index 65d815924c7e950517e8fcde222ed5a0bdff2aad..b771a4d44627dc89777083ccaa52214c0d2da4cf 100644
|
| --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
|
| +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
|
| @@ -42,6 +42,7 @@ import android.view.inputmethod.EditorInfo;
|
| import android.view.inputmethod.InputConnection;
|
| import android.webkit.JavascriptInterface;
|
| import android.webkit.ValueCallback;
|
| +import android.widget.FrameLayout;
|
|
|
| import org.chromium.android_webview.permission.AwGeolocationCallback;
|
| import org.chromium.android_webview.permission.AwPermissionRequest;
|
| @@ -58,6 +59,7 @@ import org.chromium.components.navigation_interception.NavigationParams;
|
| import org.chromium.content.browser.ContentViewClient;
|
| import org.chromium.content.browser.ContentViewCore;
|
| import org.chromium.content.browser.ContentViewStatics;
|
| +import org.chromium.content.browser.RenderCoordinates;
|
| import org.chromium.content.browser.SmartClipProvider;
|
| import org.chromium.content.common.CleanupReference;
|
| import org.chromium.content_public.browser.GestureStateListener;
|
| @@ -73,16 +75,20 @@ import org.chromium.net.NetError;
|
| import org.chromium.net.NetworkChangeNotifier;
|
| import org.chromium.ui.base.ActivityWindowAndroid;
|
| import org.chromium.ui.base.PageTransition;
|
| +import org.chromium.ui.base.ViewAndroidDelegate;
|
| import org.chromium.ui.base.WindowAndroid;
|
| import org.chromium.ui.gfx.DeviceDisplayInfo;
|
|
|
| import java.io.File;
|
| import java.lang.annotation.Annotation;
|
| +import java.lang.ref.WeakReference;
|
| import java.net.MalformedURLException;
|
| import java.net.URL;
|
| import java.util.HashMap;
|
| +import java.util.LinkedHashMap;
|
| import java.util.Locale;
|
| import java.util.Map;
|
| +import java.util.Map.Entry;
|
| import java.util.WeakHashMap;
|
| import java.util.concurrent.Callable;
|
|
|
| @@ -92,7 +98,7 @@ import java.util.concurrent.Callable;
|
| * primary entry point for the WebViewProvider implementation; it holds a 1:1 object
|
| * relationship with application WebView instances.
|
| * (We define this class independent of the hidden WebViewProvider interfaces, to allow
|
| - * continuous build & test in the open source SDK-based tree).
|
| + * continuous build & test in the open source SDK-based tree).
|
| */
|
| @JNINamespace("android_webview")
|
| public class AwContents implements SmartClipProvider,
|
| @@ -264,6 +270,7 @@ public class AwContents implements SmartClipProvider,
|
| private final Context mContext;
|
| private final int mAppTargetSdkVersion;
|
| private ContentViewCore mContentViewCore;
|
| + private AwViewAndroidDelegate mViewAndroidDelegate;
|
| private WindowAndroidWrapper mWindowAndroid;
|
| private WebContents mWebContents;
|
| private NavigationController mNavigationController;
|
| @@ -803,19 +810,145 @@ public class AwContents implements SmartClipProvider,
|
| onContainerViewChanged();
|
| }
|
|
|
| - private static ContentViewCore createAndInitializeContentViewCore(ViewGroup containerView,
|
| - Context context, InternalAccessDelegate internalDispatcher, WebContents webContents,
|
| - GestureStateListener gestureStateListener,
|
| - ContentViewClient contentViewClient,
|
| + private static void initializeContentViewCore(ContentViewCore contentViewCore,
|
| + ViewGroup containerView, Context context, ViewAndroidDelegate viewDelegate,
|
| + InternalAccessDelegate internalDispatcher, WebContents webContents,
|
| + GestureStateListener gestureStateListener, ContentViewClient contentViewClient,
|
| ContentViewCore.ZoomControlsDelegate zoomControlsDelegate,
|
| WindowAndroid windowAndroid) {
|
| - ContentViewCore contentViewCore = new ContentViewCore(context);
|
| - contentViewCore.initialize(containerView, internalDispatcher, webContents,
|
| + contentViewCore.initialize(containerView, viewDelegate, internalDispatcher, webContents,
|
| windowAndroid);
|
| contentViewCore.addGestureStateListener(gestureStateListener);
|
| contentViewCore.setContentViewClient(contentViewClient);
|
| contentViewCore.setZoomControlsDelegate(zoomControlsDelegate);
|
| - return contentViewCore;
|
| + }
|
| +
|
| + /**
|
| + * Implementation of the interface {@link org.chromium.ui.base.ViewAndroid.ViewAndroidDelegate}
|
| + * for WebView.
|
| + */
|
| + public static class AwViewAndroidDelegate extends ViewAndroidDelegate {
|
| + /**
|
| + * 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> mContainerView;
|
| +
|
| + /**
|
| + * 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<>();
|
| +
|
| + private final RenderCoordinates mRenderCoordinates;
|
| +
|
| + /**
|
| + * Represents the position of an anchor view.
|
| + */
|
| + @VisibleForTesting
|
| + private static class Position {
|
| + public final float mX;
|
| + public final float mY;
|
| + public final float mWidth;
|
| + public final float mHeight;
|
| + public final int mLeftMargin;
|
| + public final int mTopMargin;
|
| +
|
| + public Position(float x, float y, float width, float height, int leftMargin,
|
| + int topMargin) {
|
| + mX = x;
|
| + mY = y;
|
| + mWidth = width;
|
| + mHeight = height;
|
| + mLeftMargin = leftMargin;
|
| + mTopMargin = topMargin;
|
| + }
|
| + }
|
| +
|
| + AwViewAndroidDelegate(ViewGroup containerView, RenderCoordinates renderCoordinates) {
|
| + mContainerView = new WeakReference<>(containerView);
|
| + mRenderCoordinates = renderCoordinates;
|
| + }
|
| +
|
| + @Override
|
| + public View acquireView() {
|
| + ViewGroup containerView = mContainerView.get();
|
| + if (containerView == null) return null;
|
| + View anchorView = new View(containerView.getContext());
|
| + containerView.addView(anchorView);
|
| + // |mAnchorViews| will be updated with the right view position in |setViewPosition|.
|
| + mAnchorViews.put(anchorView, null);
|
| + return anchorView;
|
| + }
|
| +
|
| + @Override
|
| + public void removeView(View anchorView) {
|
| + mAnchorViews.remove(anchorView);
|
| + ViewGroup containerView = mContainerView.get();
|
| + if (containerView != null) {
|
| + containerView.removeView(anchorView);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Updates the current container view to which this class delegates. Existing anchor views
|
| + * are transferred from the old to the new container view.
|
| + */
|
| + public void updateCurrentContainerView(ViewGroup containerView) {
|
| + ViewGroup oldContainerView = mContainerView.get();
|
| + mContainerView = 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) {
|
| + float scale = (float) DeviceDisplayInfo.create(containerView.getContext())
|
| + .getDIPScale();
|
| + setViewPosition(anchorView, position.mX, position.mY,
|
| + position.mWidth, position.mHeight, scale,
|
| + position.mLeftMargin, position.mTopMargin);
|
| + }
|
| + }
|
| + }
|
| +
|
| + @SuppressWarnings("deprecation") // AbsoluteLayout
|
| + @Override
|
| + public void setViewPosition(View anchorView, float x, float y, float width, float height,
|
| + float scale, int leftMargin, int topMargin) {
|
| + if (!mAnchorViews.containsKey(anchorView)) return;
|
| + mAnchorViews.put(anchorView, new Position(x, y, width, height, leftMargin, topMargin));
|
| +
|
| + ViewGroup containerView = getContainerView();
|
| + if (containerView instanceof FrameLayout) {
|
| + super.setViewPosition(anchorView, x, y, width, height, scale, leftMargin,
|
| + topMargin);
|
| + return;
|
| + }
|
| + // 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();
|
| +
|
| + int scaledWidth = Math.round(width * scale);
|
| + int scaledHeight = Math.round(height * scale);
|
| + android.widget.AbsoluteLayout.LayoutParams lp =
|
| + new android.widget.AbsoluteLayout.LayoutParams(
|
| + scaledWidth, scaledHeight, leftMargin, topMargin);
|
| + anchorView.setLayoutParams(lp);
|
| + }
|
| +
|
| + @Override
|
| + protected ViewGroup getContainerView() {
|
| + return mContainerView.get();
|
| + }
|
| }
|
|
|
| boolean isFullScreen() {
|
| @@ -917,6 +1050,7 @@ public class AwContents implements SmartClipProvider,
|
| updateNativeAwGLFunctor();
|
| mContainerView.setWillNotDraw(false);
|
|
|
| + mViewAndroidDelegate.updateCurrentContainerView(mContainerView);
|
| mContentViewCore.setContainerView(mContainerView);
|
| if (mAwPdfExporter != null) {
|
| mAwPdfExporter.setContainerView(mContainerView);
|
| @@ -1037,9 +1171,13 @@ public class AwContents implements SmartClipProvider,
|
| WebContents webContents = nativeGetWebContents(mNativeAwContents);
|
|
|
| mWindowAndroid = getWindowAndroid(mContext);
|
| - mContentViewCore = createAndInitializeContentViewCore(mContainerView, mContext,
|
| - mInternalAccessAdapter, webContents, new AwGestureStateListener(),
|
| - mContentViewClient, mZoomControls, mWindowAndroid.getWindowAndroid());
|
| + mContentViewCore = new ContentViewCore(mContext);
|
| + mViewAndroidDelegate = new AwViewAndroidDelegate(mContainerView,
|
| + mContentViewCore.getRenderCoordinates());
|
| + initializeContentViewCore(mContentViewCore, mContainerView, mContext,
|
| + mViewAndroidDelegate, mInternalAccessAdapter, webContents,
|
| + new AwGestureStateListener(), mContentViewClient, mZoomControls,
|
| + mWindowAndroid.getWindowAndroid());
|
| nativeSetJavaPeers(mNativeAwContents, this, mWebContentsDelegate, mContentsClientBridge,
|
| mIoThreadClient, mInterceptNavigationDelegate);
|
| mWebContents = mContentViewCore.getWebContents();
|
|
|