Fix group call update backup import/export.

This commit is contained in:
Greyson Parrelli
2024-09-24 10:23:10 -04:00
parent 69e1146e2c
commit d81182633d
3 changed files with 128 additions and 117 deletions

View File

@@ -76,7 +76,9 @@ class BackupCallLinkIterator(private val cursor: Cursor) : Iterator<BackupRecipi
name = callLink.state.name,
expirationMs = try {
callLink.state.expiration.toEpochMilli()
} catch (e: ArithmeticException) { Long.MAX_VALUE },
} catch (e: ArithmeticException) {
Long.MAX_VALUE
},
restrictions = callLink.state.restrictions.toBackup()
)
)

View File

@@ -365,127 +365,120 @@ class ChatItemExportIterator(private val cursor: Cursor, private val batchSize:
private fun BackupMessageRecord.toCallUpdate(): ChatUpdateMessage? {
val call = calls.getCallByMessageId(this.id)
return if (call != null) {
call.toCallUpdate()
} else {
when {
MessageTypes.isMissedAudioCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.AUDIO_CALL,
state = IndividualCall.State.MISSED,
direction = IndividualCall.Direction.INCOMING
)
if (call != null) {
return call.toCallUpdate(this)
}
return when {
MessageTypes.isMissedAudioCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.AUDIO_CALL,
state = IndividualCall.State.MISSED,
direction = IndividualCall.Direction.INCOMING
)
}
MessageTypes.isMissedVideoCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.VIDEO_CALL,
state = IndividualCall.State.MISSED,
direction = IndividualCall.Direction.INCOMING
)
)
}
MessageTypes.isMissedVideoCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.VIDEO_CALL,
state = IndividualCall.State.MISSED,
direction = IndividualCall.Direction.INCOMING
)
}
MessageTypes.isIncomingAudioCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.AUDIO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.INCOMING
)
)
}
MessageTypes.isIncomingAudioCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.AUDIO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.INCOMING
)
}
MessageTypes.isIncomingVideoCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.VIDEO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.INCOMING
)
)
}
MessageTypes.isIncomingVideoCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.VIDEO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.INCOMING
)
}
MessageTypes.isOutgoingAudioCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.AUDIO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.OUTGOING
)
)
}
MessageTypes.isOutgoingAudioCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.AUDIO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.OUTGOING
)
}
MessageTypes.isOutgoingVideoCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.VIDEO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.OUTGOING
)
)
}
MessageTypes.isOutgoingVideoCall(this.type) -> {
ChatUpdateMessage(
individualCall = IndividualCall(
type = IndividualCall.Type.VIDEO_CALL,
state = IndividualCall.State.ACCEPTED,
direction = IndividualCall.Direction.OUTGOING
)
}
MessageTypes.isGroupCall(this.type) -> {
try {
val groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(this.body)
ChatUpdateMessage(
groupCall = GroupCall(
state = GroupCall.State.GENERIC,
startedCallRecipientId = UuidUtil.parseOrNull(groupCallUpdateDetails.startedCallUuid)?.let { recipients.getByAci(ACI.from(it)).getOrNull()?.toLong() },
startedCallTimestamp = groupCallUpdateDetails.startedCallTimestamp,
endedCallTimestamp = groupCallUpdateDetails.endedCallTimestamp
)
)
} catch (exception: IOException) {
null
}
}
else -> {
null
}
)
}
else -> {
null
}
}
}
private fun CallTable.Call.toCallUpdate(): ChatUpdateMessage? {
return if (this.type == CallTable.Type.GROUP_CALL) {
ChatUpdateMessage(
groupCall = GroupCall(
callId = this.messageId,
state = when (this.event) {
CallTable.Event.MISSED -> GroupCall.State.MISSED
CallTable.Event.ONGOING -> GroupCall.State.GENERIC
CallTable.Event.ACCEPTED -> GroupCall.State.ACCEPTED
CallTable.Event.NOT_ACCEPTED -> GroupCall.State.GENERIC
CallTable.Event.MISSED_NOTIFICATION_PROFILE -> GroupCall.State.MISSED_NOTIFICATION_PROFILE
CallTable.Event.GENERIC_GROUP_CALL -> GroupCall.State.GENERIC
CallTable.Event.JOINED -> GroupCall.State.JOINED
CallTable.Event.RINGING -> GroupCall.State.RINGING
CallTable.Event.DECLINED -> GroupCall.State.DECLINED
CallTable.Event.OUTGOING_RING -> GroupCall.State.OUTGOING_RING
CallTable.Event.DELETE -> return null
},
ringerRecipientId = this.ringerRecipient?.toLong(),
startedCallRecipientId = this.ringerRecipient?.toLong(),
startedCallTimestamp = this.timestamp
private fun CallTable.Call.toCallUpdate(messageRecord: BackupMessageRecord): ChatUpdateMessage? {
return when (this.type) {
CallTable.Type.GROUP_CALL -> {
val groupCallUpdateDetails = GroupCallUpdateDetailsUtil.parse(messageRecord.body)
ChatUpdateMessage(
groupCall = GroupCall(
callId = this.callId,
state = when (this.event) {
CallTable.Event.MISSED -> GroupCall.State.MISSED
CallTable.Event.ONGOING -> GroupCall.State.GENERIC
CallTable.Event.ACCEPTED -> GroupCall.State.ACCEPTED
CallTable.Event.NOT_ACCEPTED -> GroupCall.State.GENERIC
CallTable.Event.MISSED_NOTIFICATION_PROFILE -> GroupCall.State.MISSED_NOTIFICATION_PROFILE
CallTable.Event.GENERIC_GROUP_CALL -> GroupCall.State.GENERIC
CallTable.Event.JOINED -> GroupCall.State.JOINED
CallTable.Event.RINGING -> GroupCall.State.RINGING
CallTable.Event.DECLINED -> GroupCall.State.DECLINED
CallTable.Event.OUTGOING_RING -> GroupCall.State.OUTGOING_RING
CallTable.Event.DELETE -> return null
},
ringerRecipientId = this.ringerRecipient?.toLong(),
startedCallRecipientId = ACI.parseOrNull(groupCallUpdateDetails.startedCallUuid)?.let { recipients.getByAci(it).getOrNull()?.toLong() },
startedCallTimestamp = this.timestamp,
endedCallTimestamp = groupCallUpdateDetails.endedCallTimestamp,
read = messageRecord.read
)
)
)
} else if (this.type != CallTable.Type.AD_HOC_CALL) {
ChatUpdateMessage(
individualCall = IndividualCall(
callId = this.callId,
type = if (this.type == CallTable.Type.VIDEO_CALL) IndividualCall.Type.VIDEO_CALL else IndividualCall.Type.AUDIO_CALL,
direction = if (this.direction == CallTable.Direction.INCOMING) IndividualCall.Direction.INCOMING else IndividualCall.Direction.OUTGOING,
state = when (this.event) {
CallTable.Event.MISSED -> IndividualCall.State.MISSED
CallTable.Event.MISSED_NOTIFICATION_PROFILE -> IndividualCall.State.MISSED_NOTIFICATION_PROFILE
CallTable.Event.ACCEPTED -> IndividualCall.State.ACCEPTED
CallTable.Event.NOT_ACCEPTED -> IndividualCall.State.NOT_ACCEPTED
else -> IndividualCall.State.UNKNOWN_STATE
},
startedCallTimestamp = this.timestamp
}
CallTable.Type.AD_HOC_CALL -> {
ChatUpdateMessage(
individualCall = IndividualCall(
callId = this.callId,
type = if (this.type == CallTable.Type.VIDEO_CALL) IndividualCall.Type.VIDEO_CALL else IndividualCall.Type.AUDIO_CALL,
direction = if (this.direction == CallTable.Direction.INCOMING) IndividualCall.Direction.INCOMING else IndividualCall.Direction.OUTGOING,
state = when (this.event) {
CallTable.Event.MISSED -> IndividualCall.State.MISSED
CallTable.Event.MISSED_NOTIFICATION_PROFILE -> IndividualCall.State.MISSED_NOTIFICATION_PROFILE
CallTable.Event.ACCEPTED -> IndividualCall.State.ACCEPTED
CallTable.Event.NOT_ACCEPTED -> IndividualCall.State.NOT_ACCEPTED
else -> IndividualCall.State.UNKNOWN_STATE
},
startedCallTimestamp = this.timestamp
)
)
)
} else {
null
}
else -> null
}
}
@@ -1074,7 +1067,8 @@ class ChatItemExportIterator(private val cursor: Cursor, private val batchSize:
MessageTypes.isReportedSpam(this) ||
MessageTypes.isMessageRequestAccepted(this) ||
MessageTypes.isBlocked(this) ||
MessageTypes.isUnblocked(this)
MessageTypes.isUnblocked(this) ||
MessageTypes.isGroupCall(this)
}
private fun String.e164ToLong(): Long? {

View File

@@ -262,12 +262,15 @@ class ChatItemImportInserter(
}
} else if (this.updateMessage.groupCall != null && this.updateMessage.groupCall.callId != null) {
followUp = { messageRowId ->
val ringer: RecipientId? = this.updateMessage.groupCall.ringerRecipientId?.let { importState.remoteToLocalRecipientId[it] }
val values = contentValuesOf(
CallTable.CALL_ID to updateMessage.groupCall.callId,
CallTable.MESSAGE_ID to messageRowId,
CallTable.PEER to chatRecipientId.serialize(),
CallTable.RINGER to ringer?.serialize(),
CallTable.TYPE to CallTable.Type.serialize(CallTable.Type.GROUP_CALL),
CallTable.DIRECTION to CallTable.Direction.serialize(if (importState.remoteToLocalRecipientId[updateMessage.groupCall.ringerRecipientId] == selfId) CallTable.Direction.OUTGOING else CallTable.Direction.INCOMING),
CallTable.DIRECTION to CallTable.Direction.serialize(if (ringer == selfId) CallTable.Direction.OUTGOING else CallTable.Direction.INCOMING),
CallTable.EVENT to CallTable.Event.serialize(
when (updateMessage.groupCall.state) {
GroupCall.State.ACCEPTED -> CallTable.Event.ACCEPTED
@@ -673,15 +676,26 @@ class ChatItemImportInserter(
}
updateMessage.individualCall != null -> {
if (updateMessage.individualCall.state == IndividualCall.State.MISSED || updateMessage.individualCall.state == IndividualCall.State.MISSED_NOTIFICATION_PROFILE) {
typeFlags = if (updateMessage.individualCall.type == IndividualCall.Type.AUDIO_CALL) MessageTypes.MISSED_AUDIO_CALL_TYPE else MessageTypes.MISSED_VIDEO_CALL_TYPE
typeFlags = if (updateMessage.individualCall.type == IndividualCall.Type.AUDIO_CALL) {
MessageTypes.MISSED_AUDIO_CALL_TYPE
} else {
MessageTypes.MISSED_VIDEO_CALL_TYPE
}
} else {
typeFlags = if (updateMessage.individualCall.direction == IndividualCall.Direction.OUTGOING) {
if (updateMessage.individualCall.type == IndividualCall.Type.AUDIO_CALL) MessageTypes.OUTGOING_AUDIO_CALL_TYPE else MessageTypes.OUTGOING_VIDEO_CALL_TYPE
if (updateMessage.individualCall.type == IndividualCall.Type.AUDIO_CALL) {
MessageTypes.OUTGOING_AUDIO_CALL_TYPE
} else {
MessageTypes.OUTGOING_VIDEO_CALL_TYPE
}
} else {
if (updateMessage.individualCall.type == IndividualCall.Type.AUDIO_CALL) MessageTypes.INCOMING_AUDIO_CALL_TYPE else MessageTypes.INCOMING_VIDEO_CALL_TYPE
if (updateMessage.individualCall.type == IndividualCall.Type.AUDIO_CALL) {
MessageTypes.INCOMING_AUDIO_CALL_TYPE
} else {
MessageTypes.INCOMING_VIDEO_CALL_TYPE
}
}
}
this.put(MessageTable.TYPE, typeFlags)
}
updateMessage.groupCall != null -> {
val startedCallRecipientId = if (updateMessage.groupCall.startedCallRecipientId != null) {
@@ -695,7 +709,8 @@ class ChatItemImportInserter(
null
}
this.put(MessageTable.BODY, GroupCallUpdateDetailsUtil.createBodyFromBackup(updateMessage.groupCall, startedCall))
this.put(MessageTable.TYPE, MessageTypes.GROUP_CALL_TYPE)
this.put(MessageTable.READ, updateMessage.groupCall.read.toInt())
typeFlags = MessageTypes.GROUP_CALL_TYPE
}
updateMessage.groupChange != null -> {
put(MessageTable.BODY, "")