Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Unified Diff: android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java

Issue 815933002: [WebView] Move external video surface across container views. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2214
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
index da731d22f0b2b5136624b0cfeaf4c81919b30c83..a2131959dad2e947fc4829eb7f352656b159e692 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientFullScreenTest.java
@@ -4,12 +4,16 @@
package org.chromium.android_webview.test;
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
import android.test.suitebuilder.annotation.MediumTest;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
+import org.chromium.android_webview.ExternalVideoSurfaceContainer.NoPunchingSurfaceView;
import org.chromium.android_webview.test.util.JavascriptEventObserver;
+import org.chromium.base.CommandLine;
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.ContentVideoView;
import org.chromium.content.browser.ContentViewCore;
@@ -182,6 +186,84 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
+ public void testHolePunchingSurfaceNotCreatedForClearVideo()
+ throws Throwable {
+ loadTestPage(VIDEO_TEST_URL);
+ assertFalse(DOMUtils.isFullscreen(getWebContentsOnUiThread()));
+
+ // Play and verify that a surface view for hole punching is not created.
+ // Note that VIDEO_TEST_URL contains clear video.
+ tapPlayButton();
+ assertTrue(DOMUtils.waitForVideoPlay(getWebContentsOnUiThread(), VIDEO_ID));
+ assertContainsHolePunchingSurfaceView(mTestContainerView, false);
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView"})
+ public void testOnShowCustomViewTransfersHolePunchingSurfaceForVideoInsideDiv()
+ throws Throwable {
+ forceUseHolePunchingExternalSurface();
+
+ loadTestPage(VIDEO_INSIDE_DIV_TEST_URL);
+ assertFalse(DOMUtils.isFullscreen(getWebContentsOnUiThread()));
+
+ // Play and verify that there is a surface view for hole punching.
+ tapPlayButton();
+ assertTrue(DOMUtils.waitForVideoPlay(getWebContentsOnUiThread(), VIDEO_ID));
+ assertContainsHolePunchingSurfaceView(mTestContainerView, true);
+
+ // Enter fullscreen and verify that the hole punching surface is transferred. Note
+ // that VIDEO_INSIDE_DIV_TEST_URL goes fullscreen on a <div> element, so in fullscreen
+ // the video will still be embedded in the page and the hole punching surface required.
+ // We need to transfer the external surface so that scrolling is synchronized with the
+ // new container view.
+ DOMUtils.clickNode(this, mContentViewCore, CUSTOM_FULLSCREEN_CONTROL_ID);
+ mContentsClient.waitForCustomViewShown();
+ View customView = mContentsClient.getCustomView();
+ assertContainsHolePunchingSurfaceView(mTestContainerView, false);
+ // Wait to ensure that the surface view stays there after being transfered and not
+ // removed asynchronously.
+ waitAndAssertContainsHolePunchingSurfaceView(customView, true);
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView"})
+ public void testOnShowCustomViewRemovesHolePunchingSurfaceForVideo()
+ throws Throwable {
+ forceUseHolePunchingExternalSurface();
+
+ loadTestPage(VIDEO_TEST_URL);
+ assertFalse(DOMUtils.isFullscreen(getWebContentsOnUiThread()));
+
+ // Play and verify that there is a surface view for hole punching.
+ tapPlayButton();
+ assertTrue(DOMUtils.waitForVideoPlay(getWebContentsOnUiThread(), VIDEO_ID));
+ assertContainsHolePunchingSurfaceView(mTestContainerView, true);
+
+ // Enter fullscreen and verify that the surface view is removed. Note that
+ // VIDEO_TEST_URL goes fullscreen on the <video> element, so in fullscreen
+ // the video will not be embedded in the page and the external surface
+ // not longer required.
+ DOMUtils.clickNode(this, mContentViewCore, CUSTOM_FULLSCREEN_CONTROL_ID);
+ mContentsClient.waitForCustomViewShown();
+ View customView = mContentsClient.getCustomView();
+ assertContainsHolePunchingSurfaceView(mTestContainerView, false);
+ // We need to wait because the surface view is first transfered, and then removed
+ // asynchronously.
+ waitAndAssertContainsHolePunchingSurfaceView(customView, false);
+ }
+
+ /**
+ * Force the use of the hole punching external surface (see VIDEO_HOLE). If this method is
+ * called the external surface will also be created for clear video (that this test class uses)
+ * and not just for encrypted video.
+ */
+ private void forceUseHolePunchingExternalSurface() {
+ CommandLine.getInstance().appendSwitch("force-use-overlay-embedded-video");
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView"})
public void testFullscreenNotSupported_video() throws Throwable {
doTestFullscreenNotSupported(VIDEO_TEST_URL);
}
@@ -228,11 +310,11 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
// Play and verify that there is an active power save blocker.
tapPlayButton();
- assertKeepScreenOnActive(customView, true);
+ assertWaitForKeepScreenOnActive(customView, true);
// Stop the video and verify that the power save blocker is gone.
DOMUtils.pauseVideo(getWebContentsOnUiThread(), VIDEO_ID);
- assertKeepScreenOnActive(customView, false);
+ assertWaitForKeepScreenOnActive(customView, false);
}
@MediumTest
@@ -247,11 +329,11 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
// Play and verify that there is an active power save blocker.
tapPlayButton();
- assertKeepScreenOnActive(mTestContainerView, true);
+ assertWaitForKeepScreenOnActive(mTestContainerView, true);
// Stop the video and verify that the power save blocker is gone.
DOMUtils.pauseVideo(getWebContentsOnUiThread(), VIDEO_ID);
- assertKeepScreenOnActive(mTestContainerView, false);
+ assertWaitForKeepScreenOnActive(mTestContainerView, false);
}
@MediumTest
@@ -263,7 +345,7 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
// Play and verify that there is an active power save blocker.
tapPlayButton();
- assertKeepScreenOnActive(mTestContainerView, true);
+ assertWaitForKeepScreenOnActive(mTestContainerView, true);
// Enter fullscreen and verify that the power save blocker is
// still there.
@@ -274,7 +356,7 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
// Pause the video and the power save blocker is gone.
DOMUtils.pauseVideo(getWebContentsOnUiThread(), VIDEO_ID);
- assertKeepScreenOnActive(customView, false);
+ assertWaitForKeepScreenOnActive(customView, false);
// Exit fullscreen and the power save blocker is still gone.
DOMUtils.exitFullscreen(getWebContentsOnUiThread());
@@ -293,7 +375,7 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
// Play and verify that there is an active power save blocker
// in fullscreen.
tapPlayButton();
- assertKeepScreenOnActive(customView, true);
+ assertWaitForKeepScreenOnActive(customView, true);
// Exit fullscreen and verify that the power save blocker is
// still there.
@@ -304,18 +386,17 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
private void tapPlayButton() throws Exception {
String testUrl = mTestContainerView.getAwContents().getUrl();
- if (VIDEO_INSIDE_DIV_TEST_URL.equals(testUrl)) {
- // VIDEO_INSIDE_DIV_TEST_URL uses a custom play control with known id.
- DOMUtils.clickNode(this, mContentViewCore, CUSTOM_PLAY_CONTROL_ID);
- } else if (VIDEO_TEST_URL.equals(testUrl)
+ if (VIDEO_TEST_URL.equals(testUrl)
&& DOMUtils.isFullscreen(getWebContentsOnUiThread())) {
- // VIDEO_TEST_URL uses the standard html5 video controls. The standard
- // html5 controls are shadow html elements without any ids. In fullscreen we can still
- // tap the play button because this is rendered in the center of the custom view.
- // In embedded mode we don't have an easy way of retrieving its location.
+ // The VIDEO_TEST_URL page goes fullscreen on the <video> element. In fullscreen
+ // the button with id CUSTOM_PLAY_CONTROL_ID will not be visible, but the standard
+ // html5 video controls are. The standard html5 controls are shadow html elements
+ // without any ids so it is difficult to retrieve its precise location. However,
+ // a large play control is rendered in the center of the custom view
+ // (containing the fullscreen <video>) so we just rely on that fact here.
TouchCommon.singleClickView(mContentsClient.getCustomView());
} else {
- fail("Unable to tap standard html5 play control in embedded mode");
+ DOMUtils.clickNode(this, mContentViewCore, CUSTOM_PLAY_CONTROL_ID);
}
}
@@ -323,7 +404,7 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
* Asserts that the keep screen on property in the given {@code view} is active as
* {@code expected}. It also verifies that it is only active when the video is playing.
*/
- private void assertKeepScreenOnActive(final View view, final boolean expected)
+ private void assertWaitForKeepScreenOnActive(final View view, final boolean expected)
throws InterruptedException {
// We need to poll because it takes time to synchronize the state between the android
// views and Javascript.
@@ -342,6 +423,12 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
}));
}
+ private void assertKeepScreenOnActive(final View view, final boolean expected)
+ throws Exception {
+ assertTrue(getKeepScreenOn(view) == expected
+ && DOMUtils.isVideoPaused(getWebContentsOnUiThread(), VIDEO_ID) != expected);
+ }
+
private boolean getKeepScreenOn(View view) {
// The power save blocker is added to a child anchor view,
// so we need to traverse the hierarchy.
@@ -356,7 +443,7 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
return view.getKeepScreenOn();
}
- private void assertIsFullscreen() throws InterruptedException {
+ private void assertWaitForIsFullscreen() throws InterruptedException {
// We need to poll because the Javascript state is updated asynchronously
assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
@Override
@@ -371,35 +458,41 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
}));
}
- private void assertContainsContentVideoView()
- throws InterruptedException {
- // We need to poll because the ContentVideoView is added to the customView asynchronously
- assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
+ private void assertContainsContentVideoView() throws Exception {
+ assertTrue(containsChildOfType(mContentsClient.getCustomView(),
+ ContentVideoView.class));
+ }
+
+ private void assertContainsHolePunchingSurfaceView(View view, boolean expected)
+ throws Exception {
+ assertEquals(containsChildOfType(view, NoPunchingSurfaceView.class), expected);
+ }
+
+ private void waitAndAssertContainsHolePunchingSurfaceView(View view, boolean expected)
+ throws Exception {
+ Thread.sleep(scaleTimeout(100));
+ assertEquals(expected, containsChildOfType(view, NoPunchingSurfaceView.class));
+ }
+
+ private boolean containsChildOfType(final View view, final Class<? extends View> childType)
+ throws Exception {
+ return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
@Override
- public boolean isSatisfied() {
- try {
- return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return containsVideoView(mContentsClient.getCustomView());
- }
- });
- } catch (Exception e) {
- fail(e.getMessage());
- return false;
- }
+ public Boolean call() throws Exception {
+ return containsChildOfTypeOnUiThread(view, childType);
}
- }));
+ });
}
- private boolean containsVideoView(View view) {
- if (view instanceof ContentVideoView) {
+ private boolean containsChildOfTypeOnUiThread(final View view,
+ final Class<? extends View> childType) throws Exception {
+ if (childType.isInstance(view)) {
return true;
}
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
- if (containsVideoView(viewGroup.getChildAt(i))) {
+ if (containsChildOfTypeOnUiThread(viewGroup.getChildAt(i), childType)) {
return true;
}
}
@@ -428,7 +521,7 @@ public class AwContentsClientFullScreenTest extends AwTestBase {
private void doOnShowCustomViewTest(String videoTestUrl) throws Exception {
loadTestPageAndClickFullscreen(videoTestUrl);
mContentsClient.waitForCustomViewShown();
- assertIsFullscreen();
+ assertWaitForIsFullscreen();
if (videoTestUrl.equals(VIDEO_TEST_URL)) {
// We only create a ContentVideoView (ie. a hardware accelerated surface) when going
// fullscreen on a video element.

Powered by Google App Engine
This is Rietveld 408576698