diff options
Diffstat (limited to 'mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/MediaDelegateXOriginTest.kt')
-rw-r--r-- | mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/MediaDelegateXOriginTest.kt | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/MediaDelegateXOriginTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/MediaDelegateXOriginTest.kt new file mode 100644 index 0000000000..2caa71fc71 --- /dev/null +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/MediaDelegateXOriginTest.kt @@ -0,0 +1,197 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +package org.mozilla.geckoview.test + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.MediumTest +import org.hamcrest.Matchers +import org.json.JSONObject +import org.junit.Assume.assumeThat +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.geckoview.GeckoSession +import org.mozilla.geckoview.GeckoSession.MediaDelegate +import org.mozilla.geckoview.GeckoSession.PermissionDelegate +import org.mozilla.geckoview.test.rule.GeckoSessionTestRule + +@RunWith(AndroidJUnit4::class) +@MediumTest +@Suppress("DEPRECATION") +class MediaDelegateXOriginTest : BaseSessionTest() { + + private fun requestRecordingPermission(allowAudio: Boolean, allowCamera: Boolean) { + mainSession.delegateDuringNextWait(object : PermissionDelegate { + @GeckoSessionTestRule.AssertCalled(count = 1) + override fun onMediaPermissionRequest( + session: GeckoSession, + uri: String, + video: Array<out GeckoSession.PermissionDelegate.MediaSource>?, + audio: Array<out GeckoSession.PermissionDelegate.MediaSource>?, + callback: GeckoSession.PermissionDelegate.MediaCallback, + ) { + if (!(allowAudio || allowCamera)) { + callback.reject() + return + } + var audioDevice: GeckoSession.PermissionDelegate.MediaSource? = null + var videoDevice: GeckoSession.PermissionDelegate.MediaSource? = null + if (allowAudio) { + audioDevice = audio!![0] + } + if (allowCamera) { + videoDevice = video!![0] + } + + if (videoDevice != null || audioDevice != null) { + callback.grant(videoDevice, audioDevice) + } + } + + override fun onAndroidPermissionsRequest( + session: GeckoSession, + permissions: Array<out String>?, + callback: GeckoSession.PermissionDelegate.Callback, + ) { + callback.grant() + } + }) + + mainSession.delegateDuringNextWait(object : MediaDelegate { + @GeckoSessionTestRule.AssertCalled(count = 1) + override fun onRecordingStatusChanged( + session: GeckoSession, + devices: Array<MediaDelegate.RecordingDevice>, + ) { + var audioActive = false + var cameraActive = false + for (device in devices) { + if (device.type == MediaDelegate.RecordingDevice.Type.MICROPHONE) { + audioActive = device.status != MediaDelegate.RecordingDevice.Status.INACTIVE + } + if (device.type == MediaDelegate.RecordingDevice.Type.CAMERA) { + cameraActive = device.status != MediaDelegate.RecordingDevice.Status.INACTIVE + } + } + + assertThat( + "Camera is ${if (allowCamera) { "active" } else { "inactive" }}", + cameraActive, + Matchers.equalTo(allowCamera), + ) + + assertThat( + "Audio is ${if (allowAudio) { "active" } else { "inactive" }}", + audioActive, + Matchers.equalTo(allowAudio), + ) + } + }) + + var constraints: String? + if (allowAudio && allowCamera) { + constraints = """{ + video: { width: 320, height: 240, frameRate: 10 }, + audio: true + }""" + } else if (allowAudio) { + constraints = "{ audio: true }" + } else if (allowCamera) { + constraints = "{video: { width: 320, height: 240, frameRate: 10 }}" + } else { + return + } + + val started = mainSession.waitForJS("Start($constraints)") as String + assertThat("getUserMedia should have succeeded", started, Matchers.equalTo("ok")) + + val stopped = mainSession.waitForJS("Stop()") as Boolean + assertThat("stream should have been stopped", stopped, Matchers.equalTo(true)) + } + + private fun requestRecordingPermissionNoAllow(allowAudio: Boolean, allowCamera: Boolean) { + mainSession.delegateDuringNextWait(object : PermissionDelegate { + @GeckoSessionTestRule.AssertCalled(count = 0) + override fun onMediaPermissionRequest( + session: GeckoSession, + uri: String, + video: Array<out GeckoSession.PermissionDelegate.MediaSource>?, + audio: Array<out GeckoSession.PermissionDelegate.MediaSource>?, + callback: GeckoSession.PermissionDelegate.MediaCallback, + ) { + callback.reject() + } + + @GeckoSessionTestRule.AssertCalled(count = 0) + override fun onAndroidPermissionsRequest( + session: GeckoSession, + permissions: Array<out String>?, + callback: GeckoSession.PermissionDelegate.Callback, + ) { + callback.reject() + } + }) + + mainSession.delegateDuringNextWait(object : MediaDelegate { + @GeckoSessionTestRule.AssertCalled(count = 0) + override fun onRecordingStatusChanged( + session: GeckoSession, + devices: Array<org.mozilla.geckoview.GeckoSession.MediaDelegate.RecordingDevice>, + ) {} + }) + + var constraints: String? + if (allowAudio && allowCamera) { + constraints = """{ + video: { width: 320, height: 240, frameRate: 10 }, + audio: true + }""" + } else if (allowAudio) { + constraints = "{ audio: true }" + } else if (allowCamera) { + constraints = "{video: { width: 320, height: 240, frameRate: 10 }}" + } else { + return + } + + val started = mainSession.waitForJS("StartNoAllow($constraints)") as String + assertThat("getUserMedia should not be allowed", started, Matchers.startsWith("NotAllowedError")) + + val stopped = mainSession.waitForJS("Stop()") as Boolean + assertThat("stream stop should fail", stopped, Matchers.equalTo(false)) + } + + @Test fun testDeviceRecordingEventAudioAndVideoInXOriginIframe() { + // TODO: needs bug 1700243 + assumeThat(sessionRule.env.isIsolatedProcess, Matchers.equalTo(false)) + + mainSession.loadTestPath(GETUSERMEDIA_XORIGIN_CONTAINER_HTML_PATH) + mainSession.waitForPageStop() + + val devices = mainSession.waitForJS( + "window.navigator.mediaDevices.enumerateDevices()", + ).asJSList<JSONObject>() + val audioDevice = devices.find { map -> map.getString("kind") == "audioinput" } + val videoDevice = devices.find { map -> map.getString("kind") == "videoinput" } + requestRecordingPermission( + allowAudio = audioDevice != null, + allowCamera = videoDevice != null, + ) + } + + @Test fun testDeviceRecordingEventAudioAndVideoInXOriginIframeNoAllow() { + mainSession.loadTestPath(GETUSERMEDIA_XORIGIN_CONTAINER_HTML_PATH) + mainSession.waitForPageStop() + + val devices = mainSession.waitForJS( + "window.navigator.mediaDevices.enumerateDevices()", + ).asJSList<JSONObject>() + val audioDevice = devices.find { map -> map.getString("kind") == "audioinput" } + val videoDevice = devices.find { map -> map.getString("kind") == "videoinput" } + requestRecordingPermissionNoAllow( + allowAudio = audioDevice != null, + allowCamera = videoDevice != null, + ) + } +} |