Skip to content

Commit

Permalink
Fix onCloseWindow() behavior in WebPlatformTestActivity
Browse files Browse the repository at this point in the history
onCloseWindow() will be called on the child window's chromeclient,
so moving the handling logic there.

Also, add a test around this behavior, which can be extended to handle
multi window support.

Bug: 994939, 996790
Change-Id: Iaf7cc8b3da21c0f1ad607ae8a8c725a3cc774713
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1761650
Commit-Queue: Changwan Ryu <changwan@chromium.org>
Reviewed-by: Andrew Luo <aluo@chromium.org>
Reviewed-by: Nate Fischer <ntfschr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691524}
  • Loading branch information
galmacky authored and Commit Bot committed Aug 29, 2019
1 parent 431a2bd commit f46bbd2
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 51 deletions.
1 change: 1 addition & 0 deletions android_webview/tools/system_webview_shell/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ instrumentation_test_apk("system_webview_shell_layout_test_apk") {
apk_under_test = ":system_webview_shell_apk"
android_manifest = "layout_tests/AndroidManifest.xml"
java_files = [
"layout_tests/src/org/chromium/webview_shell/test/WebPlatformTestsActivityTest.java",
"layout_tests/src/org/chromium/webview_shell/test/WebViewLayoutTest.java",
"layout_tests/src/org/chromium/webview_shell/test/WebViewThreadTest.java",
]
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
Expand All @@ -19,6 +17,8 @@
import android.widget.RelativeLayout;
import android.widget.TextView;

import org.chromium.base.VisibleForTesting;

/**
* A main activity to handle WPT requests.
*
Expand All @@ -30,54 +30,78 @@
* children, which is not supported for now.
*/
public class WebPlatformTestsActivity extends Activity {
/**
* A callback for testing.
*/
@VisibleForTesting
public interface TestCallback {
/** Called after child layout becomes visible. */
void onChildLayoutVisible();
/** Called after child layout becomes invisible. */
void onChildLayoutInvisible();
}

private WebView mWebView;
private WebView mChildWebView;
private RelativeLayout mChildLayout;
private RelativeLayout mBrowserLayout;
private Button mChildCloseButton;
private TextView mChildTitleText;
private TestCallback mTestCallback;

private class MultiWindowWebChromeClient extends WebChromeClient {
@Override
public boolean onCreateWindow(
WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
// Make the child webview's layout visible
mChildLayout.setVisibility(View.VISIBLE);

WebView webView, boolean isDialog, boolean isUserGesture, Message resultMsg) {
removeAndDestroyChildWebView();
// Now create a new WebView
WebView newView = new WebView(WebPlatformTestsActivity.this);
WebSettings settings = newView.getSettings();
mChildWebView = new WebView(WebPlatformTestsActivity.this);
WebSettings settings = mChildWebView.getSettings();
setUpWebSettings(settings);
settings.setUseWideViewPort(false);
newView.setWebViewClient(new WebViewClient() {
mChildWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
public void onPageFinished(WebView childWebView, String url) {
// Once the view has loaded, display its title for debugging.
mChildTitleText.setText(view.getTitle());
mChildTitleText.setText(childWebView.getTitle());
}
});
mChildWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onCloseWindow(WebView childWebView) {
closeChild();
}
});
// Add the new WebView to the layout
newView.setLayoutParams(new RelativeLayout.LayoutParams(
mChildWebView.setLayoutParams(new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mBrowserLayout.addView(newView);
// Tell the transport about the new view
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(newView);
transport.setWebView(mChildWebView);
resultMsg.sendToTarget();

// Slide the new WebView up into view
Animation slideUp =
AnimationUtils.loadAnimation(WebPlatformTestsActivity.this, R.anim.slide_up);
mChildLayout.startAnimation(slideUp);
mBrowserLayout.addView(mChildWebView);
// Make the child webview's layout visible
mChildLayout.setVisibility(View.VISIBLE);
if (mTestCallback != null) mTestCallback.onChildLayoutVisible();
return true;
}

@Override
public void onCloseWindow(WebView webView) {
mBrowserLayout.removeView(webView);
webView.destroy();
// Ignore window.close() on the test runner window.
}
}

/** Remove and destroy a child webview if it exists. */
private void removeAndDestroyChildWebView() {
if (mChildWebView == null) return;
ViewGroup parent = (ViewGroup) mChildWebView.getParent();
if (parent != null) parent.removeView(mChildWebView);
mChildWebView.destroy();
mChildWebView = null;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -121,20 +145,19 @@ private void setUpWebView(String url) {
}

private void closeChild() {
Animation slideDown = AnimationUtils.loadAnimation(this, R.anim.slide_down);
mChildLayout.startAnimation(slideDown);
slideDown.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
mChildTitleText.setText("");
mChildLayout.setVisibility(View.INVISIBLE);
removeAndDestroyChildWebView();
if (mTestCallback != null) mTestCallback.onChildLayoutInvisible();
}

@Override
public void onAnimationEnd(Animation animation) {
mChildTitleText.setText("");
mChildLayout.setVisibility(View.INVISIBLE);
}
@VisibleForTesting
public void setTestCallback(TestCallback testDelegate) {
mTestCallback = testDelegate;
}

@Override
public void onAnimationRepeat(Animation animation) {}
});
@VisibleForTesting
public WebView getTestRunnerWebView() {
return mWebView;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2019 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.webview_shell.test;

import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;

import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
import android.webkit.WebView;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.webview_shell.WebPlatformTestsActivity;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
* Tests to ensure that system webview shell can handle WPT tests correctly.
*/
@RunWith(BaseJUnit4ClassRunner.class)
public class WebPlatformTestsActivityTest {
private static final String OPEN_TEST_WINDOW_SCRIPT =
"<html><head><script>function ensure_test_window() {"
+ " if (!this.test_window || this.test_window.location === null) {"
+ " this.test_window = window.open('about:blank', 800, 600);"
+ " this.test_window.close();"
+ " }"
+ "};"
+ "ensure_test_window();"
+ "</script></head><body>TestRunner Window</body></html>";

private static final int CHILD_LAYOUT_SHOWN = 1;
private static final int CHILD_LAYOUT_HIDDEN = 2;

private static final long TEST_TIMEOUT_IN_SECONDS = scaleTimeout(3);

private WebPlatformTestsActivity mTestActivity;

@Rule
public ActivityTestRule<WebPlatformTestsActivity> mActivityTestRule =
new ActivityTestRule<>(WebPlatformTestsActivity.class, false, true);

@Before
public void setUp() throws Exception {
mTestActivity = mActivityTestRule.getActivity();
}

@Test
@MediumTest
public void testOpenDestroyWindowFromTestRunner() throws Exception {
final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();

InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mTestActivity.setTestCallback(new WebPlatformTestsActivity.TestCallback() {
@Override
public void onChildLayoutVisible() {
queue.add(CHILD_LAYOUT_SHOWN);
}

@Override
public void onChildLayoutInvisible() {
queue.add(CHILD_LAYOUT_HIDDEN);
}
});
WebView webView = mTestActivity.getTestRunnerWebView();
webView.loadDataWithBaseURL(
"https://some.domain.test/", OPEN_TEST_WINDOW_SCRIPT, "text/html", null, null);
});
Assert.assertEquals("Child window should be created.", Integer.valueOf(CHILD_LAYOUT_SHOWN),
queue.poll(TEST_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS));
Assert.assertEquals("Child window should be destroyed.",
Integer.valueOf(CHILD_LAYOUT_HIDDEN),
queue.poll(TEST_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS));
}
}

0 comments on commit f46bbd2

Please sign in to comment.