Expected UTDs due to membership support
This commit is contained in:
parent
bb78c2b22d
commit
808bbf33a4
6 changed files with 70 additions and 13 deletions
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package io.element.android.features.messages.impl.timeline.components.event
|
package io.element.android.features.messages.impl.timeline.components.event
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|
@ -25,6 +26,7 @@ import io.element.android.libraries.designsystem.icons.CompoundDrawables
|
||||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.UtdCause
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -33,10 +35,17 @@ fun TimelineItemEncryptedView(
|
||||||
onContentLayoutChanged: (ContentAvoidingLayoutData) -> Unit,
|
onContentLayoutChanged: (ContentAvoidingLayoutData) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
|
var text = stringResource(id = CommonStrings.common_waiting_for_decryption_key)
|
||||||
|
var iconId = CompoundDrawables.ic_compound_time
|
||||||
|
if (content.data is UnableToDecryptContent.Data.MegolmV1AesSha2 &&
|
||||||
|
content.data.utdCause == UtdCause.Membership) {
|
||||||
|
text = stringResource(id = CommonStrings.common_unable_to_decrypt_no_access)
|
||||||
|
iconId = CompoundDrawables.ic_compound_block
|
||||||
|
}
|
||||||
TimelineItemInformativeView(
|
TimelineItemInformativeView(
|
||||||
text = stringResource(id = CommonStrings.common_waiting_for_decryption_key),
|
text = text,
|
||||||
iconDescription = stringResource(id = CommonStrings.dialog_title_warning),
|
iconDescription = stringResource(id = CommonStrings.dialog_title_warning),
|
||||||
iconResourceId = CompoundDrawables.ic_compound_time,
|
iconResourceId = iconId,
|
||||||
onContentLayoutChanged = onContentLayoutChanged,
|
onContentLayoutChanged = onContentLayoutChanged,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
)
|
)
|
||||||
|
|
@ -45,10 +54,22 @@ fun TimelineItemEncryptedView(
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun TimelineItemEncryptedViewPreview() = ElementPreview {
|
internal fun TimelineItemEncryptedViewPreview() = ElementPreview {
|
||||||
TimelineItemEncryptedView(
|
Column {
|
||||||
content = TimelineItemEncryptedContent(
|
TimelineItemEncryptedView(
|
||||||
data = UnableToDecryptContent.Data.Unknown
|
content = TimelineItemEncryptedContent(
|
||||||
),
|
data = UnableToDecryptContent.Data.Unknown
|
||||||
onContentLayoutChanged = {},
|
),
|
||||||
)
|
onContentLayoutChanged = {},
|
||||||
|
)
|
||||||
|
|
||||||
|
TimelineItemEncryptedView(
|
||||||
|
content = TimelineItemEncryptedContent(
|
||||||
|
data = UnableToDecryptContent.Data.MegolmV1AesSha2(
|
||||||
|
sessionId = "sessionId",
|
||||||
|
utdCause = UtdCause.Membership
|
||||||
|
)
|
||||||
|
),
|
||||||
|
onContentLayoutChanged = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ posthog = "com.posthog:posthog-android:3.1.18"
|
||||||
sentry = "io.sentry:sentry-android:7.8.0"
|
sentry = "io.sentry:sentry-android:7.8.0"
|
||||||
# Note: only 0.19.0 will compile properly
|
# Note: only 0.19.0 will compile properly
|
||||||
# main branch can be tested replacing the version with main-SNAPSHOT
|
# main branch can be tested replacing the version with main-SNAPSHOT
|
||||||
matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.15.0"
|
matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.20.0"
|
||||||
|
|
||||||
# Emojibase
|
# Emojibase
|
||||||
matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.1.3"
|
matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.1.3"
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,8 @@ data class UnableToDecryptContent(
|
||||||
) : Data
|
) : Data
|
||||||
|
|
||||||
data class MegolmV1AesSha2(
|
data class MegolmV1AesSha2(
|
||||||
val sessionId: String
|
val sessionId: String,
|
||||||
|
val utdCause: UtdCause
|
||||||
) : Data
|
) : Data
|
||||||
|
|
||||||
data object Unknown : Data
|
data object Unknown : Data
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.matrix.api.timeline.item.event
|
||||||
|
|
||||||
|
enum class UtdCause {
|
||||||
|
Unknown,
|
||||||
|
Membership,
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@ import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate
|
import org.matrix.rustcomponents.sdk.UnableToDecryptDelegate
|
||||||
import org.matrix.rustcomponents.sdk.UnableToDecryptInfo
|
import org.matrix.rustcomponents.sdk.UnableToDecryptInfo
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import uniffi.matrix_sdk_crypto.UtdCause
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UtdTracker @Inject constructor(
|
class UtdTracker @Inject constructor(
|
||||||
|
|
@ -28,6 +29,10 @@ class UtdTracker @Inject constructor(
|
||||||
) : UnableToDecryptDelegate {
|
) : UnableToDecryptDelegate {
|
||||||
override fun onUtd(info: UnableToDecryptInfo) {
|
override fun onUtd(info: UnableToDecryptInfo) {
|
||||||
Timber.d("onUtd for event ${info.eventId}, timeToDecryptMs: ${info.timeToDecryptMs}")
|
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(
|
val event = Error(
|
||||||
context = null,
|
context = null,
|
||||||
// Keep cryptoModule for compatibility.
|
// Keep cryptoModule for compatibility.
|
||||||
|
|
@ -35,8 +40,7 @@ class UtdTracker @Inject constructor(
|
||||||
cryptoSDK = Error.CryptoSDK.Rust,
|
cryptoSDK = Error.CryptoSDK.Rust,
|
||||||
timeToDecryptMillis = info.timeToDecryptMs?.toInt() ?: -1,
|
timeToDecryptMillis = info.timeToDecryptMs?.toInt() ?: -1,
|
||||||
domain = Error.Domain.E2EE,
|
domain = Error.Domain.E2EE,
|
||||||
// TODO get a more specific error name from `info`
|
name = name,
|
||||||
name = Error.Name.OlmKeysNotSentError,
|
|
||||||
)
|
)
|
||||||
analyticsService.capture(event)
|
analyticsService.capture(event)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.StickerContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
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.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.media.map
|
||||||
import io.element.android.libraries.matrix.impl.poll.map
|
import io.element.android.libraries.matrix.impl.poll.map
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
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.EncryptedMessage as RustEncryptedMessage
|
||||||
import org.matrix.rustcomponents.sdk.MembershipChange as RustMembershipChange
|
import org.matrix.rustcomponents.sdk.MembershipChange as RustMembershipChange
|
||||||
import org.matrix.rustcomponents.sdk.OtherState as RustOtherState
|
import org.matrix.rustcomponents.sdk.OtherState as RustOtherState
|
||||||
|
import uniffi.matrix_sdk_crypto.UtdCause as RustUtdCause
|
||||||
|
|
||||||
class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMapper = EventMessageMapper()) {
|
class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMapper = EventMessageMapper()) {
|
||||||
fun map(content: TimelineItemContent): EventContent {
|
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?
|
// TODO extract state events?
|
||||||
private fun RustOtherState.map(): OtherState {
|
private fun RustOtherState.map(): OtherState {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
|
@ -177,7 +186,7 @@ private fun RustOtherState.map(): OtherState {
|
||||||
|
|
||||||
private fun RustEncryptedMessage.map(): UnableToDecryptContent.Data {
|
private fun RustEncryptedMessage.map(): UnableToDecryptContent.Data {
|
||||||
return when (this) {
|
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)
|
is RustEncryptedMessage.OlmV1Curve25519AesSha2 -> UnableToDecryptContent.Data.OlmV1Curve25519AesSha2(senderKey)
|
||||||
RustEncryptedMessage.Unknown -> UnableToDecryptContent.Data.Unknown
|
RustEncryptedMessage.Unknown -> UnableToDecryptContent.Data.Unknown
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue