| 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);
|
| + }
|
| +}
|
|
|