[tbb-commits] [Git][tpo/applications/android-components][android-components-102.0.14-12.0-1] Improve the media delegate
Richard Pospesel (@richard)
git at gitlab.torproject.org
Wed Aug 31 18:15:27 UTC 2022
Richard Pospesel pushed to branch android-components-102.0.14-12.0-1 at The Tor Project / Applications / android-components
Commits:
b65622fa by Arturo Mejia at 2022-08-30T21:22:54+00:00
Improve the media delegate
- - - - -
4 changed files:
- components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt
- + components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/media/GeckoMediaDelegate.kt
- components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt
- + components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/media/GeckoMediaDelegateTest.kt
Changes:
=====================================
components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/GeckoEngineSession.kt
=====================================
@@ -16,6 +16,7 @@ import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import mozilla.components.browser.engine.gecko.ext.isExcludedForTrackingProtection
import mozilla.components.browser.engine.gecko.fetch.toResponse
+import mozilla.components.browser.engine.gecko.media.GeckoMediaDelegate
import mozilla.components.browser.engine.gecko.mediasession.GeckoMediaSessionDelegate
import mozilla.components.browser.engine.gecko.permission.GeckoPermissionRequest
import mozilla.components.browser.engine.gecko.prompt.GeckoPromptDelegate
@@ -1098,6 +1099,7 @@ class GeckoEngineSession(
geckoSession.contentBlockingDelegate = createContentBlockingDelegate()
geckoSession.permissionDelegate = createPermissionDelegate()
geckoSession.promptDelegate = GeckoPromptDelegate(this)
+ geckoSession.mediaDelegate = GeckoMediaDelegate(this)
geckoSession.historyDelegate = createHistoryDelegate()
geckoSession.mediaSessionDelegate = GeckoMediaSessionDelegate(this)
geckoSession.scrollDelegate = createScrollDelegate()
=====================================
components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/media/GeckoMediaDelegate.kt
=====================================
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.browser.engine.gecko.media
+
+import androidx.annotation.VisibleForTesting
+import mozilla.components.browser.engine.gecko.GeckoEngineSession
+import mozilla.components.concept.engine.media.RecordingDevice
+import org.mozilla.geckoview.GeckoSession
+import java.security.InvalidParameterException
+import org.mozilla.geckoview.GeckoSession.MediaDelegate.RecordingDevice as GeckoRecordingDevice
+
+/**
+ * Gecko-based GeckoMediaDelegate implementation.
+ */
+internal class GeckoMediaDelegate(private val geckoEngineSession: GeckoEngineSession) :
+ GeckoSession.MediaDelegate {
+
+ override fun onRecordingStatusChanged(
+ session: GeckoSession,
+ geckoDevices: Array<out GeckoRecordingDevice>
+ ) {
+ val devices = geckoDevices.map { geckoRecording ->
+ val type = geckoRecording.toType()
+ val status = geckoRecording.toStatus()
+ RecordingDevice(type, status)
+ }
+ geckoEngineSession.notifyObservers { onRecordingStateChanged(devices) }
+ }
+}
+
+ at VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+internal fun GeckoRecordingDevice.toType(): RecordingDevice.Type {
+ return when (type) {
+ GeckoRecordingDevice.Type.CAMERA -> RecordingDevice.Type.CAMERA
+ GeckoRecordingDevice.Type.MICROPHONE -> RecordingDevice.Type.MICROPHONE
+ else -> {
+ throw InvalidParameterException("Unexpected Gecko Media type $type status $status")
+ }
+ }
+}
+
+ at VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+internal fun GeckoRecordingDevice.toStatus(): RecordingDevice.Status {
+ return when (status) {
+ GeckoRecordingDevice.Status.RECORDING -> RecordingDevice.Status.RECORDING
+ GeckoRecordingDevice.Status.INACTIVE -> RecordingDevice.Status.INACTIVE
+ else -> {
+ throw InvalidParameterException("Unexpected Gecko Media type $type status $status")
+ }
+ }
+}
=====================================
components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/GeckoEngineSessionTest.kt
=====================================
@@ -113,6 +113,7 @@ class GeckoEngineSessionTest {
private lateinit var navigationDelegate: ArgumentCaptor<GeckoSession.NavigationDelegate>
private lateinit var progressDelegate: ArgumentCaptor<GeckoSession.ProgressDelegate>
+ private lateinit var mediaDelegate: ArgumentCaptor<GeckoSession.MediaDelegate>
private lateinit var contentDelegate: ArgumentCaptor<GeckoSession.ContentDelegate>
private lateinit var permissionDelegate: ArgumentCaptor<GeckoSession.PermissionDelegate>
private lateinit var contentBlockingDelegate: ArgumentCaptor<ContentBlocking.Delegate>
@@ -140,6 +141,7 @@ class GeckoEngineSessionTest {
whenever(runtime.settings).thenReturn(mock())
navigationDelegate = ArgumentCaptor.forClass(GeckoSession.NavigationDelegate::class.java)
progressDelegate = ArgumentCaptor.forClass(GeckoSession.ProgressDelegate::class.java)
+ mediaDelegate = ArgumentCaptor.forClass(GeckoSession.MediaDelegate::class.java)
contentDelegate = ArgumentCaptor.forClass(GeckoSession.ContentDelegate::class.java)
permissionDelegate = ArgumentCaptor.forClass(GeckoSession.PermissionDelegate::class.java)
contentBlockingDelegate = ArgumentCaptor.forClass(ContentBlocking.Delegate::class.java)
@@ -156,6 +158,7 @@ class GeckoEngineSessionTest {
verify(geckoSession).permissionDelegate = permissionDelegate.capture()
verify(geckoSession).contentBlockingDelegate = contentBlockingDelegate.capture()
verify(geckoSession).historyDelegate = historyDelegate.capture()
+ verify(geckoSession).mediaDelegate = mediaDelegate.capture()
}
@Test
=====================================
components/browser/engine-gecko/src/test/java/mozilla/components/browser/engine/gecko/media/GeckoMediaDelegateTest.kt
=====================================
@@ -0,0 +1,113 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package mozilla.components.browser.engine.gecko.media
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import junit.framework.TestCase.assertEquals
+import junit.framework.TestCase.assertTrue
+import junit.framework.TestCase.fail
+import mozilla.components.browser.engine.gecko.GeckoEngineSession
+import mozilla.components.concept.engine.EngineSession
+import mozilla.components.concept.engine.media.RecordingDevice
+import mozilla.components.support.test.mock
+import mozilla.components.support.test.whenever
+import mozilla.components.test.ReflectionUtils
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mozilla.geckoview.GeckoRuntime
+import java.security.InvalidParameterException
+import org.mozilla.geckoview.GeckoSession.MediaDelegate.RecordingDevice as GeckoRecordingDevice
+
+ at RunWith(AndroidJUnit4::class)
+class GeckoMediaDelegateTest {
+ private lateinit var runtime: GeckoRuntime
+
+ @Before
+ fun setup() {
+ runtime = mock()
+ whenever(runtime.settings).thenReturn(mock())
+ }
+
+ @Test
+ fun `WHEN onRecordingStatusChanged is called THEN notify onRecordingStateChanged`() {
+ val mockSession = GeckoEngineSession(runtime)
+ var onRecordingWasCalled = false
+ val geckoRecordingDevice = createGeckoRecordingDevice(
+ status = GeckoRecordingDevice.Status.RECORDING, type = GeckoRecordingDevice.Type.CAMERA
+ )
+ val gecko = GeckoMediaDelegate(mockSession)
+
+ mockSession.register(object : EngineSession.Observer {
+ override fun onRecordingStateChanged(devices: List<RecordingDevice>) {
+ onRecordingWasCalled = true
+ }
+ })
+
+ gecko.onRecordingStatusChanged(mock(), arrayOf(geckoRecordingDevice))
+
+ assertTrue(onRecordingWasCalled)
+ }
+
+ @Test
+ fun `GIVEN a GeckoRecordingDevice status WHEN calling toStatus THEN covert to the RecordingDevice status`() {
+ val geckoRecordingDevice = createGeckoRecordingDevice(
+ status = GeckoRecordingDevice.Status.RECORDING
+ )
+ val geckoInactiveDevice = createGeckoRecordingDevice(
+ status = GeckoRecordingDevice.Status.INACTIVE
+ )
+
+ assertEquals(RecordingDevice.Status.RECORDING, geckoRecordingDevice.toStatus())
+ assertEquals(RecordingDevice.Status.INACTIVE, geckoInactiveDevice.toStatus())
+ }
+
+ @Test
+ fun `GIVEN an invalid GeckoRecordingDevice status WHEN calling toStatus THEN throw an exception`() {
+ val geckoInvalidDevice = createGeckoRecordingDevice(
+ status = 12
+ )
+ try {
+ geckoInvalidDevice.toStatus()
+ fail()
+ } catch (_: InvalidParameterException) {
+ }
+ }
+
+ @Test
+ fun `GIVEN a GeckoRecordingDevice type WHEN calling toType THEN covert to the RecordingDevice type`() {
+ val geckoCameraDevice = createGeckoRecordingDevice(
+ type = GeckoRecordingDevice.Type.CAMERA
+ )
+ val geckoMicDevice = createGeckoRecordingDevice(
+ type = GeckoRecordingDevice.Type.MICROPHONE
+ )
+
+ assertEquals(RecordingDevice.Type.CAMERA, geckoCameraDevice.toType())
+ assertEquals(RecordingDevice.Type.MICROPHONE, geckoMicDevice.toType())
+ }
+
+ @Test
+ fun `GIVEN an invalid GeckoRecordingDevice type WHEN calling toType THEN throw an exception`() {
+ val geckoInvalidDevice = createGeckoRecordingDevice(
+ type = 12
+ )
+ try {
+ geckoInvalidDevice.toType()
+ fail()
+ } catch (_: InvalidParameterException) {
+ }
+ }
+
+ private fun createGeckoRecordingDevice(
+ status: Long = GeckoRecordingDevice.Status.RECORDING,
+ type: Long = GeckoRecordingDevice.Type.CAMERA
+ ): GeckoRecordingDevice {
+ val device: GeckoRecordingDevice = mock()
+ ReflectionUtils.setField(device, "status", status)
+ ReflectionUtils.setField(device, "type", type)
+ return device
+ }
+}
View it on GitLab: https://gitlab.torproject.org/tpo/applications/android-components/-/commit/b65622fae0b6f67f3f7f8614e2512c4b8ab6aa3f
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/android-components/-/commit/b65622fae0b6f67f3f7f8614e2512c4b8ab6aa3f
You're receiving this email because of your account on gitlab.torproject.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20220831/4f2911fd/attachment-0001.htm>
More information about the tbb-commits
mailing list