Ensure call links only ever have one call event associated with them.

This commit is contained in:
Alex Hart 2023-06-13 16:42:55 -03:00 committed by Cody Henthorne
parent d19b8a125c
commit cff01021c2
2 changed files with 58 additions and 9 deletions

View file

@ -353,6 +353,7 @@ class CallLogAdapter(
MessageTypes.INCOMING_AUDIO_CALL_TYPE, MessageTypes.INCOMING_VIDEO_CALL_TYPE -> R.drawable.symbol_arrow_downleft_compact_16
MessageTypes.OUTGOING_AUDIO_CALL_TYPE, MessageTypes.OUTGOING_VIDEO_CALL_TYPE -> R.drawable.symbol_arrow_upright_compact_16
MessageTypes.GROUP_CALL_TYPE -> when {
call.type == CallTable.Type.AD_HOC_CALL -> R.drawable.symbol_link_compact_16
call.event == CallTable.Event.MISSED -> R.drawable.symbol_missed_incoming_24
call.event == CallTable.Event.GENERIC_GROUP_CALL || call.event == CallTable.Event.JOINED -> R.drawable.symbol_group_compact_16
call.direction == CallTable.Direction.INCOMING -> R.drawable.symbol_arrow_downleft_compact_16
@ -374,6 +375,7 @@ class CallLogAdapter(
MessageTypes.OUTGOING_AUDIO_CALL_TYPE -> R.string.CallLogAdapter__outgoing
MessageTypes.OUTGOING_VIDEO_CALL_TYPE -> R.string.CallLogAdapter__outgoing
MessageTypes.GROUP_CALL_TYPE -> when {
call.type == CallTable.Type.AD_HOC_CALL -> R.string.CallLogAdapter__call_link
call.event == CallTable.Event.MISSED -> R.string.CallLogAdapter__missed
call.event == CallTable.Event.GENERIC_GROUP_CALL || call.event == CallTable.Event.JOINED -> R.string.CallPreference__group_call
call.direction == CallTable.Direction.INCOMING -> R.string.CallLogAdapter__incoming

View file

@ -428,6 +428,23 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
peekJoinedUuids: Collection<UUID>,
isCallFull: Boolean
) {
val recipient = Recipient.resolved(groupRecipientId)
if (recipient.isCallLink) {
handleCallLinkUpdate(recipient, timestamp, peekGroupCallEraId)
} else {
handleGroupUpdate(recipient, sender, timestamp, peekGroupCallEraId, peekJoinedUuids, isCallFull)
}
}
private fun handleGroupUpdate(
groupRecipient: Recipient,
sender: RecipientId,
timestamp: Long,
peekGroupCallEraId: String?,
peekJoinedUuids: Collection<UUID>,
isCallFull: Boolean
) {
check(groupRecipient.isPushV2Group)
writableDatabase.withinTransaction {
if (peekGroupCallEraId.isNullOrEmpty()) {
Log.w(TAG, "Dropping local call event with null era id.")
@ -435,7 +452,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
}
val callId = CallId.fromEra(peekGroupCallEraId).longValue()
val call = getCallById(callId, groupRecipientId)
val call = getCallById(callId, groupRecipient.id)
val messageId: MessageId = if (call != null) {
if (call.event == Event.DELETE) {
Log.d(TAG, "Dropping group call update for deleted call.")
@ -460,7 +477,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
)
} else {
SignalDatabase.messages.insertGroupCall(
groupRecipientId,
groupRecipient.id,
sender,
timestamp,
peekGroupCallEraId,
@ -473,12 +490,43 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
callId,
messageId,
sender,
groupRecipientId,
groupRecipient.id,
timestamp
)
}
}
private fun handleCallLinkUpdate(
callLinkRecipient: Recipient,
timestamp: Long,
peekGroupCallEraId: String?
) {
check(callLinkRecipient.isCallLink)
val callId = peekGroupCallEraId?.let { CallId.fromEra(it).longValue() } ?: return
writableDatabase.withinTransaction { db ->
db.delete(TABLE_NAME)
.where("$PEER = ?", callLinkRecipient.id.serialize())
.run()
db.insertInto(TABLE_NAME)
.values(
CALL_ID to callId,
MESSAGE_ID to null,
PEER to callLinkRecipient.id.toLong(),
EVENT to Event.serialize(Event.GENERIC_GROUP_CALL),
TYPE to Type.serialize(Type.AD_HOC_CALL),
DIRECTION to Direction.serialize(Direction.OUTGOING),
TIMESTAMP to timestamp,
RINGER to null
).run(SQLiteDatabase.CONFLICT_ABORT)
}
Log.d(TAG, "Inserted new call event for call link. Call Id: $callId")
ApplicationDependencies.getDatabaseObserver().notifyCallUpdateObservers()
}
private fun insertCallEventFromGroupUpdate(
callId: Long,
messageId: MessageId?,
@ -691,6 +739,9 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
) {
val direction = if (ringerRecipient == Recipient.self().id) Direction.OUTGOING else Direction.INCOMING
val recipient = Recipient.resolved(groupRecipientId)
check(recipient.isPushV2Group)
writableDatabase.withinTransaction { db ->
val messageId = SignalDatabase.messages.insertGroupCall(
groupRecipientId = groupRecipientId,
@ -977,7 +1028,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
cte
) p
INNER JOIN ${RecipientTable.TABLE_NAME} ON ${RecipientTable.TABLE_NAME}.${RecipientTable.ID} = $PEER
INNER JOIN ${MessageTable.TABLE_NAME} ON ${MessageTable.TABLE_NAME}.${MessageTable.ID} = $MESSAGE_ID
LEFT JOIN ${MessageTable.TABLE_NAME} ON ${MessageTable.TABLE_NAME}.${MessageTable.ID} = $MESSAGE_ID
LEFT JOIN ${GroupTable.TABLE_NAME} ON ${GroupTable.TABLE_NAME}.${GroupTable.RECIPIENT_ID} = ${RecipientTable.TABLE_NAME}.${RecipientTable.ID}
WHERE true_parent = p.$ID ${if (queryClause.where.isNotEmpty()) "AND ${queryClause.where}" else ""}
ORDER BY p.$TIMESTAMP DESC
@ -1050,14 +1101,10 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
companion object Deserializer : Serializer<Call, Cursor> {
fun getMessageType(type: Type, direction: Direction, event: Event): Long {
if (type == Type.GROUP_CALL) {
if (type == Type.GROUP_CALL || type == Type.AD_HOC_CALL) {
return MessageTypes.GROUP_CALL_TYPE
}
if (type == Type.AD_HOC_CALL) {
error("Ad-Hoc calls are not linked to messages.")
}
return if (direction == Direction.INCOMING && event == Event.MISSED) {
if (type == Type.VIDEO_CALL) MessageTypes.MISSED_VIDEO_CALL_TYPE else MessageTypes.MISSED_AUDIO_CALL_TYPE
} else if (direction == Direction.INCOMING) {