[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