Merge pull request #2754 from element-hq/feature/valere/expected_utd_integration

Expected UTDs due to membership support
This commit is contained in:
Benoit Marty 2024-04-30 11:03:36 +02:00 committed by GitHub
commit 60c8d6e147
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 147 additions and 13 deletions

View file

@ -21,6 +21,7 @@ import io.element.android.services.analytics.api.AnalyticsService
import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate
import org.matrix.rustcomponents.sdk.UnableToDecryptInfo
import timber.log.Timber
import uniffi.matrix_sdk_crypto.UtdCause
import javax.inject.Inject
class UtdTracker @Inject constructor(
@ -28,6 +29,10 @@ class UtdTracker @Inject constructor(
) : UnableToDecryptDelegate {
override fun onUtd(info: UnableToDecryptInfo) {
Timber.d("onUtd for event ${info.eventId}, timeToDecryptMs: ${info.timeToDecryptMs}")
val name = when (info.cause) {
UtdCause.UNKNOWN -> Error.Name.OlmKeysNotSentError
UtdCause.MEMBERSHIP -> Error.Name.ExpectedDueToMembership
}
val event = Error(
context = null,
// Keep cryptoModule for compatibility.
@ -35,8 +40,7 @@ class UtdTracker @Inject constructor(
cryptoSDK = Error.CryptoSDK.Rust,
timeToDecryptMillis = info.timeToDecryptMs?.toInt() ?: -1,
domain = Error.Domain.E2EE,
// TODO get a more specific error name from `info`
name = Error.Name.OlmKeysNotSentError,
name = name,
)
analyticsService.capture(event)
}

View file

@ -31,6 +31,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownContent
import io.element.android.libraries.matrix.api.timeline.item.event.UtdCause
import io.element.android.libraries.matrix.impl.media.map
import io.element.android.libraries.matrix.impl.poll.map
import kotlinx.collections.immutable.toImmutableList
@ -41,6 +42,7 @@ import org.matrix.rustcomponents.sdk.use
import org.matrix.rustcomponents.sdk.EncryptedMessage as RustEncryptedMessage
import org.matrix.rustcomponents.sdk.MembershipChange as RustMembershipChange
import org.matrix.rustcomponents.sdk.OtherState as RustOtherState
import uniffi.matrix_sdk_crypto.UtdCause as RustUtdCause
class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMapper = EventMessageMapper()) {
fun map(content: TimelineItemContent): EventContent {
@ -148,6 +150,13 @@ private fun RustMembershipChange.map(): MembershipChange {
}
}
private fun RustUtdCause.map(): UtdCause {
return when (this) {
RustUtdCause.MEMBERSHIP -> UtdCause.Membership
RustUtdCause.UNKNOWN -> UtdCause.Unknown
}
}
// TODO extract state events?
private fun RustOtherState.map(): OtherState {
return when (this) {
@ -177,7 +186,7 @@ private fun RustOtherState.map(): OtherState {
private fun RustEncryptedMessage.map(): UnableToDecryptContent.Data {
return when (this) {
is RustEncryptedMessage.MegolmV1AesSha2 -> UnableToDecryptContent.Data.MegolmV1AesSha2(sessionId)
is RustEncryptedMessage.MegolmV1AesSha2 -> UnableToDecryptContent.Data.MegolmV1AesSha2(sessionId, cause.map())
is RustEncryptedMessage.OlmV1Curve25519AesSha2 -> UnableToDecryptContent.Data.OlmV1Curve25519AesSha2(senderKey)
RustEncryptedMessage.Unknown -> UnableToDecryptContent.Data.Unknown
}

View file

@ -74,4 +74,29 @@ class UtdTrackerTest {
assertThat(fakeAnalyticsService.screenEvents).isEmpty()
assertThat(fakeAnalyticsService.trackedErrors).isEmpty()
}
@Test
fun `when onUtd is called with membership cause, the expected analytics Event is sent`() {
val fakeAnalyticsService = FakeAnalyticsService()
val sut = UtdTracker(fakeAnalyticsService)
sut.onUtd(
UnableToDecryptInfo(
eventId = AN_EVENT_ID.value,
timeToDecryptMs = 123.toULong(),
cause = UtdCause.MEMBERSHIP,
)
)
assertThat(fakeAnalyticsService.capturedEvents).containsExactly(
Error(
context = null,
cryptoModule = Error.CryptoModule.Rust,
cryptoSDK = Error.CryptoSDK.Rust,
timeToDecryptMillis = 123,
domain = Error.Domain.E2EE,
name = Error.Name.ExpectedDueToMembership
)
)
assertThat(fakeAnalyticsService.screenEvents).isEmpty()
assertThat(fakeAnalyticsService.trackedErrors).isEmpty()
}
}