diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f59cb56485e2..05308e4a1fba 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -17,7 +17,11 @@
tools:ignore="QueryAllPackagesPermission" />
-
+
+
+
+
+
diff --git a/app/version/release-notes b/app/version/release-notes
index 8ed107e79663..95a9ae75253a 100644
--- a/app/version/release-notes
+++ b/app/version/release-notes
@@ -1,2 +1 @@
-When websites ask for camera and mic permissions, you can now use these features on sites you visit.
-We've also improved how you manage the permissions you've already granted, giving you global controls over permissions for individual websites and the ability to restrict whether websites can ask for permissions at all.
\ No newline at end of file
+When websites ask for camera and mic permissions, you can now use these features on sites you visit.
\ No newline at end of file
diff --git a/app/version/version.properties b/app/version/version.properties
index 2d3e08f4663b..3c124a39c60d 100644
--- a/app/version/version.properties
+++ b/app/version/version.properties
@@ -1 +1 @@
-VERSION=5.139.0
\ No newline at end of file
+VERSION=5.139.1
\ No newline at end of file
diff --git a/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerImpl.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerImpl.kt
index c86e2fb1997d..5a56437e5b24 100644
--- a/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerImpl.kt
+++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerImpl.kt
@@ -16,22 +16,31 @@
package com.duckduckgo.site.permissions.impl
+import android.content.pm.PackageManager
import android.webkit.PermissionRequest
import com.duckduckgo.site.permissions.api.SitePermissionsManager
import javax.inject.Inject
class SitePermissionsManagerImpl @Inject constructor(
+ private val packageManager: PackageManager,
private val sitePermissionsRepository: SitePermissionsRepository
) : SitePermissionsManager {
- override suspend fun getSitePermissionsGranted(url: String, tabId: String, resources: Array): Array =
+ override suspend fun getSitePermissionsGranted(
+ url: String,
+ tabId: String,
+ resources: Array
+ ): Array =
resources
.filter { sitePermissionsRepository.isDomainGranted(url, tabId, it) }
.toTypedArray()
- override suspend fun getSitePermissionsAllowedToAsk(url: String, resources: Array): Array =
+ override suspend fun getSitePermissionsAllowedToAsk(
+ url: String,
+ resources: Array
+ ): Array =
resources
- .filter { isPermissionSupported(it) }
+ .filter { isPermissionSupported(it) && isHardwareSupported(it) }
.filter { sitePermissionsRepository.isDomainAllowedToAsk(url, it) }
.toTypedArray()
@@ -49,4 +58,12 @@ class SitePermissionsManagerImpl @Inject constructor(
private fun isPermissionSupported(permission: String): Boolean =
permission == PermissionRequest.RESOURCE_AUDIO_CAPTURE || permission == PermissionRequest.RESOURCE_VIDEO_CAPTURE
+ private fun isHardwareSupported(permission: String): Boolean = when (permission) {
+ PermissionRequest.RESOURCE_VIDEO_CAPTURE -> {
+ kotlin.runCatching { packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) }.getOrDefault(false)
+ }
+ else -> {
+ true
+ }
+ }
}
diff --git a/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/di/SitePermissionsModule.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/di/SitePermissionsModule.kt
index 3f393af23089..3cc7f9a3bc2d 100644
--- a/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/di/SitePermissionsModule.kt
+++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/di/SitePermissionsModule.kt
@@ -17,6 +17,7 @@
package com.duckduckgo.site.permissions.impl.di
import android.content.Context
+import android.content.pm.PackageManager
import androidx.room.Room
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.site.permissions.api.SitePermissionsManager
@@ -58,8 +59,11 @@ object SitePermissionsModule {
}
@Provides
- fun providesSitePermissionsManager(sitePermissionsRepository: SitePermissionsRepositoryImpl): SitePermissionsManager {
- return SitePermissionsManagerImpl(sitePermissionsRepository)
+ fun providesSitePermissionsManager(
+ sitePermissionsRepository: SitePermissionsRepositoryImpl,
+ packageManager: PackageManager
+ ): SitePermissionsManager {
+ return SitePermissionsManagerImpl(packageManager, sitePermissionsRepository)
}
@Provides
diff --git a/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerTest.kt b/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerTest.kt
index 8a553b0154af..24d05e3db880 100644
--- a/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerTest.kt
+++ b/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerTest.kt
@@ -16,9 +16,11 @@
package com.duckduckgo.site.permissions.impl
+import android.content.pm.PackageManager
import android.webkit.PermissionRequest
import com.duckduckgo.app.CoroutineTestRule
import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionsEntity
+import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.verify
@@ -28,8 +30,11 @@ import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
@ExperimentalCoroutinesApi
+@RunWith(RobolectricTestRunner::class)
class SitePermissionsManagerTest {
@ExperimentalCoroutinesApi
@@ -37,8 +42,9 @@ class SitePermissionsManagerTest {
var coroutineRule = CoroutineTestRule()
private val mockSitePermissionsRepository: SitePermissionsRepository = mock()
+ private val mockPackageManager = mock()
- private val testee = SitePermissionsManagerImpl(mockSitePermissionsRepository)
+ private val testee = SitePermissionsManagerImpl(mockPackageManager, mockSitePermissionsRepository)
private val url = "https://domain.com/whatever"
@@ -60,12 +66,25 @@ class SitePermissionsManagerTest {
arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_MIDI_SYSEX, PermissionRequest.RESOURCE_AUDIO_CAPTURE)
whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(true)
whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_AUDIO_CAPTURE)).thenReturn(false)
+ whenever(mockPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)).thenReturn(true)
val permissionsAllowedToAsk = testee.getSitePermissionsAllowedToAsk(url, resources)
assertEquals(1, permissionsAllowedToAsk.size)
assertEquals(PermissionRequest.RESOURCE_VIDEO_CAPTURE, permissionsAllowedToAsk.first())
}
+ @Test
+ fun givenListOfPermissionsNoHardwareCameraThenFilterNotSupportedAndReturnOnlyPermissionsAllowedToAsk() = runTest {
+ val resources =
+ arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_MIDI_SYSEX, PermissionRequest.RESOURCE_AUDIO_CAPTURE)
+ whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(true)
+ whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_AUDIO_CAPTURE)).thenReturn(false)
+ whenever(mockPackageManager.hasSystemFeature(any())).thenReturn(false)
+
+ val permissionsAllowedToAsk = testee.getSitePermissionsAllowedToAsk(url, resources)
+ assertEquals(0, permissionsAllowedToAsk.size)
+ }
+
@Test
fun whenClearAllButFireproofThenDontDeleteEntitiesWhichDomainIsInTheFireproofList() = runTest {
val fireproofDomain = "domain.com"