Skip to content

Commit ebdd2d0

Browse files
committed
Disable autofill instead of crashing on exceptions
1 parent 27c4c17 commit ebdd2d0

4 files changed

Lines changed: 74 additions & 28 deletions

File tree

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/InBrowserImportPromo.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.duckduckgo.di.scopes.AppScope
2525
import com.squareup.anvil.annotations.ContributesBinding
2626
import kotlinx.coroutines.flow.firstOrNull
2727
import kotlinx.coroutines.withContext
28+
import logcat.logcat
2829
import javax.inject.Inject
2930

3031
interface InBrowserImportPromo {
@@ -73,7 +74,12 @@ class RealInBrowserImportPromo @Inject constructor(
7374
return@withContext false
7475
}
7576

76-
if ((autofillStore.getCredentialCount().firstOrNull() ?: 0) >= MAX_CREDENTIALS_FOR_PROMO) {
77+
runCatching {
78+
if ((autofillStore.getCredentialCount().firstOrNull() ?: 0) >= MAX_CREDENTIALS_FOR_PROMO) {
79+
return@withContext false
80+
}
81+
}.getOrElse {
82+
logcat { "InSettingsPasswordImportPromoRules - Couldn't retrieve credentials count" }
7783
return@withContext false
7884
}
7985

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/importing/InSettingsPasswordImportPromoRules.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.duckduckgo.di.scopes.AppScope
2424
import com.squareup.anvil.annotations.ContributesBinding
2525
import kotlinx.coroutines.flow.firstOrNull
2626
import kotlinx.coroutines.withContext
27+
import logcat.logcat
2728
import javax.inject.Inject
2829

2930
interface InSettingsPasswordImportPromoRules {
@@ -52,7 +53,12 @@ class RealInSettingsPasswordImportPromoRules @Inject constructor(
5253
return@withContext false
5354
}
5455

55-
if ((autofillStore.getCredentialCount().firstOrNull() ?: 0) >= MAX_CREDENTIALS_FOR_PROMO) {
56+
runCatching {
57+
if ((autofillStore.getCredentialCount().firstOrNull() ?: 0) >= MAX_CREDENTIALS_FOR_PROMO) {
58+
return@withContext false
59+
}
60+
}.getOrElse {
61+
logcat { "InSettingsPasswordImportPromoRules - Couldn't retrieve credentials count" }
5662
return@withContext false
5763
}
5864

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/credential/management/AutofillPasswordsManagementViewModel.kt

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ import com.duckduckgo.sync.api.engine.SyncEngine
103103
import com.duckduckgo.sync.api.engine.SyncEngine.SyncTrigger.FEATURE_READ
104104
import com.squareup.anvil.annotations.ContributesBinding
105105
import kotlinx.coroutines.Job
106+
import kotlinx.coroutines.currentCoroutineContext
107+
import kotlinx.coroutines.ensureActive
106108
import kotlinx.coroutines.flow.MutableStateFlow
107109
import kotlinx.coroutines.flow.StateFlow
108110
import kotlinx.coroutines.flow.combine
@@ -324,7 +326,15 @@ class AutofillPasswordsManagementViewModel @Inject constructor(
324326
return
325327
}
326328

327-
val credentialCount = autofillStore.getCredentialCount().firstOrNull()
329+
val credentialCount = runCatching {
330+
autofillStore.getCredentialCount().firstOrNull()
331+
}.getOrElse {
332+
currentCoroutineContext().ensureActive()
333+
logcat { "Error accessing secure storage so can't offer autofill functionality" }
334+
deviceUnsupported()
335+
return
336+
}
337+
328338
val shouldAskAuth = credentialCount == null || credentialCount == 0
329339
if (shouldAskAuth) {
330340
logcat(VERBOSE) { "No credentials; can skip showing device auth" }
@@ -433,17 +443,23 @@ class AutofillPasswordsManagementViewModel @Inject constructor(
433443
prioritizeDomainMatchesOnSearch = autofillFeature.prioritizeDomainMatchesOnSearch().isEnabled(),
434444
)
435445

436-
val allCredentials = autofillStore.getAllCredentials().distinctUntilChanged()
437-
val combined = allCredentials.combine(searchQueryFilter) { credentials, filter ->
438-
credentialListFilter.filter(credentials, filter)
439-
}
440-
combined.collect { credentials ->
441-
val updatedBreakageState = _viewState.value.reportBreakageState.copy(allowBreakageReporting = isBreakageReportingAllowed())
442-
_viewState.value = _viewState.value.copy(
443-
logins = credentials,
444-
reportBreakageState = updatedBreakageState,
445-
)
446-
showPromotionIfEligible()
446+
runCatching {
447+
val allCredentials = autofillStore.getAllCredentials().distinctUntilChanged()
448+
val combined = allCredentials.combine(searchQueryFilter) { credentials, filter ->
449+
credentialListFilter.filter(credentials, filter)
450+
}
451+
combined.collect { credentials ->
452+
val updatedBreakageState = _viewState.value.reportBreakageState.copy(allowBreakageReporting = isBreakageReportingAllowed())
453+
_viewState.value = _viewState.value.copy(
454+
logins = credentials,
455+
reportBreakageState = updatedBreakageState,
456+
)
457+
showPromotionIfEligible()
458+
}
459+
}.getOrElse {
460+
logcat { "Error accessing secure storage so can't offer autofill functionality" }
461+
deviceUnsupported()
462+
return@launch
447463
}
448464
}
449465

@@ -681,10 +697,17 @@ class AutofillPasswordsManagementViewModel @Inject constructor(
681697
logcat(VERBOSE) { "Opened autofill management screen from from $launchSource" }
682698

683699
val source = launchSource.asString()
684-
val hasCredentialsSaved = (autofillStore.getCredentialCount().firstOrNull() ?: 0) > 0
685-
pixel.fire(AUTOFILL_MANAGEMENT_SCREEN_OPENED, mapOf("source" to source, "has_credentials_saved" to hasCredentialsSaved.toBinaryString()))
686-
pixel.fire(AutofillPixelNames.PRODUCT_TELEMETRY_SURFACE_PASSWORDS_OPENED)
687-
pixel.fire(AutofillPixelNames.PRODUCT_TELEMETRY_SURFACE_PASSWORDS_OPENED_DAILY, type = Pixel.PixelType.Daily())
700+
runCatching {
701+
val hasCredentialsSaved = (autofillStore.getCredentialCount().firstOrNull() ?: 0) > 0
702+
pixel.fire(
703+
AUTOFILL_MANAGEMENT_SCREEN_OPENED,
704+
mapOf("source" to source, "has_credentials_saved" to hasCredentialsSaved.toBinaryString()),
705+
)
706+
pixel.fire(AutofillPixelNames.PRODUCT_TELEMETRY_SURFACE_PASSWORDS_OPENED)
707+
pixel.fire(AutofillPixelNames.PRODUCT_TELEMETRY_SURFACE_PASSWORDS_OPENED_DAILY, type = Pixel.PixelType.Daily())
708+
}.getOrElse {
709+
logcat { "Couldn't get credential count" }
710+
}
688711
}
689712
}
690713

autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/ui/settings/AutofillSettingsViewModel.kt

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import com.duckduckgo.common.utils.DispatcherProvider
4444
import com.duckduckgo.common.utils.extensions.toBinaryString
4545
import com.duckduckgo.di.scopes.ActivityScope
4646
import kotlinx.coroutines.channels.Channel
47+
import kotlinx.coroutines.ensureActive
4748
import kotlinx.coroutines.flow.Flow
4849
import kotlinx.coroutines.flow.MutableStateFlow
4950
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -52,6 +53,7 @@ import kotlinx.coroutines.flow.map
5253
import kotlinx.coroutines.flow.onStart
5354
import kotlinx.coroutines.flow.receiveAsFlow
5455
import kotlinx.coroutines.launch
56+
import logcat.logcat
5557
import javax.inject.Inject
5658

5759
@ContributesViewModel(ActivityScope::class)
@@ -107,21 +109,30 @@ class AutofillSettingsViewModel @Inject constructor(
107109

108110
fun sendLaunchPixel(autofillScreenLaunchSource: AutofillScreenLaunchSource) {
109111
viewModelScope.launch {
110-
val hasCredentialsSaved = (autofillStore.getCredentialCount().firstOrNull() ?: 0) > 0
111-
pixel.fire(
112-
AUTOFILL_SETTINGS_OPENED,
113-
parameters = mapOf(
114-
"source" to autofillScreenLaunchSource.asString(),
115-
"has_credentials_saved" to hasCredentialsSaved.toBinaryString(),
116-
),
117-
)
112+
runCatching {
113+
val hasCredentialsSaved = (autofillStore.getCredentialCount().firstOrNull() ?: 0) > 0
114+
pixel.fire(
115+
AUTOFILL_SETTINGS_OPENED,
116+
parameters = mapOf(
117+
"source" to autofillScreenLaunchSource.asString(),
118+
"has_credentials_saved" to hasCredentialsSaved.toBinaryString(),
119+
),
120+
)
121+
}.getOrElse {
122+
ensureActive()
123+
logcat { "Autofill-settings: Can't get credential count" }
124+
}
118125
}
119126
}
120127

121128
private fun onViewStateFlowStart() {
122129
viewModelScope.launch(dispatchers.io()) {
123-
autofillStore.getCredentialCount().collect { count ->
124-
_viewState.value = _viewState.value.copy(loginsCount = count)
130+
runCatching {
131+
autofillStore.getCredentialCount().collect { count ->
132+
_viewState.value = _viewState.value.copy(loginsCount = count)
133+
}
134+
}.getOrElse {
135+
_viewState.value = _viewState.value.copy(autofillUnsupported = true)
125136
}
126137
}
127138

0 commit comments

Comments
 (0)