summaryrefslogtreecommitdiffstats
path: root/android_webview/java
diff options
context:
space:
mode:
authormkosiba@chromium.org <mkosiba@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-16 19:56:45 +0000
committermkosiba@chromium.org <mkosiba@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-16 19:56:45 +0000
commitafb59f5fd23a2392761e8be2e4a23bcc63b4a1fd (patch)
tree86be51026d615480678bb75b9f1e894e7b845d63 /android_webview/java
parent4b6bff3ea78537b5e8cd3811bf6c131a506fc7ea (diff)
downloadchromium_src-afb59f5fd23a2392761e8be2e4a23bcc63b4a1fd.zip
chromium_src-afb59f5fd23a2392761e8be2e4a23bcc63b4a1fd.tar.gz
chromium_src-afb59f5fd23a2392761e8be2e4a23bcc63b4a1fd.tar.bz2
[android_webview] Fixes for wrap_content layouts.
This changes AwContents to work correctly when in a WRAP_CONTENT layout mode. TBR=danakj@chromium.org BUG=246621 Review URL: https://chromiumcodereview.appspot.com/23478022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223386 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview/java')
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java7
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java76
2 files changed, 68 insertions, 15 deletions
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 2d7c101..700b9c1 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -344,6 +344,11 @@ public class AwContents {
public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
mInternalAccessAdapter.setMeasuredDimension(measuredWidth, measuredHeight);
}
+
+ @Override
+ public void setFixedLayoutSize(int widthDip, int heightDip) {
+ nativeSetFixedLayoutSize(mNativeAwContents, widthDip, heightDip);
+ }
}
//--------------------------------------------------------------------------------------------
@@ -1514,6 +1519,7 @@ public class AwContents {
mScrollOffsetManager.setContainerViewSize(w, h);
mContentViewCore.onPhysicalBackingSizeChanged(w, h);
mContentViewCore.onSizeChanged(w, h, ow, oh);
+ mLayoutSizer.onSizeChanged(w, h, ow, oh);
nativeOnSizeChanged(mNativeAwContents, w, h, ow, oh);
}
@@ -1907,6 +1913,7 @@ public class AwContents {
private native void nativeSetDipScale(int nativeAwContents, float dipScale);
private native void nativeSetDisplayedPageScaleFactor(int nativeAwContents,
float pageScaleFactor);
+ private native void nativeSetFixedLayoutSize(int nativeAwContents, int widthDip, int heightDip);
// Returns null if save state fails.
private native byte[] nativeGetOpaqueState(int nativeAwContents);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java b/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java
index e09259b..bee46a1 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java
@@ -14,6 +14,8 @@ import org.chromium.content.browser.ContentViewCore;
* Helper methods used to manage the layout of the View that contains AwContents.
*/
public class AwLayoutSizer {
+ public static final int FIXED_LAYOUT_HEIGHT = 0;
+
// These are used to prevent a re-layout if the content size changes within a dimension that is
// fixed by the view system.
private boolean mWidthMeasurementIsFixed;
@@ -26,6 +28,8 @@ public class AwLayoutSizer {
// Page scale factor. This is set to zero initially so that we don't attempt to do a layout if
// we get the content size change notification first and a page scale change second.
private double mPageScaleFactor = 0.0;
+ // The page scale factor that was used in the most recent onMeasure call.
+ private double mLastMeasuredPageScaleFactor = 0.0;
// Whether to postpone layout requests.
private boolean mFreezeLayoutRequests;
@@ -34,12 +38,18 @@ public class AwLayoutSizer {
private double mDIPScale;
+ // Was our heightSpec set to AT_MOST the last time onMeasure was called?
+ private boolean mHeightMeasurementLimited;
+ // If mHeightMeasurementLimited is true then this contains the height limit.
+ private int mHeightMeasurementLimit;
+
// Callback object for interacting with the View.
private Delegate mDelegate;
public interface Delegate {
void requestLayout();
void setMeasuredDimension(int measuredWidth, int measuredHeight);
+ void setFixedLayoutSize(int widthDip, int heightDip);
}
/**
@@ -116,9 +126,12 @@ public class AwLayoutSizer {
// We want to request layout only if the size or scale change, however if any of the
// measurements are 'fixed', then changing the underlying size won't have any effect, so we
// ignore changes to dimensions that are 'fixed'.
+ final int heightPix = (int) (heightCss * mPageScaleFactor * mDIPScale);
boolean anyMeasurementNotFixed = !mWidthMeasurementIsFixed || !mHeightMeasurementIsFixed;
+ boolean contentHeightChangeMeaningful = !mHeightMeasurementIsFixed &&
+ (!mHeightMeasurementLimited || heightPix < mHeightMeasurementLimit);
boolean layoutNeeded = (mContentWidthCss != widthCss && !mWidthMeasurementIsFixed) ||
- (mContentHeightCss != heightCss && !mHeightMeasurementIsFixed) ||
+ (mContentHeightCss != heightCss && contentHeightChangeMeaningful) ||
(mPageScaleFactor != pageScaleFactor && anyMeasurementNotFixed);
mContentWidthCss = widthCss;
@@ -144,27 +157,28 @@ public class AwLayoutSizer {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- int measuredHeight = heightSize;
- int measuredWidth = widthSize;
-
int contentHeightPix = (int) (mContentHeightCss * mPageScaleFactor * mDIPScale);
int contentWidthPix = (int) (mContentWidthCss * mPageScaleFactor * mDIPScale);
+ int measuredHeight = contentHeightPix;
+ int measuredWidth = contentWidthPix;
+
+ mLastMeasuredPageScaleFactor = mPageScaleFactor;
+
// Always use the given size unless unspecified. This matches WebViewClassic behavior.
mWidthMeasurementIsFixed = (widthMode != MeasureSpec.UNSPECIFIED);
- // Freeze the height if an exact size is given by the parent or if the content size has
- // exceeded the maximum size specified by the parent.
- // TODO(mkosiba): Actually we'd like the reduction in content size to cause the WebView to
- // shrink back again but only as a result of a page load.
- mHeightMeasurementIsFixed = (heightMode == MeasureSpec.EXACTLY) ||
- (heightMode == MeasureSpec.AT_MOST && contentHeightPix > heightSize);
-
- if (!mHeightMeasurementIsFixed) {
- measuredHeight = contentHeightPix;
+ mHeightMeasurementIsFixed = (heightMode == MeasureSpec.EXACTLY);
+ mHeightMeasurementLimited = (heightMode == MeasureSpec.AT_MOST);
+ mHeightMeasurementLimit = heightSize;
+
+ final boolean measuredHeightClipped =
+ mHeightMeasurementLimited && (contentHeightPix > heightSize);
+ if (mHeightMeasurementIsFixed || measuredHeightClipped) {
+ measuredHeight = heightSize;
}
- if (!mWidthMeasurementIsFixed) {
- measuredWidth = contentWidthPix;
+ if (mWidthMeasurementIsFixed) {
+ measuredWidth = widthSize;
}
if (measuredHeight < contentHeightPix) {
@@ -177,4 +191,36 @@ public class AwLayoutSizer {
mDelegate.setMeasuredDimension(measuredWidth, measuredHeight);
}
+
+ public void onSizeChanged(int w, int h, int ow, int oh) {
+ // If the WebView's measuredDimension depends on the size of its contents (which is the
+ // case if any of the measurement modes are AT_MOST or UNSPECIFIED) the viewport size
+ // cannot be directly calculated from the size as that can result in the layout being
+ // unstable or unpredictable.
+ // If both the width and height are fixed (specified by the parent) then content size
+ // changes will not cause subsequent layout passes and so we don't need to do anything
+ // special.
+ if ((mWidthMeasurementIsFixed && mHeightMeasurementIsFixed) ||
+ mLastMeasuredPageScaleFactor == 0) {
+ mDelegate.setFixedLayoutSize(0, 0);
+ return;
+ }
+
+ final double dipAndPageScale = mLastMeasuredPageScaleFactor * mDIPScale;
+ final int contentWidthPix = (int) (mContentWidthCss * dipAndPageScale);
+
+ int widthDip = (int) Math.ceil(w / dipAndPageScale);
+
+ // Make sure that we don't introduce rounding errors if the viewport is to be exactly as
+ // wide as the contents.
+ if (w == contentWidthPix) {
+ widthDip = mContentWidthCss;
+ }
+
+ // This is workaround due to the fact that in wrap content mode we need to use a fixed
+ // layout size independent of view height, otherwise things like <div style="height:120%">
+ // cause the webview to grow indefinitely. We need to use a height independent of the
+ // webview's height. 0 is the value used in WebViewClassic.
+ mDelegate.setFixedLayoutSize(widthDip, FIXED_LAYOUT_HEIGHT);
+ }
}