1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.android_webview.test;
6
7import android.graphics.RectF;
8import android.test.suitebuilder.annotation.SmallTest;
9
10import org.chromium.android_webview.ExternalVideoSurfaceContainer;
11import org.chromium.android_webview.test.util.VideoTestUtil;
12import org.chromium.base.CommandLine;
13import org.chromium.base.test.util.Feature;
14import org.chromium.content.browser.ContentViewCore;
15import org.chromium.content.browser.test.util.CallbackHelper;
16
17/**
18 * A test suite for ExternalVideoSurfaceContainerTest.
19 */
20public class ExternalVideoSurfaceContainerTest extends AwTestBase {
21
22    // Callback helper to track the position/size of the external surface.
23    private static class OnExternalVideoSurfacePositionChanged extends CallbackHelper {
24        private RectF mRect;
25
26        public RectF getRectF() {
27            return mRect;
28        }
29
30        public void notifyCalled(RectF rect) {
31            mRect = rect;
32            notifyCalled();
33        }
34    }
35    private OnExternalVideoSurfacePositionChanged mOnExternalVideoSurfacePositionChanged =
36            new OnExternalVideoSurfacePositionChanged();
37    private CallbackHelper mOnRequestExternalVideoSurface = new CallbackHelper();
38
39    private static void waitForVideoSizeChangeTo(OnExternalVideoSurfacePositionChanged helper,
40            int callCount, float widthCss, float heightCss) throws Exception {
41        final int maxSizeChangeNotificationToWaitFor = 5;
42        final float epsilon = 0.000001f;
43        for (int i = 1; i <= maxSizeChangeNotificationToWaitFor; ++i) {
44            helper.waitForCallback(callCount, i);
45            RectF rect = helper.getRectF();
46            if (Math.abs(rect.width() - widthCss) < epsilon
47                    && Math.abs(rect.height() - heightCss) < epsilon) {
48                break;
49            }
50            assertTrue(i < maxSizeChangeNotificationToWaitFor);
51        }
52    }
53
54    private class MockExternalVideoSurfaceContainer extends ExternalVideoSurfaceContainer {
55        private int mPlayerId = INVALID_PLAYER_ID;
56
57        public MockExternalVideoSurfaceContainer(
58                long nativeExternalVideoSurfaceContainer, ContentViewCore contentViewCore) {
59            super(nativeExternalVideoSurfaceContainer, contentViewCore);
60        }
61
62        @Override
63        protected void requestExternalVideoSurface(int playerId) {
64            mPlayerId = playerId;
65            mOnRequestExternalVideoSurface.notifyCalled();
66        }
67
68        @Override
69        protected void releaseExternalVideoSurface(int playerId) {
70            mPlayerId = INVALID_PLAYER_ID;
71        }
72
73        @Override
74        protected void destroy() {}
75
76        @Override
77        protected void onExternalVideoSurfacePositionChanged(
78                int playerId, float left, float top, float right, float bottom) {
79            if (mPlayerId != playerId) {
80                return;
81            }
82            mOnExternalVideoSurfacePositionChanged.notifyCalled(
83                    new RectF(left, top, right, bottom));
84        }
85
86        @Override
87        protected void onFrameInfoUpdated() {}
88    }
89
90    private void setUpMockExternalVideoSurfaceContainer() {
91        ExternalVideoSurfaceContainer.setFactory(new ExternalVideoSurfaceContainer.Factory() {
92            @Override
93            public ExternalVideoSurfaceContainer create(
94                    long nativeContainer, ContentViewCore contentViewCore) {
95                return new MockExternalVideoSurfaceContainer(nativeContainer, contentViewCore);
96            }
97        });
98    }
99
100    @SmallTest
101    @Feature({"AndroidWebView"})
102    public void testEnableVideoOverlayForEmbeddedVideo() throws Throwable {
103        setUpMockExternalVideoSurfaceContainer();
104
105        CommandLine.getInstance().appendSwitch("force-use-overlay-embedded-video");
106
107        int onRequestCallCount = mOnRequestExternalVideoSurface.getCallCount();
108        int onPositionChangedCallCount = mOnExternalVideoSurfacePositionChanged.getCallCount();
109
110        assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS));
111
112        mOnRequestExternalVideoSurface.waitForCallback(onRequestCallCount);
113        waitForVideoSizeChangeTo(mOnExternalVideoSurfacePositionChanged,
114                                 onPositionChangedCallCount, 150.0f, 150.0f);
115    }
116
117    @SmallTest
118    @Feature({"AndroidWebView"})
119    public void testDisableVideoOverlayForEmbeddedVideo() throws Throwable {
120        setUpMockExternalVideoSurfaceContainer();
121
122        assertTrue(VideoTestUtil.runVideoTest(this, false, WAIT_TIMEOUT_MS));
123
124        assertEquals(0, mOnRequestExternalVideoSurface.getCallCount());
125        assertEquals(0, mOnExternalVideoSurfacePositionChanged.getCallCount());
126    }
127}
128