Skip to content

Commit e088309

Browse files
CrisBarreirojoshliebe
authored andcommitted
Fix database access on main thread that caused a crash (#5006)
Task/Issue URL: https://app.asana.com/0/1202552961248957/1208294040908744/f ### Description ### Steps to test this PR _Feature 1_ - [x] Open https://www.disneyaulani.com/ - [x] Check app doesn't crash and works normally - [x] Open maps.google.com and click on the location button - [x] Check app doesn't crash and works normally
1 parent 7b8f9a3 commit e088309

File tree

9 files changed

+40
-41
lines changed

9 files changed

+40
-41
lines changed

app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,9 +2429,7 @@ class BrowserTabFragment :
24292429
id: String?,
24302430
data: JSONObject?,
24312431
) {
2432-
appCoroutineScope.launch(dispatchers.main()) {
2433-
viewModel.processJsCallbackMessage(featureName, method, id, data, it.url)
2434-
}
2432+
viewModel.processJsCallbackMessage(featureName, method, id, data, it.url)
24352433
}
24362434
},
24372435
)
@@ -2444,9 +2442,7 @@ class BrowserTabFragment :
24442442
id: String?,
24452443
data: JSONObject?,
24462444
) {
2447-
appCoroutineScope.launch(dispatchers.main()) {
2448-
viewModel.processJsCallbackMessage(featureName, method, id, data, it.url)
2449-
}
2445+
viewModel.processJsCallbackMessage(featureName, method, id, data, it.url)
24502446
}
24512447
},
24522448
)

app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3167,7 +3167,7 @@ class BrowserTabViewModel @Inject constructor(
31673167
)
31683168
}
31693169

3170-
suspend fun processJsCallbackMessage(
3170+
fun processJsCallbackMessage(
31713171
featureName: String,
31723172
method: String,
31733173
id: String?,
@@ -3200,7 +3200,7 @@ class BrowserTabViewModel @Inject constructor(
32003200

32013201
when (featureName) {
32023202
DUCK_PLAYER_FEATURE_NAME, DUCK_PLAYER_PAGE_FEATURE_NAME -> {
3203-
withContext(dispatchers.io()) {
3203+
viewModelScope.launch(dispatchers.io()) {
32043204
val response = duckPlayerJSHelper.processJsCallbackMessage(featureName, method, id, data, url)
32053205
withContext(dispatchers.main()) {
32063206
response?.let {
@@ -3230,15 +3230,17 @@ class BrowserTabViewModel @Inject constructor(
32303230
id: String,
32313231
data: JSONObject,
32323232
) {
3233-
val response = if (url == null) {
3234-
getDataForPermissionState(featureName, method, id, SitePermissionQueryResponse.Denied)
3235-
} else {
3236-
val permissionState = sitePermissionsManager.getPermissionsQueryResponse(url!!, tabId, data.optString("name"))
3237-
getDataForPermissionState(featureName, method, id, permissionState)
3238-
}
3233+
viewModelScope.launch(dispatchers.io()) {
3234+
val response = if (url == null) {
3235+
getDataForPermissionState(featureName, method, id, SitePermissionQueryResponse.Denied)
3236+
} else {
3237+
val permissionState = sitePermissionsManager.getPermissionsQueryResponse(url!!, tabId, data.optString("name"))
3238+
getDataForPermissionState(featureName, method, id, permissionState)
3239+
}
32393240

3240-
viewModelScope.launch(dispatchers.main()) {
3241-
command.value = SendResponseToJs(response)
3241+
withContext(dispatchers.main()) {
3242+
command.value = SendResponseToJs(response)
3243+
}
32423244
}
32433245
}
32443246

site-permissions/site-permissions-api/src/main/java/com/duckduckgo/site/permissions/api/SitePermissionsManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ interface SitePermissionsManager {
4545
* @param queriedPermission permission being queried (note: this is different from WebView permissions, check link above)
4646
* @return state of the permission as expected by the API: 'granted', 'prompt', or 'denied'
4747
*/
48-
fun getPermissionsQueryResponse(url: String, tabId: String, queriedPermission: String): SitePermissionQueryResponse
48+
suspend fun getPermissionsQueryResponse(url: String, tabId: String, queriedPermission: String): SitePermissionQueryResponse
4949

5050
data class SitePermissions(
5151
val autoAccept: List<String>,

site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class SitePermissionsManagerImpl @Inject constructor(
3535
private val dispatcherProvider: DispatcherProvider,
3636
) : SitePermissionsManager {
3737

38-
private fun getSitePermissionsGranted(
38+
private suspend fun getSitePermissionsGranted(
3939
url: String,
4040
tabId: String,
4141
resources: Array<String>,
@@ -85,7 +85,7 @@ class SitePermissionsManagerImpl @Inject constructor(
8585
}
8686
}
8787

88-
override fun getPermissionsQueryResponse(
88+
override suspend fun getPermissionsQueryResponse(
8989
url: String,
9090
tabId: String,
9191
queriedPermission: String,

site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/SitePermissionsRepository.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ interface SitePermissionsRepository {
3939
var askCameraEnabled: Boolean
4040
var askMicEnabled: Boolean
4141
var askDrmEnabled: Boolean
42-
fun isDomainAllowedToAsk(url: String, permission: String): Boolean
43-
fun isDomainGranted(url: String, tabId: String, permission: String): Boolean
42+
suspend fun isDomainAllowedToAsk(url: String, permission: String): Boolean
43+
suspend fun isDomainGranted(url: String, tabId: String, permission: String): Boolean
4444
fun sitePermissionGranted(url: String, tabId: String, permission: String)
4545
fun sitePermissionsWebsitesFlow(): Flow<List<SitePermissionsEntity>>
4646
fun sitePermissionsForAllWebsites(): List<SitePermissionsEntity>
@@ -85,7 +85,7 @@ class SitePermissionsRepositoryImpl @Inject constructor(
8585

8686
private val drmSessions = mutableMapOf<String, Boolean>()
8787

88-
override fun isDomainAllowedToAsk(url: String, permission: String): Boolean {
88+
override suspend fun isDomainAllowedToAsk(url: String, permission: String): Boolean {
8989
val domain = url.extractDomain() ?: url
9090
val sitePermissionsForDomain = sitePermissionsDao.getSitePermissionsByDomain(domain)
9191
return when (permission) {
@@ -111,7 +111,7 @@ class SitePermissionsRepositoryImpl @Inject constructor(
111111
}
112112
}
113113

114-
override fun isDomainGranted(url: String, tabId: String, permission: String): Boolean {
114+
override suspend fun isDomainGranted(url: String, tabId: String, permission: String): Boolean {
115115
val domain = url.extractDomain() ?: url
116116
val sitePermissionForDomain = sitePermissionsDao.getSitePermissionsByDomain(domain)
117117
val permissionAllowedEntity = sitePermissionsAllowedDao.getSitePermissionAllowed(domain, tabId, permission)

site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/SitePermissionsManagerTest.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class SitePermissionsManagerTest {
9898
whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(true)
9999
whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_AUDIO_CAPTURE)).thenReturn(false)
100100
whenever(mockPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)).thenReturn(true)
101+
whenever(mockSitePermissionsRepository.isDomainGranted(url, tabId, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(false)
101102

102103
val permissionRequest: PermissionRequest = mock()
103104
whenever(permissionRequest.origin).thenReturn(url.toUri())
@@ -167,14 +168,14 @@ class SitePermissionsManagerTest {
167168
}
168169

169170
@Test
170-
fun whenDomainGrantedThenGetPermissionsQueryResponseReturnsGranted() {
171+
fun whenDomainGrantedThenGetPermissionsQueryResponseReturnsGranted() = runTest {
171172
whenever(mockSitePermissionsRepository.isDomainGranted(url, tabId, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(true)
172173

173174
assertEquals(SitePermissionQueryResponse.Granted, testee.getPermissionsQueryResponse(url, tabId, "camera"))
174175
}
175176

176177
@Test
177-
fun whenDomainAllowedToAskThenGetPermissionsQueryResponseReturnsPrompt() {
178+
fun whenDomainAllowedToAskThenGetPermissionsQueryResponseReturnsPrompt() = runTest {
178179
whenever(mockSitePermissionsRepository.isDomainGranted(url, tabId, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(false)
179180
whenever(mockPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)).thenReturn(true)
180181
whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(true)
@@ -183,7 +184,7 @@ class SitePermissionsManagerTest {
183184
}
184185

185186
@Test
186-
fun whenDomainNotAllowedToAskThenGetPermissionsQueryResponseReturnsDenied() {
187+
fun whenDomainNotAllowedToAskThenGetPermissionsQueryResponseReturnsDenied() = runTest {
187188
whenever(mockSitePermissionsRepository.isDomainGranted(url, tabId, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(false)
188189
whenever(mockPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)).thenReturn(true)
189190
whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(false)
@@ -192,7 +193,7 @@ class SitePermissionsManagerTest {
192193
}
193194

194195
@Test
195-
fun whenHardwareNotSupportedThenGetPermissionsQueryResponseReturnsDenied() {
196+
fun whenHardwareNotSupportedThenGetPermissionsQueryResponseReturnsDenied() = runTest {
196197
whenever(mockSitePermissionsRepository.isDomainGranted(url, tabId, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(false)
197198
whenever(mockPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)).thenReturn(false)
198199
whenever(mockSitePermissionsRepository.isDomainAllowedToAsk(url, PermissionRequest.RESOURCE_VIDEO_CAPTURE)).thenReturn(true)
@@ -201,7 +202,7 @@ class SitePermissionsManagerTest {
201202
}
202203

203204
@Test
204-
fun whenAndroidPermissionNotSupportedThenGetPermissionsQueryResponseReturnsDenied() {
205+
fun whenAndroidPermissionNotSupportedThenGetPermissionsQueryResponseReturnsDenied() = runTest {
205206
assertEquals(SitePermissionQueryResponse.Denied, testee.getPermissionsQueryResponse(url, tabId, "unsupported"))
206207
}
207208
}

site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/SitePermissionsRepositoryTest.kt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,31 +63,31 @@ class SitePermissionsRepositoryTest {
6363
private val domain = "domain.com"
6464

6565
@Test
66-
fun givenPermissionNotSupportedThenDomainIsNotAllowedToAsk() {
66+
fun givenPermissionNotSupportedThenDomainIsNotAllowedToAsk() = runTest {
6767
setInitialSettings()
6868
val permission = PermissionRequest.RESOURCE_MIDI_SYSEX
6969

7070
assertFalse(repository.isDomainAllowedToAsk(url, permission))
7171
}
7272

7373
@Test
74-
fun givenPermissionSupportedThenDomainIsAllowedToAsk() {
74+
fun givenPermissionSupportedThenDomainIsAllowedToAsk() = runTest {
7575
setInitialSettings()
7676
val permission = PermissionRequest.RESOURCE_AUDIO_CAPTURE
7777

7878
assertTrue(repository.isDomainAllowedToAsk(url, permission))
7979
}
8080

8181
@Test
82-
fun whenAskForPermissionIsDisabledThenDomainIsNotAllowedToAsk() {
82+
fun whenAskForPermissionIsDisabledThenDomainIsNotAllowedToAsk() = runTest {
8383
setInitialSettings(cameraEnabled = false)
8484
val permission = PermissionRequest.RESOURCE_VIDEO_CAPTURE
8585

8686
assertFalse(repository.isDomainAllowedToAsk(url, permission))
8787
}
8888

8989
@Test
90-
fun whenAskForPermissionDisabledButSitePermissionSettingIsAlwaysAllowThenIsAllowedToAsk() {
90+
fun whenAskForPermissionDisabledButSitePermissionSettingIsAlwaysAllowThenIsAllowedToAsk() = runTest {
9191
val testEntity = SitePermissionsEntity(domain, askMicSetting = SitePermissionAskSettingType.ALLOW_ALWAYS.name)
9292
setInitialSettings(micEnabled = false, sitePermissionEntity = testEntity)
9393
val permission = PermissionRequest.RESOURCE_AUDIO_CAPTURE
@@ -96,7 +96,7 @@ class SitePermissionsRepositoryTest {
9696
}
9797

9898
@Test
99-
fun whenSitePermissionSettingIsDenyAlwaysThenDomainIsNotAllowedToAsk() {
99+
fun whenSitePermissionSettingIsDenyAlwaysThenDomainIsNotAllowedToAsk() = runTest {
100100
val testEntity = SitePermissionsEntity(domain, askCameraSetting = SitePermissionAskSettingType.DENY_ALWAYS.name)
101101
setInitialSettings(sitePermissionEntity = testEntity)
102102
val permission = PermissionRequest.RESOURCE_VIDEO_CAPTURE
@@ -105,7 +105,7 @@ class SitePermissionsRepositoryTest {
105105
}
106106

107107
@Test
108-
fun whenNoSitePermissionSettingAndDrmBlockedThenDomainIsNotAllowedToAsk() {
108+
fun whenNoSitePermissionSettingAndDrmBlockedThenDomainIsNotAllowedToAsk() = runTest {
109109
val permission = PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID
110110

111111
whenever(mockDrmBlock.isDrmBlockedForUrl(url)).thenReturn(true)
@@ -114,7 +114,7 @@ class SitePermissionsRepositoryTest {
114114
}
115115

116116
@Test
117-
fun whenSitePermissionSettingIsAskAndDrmBlockedThenDomainIsAllowedToAsk() {
117+
fun whenSitePermissionSettingIsAskAndDrmBlockedThenDomainIsAllowedToAsk() = runTest {
118118
val testEntity = SitePermissionsEntity(domain, askDrmSetting = SitePermissionAskSettingType.ASK_EVERY_TIME.name)
119119
setInitialSettings(sitePermissionEntity = testEntity)
120120
val permission = PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID
@@ -125,7 +125,7 @@ class SitePermissionsRepositoryTest {
125125
}
126126

127127
@Test
128-
fun whenSitePermissionsWasGrantedWithin24hThenReturnPermissionGranted() {
128+
fun whenSitePermissionsWasGrantedWithin24hThenReturnPermissionGranted() = runTest {
129129
setInitialSettings()
130130
val permission = PermissionRequest.RESOURCE_VIDEO_CAPTURE
131131
val tabId = "tabId"
@@ -136,7 +136,7 @@ class SitePermissionsRepositoryTest {
136136
}
137137

138138
@Test
139-
fun whenSitePermissionsWasMoreThen24hAgoThenReturnPermissionNotGranted() {
139+
fun whenSitePermissionsWasMoreThen24hAgoThenReturnPermissionNotGranted() = runTest {
140140
setInitialSettings()
141141
val permission = PermissionRequest.RESOURCE_VIDEO_CAPTURE
142142
val tabId = "tabId"
@@ -147,7 +147,7 @@ class SitePermissionsRepositoryTest {
147147
}
148148

149149
@Test
150-
fun whenSitePermissionsSettingIsAllowAlwaysThenReturnPermissionGranted() {
150+
fun whenSitePermissionsSettingIsAllowAlwaysThenReturnPermissionGranted() = runTest {
151151
val testEntity = SitePermissionsEntity(domain, askCameraSetting = SitePermissionAskSettingType.ALLOW_ALWAYS.name)
152152
setInitialSettings(sitePermissionEntity = testEntity)
153153
val permission = PermissionRequest.RESOURCE_VIDEO_CAPTURE
@@ -264,7 +264,7 @@ class SitePermissionsRepositoryTest {
264264
micEnabled: Boolean = true,
265265
drmEnabled: Boolean = true,
266266
sitePermissionEntity: SitePermissionsEntity? = null,
267-
) {
267+
) = runTest {
268268
whenever(mockSitePermissionsPreferences.askCameraEnabled).thenReturn(cameraEnabled)
269269
whenever(mockSitePermissionsPreferences.askMicEnabled).thenReturn(micEnabled)
270270
whenever(mockSitePermissionsPreferences.askDrmEnabled).thenReturn(drmEnabled)

site-permissions/site-permissions-store/src/main/java/com/duckduckgo/site/permissions/store/sitepermissions/SitePermissionsDao.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ interface SitePermissionsDao {
3636
fun getAllSitesPermissionsAsFlow(): Flow<List<SitePermissionsEntity>>
3737

3838
@Query("select * from site_permissions where domain = :domain")
39-
fun getSitePermissionsByDomain(domain: String): SitePermissionsEntity?
39+
suspend fun getSitePermissionsByDomain(domain: String): SitePermissionsEntity?
4040

4141
@Delete
4242
fun delete(sitePermissionsEntity: SitePermissionsEntity): Int

site-permissions/site-permissions-store/src/main/java/com/duckduckgo/site/permissions/store/sitepermissionsallowed/SitePermissionsAllowedDao.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ interface SitePermissionsAllowedDao {
3333
fun getAllSitesPermissionsAllowedAsFlow(): Flow<List<SitePermissionAllowedEntity>>
3434

3535
@Query("select * from site_permission_allowed where domain = :domain and tabId = :tabId and permissionAllowed = :permissionAllowed")
36-
fun getSitePermissionAllowed(domain: String, tabId: String, permissionAllowed: String): SitePermissionAllowedEntity?
36+
suspend fun getSitePermissionAllowed(domain: String, tabId: String, permissionAllowed: String): SitePermissionAllowedEntity?
3737

3838
@Delete
3939
fun delete(sitePermissionsEntity: SitePermissionAllowedEntity): Int

0 commit comments

Comments
 (0)