Update RingRTC to 2.65.0

Co-authored-by: emir-signal <emir@signal.org>
Co-authored-by: Cody Henthorne <cody@signal.org>
This commit is contained in:
adel-signal
2026-02-17 14:40:48 -08:00
committed by Alex Hart
parent 2bc571ffd3
commit 6986acd6f4
39 changed files with 85 additions and 172 deletions

View File

@@ -21,21 +21,18 @@ import org.signal.core.util.requireNonNullString
import org.signal.core.util.select
import org.signal.core.util.update
import org.signal.core.util.withinTransaction
import org.signal.ringrtc.CallLinkEpoch
import org.signal.ringrtc.CallLinkRootKey
import org.signal.ringrtc.CallLinkState.Restrictions
import org.thoughtcrime.securesms.calls.log.CallLogRow
import org.thoughtcrime.securesms.conversation.colors.AvatarColor
import org.thoughtcrime.securesms.conversation.colors.AvatarColorHash
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.jobs.CallLinkUpdateSendJob
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkCredentials
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
import org.thoughtcrime.securesms.service.webrtc.links.SignalCallLinkState
import org.whispersystems.signalservice.api.storage.StorageId
import org.whispersystems.signalservice.internal.push.SyncMessage
import java.time.Instant
import java.time.temporal.ChronoUnit
@@ -50,7 +47,6 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
const val TABLE_NAME = "call_link"
const val ID = "_id"
const val ROOT_KEY = "root_key"
const val EPOCH = "epoch"
const val ROOM_ID = "room_id"
const val ADMIN_KEY = "admin_key"
const val NAME = "name"
@@ -72,8 +68,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
$REVOKED INTEGER NOT NULL,
$EXPIRATION INTEGER NOT NULL,
$RECIPIENT_ID INTEGER UNIQUE REFERENCES ${RecipientTable.TABLE_NAME} (${RecipientTable.ID}) ON DELETE CASCADE,
$DELETION_TIMESTAMP INTEGER DEFAULT 0 NOT NULL,
$EPOCH BLOB DEFAULT NULL
$DELETION_TIMESTAMP INTEGER DEFAULT 0 NOT NULL
)
"""
@@ -133,7 +128,6 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
.values(
contentValuesOf(
ROOT_KEY to credentials.linkKeyBytes,
EPOCH to credentials.epochBytes,
ADMIN_KEY to credentials.adminPassBytes
)
)
@@ -193,10 +187,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
.readToSingleObject { CallLinkDeserializer.deserialize(it) }
}
fun getOrCreateCallLinkByRootKey(
callLinkRootKey: CallLinkRootKey,
callLinkEpoch: CallLinkEpoch?
): CallLink {
fun getOrCreateCallLinkByRootKey(callLinkRootKey: CallLinkRootKey): CallLink {
val roomId = CallLinkRoomId.fromBytes(callLinkRootKey.deriveRoomId())
val callLink = getCallLinkByRoomId(roomId)
return if (callLink == null) {
@@ -205,7 +196,6 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
roomId = roomId,
credentials = CallLinkCredentials(
linkKeyBytes = callLinkRootKey.keyBytes,
epochBytes = callLinkEpoch?.bytes,
adminPassBytes = null
),
state = SignalCallLinkState(),
@@ -215,33 +205,12 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
insertCallLink(link)
return getCallLinkByRoomId(roomId)!!
} else {
if (callLink.credentials?.epoch != callLinkEpoch) {
val modifiedCallLink = overwriteEpoch(callLink, callLinkEpoch)
AppDependencies.jobManager.add(
CallLinkUpdateSendJob(
callLink.credentials!!.roomId,
SyncMessage.CallLinkUpdate.Type.UPDATE
)
)
modifiedCallLink
} else {
callLink
}
callLink
}
}
private fun overwriteEpoch(callLink: CallLink, callLinkEpoch: CallLinkEpoch?): CallLink {
val modifiedCallLink = callLink.copy(
deletionTimestamp = 0,
credentials = callLink.credentials!!.copy(epochBytes = callLinkEpoch?.bytes)
)
updateCallLinkCredentials(modifiedCallLink.roomId, modifiedCallLink.credentials!!)
return modifiedCallLink
}
fun insertOrUpdateCallLinkByRootKey(
callLinkRootKey: CallLinkRootKey,
callLinkEpoch: CallLinkEpoch?,
adminPassKey: ByteArray?,
deletionTimestamp: Long = 0L,
storageId: StorageId? = null
@@ -256,7 +225,6 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
roomId = roomId,
credentials = CallLinkCredentials(
linkKeyBytes = callLinkRootKey.keyBytes,
epochBytes = callLinkEpoch?.bytes,
adminPassBytes = adminPassKey
),
state = SignalCallLinkState(),
@@ -283,8 +251,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
writableDatabase.update(TABLE_NAME)
.values(
ADMIN_KEY to adminPassKey,
ROOT_KEY to callLinkRootKey.keyBytes,
EPOCH to callLinkEpoch?.bytes
ROOT_KEY to callLinkRootKey.keyBytes
)
.where("$ROOM_ID = ?", callLink.roomId.serialize())
.run()
@@ -495,7 +462,6 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
RECIPIENT_ID to data.recipientId.takeIf { it != RecipientId.UNKNOWN }?.toLong(),
ROOM_ID to data.roomId.serialize(),
ROOT_KEY to data.credentials?.linkKeyBytes,
EPOCH to data.credentials?.epochBytes,
ADMIN_KEY to data.credentials?.adminPassBytes
).apply {
putAll(data.state.serialize())
@@ -519,7 +485,6 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
credentials = data.requireBlob(ROOT_KEY)?.let { linkKey ->
CallLinkCredentials(
linkKeyBytes = linkKey,
epochBytes = data.requireBlob(EPOCH),
adminPassBytes = data.requireBlob(ADMIN_KEY)
)
},

View File

@@ -154,6 +154,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V297_AddPinnedMessa
import org.thoughtcrime.securesms.database.helpers.migration.V298_DoNotBackupReleaseNotes
import org.thoughtcrime.securesms.database.helpers.migration.V299_AddAttachmentMetadataTable
import org.thoughtcrime.securesms.database.helpers.migration.V300_AddKeyTransparencyColumn
import org.thoughtcrime.securesms.database.helpers.migration.V301_RemoveCallLinkEpoch
import org.thoughtcrime.securesms.database.SQLiteDatabase as SignalSqliteDatabase
/**
@@ -314,10 +315,11 @@ object SignalDatabaseMigrations {
297 to V297_AddPinnedMessageColumns,
298 to V298_DoNotBackupReleaseNotes,
299 to V299_AddAttachmentMetadataTable,
300 to V300_AddKeyTransparencyColumn
300 to V300_AddKeyTransparencyColumn,
301 to V301_RemoveCallLinkEpoch
)
const val DATABASE_VERSION = 300
const val DATABASE_VERSION = 301
@JvmStatic
fun migrate(context: Application, db: SignalSqliteDatabase, oldVersion: Int, newVersion: Int) {

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import org.thoughtcrime.securesms.database.SQLiteDatabase
/**
* We planned to introduce CallLink epochs as a first-class field to clients.
* Now, we plan to introduce epochs as an internal detail in CallLink root keys.
* Epochs were never enabled in production so no clients should have them.
*/
object V301_RemoveCallLinkEpoch : SignalDatabaseMigration {
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("ALTER TABLE call_link DROP COLUMN epoch")
}
}