blob: 26f10caf216c05d61a2e0a4ced83e0dd8dc1f7c5 [file] [log] [blame]
// 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.support.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.permission.AwPermissionRequest;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisableIf;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.content_public.common.ContentSwitches;
import org.chromium.net.test.util.TestWebServer;
/**
* Test MediaAccessPermissionRequest.
*/
@RunWith(AwJUnit4ClassRunner.class)
public class MediaAccessPermissionRequestTest {
@Rule
public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();
private static class OnPermissionRequestHelper extends CallbackHelper {
private boolean mCanceled;
public void notifyCanceled() {
mCanceled = true;
notifyCalled();
}
public boolean canceled() {
return mCanceled;
}
}
private static final String DATA = "<html> <script> "
+ "var constraints = {audio: true, video: true};"
+ "var video = document.querySelector('video');"
+ "function successCallback(stream) {"
+ " window.document.title = 'grant';"
+ " video.srcObject = stream;"
+ "}"
+ "function errorCallback(error){"
+ " window.document.title = 'deny';"
+ " console.log('navigator.getUserMedia error: ', error);"
+ "}"
+ "navigator.webkitGetUserMedia(constraints, successCallback, errorCallback)"
+ "</script><body>"
+ "<video autoplay></video>"
+ "</body></html>";
private TestWebServer mTestWebServer;
private String mWebRTCPage;
@Before
public void setUp() throws Exception {
mTestWebServer = TestWebServer.start();
mWebRTCPage = mTestWebServer.setResponse("/WebRTC", DATA,
CommonResources.getTextHtmlHeaders(true));
}
@After
public void tearDown() throws Exception {
mTestWebServer.shutdown();
mTestWebServer = null;
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
@DisableIf.Build(sdk_is_greater_than = 22, message = "crbug.com/623921")
@CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@RetryOnFailure
public void testGrantAccess() throws Throwable {
final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
TestAwContentsClient contentsClient =
new TestAwContentsClient() {
@Override
public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
awPermissionRequest.grant();
helper.notifyCalled();
}
};
final AwTestContainerView testContainerView =
mActivityTestRule.createAwTestContainerViewOnMainSync(contentsClient);
final AwContents awContents = testContainerView.getAwContents();
AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
int callCount = helper.getCallCount();
mActivityTestRule.loadUrlAsync(awContents, mWebRTCPage, null);
helper.waitForCallback(callCount);
pollTitleAs("grant", awContents);
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
@DisableIf
.Build(sdk_is_greater_than = 22, message = "crbug.com/614347")
@CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@RetryOnFailure
public void testDenyAccess() throws Throwable {
final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
TestAwContentsClient contentsClient =
new TestAwContentsClient() {
@Override
public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
awPermissionRequest.deny();
helper.notifyCalled();
}
};
final AwTestContainerView testContainerView =
mActivityTestRule.createAwTestContainerViewOnMainSync(contentsClient);
final AwContents awContents = testContainerView.getAwContents();
AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
int callCount = helper.getCallCount();
mActivityTestRule.loadUrlAsync(awContents, mWebRTCPage, null);
helper.waitForCallback(callCount);
pollTitleAs("deny", awContents);
}
private void pollTitleAs(final String title, final AwContents awContents)
throws Exception {
AwActivityTestRule.pollInstrumentationThread(
() -> title.equals(mActivityTestRule.getTitleOnUiThread(awContents)));
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
@DisableIf
.Build(sdk_is_greater_than = 22, message = "crbug.com/614347")
@CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@RetryOnFailure
public void testDenyAccessByDefault() throws Throwable {
final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
TestAwContentsClient contentsClient =
new TestAwContentsClient() {
@Override
public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
// Intentionally do nothing with awPermissionRequest.
helper.notifyCalled();
}
};
final AwTestContainerView testContainerView =
mActivityTestRule.createAwTestContainerViewOnMainSync(contentsClient);
final AwContents awContents = testContainerView.getAwContents();
AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
int callCount = helper.getCallCount();
mActivityTestRule.loadUrlAsync(awContents, mWebRTCPage, null);
helper.waitForCallback(callCount);
// Cause AwPermissionRequest to be garbage collected, which should deny
// the request.
Runtime.getRuntime().gc();
// Poll with gc in each iteration to reduce flake.
AwActivityTestRule.pollInstrumentationThread(() -> {
Runtime.getRuntime().gc();
return "deny".equals(mActivityTestRule.getTitleOnUiThread(awContents));
});
}
@Test
@Feature({"AndroidWebView"})
@SmallTest
@DisableIf
.Build(sdk_is_greater_than = 22, message = "crbug.com/614347")
@CommandLineFlags.Add(ContentSwitches.USE_FAKE_DEVICE_FOR_MEDIA_STREAM)
@RetryOnFailure
public void testCancelPermission() throws Throwable {
final OnPermissionRequestHelper helper = new OnPermissionRequestHelper();
TestAwContentsClient contentsClient =
new TestAwContentsClient() {
private AwPermissionRequest mRequest;
@Override
public void onPermissionRequest(AwPermissionRequest awPermissionRequest) {
Assert.assertNull(mRequest);
mRequest = awPermissionRequest;
// Don't respond and wait for the request canceled.
helper.notifyCalled();
}
@Override
public void onPermissionRequestCanceled(
AwPermissionRequest awPermissionRequest) {
Assert.assertNotNull(mRequest);
if (mRequest == awPermissionRequest) helper.notifyCanceled();
mRequest = null;
}
};
final AwTestContainerView testContainerView =
mActivityTestRule.createAwTestContainerViewOnMainSync(contentsClient);
final AwContents awContents = testContainerView.getAwContents();
AwActivityTestRule.enableJavaScriptOnUiThread(awContents);
int callCount = helper.getCallCount();
mActivityTestRule.loadUrlAsync(awContents, mWebRTCPage, null);
helper.waitForCallback(callCount);
callCount = helper.getCallCount();
// Load the same page again, the previous request should be canceled.
mActivityTestRule.loadUrlAsync(awContents, mWebRTCPage, null);
helper.waitForCallback(callCount);
Assert.assertTrue(helper.canceled());
}
}