summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authorycheo@chromium.org <ycheo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 07:58:31 +0000
committerycheo@chromium.org <ycheo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 07:58:31 +0000
commitdafd4e72466ce739e14f4a365f5158ca1a39bf97 (patch)
treeb43a6c00255858efb27040da21dd328132e86b9f /android_webview
parentd0359da7b7917230b3d6ea8d2ec66e90b6bf9972 (diff)
downloadchromium_src-dafd4e72466ce739e14f4a365f5158ca1a39bf97.zip
chromium_src-dafd4e72466ce739e14f4a365f5158ca1a39bf97.tar.gz
chromium_src-dafd4e72466ce739e14f4a365f5158ca1a39bf97.tar.bz2
[Android WebView] Add tests to check whether the hole punching works.
- Add ExternalVideoSurfaceContainerTest. - Add a dependency fatory into ExternalVideoSurfaceContainer. - Move AwSettingsTest.runVideoTest() into AwTestBase. BUG=329447 Review URL: https://codereview.chromium.org/250483002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267125 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java36
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java46
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java47
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java131
4 files changed, 205 insertions, 55 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java b/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java
index 7bc1e11..985fc42 100644
--- a/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java
+++ b/android_webview/java/src/org/chromium/android_webview/ExternalVideoSurfaceContainer.java
@@ -11,6 +11,8 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
+import com.google.common.annotations.VisibleForTesting;
+
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.content.browser.ContentViewCore;
@@ -38,7 +40,7 @@ import java.lang.ref.WeakReference;
*/
@JNINamespace("android_webview")
public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
- private static final int INVALID_PLAYER_ID = -1;
+ protected static final int INVALID_PLAYER_ID = -1;
// Because WebView does hole-punching by itself, instead, the hole-punching logic
// in SurfaceView can clear out some web elements like media control or subtitle.
@@ -78,14 +80,30 @@ public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
private int mWidth;
private int mHeight;
+ /**
+ * Factory class to facilitate dependency injection.
+ */
+ public static class Factory {
+ public ExternalVideoSurfaceContainer create(
+ int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+ return new ExternalVideoSurfaceContainer(
+ nativeExternalVideoSurfaceContainer, contentViewCore);
+ }
+ }
+ private static Factory sFactory = new Factory();
+
+ @VisibleForTesting
+ public static void setFactory(Factory factory) {
+ sFactory = factory;
+ }
+
@CalledByNative
private static ExternalVideoSurfaceContainer create(
int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
- return new ExternalVideoSurfaceContainer(
- nativeExternalVideoSurfaceContainer, contentViewCore);
+ return sFactory.create(nativeExternalVideoSurfaceContainer, contentViewCore);
}
- private ExternalVideoSurfaceContainer(
+ protected ExternalVideoSurfaceContainer(
int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
assert contentViewCore != null;
mNativeExternalVideoSurfaceContainer = nativeExternalVideoSurfaceContainer;
@@ -98,7 +116,7 @@ public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
* @param playerId The ID of the media player.
*/
@CalledByNative
- private void requestExternalVideoSurface(int playerId) {
+ protected void requestExternalVideoSurface(int playerId) {
if (mPlayerId == playerId) return;
if (mPlayerId == INVALID_PLAYER_ID) {
@@ -116,7 +134,7 @@ public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
* @param playerId The ID of the media player.
*/
@CalledByNative
- private void releaseExternalVideoSurface(int playerId) {
+ protected void releaseExternalVideoSurface(int playerId) {
if (mPlayerId != playerId) return;
releaseIfActiveContainer(this);
@@ -125,7 +143,7 @@ public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
}
@CalledByNative
- private void destroy() {
+ protected void destroy() {
releaseExternalVideoSurface(mPlayerId);
}
@@ -176,7 +194,7 @@ public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
* @param bottom The absolute CSS Y coordinate of the bottom side of the video element.
*/
@CalledByNative
- private void onExternalVideoSurfacePositionChanged(
+ protected void onExternalVideoSurfacePositionChanged(
int playerId, float left, float top, float right, float bottom) {
if (mPlayerId != playerId) return;
@@ -192,7 +210,7 @@ public class ExternalVideoSurfaceContainer implements SurfaceHolder.Callback {
* Called when the page that contains the video element is scrolled or zoomed.
*/
@CalledByNative
- private void onFrameInfoUpdated() {
+ protected void onFrameInfoUpdated() {
if (mPlayerId == INVALID_PLAYER_ID) return;
layOutSurfaceView();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index 16ab9d9..e21e2e8 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -24,7 +24,6 @@ import org.chromium.android_webview.AwSettings.LayoutAlgorithm;
import org.chromium.android_webview.InterceptedRequestData;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.ImagePageGenerator;
-import org.chromium.android_webview.test.util.JavascriptEventObserver;
import org.chromium.android_webview.test.util.VideoTestWebServer;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
@@ -2537,51 +2536,6 @@ public class AwSettingsTest extends AwTestBase {
assertEquals(defaultScale, getPixelScaleOnUiThread(awContents), .01f);
}
- /**
- * Run video test.
- * @param requiredUserGesture the settings of MediaPlaybackRequiresUserGesture.
- * @param waitTime time for waiting event happen, -1 means forever.
- * @return true if the event happened,
- * @throws Throwable throw exception if timeout.
- */
- private boolean runVideoTest(final boolean requiredUserGesture, long waitTime)
- throws Throwable {
- final JavascriptEventObserver observer = new JavascriptEventObserver();
- TestAwContentsClient client = new TestAwContentsClient();
- final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents();
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- AwSettings awSettings = awContents.getSettings();
- awSettings.setJavaScriptEnabled(true);
- awSettings.setMediaPlaybackRequiresUserGesture(requiredUserGesture);
- observer.register(awContents.getContentViewCore(), "javaObserver");
- }
- });
- VideoTestWebServer webServer = new VideoTestWebServer(getActivity());
- try {
- String data = "<html><head><script>" +
- "addEventListener('DOMContentLoaded', function() { " +
- " document.getElementById('video').addEventListener('play', function() { " +
- " javaObserver.notifyJava(); " +
- " }, false); " +
- "}, false); " +
- "</script></head><body>" +
- "<video id='video' autoplay control src='" +
- webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
- loadDataAsync(awContents, data, "text/html", false);
- if (waitTime == -1) {
- observer.waitForEvent();
- return true;
- } else {
- return observer.waitForEvent(waitTime);
- }
- } finally {
- if (webServer != null && webServer.getTestWebServer() != null)
- webServer.getTestWebServer().shutdown();
- }
- }
-
/*
@LargeTest
@Feature({"AndroidWebView", "Preferences"})
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
index f362c37..4008b8d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwTestBase.java
@@ -17,6 +17,8 @@ import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwSettings;
import org.chromium.android_webview.test.util.JSUtils;
+import org.chromium.android_webview.test.util.JavascriptEventObserver;
+import org.chromium.android_webview.test.util.VideoTestWebServer;
import org.chromium.base.test.util.InMemorySharedPreferences;
import org.chromium.content.browser.ContentSettings;
import org.chromium.content.browser.LoadUrlParams;
@@ -465,4 +467,49 @@ public class AwTestBase
}
});
}
+
+ /**
+ * Run video test.
+ * @param requiredUserGesture the settings of MediaPlaybackRequiresUserGesture.
+ * @param waitTime time for waiting event happen, -1 means forever.
+ * @return true if the event happened,
+ * @throws Throwable throw exception if timeout.
+ */
+ protected boolean runVideoTest(final boolean requiredUserGesture, long waitTime)
+ throws Throwable {
+ final JavascriptEventObserver observer = new JavascriptEventObserver();
+ TestAwContentsClient client = new TestAwContentsClient();
+ final AwContents awContents = createAwTestContainerViewOnMainSync(client).getAwContents();
+ getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ AwSettings awSettings = awContents.getSettings();
+ awSettings.setJavaScriptEnabled(true);
+ awSettings.setMediaPlaybackRequiresUserGesture(requiredUserGesture);
+ observer.register(awContents.getContentViewCore(), "javaObserver");
+ }
+ });
+ VideoTestWebServer webServer = new VideoTestWebServer(getActivity());
+ try {
+ String data = "<html><head><script>" +
+ "addEventListener('DOMContentLoaded', function() { " +
+ " document.getElementById('video').addEventListener('play', function() { " +
+ " javaObserver.notifyJava(); " +
+ " }, false); " +
+ "}, false); " +
+ "</script></head><body>" +
+ "<video id='video' autoplay control src='" +
+ webServer.getOnePixelOneFrameWebmURL() + "' /> </body></html>";
+ loadDataAsync(awContents, data, "text/html", false);
+ if (waitTime == -1) {
+ observer.waitForEvent();
+ return true;
+ } else {
+ return observer.waitForEvent(waitTime);
+ }
+ } finally {
+ if (webServer != null && webServer.getTestWebServer() != null)
+ webServer.getTestWebServer().shutdown();
+ }
+ }
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java
new file mode 100644
index 0000000..ca4df0c
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ExternalVideoSurfaceContainerTest.java
@@ -0,0 +1,131 @@
+// Copyright 2014 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.graphics.RectF;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.android_webview.ExternalVideoSurfaceContainer;
+import org.chromium.base.CommandLine;
+import org.chromium.base.test.util.DisabledTest;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.content.browser.test.util.CallbackHelper;
+
+/**
+ * A test suite for ExternalVideoSurfaceContainerTest.
+ */
+public class ExternalVideoSurfaceContainerTest extends AwTestBase {
+
+ // Callback helper to track the position/size of the external surface.
+ private static class OnExternalVideoSurfacePositionChanged extends CallbackHelper {
+ private RectF mRect;
+
+ public RectF getRectF() {
+ return mRect;
+ }
+
+ public void notifyCalled(RectF rect) {
+ mRect = rect;
+ notifyCalled();
+ }
+ }
+ private OnExternalVideoSurfacePositionChanged mOnExternalVideoSurfacePositionChanged =
+ new OnExternalVideoSurfacePositionChanged();
+ private CallbackHelper mOnRequestExternalVideoSurface = new CallbackHelper();
+
+ private static void waitForVideoSizeChangeTo(OnExternalVideoSurfacePositionChanged helper,
+ int callCount, float widthCss, float heightCss) throws Exception {
+ final int maxSizeChangeNotificationToWaitFor = 5;
+ final float epsilon = 0.000001f;
+ for (int i = 1; i <= maxSizeChangeNotificationToWaitFor; ++i) {
+ helper.waitForCallback(callCount, i);
+ RectF rect = helper.getRectF();
+ if (Math.abs(rect.width() - widthCss) < epsilon
+ && Math.abs(rect.height() - heightCss) < epsilon) {
+ break;
+ }
+ assertTrue(i < maxSizeChangeNotificationToWaitFor);
+ }
+ }
+
+ private class MockExternalVideoSurfaceContainer extends ExternalVideoSurfaceContainer {
+ private int mPlayerId = INVALID_PLAYER_ID;
+
+ public MockExternalVideoSurfaceContainer(
+ int nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
+ super(nativeExternalVideoSurfaceContainer, contentViewCore);
+ }
+
+ @Override
+ protected void requestExternalVideoSurface(int playerId) {
+ mPlayerId = playerId;
+ mOnRequestExternalVideoSurface.notifyCalled();
+ }
+
+ @Override
+ protected void releaseExternalVideoSurface(int playerId) {
+ mPlayerId = INVALID_PLAYER_ID;
+ }
+
+ @Override
+ protected void destroy() {}
+
+ @Override
+ protected void onExternalVideoSurfacePositionChanged(
+ int playerId, float left, float top, float right, float bottom) {
+ if (mPlayerId != playerId) {
+ return;
+ }
+ mOnExternalVideoSurfacePositionChanged.notifyCalled(
+ new RectF(left, top, right, bottom));
+ }
+
+ @Override
+ protected void onFrameInfoUpdated() {}
+ }
+
+ private void setUpMockExternalVideoSurfaceContainer() {
+ ExternalVideoSurfaceContainer.setFactory(new ExternalVideoSurfaceContainer.Factory() {
+ @Override
+ public ExternalVideoSurfaceContainer create(
+ int nativeContainer, ContentViewCore contentViewCore) {
+ return new MockExternalVideoSurfaceContainer(nativeContainer, contentViewCore);
+ }
+ });
+ }
+
+ /*
+ @SmallTest
+ @Feature({"AndroidWebView"})
+ TODO(ycheo): Enable this after turing on the flag 'video_hole=1'.
+ */
+ @DisabledTest
+ public void testEnableVideoOverlayForEmbeddedVideo() throws Throwable {
+ setUpMockExternalVideoSurfaceContainer();
+
+ CommandLine.getInstance().appendSwitch("force-use-overlay-embedded-video");
+
+ int onRequestCallCount = mOnRequestExternalVideoSurface.getCallCount();
+ int onPositionChangedCallCount = mOnExternalVideoSurfacePositionChanged.getCallCount();
+
+ assertTrue(runVideoTest(false, -1));
+
+ mOnRequestExternalVideoSurface.waitForCallback(onRequestCallCount);
+ waitForVideoSizeChangeTo(mOnExternalVideoSurfacePositionChanged,
+ onPositionChangedCallCount, 150.0f, 150.0f);
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView"})
+ public void testDisableVideoOverlayForEmbeddedVideo() throws Throwable {
+ setUpMockExternalVideoSurfaceContainer();
+
+ assertTrue(runVideoTest(false, -1));
+
+ assertEquals(0, mOnRequestExternalVideoSurface.getCallCount());
+ assertEquals(0, mOnExternalVideoSurfacePositionChanged.getCallCount());
+ }
+}