Index: android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java |
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..18c6dd698ad5056e839ef0bfd8043198ced15668 |
--- /dev/null |
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java |
@@ -0,0 +1,217 @@ |
+// Copyright 2013 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.test; |
+ |
+import android.test.suitebuilder.annotation.SmallTest; |
+import android.view.View; |
+import android.view.ViewGroup.LayoutParams; |
+import android.widget.LinearLayout; |
+import android.util.Log; |
+ |
+import org.chromium.android_webview.AwContents; |
+import org.chromium.android_webview.AwContentsClient; |
+import org.chromium.android_webview.test.util.CommonResources; |
+import org.chromium.base.test.util.Feature; |
+import org.chromium.content.browser.ContentViewCore; |
+import org.chromium.content.browser.test.util.CallbackHelper; |
+ |
+import java.util.concurrent.atomic.AtomicReference; |
+import java.util.concurrent.TimeoutException; |
+ |
+/** |
+ * Tests for certain edge cases related to integrating with the Android view system. |
+ */ |
+public class AndroidViewIntegrationTest extends AwTestBase { |
+ |
+ private static class TestLayoutChangeListener |
+ extends CallbackHelper implements View.OnLayoutChangeListener { |
+ private int mWidth; |
+ private int mHeight; |
+ |
+ public int getWidth() { |
+ assert(getCallCount() > 0); |
+ return mWidth; |
+ } |
+ |
+ public int getHeight() { |
+ assert(getCallCount() > 0); |
+ return mHeight; |
+ } |
+ |
+ @Override |
+ public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, |
+ int oldTop, int oldRight, int oldBottom) { |
+ mWidth = right - left; |
+ mHeight = bottom - top; |
+ notifyCalled(); |
+ } |
+ } |
+ |
+ final LinearLayout.LayoutParams wrapContentLayoutParams = |
+ new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); |
+ |
+ private AwTestContainerView createCustomTestContainerViewOnMainSync( |
+ final AwContentsClient awContentsClient, final int visibility) throws Exception { |
+ final AtomicReference<AwTestContainerView> testContainerView = |
+ new AtomicReference<AwTestContainerView>(); |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ testContainerView.set(createAwTestContainerView(awContentsClient)); |
+ testContainerView.get().setLayoutParams(wrapContentLayoutParams); |
+ testContainerView.get().setVisibility(visibility); |
+ } |
+ }); |
+ return testContainerView.get(); |
+ } |
+ |
+ private AwTestContainerView createDetachedTestContainerViewOnMainSync( |
+ final AwContentsClient awContentsClient) { |
+ final AtomicReference<AwTestContainerView> testContainerView = |
+ new AtomicReference<AwTestContainerView>(); |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ testContainerView.set(createDetachedAwTestContainerView(awContentsClient)); |
+ } |
+ }); |
+ return testContainerView.get(); |
+ } |
+ |
+ private void attachLayoutChangeListener(final AwTestContainerView testContainerView, |
+ final View.OnLayoutChangeListener listener) { |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ testContainerView.addOnLayoutChangeListener(listener); |
+ } |
+ }); |
+ } |
+ |
+ private void ensureZeroHeight(final AwTestContainerView testContainerView) throws Throwable { |
+ // Make sure the test isn't broken by the view having a non-zero height. |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ assertEquals(0, testContainerView.getHeight()); |
+ } |
+ }); |
+ } |
+ |
+ void waitForNonZeroContentSize(TestLayoutChangeListener testLayoutChangeListener, |
+ int callCount) throws Throwable { |
+ |
+ // Wait for a non-zero content size. |
+ int contentSizeChangeWaitLoopIterations = 1; |
+ do { |
+ testLayoutChangeListener.waitForCallback(callCount, |
+ contentSizeChangeWaitLoopIterations); |
+ contentSizeChangeWaitLoopIterations++; |
+ if (contentSizeChangeWaitLoopIterations > 5) { |
+ throw new TimeoutException("Timed out waiting for a non-zero content size"); |
+ } |
+ } while(testLayoutChangeListener.getWidth() == 0 || |
+ testLayoutChangeListener.getHeight() == 0); |
+ } |
+ |
+ /** |
+ * This checks for issues related to loading content into a 0x0 view. |
+ * |
+ * A 0x0 sized view is common if the WebView is set to wrap_content and newly created. The |
+ * expected behavior is for the WebView to expand after some content is loaded. |
+ * In Chromium it would be valid to not load or render content into a WebContents with a 0x0 |
+ * view (since the user can't see it anyway) and only do so after the view's size is non-zero. |
+ * Such behavior is unacceptable for the WebView and this test is to ensure that such behavior |
+ * is not re-introduced. |
+ */ |
+ @SmallTest |
+ @Feature({"AndroidWebView"}) |
+ public void testZeroByZeroViewLoadsContent() throws Throwable { |
+ final TestLayoutChangeListener testLayoutChangeListener = |
+ new TestLayoutChangeListener(); |
+ final TestAwContentsClient contentsClient = new TestAwContentsClient(); |
+ final AwTestContainerView testContainerView = createCustomTestContainerViewOnMainSync( |
+ contentsClient, View.VISIBLE); |
+ attachLayoutChangeListener(testContainerView, testLayoutChangeListener); |
+ ensureZeroHeight(testContainerView); |
+ |
+ |
+ final int contentSizeChangeCallCount = testLayoutChangeListener.getCallCount(); |
+ loadUrlSync(testContainerView.getAwContents(), contentsClient.getOnPageFinishedHelper(), |
+ CommonResources.ABOUT_HTML); |
+ |
+ waitForNonZeroContentSize(testLayoutChangeListener, contentSizeChangeCallCount); |
+ } |
+ |
+ /** |
+ * Check that a content size change notification is issued when the view is invisible. |
+ * |
+ * This makes sure that any optimizations related to the view's visibility don't inhibit |
+ * the ability to load pages. Many applications keep the WebView hidden when it's loading. |
+ */ |
+ @SmallTest |
+ @Feature({"AndroidWebView"}) |
+ public void testInvisibleViewLoadsContent() throws Throwable { |
+ final TestLayoutChangeListener testLayoutChangeListener = |
+ new TestLayoutChangeListener(); |
+ final TestAwContentsClient contentsClient = new TestAwContentsClient(); |
+ final AwTestContainerView testContainerView = createCustomTestContainerViewOnMainSync( |
+ contentsClient, View.INVISIBLE); |
+ attachLayoutChangeListener(testContainerView, testLayoutChangeListener); |
+ ensureZeroHeight(testContainerView); |
+ |
+ final int contentSizeChangeCallCount = testLayoutChangeListener.getCallCount(); |
+ loadUrlSync(testContainerView.getAwContents(), contentsClient.getOnPageFinishedHelper(), |
+ CommonResources.ABOUT_HTML); |
+ waitForNonZeroContentSize(testLayoutChangeListener, contentSizeChangeCallCount); |
+ |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ assertEquals(View.INVISIBLE, testContainerView.getVisibility()); |
+ } |
+ }); |
+ } |
+ |
+ /** |
+ * Check that a content size change notification is sent even if the WebView is off screen. |
+ */ |
+ @SmallTest |
+ @Feature({"AndroidWebView"}) |
+ public void testDisconnectedViewLoadsContent() throws Throwable { |
+ final TestLayoutChangeListener testLayoutChangeListener = |
+ new TestLayoutChangeListener(); |
+ final TestAwContentsClient contentsClient = new TestAwContentsClient(); |
+ final AwTestContainerView testContainerView = |
+ createDetachedTestContainerViewOnMainSync(contentsClient); |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ testContainerView.setLayoutParams(wrapContentLayoutParams); |
+ } |
+ }); |
+ attachLayoutChangeListener(testContainerView, testLayoutChangeListener); |
+ ensureZeroHeight(testContainerView); |
+ |
+ final int contentSizeChangeCallCount = testLayoutChangeListener.getCallCount(); |
+ |
+ /* |
+ TODO: mkosiba - need to find a way to inject a custom PreferredSizeChangedListener |
+ into AwContents as this test passes regardless of whether the content size changes or not. |
+ |
+ |
+ loadUrlSync(testContainerView.getAwContents(), contentsClient.getOnPageFinishedHelper(), |
+ CommonResources.ABOUT_HTML); |
+ */ |
+ getInstrumentation().runOnMainSync(new Runnable() { |
+ @Override |
+ public void run() { |
+ getActivity().addView(testContainerView); |
+ } |
+ }); |
+ |
+ waitForNonZeroContentSize(testLayoutChangeListener, contentSizeChangeCallCount); |
+ } |
+} |