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 bbf71012109650a0d0bbe4d76e7f079c8b53e201..1236b5a8069ff01024138fa402005aa8799aa76a 100644 |
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java |
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java |
@@ -28,6 +28,8 @@ import android.view.inputmethod.InputConnection; |
import android.webkit.GeolocationPermissions; |
import android.webkit.ValueCallback; |
+import com.google.common.annotations.VisibleForTesting; |
+ |
import org.chromium.base.CalledByNative; |
import org.chromium.base.JNINamespace; |
import org.chromium.base.ThreadUtils; |
@@ -92,23 +94,13 @@ public class AwContents { |
void setMeasuredDimension(int measuredWidth, int measuredHeight); |
} |
- /** |
- * Listener for renderer state change notifications coming through ContentViewCore. |
- */ |
- private class AwContentStateChangeListener |
- implements ContentViewCore.ContentSizeChangeListener { |
- @Override |
- public void onContentSizeChanged(int contentWidthPix, int contentHeightPix) { |
- mLayoutSizer.onContentSizeChanged(contentWidthPix, contentHeightPix); |
- } |
- } |
- |
private int mNativeAwContents; |
private AwBrowserContext mBrowserContext; |
private ViewGroup mContainerView; |
private ContentViewCore mContentViewCore; |
private AwContentsClient mContentsClient; |
private AwContentsClientBridge mContentsClientBridge; |
+ private AwWebContentsDelegate mWebContentsDelegate; |
private AwContentsIoThreadClient mIoThreadClient; |
private InterceptNavigationDelegateImpl mInterceptNavigationDelegate; |
private InternalAccessDelegate mInternalAccessAdapter; |
@@ -139,6 +131,7 @@ public class AwContents { |
private CleanupReference mCleanupReference; |
+ //-------------------------------------------------------------------------------------------- |
private class IoThreadClientImpl implements AwContentsIoThreadClient { |
// All methods are called on the IO thread. |
@@ -204,6 +197,7 @@ public class AwContents { |
} |
} |
+ //-------------------------------------------------------------------------------------------- |
private class InterceptNavigationDelegateImpl implements InterceptNavigationDelegate { |
private String mLastLoadUrlAddress; |
@@ -248,6 +242,7 @@ public class AwContents { |
} |
} |
+ //-------------------------------------------------------------------------------------------- |
private class AwLayoutSizerDelegate implements AwLayoutSizer.Delegate { |
@Override |
public void requestLayout() { |
@@ -260,26 +255,65 @@ public class AwContents { |
} |
} |
+ //-------------------------------------------------------------------------------------------- |
+ private class AwPinchGestureStateListener implements ContentViewCore.PinchGestureStateListener { |
+ @Override |
+ public void onPinchGestureStart() { |
+ // While it's possible to re-layout the view during a pinch gesture, the effect is very |
+ // janky (especially that the page scale update notification comes from the renderer |
+ // main thread, not from the impl thread, so it's usually out of sync with what's on |
+ // screen). It's also quite expensive to do a re-layout, so we simply postpone |
+ // re-layout for the duration of the gesture. This is compatible with what |
+ // WebViewClassic does. |
+ mLayoutSizer.freezeLayoutRequests(); |
+ } |
+ |
+ public void onPinchGestureEnd() { |
+ mLayoutSizer.unfreezeLayoutRequests(); |
+ } |
+ } |
+ |
/** |
* @param browserContext the browsing context to associate this view contents with. |
* @param containerView the view-hierarchy item this object will be bound to. |
* @param internalAccessAdapter to access private methods on containerView. |
* @param contentsClient will receive API callbacks from this WebView Contents |
* @param isAccessFromFileURLsGrantedByDefault passed to ContentViewCore.initialize. |
+ * |
+ * This constructor uses the default view sizing policy. |
*/ |
public AwContents(AwBrowserContext browserContext, ViewGroup containerView, |
InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient, |
boolean isAccessFromFileURLsGrantedByDefault) { |
+ this(browserContext, containerView, internalAccessAdapter, contentsClient, |
+ isAccessFromFileURLsGrantedByDefault, new AwLayoutSizer()); |
+ } |
+ |
+ /** |
+ * @param layoutSizer the AwLayoutSizer instance implementing the sizing policy for the view. |
+ * |
+ * This version of the constructor is used in test code to inject test versions of the above |
+ * documented classes |
+ */ |
+ public AwContents(AwBrowserContext browserContext, ViewGroup containerView, |
+ InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient, |
+ boolean isAccessFromFileURLsGrantedByDefault, AwLayoutSizer layoutSizer) { |
mBrowserContext = browserContext; |
mContainerView = containerView; |
mInternalAccessAdapter = internalAccessAdapter; |
+ mDIPScale = DeviceDisplayInfo.create(containerView.getContext()).getDIPScale(); |
// Note that ContentViewCore must be set up before AwContents, as ContentViewCore |
// setup performs process initialisation work needed by AwContents. |
mContentViewCore = new ContentViewCore(containerView.getContext(), |
ContentViewCore.PERSONALITY_VIEW); |
+ mContentViewCore.setPinchGestureStateListener(new AwPinchGestureStateListener()); |
mContentsClientBridge = new AwContentsClientBridge(contentsClient); |
- mNativeAwContents = nativeInit(contentsClient.getWebContentsDelegate(), |
- mContentsClientBridge); |
+ mLayoutSizer = layoutSizer; |
+ mLayoutSizer.setDelegate(new AwLayoutSizerDelegate()); |
+ mLayoutSizer.setDIPScale(mDIPScale); |
+ mWebContentsDelegate = new AwWebContentsDelegateAdapter(contentsClient, |
+ mLayoutSizer.getPreferredSizeChangedListener()); |
+ mNativeAwContents = nativeInit(mWebContentsDelegate, mContentsClientBridge); |
mContentsClient = contentsClient; |
mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeAwContents)); |
@@ -289,8 +323,6 @@ public class AwContents { |
new AwNativeWindow(mContainerView.getContext()), |
isAccessFromFileURLsGrantedByDefault); |
mContentViewCore.setContentViewClient(mContentsClient); |
- mLayoutSizer = new AwLayoutSizer(new AwLayoutSizerDelegate()); |
- mContentViewCore.setContentSizeChangeListener(new AwContentStateChangeListener()); |
mContentsClient.installWebContentsObserver(mContentViewCore); |
mSettings = new AwSettings(mContentViewCore.getContext(), nativeWebContents); |
@@ -301,7 +333,6 @@ public class AwContents { |
nativeDidInitializeContentViewCore(mNativeAwContents, |
mContentViewCore.getNativeContentViewCore()); |
- mDIPScale = DeviceDisplayInfo.create(containerView.getContext()).getDIPScale(); |
mContentsClient.setDIPScale(mDIPScale); |
mSettings.setDIPScale(mDIPScale); |
mDefaultVideoPosterRequestHandler = new DefaultVideoPosterRequestHandler(mContentsClient); |
@@ -312,7 +343,7 @@ public class AwContents { |
new AwContentVideoViewDelegate(contentsClient, containerView.getContext())); |
} |
- // TODO(mkosiba): Remove this once we move the embedding layer to use methods on AwContents. |
+ @VisibleForTesting |
public ContentViewCore getContentViewCore() { |
return mContentViewCore; |
} |
@@ -339,7 +370,7 @@ public class AwContents { |
// We explicitly do not null out the mContentViewCore reference here |
// because ContentViewCore already has code to deal with the case |
// methods are called on it after it's been destroyed, and other |
- // code relies on AwContents.getContentViewCore to return non-null. |
+ // code relies on AwContents.mContentViewCore to be non-null. |
mCleanupReference.cleanupNow(); |
mNativeAwContents = 0; |
} |
@@ -435,7 +466,7 @@ public class AwContents { |
*/ |
public int getMostRecentProgress() { |
// WebContentsDelegateAndroid conveniently caches the most recent notified value for us. |
- return mContentsClient.getWebContentsDelegate().getMostRecentProgress(); |
+ return mWebContentsDelegate.getMostRecentProgress(); |
} |
public Bitmap getFavicon() { |
@@ -1249,6 +1280,12 @@ public class AwContents { |
return result; |
} |
+ @CalledByNative |
+ private void onPageScaleFactorChanged(float pageScaleFactor) { |
+ // This change notification comes from the renderer thread, not from the cc/ impl thread. |
+ mLayoutSizer.onPageScaleChanged(pageScaleFactor); |
+ } |
+ |
// ------------------------------------------------------------------------------------------- |
// Helper methods |
// ------------------------------------------------------------------------------------------- |