Chromium Code Reviews| 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..808f32d6485a093dc3ede3cb29efcf26760bb98e 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; |
| @@ -810,7 +817,9 @@ public class AwContents implements SmartClipProvider, |
| ContentViewCore.ZoomControlsDelegate zoomControlsDelegate, |
| WindowAndroid windowAndroid) { |
| ContentViewCore contentViewCore = new ContentViewCore(context); |
| - contentViewCore.initialize(containerView, internalDispatcher, webContents, |
| + AwViewAndroidDelegate viewDelegate = new AwViewAndroidDelegate(containerView, |
| + contentViewCore.getRenderCoordinates()); |
| + contentViewCore.initialize(containerView, viewDelegate, internalDispatcher, webContents, |
| windowAndroid); |
| contentViewCore.addGestureStateListener(gestureStateListener); |
| contentViewCore.setContentViewClient(contentViewClient); |
| @@ -818,6 +827,135 @@ public class AwContents implements SmartClipProvider, |
| 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) { |
| + super(null); |
| + 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() { |
| return mFullScreenTransitionsState.isFullScreen(); |
| } |
| @@ -917,6 +1055,7 @@ public class AwContents implements SmartClipProvider, |
| updateNativeAwGLFunctor(); |
| mContainerView.setWillNotDraw(false); |
| + mViewAndroidDelegate.updateCurrentContainerView(mContainerView); |
| mContentViewCore.setContainerView(mContainerView); |
| if (mAwPdfExporter != null) { |
| mAwPdfExporter.setContainerView(mContainerView); |
| @@ -1040,6 +1179,7 @@ public class AwContents implements SmartClipProvider, |
| mContentViewCore = createAndInitializeContentViewCore(mContainerView, mContext, |
| mInternalAccessAdapter, webContents, new AwGestureStateListener(), |
| mContentViewClient, mZoomControls, mWindowAndroid.getWindowAndroid()); |
| + mViewAndroidDelegate = (AwViewAndroidDelegate) mContentViewCore.getViewAndroidDelegate(); |
|
no sievers
2016/07/18 22:14:16
Since we create the delegate in createAndInitializ
Jinsuk Kim
2016/07/19 07:08:39
Done.
|
| nativeSetJavaPeers(mNativeAwContents, this, mWebContentsDelegate, mContentsClientBridge, |
| mIoThreadClient, mInterceptNavigationDelegate); |
| mWebContents = mContentViewCore.getWebContents(); |