summaryrefslogtreecommitdiffstats
path: root/android_webview/java
diff options
context:
space:
mode:
authormkosiba@chromium.org <mkosiba@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 16:36:47 +0000
committermkosiba@chromium.org <mkosiba@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 16:36:47 +0000
commitea1d5f036926ae0c19f98daf211c5076ee50f5c3 (patch)
treef84b03d144e9d0dd99103312bf63d9762e22d9fd /android_webview/java
parent2c035f1fe7843d469ce09162f83ce13434c3bc89 (diff)
downloadchromium_src-ea1d5f036926ae0c19f98daf211c5076ee50f5c3.zip
chromium_src-ea1d5f036926ae0c19f98daf211c5076ee50f5c3.tar.gz
chromium_src-ea1d5f036926ae0c19f98daf211c5076ee50f5c3.tar.bz2
[android_webview] Add onMeasure support.
This change makes it possible for the AwContents embeddder to implement the android.view.View#onMeasure method. A content size change listener is added to ContentViewCore to support the wrap_content layout mode. The layout logic is encapsulated in AwLayoutSizer class. BUG=None TEST=AndroidWebViewTests Java-only change, passes on the trybots. NOTRY=true Review URL: https://chromiumcodereview.appspot.com/11529016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176370 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview/java')
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java29
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java96
2 files changed, 122 insertions, 3 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 93a78d4..3d51cb7 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -82,6 +82,10 @@ public class AwContents {
* dispatching of view methods through the containing view.
*/
public interface InternalAccessDelegate extends ContentViewCore.InternalAccessDelegate {
+ /**
+ * @see View#setMeasuredDimension(int, int)
+ */
+ void setMeasuredDimension(int measuredWidth, int measuredHeight);
}
private int mNativeAwContents;
@@ -90,7 +94,8 @@ public class AwContents {
private AwContentsClient mContentsClient;
private AwContentsIoThreadClient mIoThreadClient;
private InterceptNavigationDelegateImpl mInterceptNavigationDelegate;
- private ContentViewCore.InternalAccessDelegate mInternalAccessAdapter;
+ private InternalAccessDelegate mInternalAccessAdapter;
+ private final AwLayoutSizer mLayoutSizer;
// This can be accessed on any thread after construction. See AwContentsIoThreadClient.
private final AwSettings mSettings;
private final ClientCallbackHandler mClientCallbackHandler;
@@ -271,9 +276,21 @@ public class AwContents {
}
}
+ private class AwLayoutSizerDelegate implements AwLayoutSizer.Delegate {
+ @Override
+ public void requestLayout() {
+ mContainerView.requestLayout();
+ }
+
+ @Override
+ public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
+ mInternalAccessAdapter.setMeasuredDimension(measuredWidth, measuredHeight);
+ }
+ }
+
// TODO(kristianm): Delete this when privateBrowsing parameter is removed in Android
public AwContents(ViewGroup containerView,
- ContentViewCore.InternalAccessDelegate internalAccessAdapter,
+ InternalAccessDelegate internalAccessAdapter,
AwContentsClient contentsClient,
NativeWindow nativeWindow, boolean privateBrowsing,
boolean isAccessFromFileURLsGrantedByDefault) {
@@ -289,7 +306,7 @@ public class AwContents {
* TODO(benm): Remove the nativeWindow parameter.
*/
public AwContents(ViewGroup containerView,
- ContentViewCore.InternalAccessDelegate internalAccessAdapter,
+ InternalAccessDelegate internalAccessAdapter,
AwContentsClient contentsClient,
NativeWindow nativeWindow,
boolean isAccessFromFileURLsGrantedByDefault) {
@@ -309,6 +326,8 @@ public class AwContents {
new AwNativeWindow(mContainerView.getContext()),
isAccessFromFileURLsGrantedByDefault);
mContentViewCore.setContentViewClient(mContentsClient);
+ mLayoutSizer = new AwLayoutSizer(new AwLayoutSizerDelegate());
+ mContentViewCore.setContentSizeChangeListener(mLayoutSizer);
mContentsClient.installWebContentsObserver(mContentViewCore);
mSettings = new AwSettings(mContentViewCore.getContext());
@@ -379,6 +398,10 @@ public class AwContents {
}
}
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ mLayoutSizer.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
public int findAllSync(String searchString) {
if (mNativeAwContents == 0) return 0;
return nativeFindAllSync(mNativeAwContents, searchString);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java b/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java
new file mode 100644
index 0000000..c698ade
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwLayoutSizer.java
@@ -0,0 +1,96 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview;
+
+import android.util.Pair;
+import android.view.View.MeasureSpec;
+import android.view.View;
+
+import org.chromium.content.browser.ContentViewCore;
+
+/**
+ * Helper methods used to manage the layout of the View that contains AwContents.
+ */
+public class AwLayoutSizer implements ContentViewCore.ContentSizeChangeListener {
+ // 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;
+ private boolean mHeightMeasurementIsFixed;
+
+ // Size of the rendered content, as reported by native.
+ private int mContentHeight;
+ private int mContentWidth;
+
+ // Callback object for interacting with the View.
+ Delegate mDelegate;
+
+ public interface Delegate {
+ void requestLayout();
+ void setMeasuredDimension(int measuredWidth, int measuredHeight);
+ }
+
+ public AwLayoutSizer(Delegate delegate) {
+ mDelegate = delegate;
+ }
+
+ /**
+ * Update the contents size.
+ * This should be called whenever the content size changes (due to DOM manipulation or page
+ * load, for example).
+ */
+ @Override
+ public void onContentSizeChanged(int width, int height) {
+ boolean layoutNeeded = (mContentWidth != width && !mWidthMeasurementIsFixed) ||
+ (mContentHeight != height && !mHeightMeasurementIsFixed);
+
+ mContentWidth = width;
+ mContentHeight = height;
+
+ if (layoutNeeded) {
+ mDelegate.requestLayout();
+ }
+ }
+
+ /**
+ * Calculate the size of the view.
+ * This is designed to be used to implement the android.view.View#onMeasure() method.
+ */
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+
+ int measuredHeight = heightSize;
+ int measuredWidth = widthSize;
+
+ // 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 && mContentHeight > heightSize);
+
+ if (!mHeightMeasurementIsFixed) {
+ measuredHeight = mContentHeight;
+ }
+
+ if (!mWidthMeasurementIsFixed) {
+ measuredWidth = mContentWidth;
+ }
+
+ if (measuredHeight < mContentHeight) {
+ measuredHeight |= View.MEASURED_STATE_TOO_SMALL;
+ }
+
+ if (measuredWidth < mContentWidth) {
+ measuredWidth |= View.MEASURED_STATE_TOO_SMALL;
+ }
+
+ mDelegate.setMeasuredDimension(measuredWidth, measuredHeight);
+ }
+}