From 6986acd6f4f5c6f3af159b5021473f3f2d0be25a Mon Sep 17 00:00:00 2001 From: adel-signal Date: Tue, 17 Feb 2026 14:40:48 -0800 Subject: [PATCH] Update RingRTC to 2.65.0 Co-authored-by: emir-signal Co-authored-by: Cody Henthorne --- .../v2/items/V2ConversationItemShapeTest.kt | 3 +- .../securesms/database/CallLinkTableTest.kt | 3 +- .../test/InternalConversationTestFragment.kt | 3 +- .../securesms/BindableConversationItem.java | 5 +-- .../v2/exporters/CallLinkArchiveExporter.kt | 1 - .../v2/importer/CallLinkArchiveImporter.kt | 6 +-- .../securesms/calls/links/CallLinks.kt | 25 ++--------- .../securesms/calls/links/SignalCallRow.kt | 4 +- ...CreateCallLinkBottomSheetDialogFragment.kt | 6 +-- .../links/create/CreateCallLinkViewModel.kt | 3 -- .../links/details/CallLinkDetailsScreen.kt | 7 ++- .../links/details/CallLinkDetailsViewModel.kt | 3 -- .../securesms/components/LinkPreviewView.java | 12 +++--- .../controls/ControlsAndInfoViewModel.kt | 2 - .../components/webrtc/v2/CallInfoCallbacks.kt | 2 +- .../conversation/ConversationItem.java | 7 +-- .../conversation/v2/ConversationFragment.kt | 5 +-- .../securesms/database/CallLinkTable.kt | 43 ++----------------- .../helpers/SignalDatabaseMigrations.kt | 6 ++- .../migration/V301_RemoveCallLinkEpoch.kt | 20 +++++++++ .../securesms/jobs/CallLinkUpdateSendJob.kt | 1 - .../jobs/RefreshCallLinkDetailsJob.kt | 1 - .../linkpreview/LinkPreviewRepository.java | 12 ++---- .../messagedetails/MessageDetailsFragment.kt | 3 +- .../messages/SyncMessageProcessor.kt | 2 - .../webrtc/CallLinkPreJoinActionProcessor.kt | 1 - .../service/webrtc/SignalCallManager.java | 4 +- .../webrtc/links/CallLinkCredentials.kt | 13 ------ .../webrtc/links/SignalCallLinkManager.kt | 10 ++--- .../storage/CallLinkRecordProcessor.kt | 5 --- .../securesms/storage/StorageSyncModels.kt | 1 - .../securesms/util/CommunicationActions.java | 15 +++---- app/src/main/protowire/Backup.proto | 4 +- .../database/DatabaseConsistencyTest.kt | 2 +- .../storage/CallLinkRecordProcessorTest.kt | 1 - gradle/libs.versions.toml | 2 +- gradle/verification-metadata.xml | 10 ++--- .../src/main/protowire/SignalService.proto | 2 +- .../src/main/protowire/StorageService.proto | 2 +- 39 files changed, 85 insertions(+), 172 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V301_RemoveCallLinkEpoch.kt diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemShapeTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemShapeTest.kt index a7b36cb1d6..d6d1471e0c 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemShapeTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/conversation/v2/items/V2ConversationItemShapeTest.kt @@ -18,7 +18,6 @@ import com.bumptech.glide.RequestManager import org.junit.Assert.assertEquals import org.junit.Rule import org.junit.Test -import org.signal.ringrtc.CallLinkEpoch import org.signal.ringrtc.CallLinkRootKey import org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState import org.thoughtcrime.securesms.contactshare.Contact @@ -329,7 +328,7 @@ class V2ConversationItemShapeTest { override fun onShowGroupDescriptionClicked(groupName: String, description: String, shouldLinkifyWebLinks: Boolean) = Unit - override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey, callLinkEpoch: CallLinkEpoch?) = Unit + override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey) = Unit override fun onItemClick(item: MultiselectPart?) = Unit diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/CallLinkTableTest.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/CallLinkTableTest.kt index 0a22616dda..ff49dedf11 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/CallLinkTableTest.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/CallLinkTableTest.kt @@ -81,8 +81,7 @@ class CallLinkTableTest { roomId = CallLinkRoomId.fromBytes(roomId), credentials = CallLinkCredentials( linkKeyBytes = roomId, - adminPassBytes = null, - epochBytes = null + adminPassBytes = null ), state = SignalCallLinkState(), deletionTimestamp = 0L diff --git a/app/src/debug/java/org/thoughtcrime/securesms/components/settings/app/internal/conversation/test/InternalConversationTestFragment.kt b/app/src/debug/java/org/thoughtcrime/securesms/components/settings/app/internal/conversation/test/InternalConversationTestFragment.kt index b590f5fa25..7171355c6c 100644 --- a/app/src/debug/java/org/thoughtcrime/securesms/components/settings/app/internal/conversation/test/InternalConversationTestFragment.kt +++ b/app/src/debug/java/org/thoughtcrime/securesms/components/settings/app/internal/conversation/test/InternalConversationTestFragment.kt @@ -18,7 +18,6 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.kotlin.subscribeBy import org.signal.core.util.concurrent.LifecycleDisposable import org.signal.core.util.logging.Log -import org.signal.ringrtc.CallLinkEpoch import org.signal.ringrtc.CallLinkRootKey import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.ViewBinderDelegate @@ -295,7 +294,7 @@ class InternalConversationTestFragment : Fragment(R.layout.conversation_test_fra Toast.makeText(requireContext(), "Can't touch this.", Toast.LENGTH_SHORT).show() } - override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey, callLinkEpoch: CallLinkEpoch?) { + override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey) { Toast.makeText(requireContext(), "Can't touch this.", Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java index 4ed42de69e..86fab60d23 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java @@ -11,7 +11,6 @@ import androidx.lifecycle.Observer; import com.bumptech.glide.RequestManager; -import org.signal.ringrtc.CallLinkEpoch; import org.signal.ringrtc.CallLinkRootKey; import org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState; import org.thoughtcrime.securesms.contactshare.Contact; @@ -30,8 +29,8 @@ import org.thoughtcrime.securesms.groups.GroupId; import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange; import org.thoughtcrime.securesms.linkpreview.LinkPreview; import org.thoughtcrime.securesms.mediapreview.MediaIntentFactory; -import org.thoughtcrime.securesms.polls.PollRecord; import org.thoughtcrime.securesms.polls.PollOption; +import org.thoughtcrime.securesms.polls.PollRecord; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.stickers.StickerLocator; @@ -136,7 +135,7 @@ public interface BindableConversationItem extends Unbindable, GiphyMp4Playable, void goToMediaPreview(ConversationItem parent, View sharedElement, MediaIntentFactory.MediaPreviewArgs args); void onEditedIndicatorClicked(@NonNull ConversationMessage conversationMessage); void onShowGroupDescriptionClicked(@NonNull String groupName, @NonNull String description, boolean shouldLinkifyWebLinks); - void onJoinCallLink(@NonNull CallLinkRootKey callLinkRootKey, @Nullable CallLinkEpoch callLinkEpoch); + void onJoinCallLink(@NonNull CallLinkRootKey callLinkRootKey); void onShowSafetyTips(boolean forGroup); void onReportSpamLearnMoreClicked(); void onMessageRequestAcceptOptionsClicked(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/CallLinkArchiveExporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/CallLinkArchiveExporter.kt index 0c56e2a105..41d06eb952 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/CallLinkArchiveExporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/CallLinkArchiveExporter.kt @@ -40,7 +40,6 @@ class CallLinkArchiveExporter(private val cursor: Cursor) : Iterator { return Observable.create { emitter -> @@ -78,13 +70,8 @@ object CallLinks { return url.split("#").last().startsWith("key=") } - data class CallLinkParseResult( - val rootKey: CallLinkRootKey, - val epoch: CallLinkEpoch? - ) - @JvmStatic - fun parseUrl(url: String): CallLinkParseResult? { + fun parseUrl(url: String): CallLinkRootKey? { if (!isPrefixedCallLink(url)) { Log.w(TAG, "Invalid url prefix.") return null @@ -132,13 +119,9 @@ object CallLinks { } return try { - val epoch = fragmentQuery[EPOCH]?.let { s -> CallLinkEpoch(s) } - CallLinkParseResult( - rootKey = CallLinkRootKey(key), - epoch = epoch - ) + return CallLinkRootKey(key) } catch (e: CallException) { - Log.w(TAG, "Invalid root key or epoch found in fragment query string.") + Log.w(TAG, "Invalid root key found in fragment query string.") null } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/SignalCallRow.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/SignalCallRow.kt index 8aa5e30fcc..94fae07a6e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/SignalCallRow.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/SignalCallRow.kt @@ -53,7 +53,7 @@ import org.signal.core.ui.R as CoreUiR @Composable private fun SignalCallRowPreview() { val callLink = remember { - val credentials = CallLinkCredentials(byteArrayOf(1, 2, 3, 4), byteArrayOf(0, 1, 2, 3), byteArrayOf(5, 6, 7, 8)) + val credentials = CallLinkCredentials(byteArrayOf(1, 2, 3, 4), byteArrayOf(5, 6, 7, 8)) CallLinkTable.CallLink( recipientId = RecipientId.UNKNOWN, roomId = CallLinkRoomId.fromBytes(byteArrayOf(1, 3, 5, 7)), @@ -97,7 +97,7 @@ fun SignalCallRow( "https://signal.call.example.com" } else { remember(callLink.credentials) { - callLink.credentials?.let { CallLinks.url(it.linkKeyBytes, it.epochBytes) } ?: "" + callLink.credentials?.let { CallLinks.url(it.linkKeyBytes) } ?: "" } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkBottomSheetDialogFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkBottomSheetDialogFragment.kt index fae72cd1b1..43ac744ad6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkBottomSheetDialogFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkBottomSheetDialogFragment.kt @@ -162,7 +162,7 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment startActivity( ShareActivity.sendSimpleText( requireContext(), - getString(R.string.CreateCallLink__use_this_link_to_join_a_signal_call, CallLinks.url(viewModel.linkKeyBytes, viewModel.epochBytes)) + getString(R.string.CreateCallLink__use_this_link_to_join_a_signal_call, CallLinks.url(viewModel.linkKeyBytes)) ) ) } @@ -176,7 +176,7 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment lifecycleDisposable += viewModel.commitCallLink().subscribeBy(onSuccess = { when (it) { is EnsureCallLinkCreatedResult.Success -> { - Util.copyToClipboard(requireContext(), CallLinks.url(viewModel.linkKeyBytes, viewModel.epochBytes)) + Util.copyToClipboard(requireContext(), CallLinks.url(viewModel.linkKeyBytes)) Toast.makeText(requireContext(), R.string.CreateCallLinkBottomSheetDialogFragment__copied_to_clipboard, Toast.LENGTH_LONG).show() } @@ -191,7 +191,7 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment is EnsureCallLinkCreatedResult.Success -> { val mimeType = Intent.normalizeMimeType("text/plain") val shareIntent = ShareCompat.IntentBuilder(requireContext()) - .setText(CallLinks.url(viewModel.linkKeyBytes, viewModel.epochBytes)) + .setText(CallLinks.url(viewModel.linkKeyBytes)) .setType(mimeType) .createChooserIntent() diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkViewModel.kt index 71443dce38..4ee2bd42de 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/create/CreateCallLinkViewModel.kt @@ -52,9 +52,6 @@ class CreateCallLinkViewModel( val linkKeyBytes: ByteArray get() = callLink.value.credentials!!.linkKeyBytes - val epochBytes: ByteArray? - get() = callLink.value.credentials!!.epochBytes - private val internalShowAlreadyInACall = MutableStateFlow(false) val showAlreadyInACall: StateFlow = internalShowAlreadyInACall diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt index e2714fcb02..13815b6271 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsScreen.kt @@ -119,7 +119,7 @@ class DefaultCallLinkDetailsCallback( override fun onShareClicked() { val mimeType = Intent.normalizeMimeType("text/plain") val shareIntent = ShareCompat.IntentBuilder(activity) - .setText(CallLinks.url(viewModel.rootKeySnapshot, viewModel.epochSnapshot)) + .setText(CallLinks.url(viewModel.rootKeySnapshot)) .setType(mimeType) .createChooserIntent() @@ -131,7 +131,7 @@ class DefaultCallLinkDetailsCallback( } override fun onCopyClicked() { - Util.copyToClipboard(activity, CallLinks.url(viewModel.rootKeySnapshot, viewModel.epochSnapshot)) + Util.copyToClipboard(activity, CallLinks.url(viewModel.rootKeySnapshot)) Toast.makeText(activity, R.string.CreateCallLinkBottomSheetDialogFragment__copied_to_clipboard, Toast.LENGTH_LONG).show() } @@ -139,7 +139,7 @@ class DefaultCallLinkDetailsCallback( activity.startActivity( ShareActivity.sendSimpleText( activity, - activity.getString(R.string.CreateCallLink__use_this_link_to_join_a_signal_call, CallLinks.url(viewModel.rootKeySnapshot, viewModel.epochSnapshot)) + activity.getString(R.string.CreateCallLink__use_this_link_to_join_a_signal_call, CallLinks.url(viewModel.rootKeySnapshot)) ) ) } @@ -324,7 +324,6 @@ private fun CallLinkDetailsScreenPreview() { val callLink = remember { val credentials = CallLinkCredentials( byteArrayOf(1, 2, 3, 4), - byteArrayOf(0, 1, 2, 3), byteArrayOf(3, 4, 5, 6) ) CallLinkTable.CallLink( diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsViewModel.kt index 34c92584be..59c51685b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsViewModel.kt @@ -48,9 +48,6 @@ class CallLinkDetailsViewModel( val rootKeySnapshot: ByteArray get() = state.value.callLink?.credentials?.linkKeyBytes ?: error("Call link not loaded yet.") - val epochSnapshot: ByteArray? - get() = state.value.callLink?.credentials?.epochBytes - private val recipientSubject = BehaviorSubject.create() val recipientSnapshot: Recipient? get() = recipientSubject.value diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java b/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java index ad63312289..827cbb9eab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java @@ -172,11 +172,11 @@ public class LinkPreviewView extends FrameLayout { spinner.setVisibility(GONE); noPreview.setVisibility(GONE); - CallLinks.CallLinkParseResult callLinkParseResult = CallLinks.isCallLink(linkPreview.getUrl()) ? CallLinks.parseUrl(linkPreview.getUrl()) : null; + CallLinkRootKey callLinkRootKey = CallLinks.isCallLink(linkPreview.getUrl()) ? CallLinks.parseUrl(linkPreview.getUrl()) : null; if (!Util.isEmpty(linkPreview.getTitle())) { title.setText(linkPreview.getTitle()); title.setVisibility(VISIBLE); - } else if (callLinkParseResult != null) { + } else if (callLinkRootKey != null) { title.setText(R.string.Recipient_signal_call); title.setVisibility(VISIBLE); } else { @@ -186,7 +186,7 @@ public class LinkPreviewView extends FrameLayout { if (showDescription && !Util.isEmpty(linkPreview.getDescription())) { description.setText(linkPreview.getDescription()); description.setVisibility(VISIBLE); - } else if (callLinkParseResult != null) { + } else if (callLinkRootKey != null) { description.setText(R.string.LinkPreviewView__use_this_link_to_join_a_signal_call); description.setVisibility(VISIBLE); } else { @@ -221,14 +221,14 @@ public class LinkPreviewView extends FrameLayout { thumbnail.get().setImageResource(requestManager, new ImageSlide(linkPreview.getThumbnail().get()), type == TYPE_CONVERSATION && !scheduleMessageMode, false); thumbnail.get().showSecondaryText(false); thumbnail.get().setOutlineEnabled(true); - } else if (callLinkParseResult != null) { + } else if (callLinkRootKey != null) { thumbnail.setVisibility(VISIBLE); thumbnailState.applyState(thumbnail); thumbnail.get().setImageDrawable( requestManager, new FallbackAvatarDrawable( getContext(), - new FallbackAvatar.Resource.CallLink(AvatarColorHash.forCallLink(callLinkParseResult.getRootKey().getKeyBytes())) + new FallbackAvatar.Resource.CallLink(AvatarColorHash.forCallLink(callLinkRootKey.getKeyBytes())) ).circleCrop() ); thumbnail.get().showSecondaryText(false); @@ -272,7 +272,7 @@ public class LinkPreviewView extends FrameLayout { thumbnailState.applyState(thumbnail); } - private @StringRes static int getLinkPreviewErrorString(@Nullable LinkPreviewRepository.Error customError) { + private @StringRes static int getLinkPreviewErrorString(@Nullable LinkPreviewRepository.Error customError) { return customError == LinkPreviewRepository.Error.GROUP_LINK_INACTIVE ? R.string.LinkPreviewView_this_group_link_is_not_active : R.string.LinkPreviewView_no_link_preview_available; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/ControlsAndInfoViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/ControlsAndInfoViewModel.kt index 195727c3aa..f997668f94 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/ControlsAndInfoViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/controls/ControlsAndInfoViewModel.kt @@ -34,8 +34,6 @@ class ControlsAndInfoViewModel( val rootKeySnapshot: ByteArray get() = state.value.callLink?.credentials?.linkKeyBytes ?: error("Call link not loaded yet.") - val epochSnapshot: ByteArray? - get() = state.value.callLink?.credentials?.epochBytes fun setRecipient(recipient: Recipient) { if (recipient.isCallLink && callRecipientId != recipient.id) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallInfoCallbacks.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallInfoCallbacks.kt index b432721980..82e1c7c6e2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallInfoCallbacks.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/v2/CallInfoCallbacks.kt @@ -31,7 +31,7 @@ class CallInfoCallbacks( override fun onShareLinkClicked() { val mimeType = Intent.normalizeMimeType("text/plain") val shareIntent = ShareCompat.IntentBuilder(activity) - .setText(CallLinks.url(controlsAndInfoViewModel.rootKeySnapshot, controlsAndInfoViewModel.epochSnapshot)) + .setText(CallLinks.url(controlsAndInfoViewModel.rootKeySnapshot)) .setType(mimeType) .createChooserIntent() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 102b01c9f5..9bdaa6e863 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -74,6 +74,7 @@ import org.signal.core.util.DimensionUnit; import org.signal.core.util.StringUtil; import org.signal.core.util.logging.Log; import org.signal.core.ui.view.Stub; +import org.signal.ringrtc.CallLinkRootKey; import org.thoughtcrime.securesms.BindableConversationItem; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.attachments.Attachment; @@ -1234,14 +1235,14 @@ public final class ConversationItem extends RelativeLayout implements BindableCo //noinspection ConstantConditions LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0); - CallLinks.CallLinkParseResult callLinkParseResult = CallLinks.isCallLink(linkPreview.getUrl()) ? CallLinks.parseUrl(linkPreview.getUrl()) : null; - if (callLinkParseResult != null) { + CallLinkRootKey callLinkRootKey = CallLinks.isCallLink(linkPreview.getUrl()) ? CallLinks.parseUrl(linkPreview.getUrl()) : null; + if (callLinkRootKey != null) { joinCallLinkStub.setVisibility(View.VISIBLE); joinCallLinkStub.get().setTextColor(ContextCompat.getColor(context, messageRecord.isOutgoing() ? org.signal.core.ui.R.color.signal_light_colorOnPrimary : org.signal.core.ui.R.color.signal_colorOnPrimaryContainer)); joinCallLinkStub.get().setBackgroundColor(ContextCompat.getColor(context, messageRecord.isOutgoing() ? org.signal.core.ui.R.color.signal_light_colorTransparent2 : org.signal.core.ui.R.color.signal_colorOnPrimary)); joinCallLinkStub.get().setOnClickListener(v -> { if (eventListener != null) { - eventListener.onJoinCallLink(callLinkParseResult.getRootKey(), callLinkParseResult.getEpoch()); + eventListener.onJoinCallLink(callLinkRootKey); } }); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index f05f39bd99..57c8da03bb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -121,7 +121,6 @@ import org.signal.core.util.logging.Log import org.signal.core.util.orNull import org.signal.core.util.setActionItemTint import org.signal.donations.InAppPaymentType -import org.signal.ringrtc.CallLinkEpoch import org.signal.ringrtc.CallLinkRootKey import org.thoughtcrime.securesms.BlockUnblockDialog import org.thoughtcrime.securesms.GroupMembersDialog @@ -3740,8 +3739,8 @@ class ConversationFragment : GroupDescriptionDialog.show(childFragmentManager, groupName, description, shouldLinkifyWebLinks) } - override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey, callLinkEpoch: CallLinkEpoch?) { - CommunicationActions.startVideoCall(this@ConversationFragment, callLinkRootKey, callLinkEpoch) { + override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey) { + CommunicationActions.startVideoCall(this@ConversationFragment, callLinkRootKey) { YouAreAlreadyInACallSnackbar.show(requireView()) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt index 7d605632ba..abbb1561c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/CallLinkTable.kt @@ -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) ) }, diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt index 584d1877b0..5156806226 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt @@ -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) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V301_RemoveCallLinkEpoch.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V301_RemoveCallLinkEpoch.kt new file mode 100644 index 0000000000..e518697f03 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V301_RemoveCallLinkEpoch.kt @@ -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") + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLinkUpdateSendJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLinkUpdateSendJob.kt index f0154c58d5..b0d7707a54 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLinkUpdateSendJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/CallLinkUpdateSendJob.kt @@ -71,7 +71,6 @@ class CallLinkUpdateSendJob private constructor( val callLinkUpdate = CallLinkUpdate( rootKey = callLink.credentials.linkKeyBytes.toByteString(), adminPasskey = callLink.credentials.adminPassBytes?.toByteString(), - epoch = callLink.credentials.epochBytes?.toByteString(), type = callLinkUpdateType ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshCallLinkDetailsJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshCallLinkDetailsJob.kt index 7081b7409f..8eee7c2186 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshCallLinkDetailsJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshCallLinkDetailsJob.kt @@ -48,7 +48,6 @@ class RefreshCallLinkDetailsJob private constructor( val manager: SignalCallLinkManager = AppDependencies.signalCallManager.callLinkManager val credentials = CallLinkCredentials( linkKeyBytes = callLinkUpdate.rootKey!!.toByteArray(), - epochBytes = callLinkUpdate.epoch?.toByteArray(), adminPassBytes = callLinkUpdate.adminPasskey?.toByteArray() ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index 8c466dcd0f..b2d700787c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -19,7 +19,6 @@ import org.signal.core.util.logging.Log; import org.signal.libsignal.protocol.InvalidMessageException; import org.signal.libsignal.zkgroup.VerificationFailedException; import org.signal.libsignal.zkgroup.groups.GroupMasterKey; -import org.signal.ringrtc.CallLinkEpoch; import org.signal.ringrtc.CallLinkRootKey; import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupJoinInfo; import org.thoughtcrime.securesms.R; @@ -328,20 +327,15 @@ public class LinkPreviewRepository { @NonNull String callLinkUrl, @NonNull Callback callback) { - CallLinks.CallLinkParseResult linkParseResult = CallLinks.parseUrl(callLinkUrl); - if (linkParseResult == null) { + CallLinkRootKey callLinkRootKey = CallLinks.parseUrl(callLinkUrl); + if (callLinkRootKey == null) { callback.onError(Error.PREVIEW_NOT_AVAILABLE); return () -> { }; } - CallLinkEpoch epoch = linkParseResult.getEpoch(); - byte[] epochBytes = epoch != null ? epoch.getBytes() : null; - Disposable disposable = AppDependencies.getSignalCallManager() .getCallLinkManager() - .readCallLink(new CallLinkCredentials(linkParseResult.getRootKey().getKeyBytes(), - epochBytes, - null)) + .readCallLink(new CallLinkCredentials(callLinkRootKey.getKeyBytes(), null)) .observeOn(Schedulers.io()) .subscribe( result -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt index 8d46bf4aad..82db83a904 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.kt @@ -13,7 +13,6 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.RequestManager import org.signal.core.util.logging.Log -import org.signal.ringrtc.CallLinkEpoch import org.signal.ringrtc.CallLinkRootKey import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.FullScreenDialogFragment @@ -362,7 +361,7 @@ class MessageDetailsFragment : FullScreenDialogFragment(), MessageDetailsAdapter Log.w(TAG, "Not yet implemented!", Exception()) } - override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey, callLinkEpoch: CallLinkEpoch?) { + override fun onJoinCallLink(callLinkRootKey: CallLinkRootKey) { Log.w(TAG, "Not yet implemented!", Exception()) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt index 7de70b22da..097a7e0839 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt @@ -1391,7 +1391,6 @@ object SyncMessageProcessor { roomId, CallLinkCredentials( callLinkUpdate.rootKey!!.toByteArray(), - callLinkUpdate.epoch?.toByteArray(), callLinkUpdate.adminPasskey?.toByteArray() ) ) @@ -1403,7 +1402,6 @@ object SyncMessageProcessor { roomId = roomId, credentials = CallLinkCredentials( linkKeyBytes = callLinkRootKey.keyBytes, - epochBytes = callLinkUpdate.epoch?.toByteArray(), adminPassBytes = callLinkUpdate.adminPasskey?.toByteArray() ), state = SignalCallLinkState(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPreJoinActionProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPreJoinActionProcessor.kt index 26248e1ab4..b62c00eea9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPreJoinActionProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPreJoinActionProcessor.kt @@ -70,7 +70,6 @@ class CallLinkPreJoinActionProcessor( serverPublicParams.endorsementPublicKey, callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, - callLink.credentials.epoch, callLink.credentials.adminPassBytes, ByteArray(0), AUDIO_LEVELS_INTERVAL, diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java index c4d97b3884..da402ba187 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java @@ -24,7 +24,6 @@ import org.signal.libsignal.zkgroup.calllinks.CallLinkSecretParams; import org.signal.libsignal.zkgroup.groups.GroupIdentifier; import org.signal.ringrtc.CallException; import org.signal.ringrtc.CallId; -import org.signal.ringrtc.CallLinkEpoch; import org.signal.ringrtc.CallLinkRootKey; import org.signal.ringrtc.CallManager; import org.signal.ringrtc.CallSummary; @@ -420,7 +419,6 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. } CallLinkRootKey callLinkRootKey = new CallLinkRootKey(callLink.getCredentials().getLinkKeyBytes()); - CallLinkEpoch callLinkEpoch = callLink.getCredentials().getEpoch(); GenericServerPublicParams genericServerPublicParams = new GenericServerPublicParams(AppDependencies.getSignalServiceNetworkAccess() .getConfiguration() .getGenericServerPublicParams()); @@ -432,7 +430,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. CallLinkSecretParams.deriveFromRootKey(callLinkRootKey.getKeyBytes()) ); - callManager.peekCallLinkCall(SignalStore.internal().getGroupCallingServer(), callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, callLinkEpoch, peekInfo -> { + callManager.peekCallLinkCall(SignalStore.internal().getGroupCallingServer(), callLinkAuthCredentialPresentation.serialize(), callLinkRootKey, peekInfo -> { PeekInfo info = peekInfo.getValue(); if (info == null) { Log.w(TAG, "Failed to get peek info: " + peekInfo.getStatus()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/CallLinkCredentials.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/CallLinkCredentials.kt index 787e41ab8f..9d9e15effb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/CallLinkCredentials.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/CallLinkCredentials.kt @@ -7,7 +7,6 @@ package org.thoughtcrime.securesms.service.webrtc.links import android.os.Parcelable import kotlinx.parcelize.Parcelize -import org.signal.ringrtc.CallLinkEpoch import org.signal.ringrtc.CallLinkRootKey /** @@ -16,7 +15,6 @@ import org.signal.ringrtc.CallLinkRootKey @Parcelize data class CallLinkCredentials( val linkKeyBytes: ByteArray, - val epochBytes: ByteArray?, val adminPassBytes: ByteArray? ) : Parcelable { @@ -24,10 +22,6 @@ data class CallLinkCredentials( CallLinkRoomId.fromCallLinkRootKey(CallLinkRootKey(linkKeyBytes)) } - val epoch: CallLinkEpoch? by lazy { - epochBytes?.let { CallLinkEpoch.fromBytes(it) } - } - override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -41,12 +35,6 @@ data class CallLinkCredentials( } else if (other.adminPassBytes != null) { return false } - if (epochBytes != null) { - if (other.epochBytes == null) return false - if (!epochBytes.contentEquals(other.epochBytes)) return false - } else if (other.epochBytes != null) { - return false - } return true } @@ -64,7 +52,6 @@ data class CallLinkCredentials( fun generate(): CallLinkCredentials { return CallLinkCredentials( CallLinkRootKey.generate().keyBytes, - null, CallLinkRootKey.generateAdminPasskey() ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/SignalCallLinkManager.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/SignalCallLinkManager.kt index 8a00763d58..6cd7519e14 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/SignalCallLinkManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/links/SignalCallLinkManager.kt @@ -120,10 +120,10 @@ class SignalCallLinkManager( ) { result -> if (result.isSuccess) { Log.d(TAG, "Successfully created call link.") - val epoch = result.value!!.epoch + val rootKey = result.value!!.rootKey emitter.onSuccess( CreateCallLinkResult.Success( - credentials = CallLinkCredentials(rootKey.keyBytes, epoch?.bytes, adminPassKey), + credentials = CallLinkCredentials(rootKey.keyBytes, adminPassKey), state = result.value!!.toAppState() ) ) @@ -142,8 +142,7 @@ class SignalCallLinkManager( callManager.readCallLink( SignalStore.internal.groupCallingServer, requestCallLinkAuthCredentialPresentation(credentials.linkKeyBytes).serialize(), - CallLinkRootKey(credentials.linkKeyBytes), - credentials.epoch + CallLinkRootKey(credentials.linkKeyBytes) ) { if (it.isSuccess) { emitter.onSuccess(ReadCallLinkResult.Success(it.value!!.toAppState())) @@ -170,7 +169,6 @@ class SignalCallLinkManager( SignalStore.internal.groupCallingServer, credentialPresentation.serialize(), CallLinkRootKey(credentials.linkKeyBytes), - credentials.epoch, credentials.adminPassBytes, name ) { result -> @@ -198,7 +196,6 @@ class SignalCallLinkManager( SignalStore.internal.groupCallingServer, credentialPresentation.serialize(), CallLinkRootKey(credentials.linkKeyBytes), - credentials.epoch, credentials.adminPassBytes, restrictions ) { result -> @@ -225,7 +222,6 @@ class SignalCallLinkManager( SignalStore.internal.groupCallingServer, credentialPresentation.serialize(), CallLinkRootKey(credentials.linkKeyBytes), - credentials.epoch, credentials.adminPassBytes ) { result -> if (result.isSuccess && result.value == true) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessor.kt index 04620b0caa..0fc7858984 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessor.kt @@ -9,7 +9,6 @@ import okio.ByteString.Companion.toByteString import org.signal.core.util.isNotEmpty import org.signal.core.util.logging.Log import org.signal.core.util.toOptional -import org.signal.ringrtc.CallLinkEpoch import org.signal.ringrtc.CallLinkRootKey import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId @@ -49,7 +48,6 @@ class CallLinkRecordProcessor : DefaultStorageRecordProcessor { CallLinkRoomId roomId = CallLinkRoomId.fromBytes(rootKey.deriveRoomId()); - CallLinkTable.CallLink callLink = SignalDatabase.callLinks().getOrCreateCallLinkByRootKey(rootKey, epoch); + CallLinkTable.CallLink callLink = SignalDatabase.callLinks().getOrCreateCallLinkByRootKey(rootKey); if (callLink.getState().hasBeenRevoked()) { return Optional.empty(); diff --git a/app/src/main/protowire/Backup.proto b/app/src/main/protowire/Backup.proto index 5a6914488a..98cc7235dc 100644 --- a/app/src/main/protowire/Backup.proto +++ b/app/src/main/protowire/Backup.proto @@ -407,7 +407,7 @@ message CallLink { string name = 3; Restrictions restrictions = 4; uint64 expirationMs = 5; - optional bytes epoch = 6; // May be absent/empty for older links + reserved /*epoch*/ 6; } message AdHocCall { @@ -1432,4 +1432,4 @@ message ChatFolder { repeated uint64 includedRecipientIds = 7; // generated recipient id of groups, contacts, and/or note to self repeated uint64 excludedRecipientIds = 8; // generated recipient id of groups, contacts, and/or note to self bytes id = 9; // should be 16 bytes -} \ No newline at end of file +} diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/DatabaseConsistencyTest.kt b/app/src/test/java/org/thoughtcrime/securesms/database/DatabaseConsistencyTest.kt index d8a0ace374..eeba9a04e1 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/DatabaseConsistencyTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/database/DatabaseConsistencyTest.kt @@ -23,7 +23,7 @@ import org.thoughtcrime.securesms.testutil.SignalDatabaseMigrationRule import org.thoughtcrime.securesms.testutil.SignalDatabaseRule @RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, application = Application::class) +@Config(manifest = Config.NONE, application = Application::class, sdk = [35]) class DatabaseConsistencyTest { @get:Rule diff --git a/app/src/test/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessorTest.kt b/app/src/test/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessorTest.kt index 5cbfa464b3..06823d3479 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessorTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/storage/CallLinkRecordProcessorTest.kt @@ -34,7 +34,6 @@ class CallLinkRecordProcessorTest { private val testSubject = CallLinkRecordProcessor() private val mockCredentials = CallLinkCredentials( "root key".toByteArray(), - "abcd".toByteArray(), "admin pass".toByteArray() ) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index af73651e94..e533268952 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -170,7 +170,7 @@ libsignal-client = { module = "org.signal:libsignal-client", version.ref = "libs libsignal-android = { module = "org.signal:libsignal-android", version.ref = "libsignal-client" } protobuf-gradle-plugin = { module = "com.google.protobuf:protobuf-gradle-plugin", version.ref = "protobuf-gradle-plugin" } signal-aesgcmprovider = "org.signal:aesgcmprovider:0.0.4" -signal-ringrtc = "org.signal:ringrtc-android:2.64.1" +signal-ringrtc = "org.signal:ringrtc-android:2.65.0" signal-android-database-sqlcipher = "org.signal:sqlcipher-android:4.6.0-S1" # Third Party diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index b2b0a36804..fd4ec16caf 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -16756,12 +16756,12 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - + + + - - + + diff --git a/lib/libsignal-service/src/main/protowire/SignalService.proto b/lib/libsignal-service/src/main/protowire/SignalService.proto index da4d44fae0..96654bb2f3 100644 --- a/lib/libsignal-service/src/main/protowire/SignalService.proto +++ b/lib/libsignal-service/src/main/protowire/SignalService.proto @@ -682,7 +682,7 @@ message SyncMessage { optional bytes rootKey = 1; optional bytes adminPasskey = 2; optional Type type = 3; // defaults to UPDATE - optional bytes epoch = 4; + reserved 4; // was epoch field, never used } message CallLogEvent { diff --git a/lib/libsignal-service/src/main/protowire/StorageService.proto b/lib/libsignal-service/src/main/protowire/StorageService.proto index 95ec8454d6..6964ea299c 100644 --- a/lib/libsignal-service/src/main/protowire/StorageService.proto +++ b/lib/libsignal-service/src/main/protowire/StorageService.proto @@ -312,7 +312,7 @@ message CallLinkRecord { bytes rootKey = 1; bytes adminPasskey = 2; uint64 deletedAtTimestampMs = 3; - optional bytes epoch = 4; + reserved 4; // was epoch field, never used } message Recipient {