Skip to content

Commit

Permalink
Makes hardware req. optional. Avoid showing dialog if camera doesn't …
Browse files Browse the repository at this point in the history
…exist
  • Loading branch information
cmonfortep committed Oct 17, 2022
1 parent d2106d5 commit bef86cd
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 7 deletions.
6 changes: 5 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.CAMERA" android:required="false" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />

<queries>
<intent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>): Array<String> =
override suspend fun getSitePermissionsGranted(
url: String,
tabId: String,
resources: Array<String>
): Array<String> =
resources
.filter { sitePermissionsRepository.isDomainGranted(url, tabId, it) }
.toTypedArray()

override suspend fun getSitePermissionsAllowedToAsk(url: String, resources: Array<String>): Array<String> =
override suspend fun getSitePermissionsAllowedToAsk(
url: String,
resources: Array<String>
): Array<String> =
resources
.filter { isPermissionSupported(it) }
.filter { isPermissionSupported(it) && isHardwareSupported(it) }
.filter { sitePermissionsRepository.isDomainAllowedToAsk(url, it) }
.toTypedArray()

Expand All @@ -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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,17 +30,21 @@ 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
@get:Rule
var coroutineRule = CoroutineTestRule()

private val mockSitePermissionsRepository: SitePermissionsRepository = mock()
private val mockPackageManager = mock<PackageManager>()

private val testee = SitePermissionsManagerImpl(mockSitePermissionsRepository)
private val testee = SitePermissionsManagerImpl(mockPackageManager, mockSitePermissionsRepository)

private val url = "https://domain.com/whatever"

Expand All @@ -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"
Expand Down

0 comments on commit bef86cd

Please sign in to comment.