Skip to content

Commit 369c0f1

Browse files
committed
Let the user know when we are not able to decrypt the voice broadcast chunks
1 parent ebd35bd commit 369c0f1

File tree

11 files changed

+77
-15
lines changed

11 files changed

+77
-15
lines changed

changelog.d/7820.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Let the user know when we are not able to decrypt the voice broadcast chunks

library/ui-strings/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3120,6 +3120,7 @@
31203120
<string name="error_voice_broadcast_already_in_progress_message">You are already recording a voice broadcast. Please end your current voice broadcast to start a new one.</string>
31213121
<string name="error_voice_broadcast_unable_to_play">Unable to play this voice broadcast.</string>
31223122
<string name="error_voice_broadcast_no_connection_recording">Connection error - Recording paused</string>
3123+
<string name="error_voice_broadcast_unable_to_decrypt">Unable to decrypt this voice broadcast.</string>
31233124
<!-- Examples of usage: 6h 15min 30sec left / 15min 30sec left / 30sec left -->
31243125
<string name="voice_broadcast_recording_time_left">%1$s left</string>
31253126
<string name="stop_voice_broadcast_dialog_title">Stop live broadcasting?</string>

vector/src/main/java/im/vector/app/core/error/ErrorFormatter.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ class DefaultErrorFormatter @Inject constructor(
160160
RecordingError.BlockedBySomeoneElse -> stringProvider.getString(R.string.error_voice_broadcast_blocked_by_someone_else_message)
161161
RecordingError.NoPermission -> stringProvider.getString(R.string.error_voice_broadcast_permission_denied_message)
162162
RecordingError.UserAlreadyBroadcasting -> stringProvider.getString(R.string.error_voice_broadcast_already_in_progress_message)
163-
is VoiceBroadcastFailure.ListeningError -> stringProvider.getString(R.string.error_voice_broadcast_unable_to_play)
163+
is VoiceBroadcastFailure.ListeningError.UnableToPlay,
164+
is VoiceBroadcastFailure.ListeningError.PrepareMediaPlayerError -> stringProvider.getString(R.string.error_voice_broadcast_unable_to_play)
165+
is VoiceBroadcastFailure.ListeningError.UnableToDecrypt -> stringProvider.getString(R.string.error_voice_broadcast_unable_to_decrypt)
164166
}
165167
}
166168

vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@ package im.vector.app.features.home.room.detail.timeline.factory
1919
import im.vector.app.core.epoxy.TimelineEmptyItem
2020
import im.vector.app.core.epoxy.TimelineEmptyItem_
2121
import im.vector.app.core.epoxy.VectorEpoxyModel
22+
import im.vector.app.core.extensions.isVoiceBroadcast
2223
import im.vector.app.features.analytics.DecryptionFailureTracker
2324
import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityHelper
2425
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
26+
import org.matrix.android.sdk.api.session.Session
2527
import org.matrix.android.sdk.api.session.events.model.EventType
28+
import org.matrix.android.sdk.api.session.events.model.RelationType
29+
import org.matrix.android.sdk.api.session.getRoom
30+
import org.matrix.android.sdk.api.session.room.getTimelineEvent
2631
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
32+
import org.matrix.android.sdk.api.session.room.timeline.getRelationContent
2733
import timber.log.Timber
2834
import javax.inject.Inject
2935

@@ -39,6 +45,7 @@ class TimelineItemFactory @Inject constructor(
3945
private val callItemFactory: CallItemFactory,
4046
private val decryptionFailureTracker: DecryptionFailureTracker,
4147
private val timelineEventVisibilityHelper: TimelineEventVisibilityHelper,
48+
private val session: Session,
4249
) {
4350

4451
/**
@@ -130,9 +137,18 @@ class TimelineItemFactory @Inject constructor(
130137
EventType.CALL_ANSWER -> callItemFactory.create(params)
131138
// Crypto
132139
EventType.ENCRYPTED -> {
140+
val relationContent = event.getRelationContent()
133141
if (event.root.isRedacted()) {
134142
// Redacted event, let the MessageItemFactory handle it
135143
messageItemFactory.create(params)
144+
} else if (relationContent?.type == RelationType.REFERENCE) {
145+
// Hide the decryption error for VoiceBroadcast chunks
146+
val startEvent = relationContent.eventId?.let { session.getRoom(event.roomId)?.getTimelineEvent(it) }
147+
if (startEvent?.isVoiceBroadcast() == false) {
148+
encryptedItemFactory.create(params)
149+
} else {
150+
null
151+
}
136152
} else {
137153
encryptedItemFactory.create(params)
138154
}

vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VoiceBroadcastItemFactory.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class VoiceBroadcastItemFactory @Inject constructor(
7575
voiceBroadcast = voiceBroadcast,
7676
voiceBroadcastState = voiceBroadcastContent.voiceBroadcastState,
7777
duration = voiceBroadcastEventsGroup.getDuration(),
78+
hasUnableToDecryptEvent = voiceBroadcastEventsGroup.hasUnableToDecryptEvent(),
7879
recorderName = params.event.senderInfo.disambiguatedDisplayName,
7980
recorder = voiceBroadcastRecorder,
8081
player = voiceBroadcastPlayer,

vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventsGroups.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
2525
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
2626
import org.matrix.android.sdk.api.extensions.orFalse
2727
import org.matrix.android.sdk.api.session.events.model.EventType
28+
import org.matrix.android.sdk.api.session.events.model.RelationType
29+
import org.matrix.android.sdk.api.session.events.model.getRelationContent
2830
import org.matrix.android.sdk.api.session.events.model.toModel
2931
import org.matrix.android.sdk.api.session.room.model.call.CallInviteContent
3032
import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent
@@ -61,6 +63,7 @@ class TimelineEventsGroups {
6163
private fun TimelineEvent.getGroupIdOrNull(): String? {
6264
val type = root.getClearType()
6365
val content = root.getClearContent()
66+
val relationContent = root.getRelationContent()
6467
return when {
6568
EventType.isCallEvent(type) -> (content?.get("call_id") as? String)
6669
type == VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> root.asVoiceBroadcastEvent()?.reference?.eventId
@@ -69,6 +72,9 @@ class TimelineEventsGroups {
6972
// Group voice messages with a reference to an eventId
7073
root.asMessageAudioEvent()?.getVoiceBroadcastEventId()
7174
}
75+
type == EventType.ENCRYPTED && relationContent?.type == RelationType.REFERENCE -> {
76+
relationContent.eventId
77+
}
7278
else -> {
7379
null
7480
}
@@ -153,4 +159,8 @@ class VoiceBroadcastEventsGroup(private val group: TimelineEventsGroup) {
153159
fun getDuration(): Int {
154160
return group.events.mapNotNull { it.root.asMessageAudioEvent()?.duration }.sum()
155161
}
162+
163+
fun hasUnableToDecryptEvent(): Boolean {
164+
return group.events.any { it.root.getClearType() == EventType.ENCRYPTED }
165+
}
156166
}

vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsMessageVoiceBroadcastItem.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ abstract class AbsMessageVoiceBroadcastItem<H : AbsMessageVoiceBroadcastItem.Hol
4545
protected val player get() = voiceBroadcastAttributes.player
4646
protected val playbackTracker get() = voiceBroadcastAttributes.playbackTracker
4747
protected val duration get() = voiceBroadcastAttributes.duration
48+
protected val hasUnableToDecryptEvent get() = voiceBroadcastAttributes.hasUnableToDecryptEvent
4849
protected val roomItem get() = voiceBroadcastAttributes.roomItem
4950
protected val colorProvider get() = voiceBroadcastAttributes.colorProvider
5051
protected val drawableProvider get() = voiceBroadcastAttributes.drawableProvider
@@ -102,6 +103,7 @@ abstract class AbsMessageVoiceBroadcastItem<H : AbsMessageVoiceBroadcastItem.Hol
102103
val voiceBroadcast: VoiceBroadcast,
103104
val voiceBroadcastState: VoiceBroadcastState?,
104105
val duration: Int,
106+
val hasUnableToDecryptEvent: Boolean,
105107
val recorderName: String,
106108
val recorder: VoiceBroadcastRecorder?,
107109
val player: VoiceBroadcastPlayer,

vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceBroadcastListeningItem.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import im.vector.app.core.epoxy.onClick
2929
import im.vector.app.core.extensions.setTextOrHide
3030
import im.vector.app.features.home.room.detail.RoomDetailAction.VoiceBroadcastAction
3131
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker.Listener.State
32+
import im.vector.app.features.voicebroadcast.VoiceBroadcastFailure
3233
import im.vector.app.features.voicebroadcast.listening.VoiceBroadcastPlayer
3334
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
3435
import im.vector.app.features.voicebroadcast.views.VoiceBroadcastBufferingView
@@ -139,6 +140,9 @@ abstract class MessageVoiceBroadcastListeningItem : AbsMessageVoiceBroadcastItem
139140
if (playbackState is State.Error) {
140141
controlsGroup.isVisible = false
141142
errorView.setTextOrHide(errorFormatter.toHumanReadable(playbackState.failure))
143+
} else if (playbackState is State.Idle && hasUnableToDecryptEvent) {
144+
controlsGroup.isVisible = false
145+
errorView.setTextOrHide(errorFormatter.toHumanReadable(VoiceBroadcastFailure.ListeningError.UnableToDecrypt))
142146
} else {
143147
errorView.isVisible = false
144148
controlsGroup.isVisible = true

vector/src/main/java/im/vector/app/features/voicebroadcast/VoiceBroadcastFailure.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ sealed class VoiceBroadcastFailure : Throwable() {
3232
*/
3333
data class UnableToPlay(val what: Int, val extra: Int) : ListeningError()
3434
data class PrepareMediaPlayerError(override val cause: Throwable? = null) : ListeningError()
35+
object UnableToDecrypt : ListeningError()
3536
}
3637
}

vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ import kotlinx.coroutines.flow.onEach
4040
import kotlinx.coroutines.launch
4141
import org.matrix.android.sdk.api.extensions.orFalse
4242
import org.matrix.android.sdk.api.extensions.tryOrNull
43+
import org.matrix.android.sdk.api.session.events.model.EventType
4344
import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent
45+
import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent
4446
import timber.log.Timber
4547
import java.util.concurrent.CopyOnWriteArrayList
4648
import javax.inject.Inject
@@ -189,9 +191,13 @@ class VoiceBroadcastPlayerImpl @Inject constructor(
189191

190192
private fun fetchPlaylistAndStartPlayback(voiceBroadcast: VoiceBroadcast) {
191193
fetchPlaylistTask = getLiveVoiceBroadcastChunksUseCase.execute(voiceBroadcast)
192-
.onEach {
193-
playlist.setItems(it)
194-
onPlaylistUpdated()
194+
.onEach { events ->
195+
if (events.any { it.getClearType() == EventType.ENCRYPTED }) {
196+
playingState = State.Error(VoiceBroadcastFailure.ListeningError.UnableToDecrypt)
197+
} else {
198+
playlist.setItems(events.mapNotNull { it.asMessageAudioEvent() })
199+
onPlaylistUpdated()
200+
}
195201
}
196202
.launchIn(sessionScope)
197203
}

0 commit comments

Comments
 (0)