diff options
author | ycheo@chromium.org <ycheo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-30 07:58:31 +0000 |
---|---|---|
committer | ycheo@chromium.org <ycheo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-30 07:58:31 +0000 |
commit | dafd4e72466ce739e14f4a365f5158ca1a39bf97 (patch) | |
tree | b43a6c00255858efb27040da21dd328132e86b9f /android_webview | |
parent | d0359da7b7917230b3d6ea8d2ec66e90b6bf9972 (diff) | |
download | chromium_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')
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()); + } +} |