This source file includes following definitions.
- getWidth
- getHeight
- onContentSizeChanged
- onContentSizeChanged
- onPageScaleChanged
- createTestDependencyFactory
- createCustomTestContainerViewOnMainSync
- createDetachedTestContainerViewOnMainSync
- assertZeroHeight
- getRootLayoutWidthOnMainThread
- Feature
- testZeroByZeroViewLoadsContent
- Feature
- testInvisibleViewLoadsContent
- Feature
- testDisconnectedViewLoadsContent
- makeHtmlPageOfSize
- waitForContentSizeToChangeTo
- loadPageOfSizeAndWaitForSizeChange
- Feature
- testSizeUpdateWhenDetached
- waitForNoLayoutsPending
- Feature
- testAbsolutePositionContributesToContentSize
- Feature
- testViewSizedCorrectlyInWrapContentMode
- Feature
- testViewSizedCorrectlyInWrapContentModeWithDynamicContents
- Feature
- testReceivingSizeAfterLoadUpdatesLayout
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 org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwLayoutSizer;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.test.util.CallbackHelper;
import org.chromium.ui.gfx.DeviceDisplayInfo;
import java.util.concurrent.atomic.AtomicReference;
public class AndroidViewIntegrationTest extends AwTestBase {
final int CONTENT_SIZE_CHANGE_STABILITY_TIMEOUT_MS = 1000;
private static class OnContentSizeChangedHelper extends CallbackHelper {
private int mWidth;
private int mHeight;
public int getWidth() {
assert getCallCount() > 0;
return mWidth;
}
public int getHeight() {
assert getCallCount() > 0;
return mHeight;
}
public void onContentSizeChanged(int widthCss, int heightCss) {
mWidth = widthCss;
mHeight = heightCss;
notifyCalled();
}
}
private OnContentSizeChangedHelper mOnContentSizeChangedHelper =
new OnContentSizeChangedHelper();
private CallbackHelper mOnPageScaleChangedHelper = new CallbackHelper();
private class TestAwLayoutSizer extends AwLayoutSizer {
@Override
public void onContentSizeChanged(int widthCss, int heightCss) {
super.onContentSizeChanged(widthCss, heightCss);
if (mOnContentSizeChangedHelper != null)
mOnContentSizeChangedHelper.onContentSizeChanged(widthCss, heightCss);
}
@Override
public void onPageScaleChanged(float pageScaleFactor) {
super.onPageScaleChanged(pageScaleFactor);
if (mOnPageScaleChangedHelper != null)
mOnPageScaleChangedHelper.notifyCalled();
}
}
@Override
protected TestDependencyFactory createTestDependencyFactory() {
return new TestDependencyFactory() {
@Override
public AwLayoutSizer createLayoutSizer() {
return new TestAwLayoutSizer();
}
};
}
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 assertZeroHeight(final AwTestContainerView testContainerView) throws Throwable {
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
assertEquals(0, testContainerView.getHeight());
}
});
}
private int getRootLayoutWidthOnMainThread() throws Exception {
final AtomicReference<Integer> width = new AtomicReference<Integer>();
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
width.set(Integer.valueOf(getActivity().getRootLayoutWidth()));
}
});
return width.get();
}
@SmallTest
@Feature({"AndroidWebView"})
public void testZeroByZeroViewLoadsContent() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView = createCustomTestContainerViewOnMainSync(
contentsClient, View.VISIBLE);
assertZeroHeight(testContainerView);
final int contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount();
final int pageScaleChangeCallCount = mOnPageScaleChangedHelper.getCallCount();
loadUrlAsync(testContainerView.getAwContents(), CommonResources.ABOUT_HTML);
mOnPageScaleChangedHelper.waitForCallback(pageScaleChangeCallCount);
mOnContentSizeChangedHelper.waitForCallback(contentSizeChangeCallCount);
assertTrue(mOnContentSizeChangedHelper.getHeight() > 0);
}
@SmallTest
@Feature({"AndroidWebView"})
public void testInvisibleViewLoadsContent() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView = createCustomTestContainerViewOnMainSync(
contentsClient, View.INVISIBLE);
assertZeroHeight(testContainerView);
final int contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount();
final int pageScaleChangeCallCount = mOnPageScaleChangedHelper.getCallCount();
loadUrlAsync(testContainerView.getAwContents(), CommonResources.ABOUT_HTML);
mOnPageScaleChangedHelper.waitForCallback(pageScaleChangeCallCount);
mOnContentSizeChangedHelper.waitForCallback(contentSizeChangeCallCount);
assertTrue(mOnContentSizeChangedHelper.getHeight() > 0);
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
assertEquals(View.INVISIBLE, testContainerView.getVisibility());
}
});
}
@SmallTest
@Feature({"AndroidWebView"})
public void testDisconnectedViewLoadsContent() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView =
createDetachedTestContainerViewOnMainSync(contentsClient);
assertZeroHeight(testContainerView);
final int contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount();
final int pageScaleChangeCallCount = mOnPageScaleChangedHelper.getCallCount();
loadUrlAsync(testContainerView.getAwContents(), CommonResources.ABOUT_HTML);
mOnPageScaleChangedHelper.waitForCallback(pageScaleChangeCallCount);
mOnContentSizeChangedHelper.waitForCallback(contentSizeChangeCallCount);
assertTrue(mOnContentSizeChangedHelper.getHeight() > 0);
}
private String makeHtmlPageOfSize(int widthCss, int heightCss, boolean heightPercent) {
String content = "<div class=\"normal\">a</div>";
if (heightPercent)
content += "<div class=\"heightPercent\"></div>";
return CommonResources.makeHtmlPageFrom(
"<style type=\"text/css\">" +
"body { margin:0px; padding:0px; } " +
".normal { " +
"width:" + widthCss + "px; " +
"height:" + heightCss + "px; " +
"background-color: red; " +
"} " +
".heightPercent { " +
"height: 150%; " +
"background-color: blue; " +
"} " +
"</style>", content);
}
private void waitForContentSizeToChangeTo(OnContentSizeChangedHelper helper, int callCount,
int widthCss, int heightCss) throws Exception {
final int maxSizeChangeNotificationsToWaitFor = 5;
for (int i = 1; i <= maxSizeChangeNotificationsToWaitFor; i++) {
helper.waitForCallback(callCount, i);
if ((heightCss == -1 || helper.getHeight() == heightCss) &&
(widthCss == -1 || helper.getWidth() == widthCss)) {
break;
}
assertTrue(i != maxSizeChangeNotificationsToWaitFor);
}
}
private void loadPageOfSizeAndWaitForSizeChange(AwContents awContents,
OnContentSizeChangedHelper helper, int widthCss, int heightCss,
boolean heightPercent) throws Exception {
final String htmlData = makeHtmlPageOfSize(widthCss, heightCss, heightPercent);
final int contentSizeChangeCallCount = helper.getCallCount();
loadDataAsync(awContents, htmlData, "text/html", false);
waitForContentSizeToChangeTo(helper, contentSizeChangeCallCount, widthCss, heightCss);
}
@SmallTest
@Feature({"AndroidWebView"})
public void testSizeUpdateWhenDetached() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView = createDetachedTestContainerViewOnMainSync(
contentsClient);
assertZeroHeight(testContainerView);
final int contentWidthCss = 142;
final int contentHeightCss = 180;
loadPageOfSizeAndWaitForSizeChange(testContainerView.getAwContents(),
mOnContentSizeChangedHelper, contentWidthCss, contentHeightCss, false);
}
public void waitForNoLayoutsPending() throws InterruptedException {
Thread.sleep(CONTENT_SIZE_CHANGE_STABILITY_TIMEOUT_MS);
}
@SmallTest
@Feature({"AndroidWebView"})
public void testAbsolutePositionContributesToContentSize() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView = createDetachedTestContainerViewOnMainSync(
contentsClient);
assertZeroHeight(testContainerView);
final int widthCss = 142;
final int heightCss = 180;
final String htmlData = CommonResources.makeHtmlPageFrom(
"<style type=\"text/css\">" +
"body { margin:0px; padding:0px; } " +
"div { " +
"position: absolute; " +
"width:" + widthCss + "px; " +
"height:" + heightCss + "px; " +
"background-color: red; " +
"} " +
"</style>", "<div>a</div>");
final int contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount();
loadDataAsync(testContainerView.getAwContents(), htmlData, "text/html", false);
waitForContentSizeToChangeTo(mOnContentSizeChangedHelper, contentSizeChangeCallCount,
widthCss, heightCss);
}
@SmallTest
@Feature({"AndroidWebView"})
public void testViewSizedCorrectlyInWrapContentMode() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView = createCustomTestContainerViewOnMainSync(
contentsClient, View.VISIBLE);
assertZeroHeight(testContainerView);
final double deviceDIPScale =
DeviceDisplayInfo.create(testContainerView.getContext()).getDIPScale();
final int contentWidthCss = 142;
final int contentHeightCss = 180;
final int expectedWidthCss =
(int) Math.ceil(getRootLayoutWidthOnMainThread() / deviceDIPScale);
final int expectedHeightCss = contentHeightCss;
loadPageOfSizeAndWaitForSizeChange(testContainerView.getAwContents(),
mOnContentSizeChangedHelper, expectedWidthCss, expectedHeightCss, false);
waitForNoLayoutsPending();
assertEquals(expectedWidthCss, mOnContentSizeChangedHelper.getWidth());
assertEquals(expectedHeightCss, mOnContentSizeChangedHelper.getHeight());
}
@SmallTest
@Feature({"AndroidWebView"})
public void testViewSizedCorrectlyInWrapContentModeWithDynamicContents() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView = createCustomTestContainerViewOnMainSync(
contentsClient, View.VISIBLE);
assertZeroHeight(testContainerView);
final double deviceDIPScale =
DeviceDisplayInfo.create(testContainerView.getContext()).getDIPScale();
final int contentWidthCss = 142;
final int contentHeightCss = 180;
final int expectedWidthCss =
(int) Math.ceil(getRootLayoutWidthOnMainThread() / deviceDIPScale);
final int expectedHeightCss = contentHeightCss +
(int) (AwLayoutSizer.FIXED_LAYOUT_HEIGHT * 1.5);
loadPageOfSizeAndWaitForSizeChange(testContainerView.getAwContents(),
mOnContentSizeChangedHelper, expectedWidthCss, contentHeightCss, true);
waitForNoLayoutsPending();
assertEquals(expectedWidthCss, mOnContentSizeChangedHelper.getWidth());
assertEquals(expectedHeightCss, mOnContentSizeChangedHelper.getHeight());
}
@SmallTest
@Feature({"AndroidWebView"})
public void testReceivingSizeAfterLoadUpdatesLayout() throws Throwable {
final TestAwContentsClient contentsClient = new TestAwContentsClient();
final AwTestContainerView testContainerView = createDetachedTestContainerViewOnMainSync(
contentsClient);
final AwContents awContents = testContainerView.getAwContents();
final double deviceDIPScale =
DeviceDisplayInfo.create(testContainerView.getContext()).getDIPScale();
final int physicalWidth = 600;
final int spanWidth = 42;
final int expectedWidthCss =
(int) Math.ceil(physicalWidth / deviceDIPScale);
StringBuilder htmlBuilder = new StringBuilder("<html><body style='margin:0px;'>");
final String spanBlock =
"<span style='width: " + spanWidth + "px; display: inline-block;'>a</span>";
for (int i = 0; i < 10; ++i) {
htmlBuilder.append(spanBlock);
}
htmlBuilder.append("</body></html>");
int contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount();
loadDataAsync(awContents, htmlBuilder.toString(), "text/html", false);
waitForContentSizeToChangeTo(mOnContentSizeChangedHelper, contentSizeChangeCallCount,
spanWidth, -1);
final int narrowLayoutHeight = mOnContentSizeChangedHelper.getHeight();
contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount();
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
testContainerView.onSizeChanged(physicalWidth, 0, 0, 0);
}
});
mOnContentSizeChangedHelper.waitForCallback(contentSizeChangeCallCount);
assertEquals(expectedWidthCss, mOnContentSizeChangedHelper.getWidth());
assertTrue(mOnContentSizeChangedHelper.getHeight() < narrowLayoutHeight);
assertTrue(mOnContentSizeChangedHelper.getHeight() > 0);
}
}