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.test.suitebuilder.annotation.SmallTest;
8
9import org.chromium.android_webview.AwContents;
10import org.chromium.android_webview.permission.AwPermissionRequest;
11import org.chromium.android_webview.test.util.CommonResources;
12import org.chromium.base.test.util.Feature;
13import org.chromium.content.browser.test.util.CallbackHelper;
14import org.chromium.net.test.util.TestWebServer;
15
16import java.util.concurrent.Callable;
17
18/**
19 * Test MediaAccessPermissionRequest.
20 */
21public class MediaAccessPermissionRequestTest extends AwTestBase {
22    private static class OnPermissionRequestHelper extends CallbackHelper {
23        private boolean mCanceled;
24
25        public void notifyCanceled() {
26            mCanceled = true;
27            notifyCalled();
28        }
29
30        public boolean canceled() {
31            return mCanceled;
32        }
33    }
34
35    private static final String DATA = "<html> <script> " +
36            "var constraints = {audio: true, video: true};" +
37            "var video = document.querySelector('video');" +
38            "function successCallback(stream) {" +
39                "window.document.title = 'grant';" +
40                "if (window.URL) {" +
41                    "video.src = window.URL.createObjectURL(stream);" +
42                "} else {" +
43                    "video.src = stream;" +
44                "}" +
45            "}" +
46            "function errorCallback(error){" +
47                "window.document.title = 'deny';" +
48                "console.log('navigator.getUserMedia error: ', error);" +
49            "}" +
50            "navigator.webkitGetUserMedia(constraints, successCallback, errorCallback)" +
51            " </script><body>" +
52            "<video autoplay></video>" +
53            "</body></html>";
54
55    private TestWebServer mTestWebServer;
56    private String mWebRTCPage;
57
58    @Override
59    protected void setUp() throws Exception {
60        super.setUp();
61        mTestWebServer = new TestWebServer(false);
62        mWebRTCPage = mTestWebServer.setResponse("/WebRTC", DATA,
63                CommonResources.getTextHtmlHeaders(true));
64    }
65
66    @Override
67    protected void tearDown() throws Exception {
68        mTestWebServer.shutdown();
69        mTestWebServer = null;
70        super.tearDown();
71    }
72
73    @Feature({"AndroidWebView"})
74    @SmallTest
75    public void testGrantAccess() throws Throwable {
76        final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
77        TestAwContentsClient contentsClient =
78                new TestAwContentsClient() {
79                    @Override
80                    public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
81                        awPermissionRequest.grant();
82                        helper.notifyCalled();
83                    }
84                };
85        final AwTestContainerView testContainerView =
86                createAwTestContainerViewOnMainSync(contentsClient);
87        final AwContents awContents = testContainerView.getAwContents();
88        enableJavaScriptOnUiThread(awContents);
89        int callCount = helper.getCallCount();
90        loadUrlAsync(awContents, mWebRTCPage, null);
91        helper.waitForCallback(callCount);
92        pollTitleAs("grant", awContents);
93    }
94
95    @Feature({"AndroidWebView"})
96    @SmallTest
97    public void testDenyAccess() throws Throwable {
98        final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
99        TestAwContentsClient contentsClient =
100                new TestAwContentsClient() {
101                    @Override
102                    public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
103                        awPermissionRequest.deny();
104                        helper.notifyCalled();
105                    }
106                };
107        final AwTestContainerView testContainerView =
108                createAwTestContainerViewOnMainSync(contentsClient);
109        final AwContents awContents = testContainerView.getAwContents();
110        enableJavaScriptOnUiThread(awContents);
111        int callCount = helper.getCallCount();
112        loadUrlAsync(awContents, mWebRTCPage, null);
113        helper.waitForCallback(callCount);
114        pollTitleAs("deny", awContents);
115    }
116
117    private void pollTitleAs(final String title, final AwContents awContents)
118            throws Exception {
119        poll(new Callable<Boolean>() {
120            @Override
121            public Boolean call() throws Exception {
122                return title.equals(getTitleOnUiThread(awContents));
123            }
124        });
125    }
126
127    @Feature({"AndroidWebView"})
128    @SmallTest
129    public void testCancelPermission() throws Throwable {
130        final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
131        TestAwContentsClient contentsClient =
132                new TestAwContentsClient() {
133                    private AwPermissionRequest mRequest;
134                    @Override
135                    public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
136                        assertNull(mRequest);
137                        mRequest = awPermissionRequest;
138                        // Don't respond and wait for the request canceled.
139                        helper.notifyCalled();
140                    }
141                    @Override
142                    public void onPermissionRequestCanceled(
143                            AwPermissionRequest awPermissionRequest) {
144                        assertNotNull(mRequest);
145                        if (mRequest == awPermissionRequest) helper.notifyCanceled();
146                        mRequest = null;
147                    }
148                };
149        final AwTestContainerView testContainerView =
150                createAwTestContainerViewOnMainSync(contentsClient);
151        final AwContents awContents = testContainerView.getAwContents();
152        enableJavaScriptOnUiThread(awContents);
153        int callCount = helper.getCallCount();
154        loadUrlAsync(awContents, mWebRTCPage, null);
155        helper.waitForCallback(callCount);
156        callCount = helper.getCallCount();
157        // Load the same page again, the previous request should be canceled.
158        loadUrlAsync(awContents, mWebRTCPage, null);
159        helper.waitForCallback(callCount);
160        assertTrue(helper.canceled());
161    }
162}
163