From 1f09f48e6be71511388b20b49bc57e60a3fc59ae Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 6 Sep 2024 13:25:28 -0300 Subject: [PATCH] Add proper call tab return state. --- .../securesms/calls/links/SignalCallRow.kt | 38 +++++++++---- ...CreateCallLinkBottomSheetDialogFragment.kt | 1 + .../links/details/CallLinkDetailsFragment.kt | 11 ++-- .../links/details/CallLinkDetailsState.kt | 4 +- .../links/details/CallLinkDetailsViewModel.kt | 29 ++++++++-- .../securesms/calls/log/CallLogAdapter.kt | 53 ++++++++++++++++--- .../securesms/calls/log/CallLogRepository.kt | 26 --------- .../securesms/calls/log/CallLogViewModel.kt | 28 ++++------ .../securesms/database/CallTable.kt | 49 +++++++++++------ .../securesms/database/MessageTable.kt | 6 +-- .../CallLinkConnectedActionProcessor.kt | 4 ++ .../service/webrtc/CallLinkPeekInfo.kt | 7 ++- .../service/webrtc/SignalCallManager.java | 14 +++-- 13 files changed, 171 insertions(+), 99 deletions(-) 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 543d88bd1a..cb3756981e 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 @@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.calls.links import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement.spacedBy import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -33,20 +34,21 @@ import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.signal.core.ui.Buttons -import org.signal.core.ui.theme.SignalTheme +import org.signal.core.ui.Previews +import org.signal.core.ui.SignalPreview import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.conversation.colors.AvatarColorPair import org.thoughtcrime.securesms.database.CallLinkTable import org.thoughtcrime.securesms.recipients.RecipientId +import org.thoughtcrime.securesms.service.webrtc.CallLinkPeekInfo 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 java.time.Instant -@Preview +@SignalPreview @Composable private fun SignalCallRowPreview() { val callLink = remember { @@ -63,17 +65,29 @@ private fun SignalCallRowPreview() { ) ) } - SignalTheme(false) { - SignalCallRow( - callLink = callLink, - onJoinClicked = {} - ) + Previews.Preview { + Column( + verticalArrangement = spacedBy(8.dp) + ) { + SignalCallRow( + callLink = callLink, + callLinkPeekInfo = null, + onJoinClicked = {} + ) + + SignalCallRow( + callLink = callLink, + callLinkPeekInfo = CallLinkPeekInfo(null, true, true), + onJoinClicked = {} + ) + } } } @Composable fun SignalCallRow( callLink: CallLinkTable.CallLink, + callLinkPeekInfo: CallLinkPeekInfo?, onJoinClicked: (() -> Unit)?, modifier: Modifier = Modifier ) { @@ -140,7 +154,13 @@ fun SignalCallRow( ), modifier = Modifier.align(CenterVertically) ) { - Text(text = stringResource(id = R.string.CreateCallLinkBottomSheetDialogFragment__join)) + val textId = if (callLinkPeekInfo?.isJoined == true) { + R.string.CallLogAdapter__return + } else { + R.string.CreateCallLinkBottomSheetDialogFragment__join + } + + Text(text = stringResource(id = textId)) } } } 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 5da370b915..edc1ed1cb0 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 @@ -100,6 +100,7 @@ class CreateCallLinkBottomSheetDialogFragment : ComposeBottomSheetDialogFragment SignalCallRow( callLink = callLink, + callLinkPeekInfo = null, onJoinClicked = this@CreateCallLinkBottomSheetDialogFragment::onJoinClicked ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsFragment.kt index 05663a4a8d..c32561d298 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsFragment.kt @@ -41,7 +41,6 @@ import org.thoughtcrime.securesms.calls.links.CallLinks import org.thoughtcrime.securesms.calls.links.EditCallLinkNameDialogFragment import org.thoughtcrime.securesms.calls.links.SignalCallRow import org.thoughtcrime.securesms.compose.ComposeFragment -import org.thoughtcrime.securesms.conversation.colors.AvatarColor import org.thoughtcrime.securesms.database.CallLinkTable import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.service.webrtc.links.CallLinkCredentials @@ -200,12 +199,11 @@ private interface CallLinkDetailsCallback { @Preview @Composable private fun CallLinkDetailsPreview() { - val avatarColor = remember { - AvatarColor.random() - } - val callLink = remember { - val credentials = CallLinkCredentials.generate() + val credentials = CallLinkCredentials( + byteArrayOf(1, 2, 3, 4), + byteArrayOf(3, 4, 5, 6) + ) CallLinkTable.CallLink( recipientId = RecipientId.UNKNOWN, roomId = credentials.roomId, @@ -258,6 +256,7 @@ private fun CallLinkDetails( Column(modifier = Modifier.padding(paddingValues)) { SignalCallRow( callLink = state.callLink, + callLinkPeekInfo = state.peekInfo, onJoinClicked = callback::onJoinClicked, modifier = Modifier.padding(top = 16.dp, bottom = 12.dp) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsState.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsState.kt index 33d1f887e9..81af3bea95 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/links/details/CallLinkDetailsState.kt @@ -7,9 +7,11 @@ package org.thoughtcrime.securesms.calls.links.details import androidx.compose.runtime.Immutable import org.thoughtcrime.securesms.database.CallLinkTable +import org.thoughtcrime.securesms.service.webrtc.CallLinkPeekInfo @Immutable data class CallLinkDetailsState( val displayRevocationDialog: Boolean = false, - val callLink: CallLinkTable.CallLink? = null + val callLink: CallLinkTable.CallLink? = null, + val peekInfo: CallLinkPeekInfo? = null ) 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 877a8186c3..11db2d97e2 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 @@ -10,14 +10,17 @@ import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.subscribeBy +import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.subjects.BehaviorSubject import org.signal.ringrtc.CallLinkState import org.thoughtcrime.securesms.calls.links.CallLinks import org.thoughtcrime.securesms.calls.links.UpdateCallLinkRepository +import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId import org.thoughtcrime.securesms.service.webrtc.links.UpdateCallLinkResult @@ -43,13 +46,33 @@ class CallLinkDetailsViewModel( init { disposables += repository.refreshCallLinkState(callLinkRoomId) - disposables += CallLinks.watchCallLink(callLinkRoomId).subscribeBy { - _state.value = _state.value.copy(callLink = it) - } + disposables += CallLinks.watchCallLink(callLinkRoomId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeBy { + _state.value = _state.value.copy(callLink = it) + } disposables += repository .watchCallLinkRecipient(callLinkRoomId) .subscribeBy(onNext = recipientSubject::onNext) + + disposables += recipientSubject + .map { it.id } + .distinctUntilChanged() + .flatMap { recipientId -> + AppDependencies.signalCallManager.peekInfoCache + .distinctUntilChanged() + .filter { it.containsKey(recipientId) } + .map { it[recipientId]!! } + .distinctUntilChanged() + .toObservable() + } + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeBy { callLinkPeekInfo -> + _state.value = _state.value.copy(peekInfo = callLinkPeekInfo) + } } override fun onCleared() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt index 488ce8ed0b..4c50cddc6c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogAdapter.kt @@ -228,13 +228,28 @@ class CallLogAdapter( ) ) - binding.callType.setImageResource(R.drawable.symbol_video_24) - binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call) - binding.callType.setOnClickListener { - onStartVideoCallClicked(model.callLink.recipient, true) + if (model.callLink.callLinkPeekInfo?.isActive == true) { + binding.groupCallButton.setText( + if (model.callLink.callLinkPeekInfo.isJoined) { + R.string.CallLogAdapter__return + } else { + R.string.CallLogAdapter__join + } + ) + binding.groupCallButton.setOnClickListener { + onStartVideoCallClicked(model.callLink.recipient, true) + } + binding.callType.visible = false + binding.groupCallButton.visible = true + } else { + binding.callType.setImageResource(R.drawable.symbol_video_24) + binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call) + binding.callType.setOnClickListener { + onStartVideoCallClicked(model.callLink.recipient, true) + } + binding.callType.visible = true + binding.groupCallButton.visible = false } - binding.callType.visible = true - binding.groupCallButton.visible = false } } @@ -338,7 +353,30 @@ class CallLogAdapter( binding.groupCallButton.visible = false } - CallTable.Type.GROUP_CALL, CallTable.Type.AD_HOC_CALL -> { + CallTable.Type.AD_HOC_CALL -> { + binding.callType.setImageResource(R.drawable.symbol_video_24) + binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call) + binding.callType.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) } + binding.groupCallButton.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) } + + if (model.call.callLinkPeekInfo?.isActive == true) { + binding.callType.visible = false + binding.groupCallButton.visible = true + + binding.groupCallButton.setText( + if (model.call.callLinkPeekInfo.isJoined) { + R.string.CallLogAdapter__return + } else { + R.string.CallLogAdapter__join + } + ) + } else { + binding.callType.visible = true + binding.groupCallButton.visible = false + } + } + + CallTable.Type.GROUP_CALL -> { binding.callType.setImageResource(R.drawable.symbol_video_24) binding.callType.contentDescription = context.getString(R.string.CallLogAdapter__start_a_video_call) binding.callType.setOnClickListener { onStartVideoCallClicked(model.call.peer, model.call.canUserBeginCall) } @@ -401,6 +439,7 @@ class CallLogAdapter( call.direction == CallTable.Direction.OUTGOING -> R.string.CallLogAdapter__outgoing else -> throw AssertionError() } + else -> if (call.isDisplayedAsMissedCallInUi) R.string.CallLogAdapter__missed else R.string.CallLogAdapter__incoming } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt index c9790465a7..0da883bccd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogRepository.kt @@ -11,7 +11,6 @@ import org.thoughtcrime.securesms.database.CallLinkTable import org.thoughtcrime.securesms.database.DatabaseObserver import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.AppDependencies -import org.thoughtcrime.securesms.jobs.CallLinkPeekJob import org.thoughtcrime.securesms.jobs.CallLogEventSendJob import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId import org.thoughtcrime.securesms.service.webrtc.links.UpdateCallLinkResult @@ -158,29 +157,4 @@ class CallLogRepository( SignalDatabase.calls.updateAdHocCallEventDeletionTimestamps() } } - - fun peekCallLinks(): Completable { - return Completable.fromAction { - val callLinks: List = SignalDatabase.callLinks.getCallLinks( - query = null, - offset = 0, - limit = 10 - ) - - val callEvents: List = SignalDatabase.calls.getCalls( - offset = 0, - limit = 10, - searchTerm = null, - filter = CallLogFilter.AD_HOC - ) - - val recipients = (callLinks.map { it.recipient } + callEvents.map { it.peer }).toSet() - - val jobs = recipients.take(10).map { - CallLinkPeekJob(it.id) - } - - AppDependencies.jobManager.addAll(jobs) - }.subscribeOn(Schedulers.io()) - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogViewModel.kt index 91818b88dd..a6d47b987b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/log/CallLogViewModel.kt @@ -6,7 +6,6 @@ import androidx.lifecycle.ViewModel import io.reactivex.rxjava3.core.BackpressureStrategy import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Maybe -import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.processors.BehaviorProcessor @@ -16,9 +15,7 @@ import org.signal.paging.PagedData import org.signal.paging.PagingConfig import org.signal.paging.ProxyPagingController import org.thoughtcrime.securesms.dependencies.AppDependencies -import org.thoughtcrime.securesms.util.RemoteConfig import org.thoughtcrime.securesms.util.rx.RxStore -import java.util.concurrent.TimeUnit /** * ViewModel for call log management. @@ -82,22 +79,15 @@ class CallLogViewModel( controller.onDataInvalidated() } - if (RemoteConfig.adHocCalling) { - disposables += Observable - .interval(30, TimeUnit.SECONDS, Schedulers.computation()) - .flatMapCompletable { callLogRepository.peekCallLinks() } - .subscribe() - - disposables += AppDependencies - .signalCallManager - .peekInfoCache - .observeOn(Schedulers.computation()) - .distinctUntilChanged() - .subscribe { - callLogPeekHelper.onDataSetInvalidated() - controller.onDataInvalidated() - } - } + disposables += AppDependencies + .signalCallManager + .peekInfoCache + .observeOn(Schedulers.computation()) + .distinctUntilChanged() + .subscribe { + callLogPeekHelper.onDataSetInvalidated() + controller.onDataInvalidated() + } } override fun onCleared() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt index 4545408082..eb03c638f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt @@ -602,7 +602,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl timestamp: Long, eraId: String ): Boolean { - return handleCallLinkUpdate(callRecipient, timestamp, CallId.fromEra(eraId), Direction.INCOMING) + return handleCallLinkUpdate(callRecipient, timestamp, CallId.fromEra(eraId), Direction.INCOMING, skipTimestampUpdate = true) } fun insertOrUpdateGroupCallFromLocalEvent( @@ -707,10 +707,16 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl .run() if (exists && !skipTimestampUpdate) { - db.update(TABLE_NAME) + val updated = db.update(TABLE_NAME) .values(TIMESTAMP to timestamp) .where("$PEER = ? AND $CALL_ID = ? AND $TIMESTAMP < ?", callLinkRecipient.id.serialize(), callId.longValue(), timestamp) - .run() + .run() > 0 + + if (updated) { + Log.d(TAG, "Updated call event for call link. Call Id: $callId") + AppDependencies.databaseObserver.notifyCallUpdateObservers() + } + false } else if (!exists) { db.insertInto(TABLE_NAME) @@ -726,11 +732,12 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl ).run(SQLiteDatabase.CONFLICT_ABORT) Log.d(TAG, "Inserted new call event for call link. Call Id: $callId") + AppDependencies.databaseObserver.notifyCallUpdateObservers() + true } else false } - AppDependencies.databaseObserver.notifyCallUpdateObservers() return didInsert } @@ -793,7 +800,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl peekGroupCallEraId: String?, peekJoinedUuids: Collection, isCallFull: Boolean - ): Boolean { + ) { val callId = peekGroupCallEraId?.let { CallId.fromEra(it) } val recipientId = SignalDatabase.threads.getRecipientIdForThreadId(threadId) val call = if (callId != null && recipientId != null) { @@ -802,7 +809,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl null } - val sameEraId = SignalDatabase.messages.updatePreviousGroupCall( + SignalDatabase.messages.updatePreviousGroupCall( threadId = threadId, peekGroupCallEraId = peekGroupCallEraId, peekJoinedUuids = peekJoinedUuids, @@ -812,10 +819,8 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl if (call != null) { updateGroupCallState(call, peekJoinedUuids) + AppDependencies.databaseObserver.notifyCallUpdateObservers() } - - AppDependencies.databaseObserver.notifyCallUpdateObservers() - return sameEraId } fun insertOrUpdateGroupCallFromRingState( @@ -846,33 +851,43 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl return call.event != Event.RINGING && call.event != Event.GENERIC_GROUP_CALL } + /** + * @return whether or not a change is detected. + */ private fun updateGroupCallState( call: Call, peekJoinedUuids: Collection - ) { - updateGroupCallState( + ): Boolean { + return updateGroupCallState( call, peekJoinedUuids.contains(Recipient.self().requireServiceId().rawUuid), peekJoinedUuids.isNotEmpty() ) } + /** + * @return Whether or not a change was detected + */ private fun updateGroupCallState( call: Call, hasLocalUserJoined: Boolean, isGroupCallActive: Boolean - ) { - writableDatabase.update(TABLE_NAME) + ): Boolean { + val localJoined = call.didLocalUserJoin || hasLocalUserJoined + + return writableDatabase.update(TABLE_NAME) .values( - LOCAL_JOINED to (call.didLocalUserJoin || hasLocalUserJoined), + LOCAL_JOINED to localJoined, GROUP_CALL_ACTIVE to isGroupCallActive ) .where( - "$CALL_ID = ? AND $PEER = ?", + "$CALL_ID = ? AND $PEER = ? AND ($LOCAL_JOINED != ? OR $GROUP_CALL_ACTIVE != ?)", call.callId, - call.peer.toLong() + call.peer.toLong(), + localJoined.toInt(), + isGroupCallActive.toInt() ) - .run() + .run() > 0 } private fun handleGroupRingState( diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt index f182c84eaa..51420bee4d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MessageTable.kt @@ -1022,8 +1022,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat peekJoinedUuids: Collection, isCallFull: Boolean, isRingingOnLocalDevice: Boolean - ): Boolean { - return writableDatabase.withinTransaction { db -> + ) { + writableDatabase.withinTransaction { db -> val cursor = db .select(*MMS_PROJECTION) .from(TABLE_NAME) @@ -1058,8 +1058,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat if (updated) { notifyConversationListeners(threadId) } - - sameEraId } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkConnectedActionProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkConnectedActionProcessor.kt index 99fe05ec92..3bdc968bc7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkConnectedActionProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkConnectedActionProcessor.kt @@ -12,6 +12,7 @@ import org.signal.ringrtc.PeekInfo import org.thoughtcrime.securesms.components.webrtc.CallLinkProfileKeySender import org.thoughtcrime.securesms.database.CallLinkTable import org.thoughtcrime.securesms.database.SignalDatabase +import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.events.CallParticipant import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId @@ -58,6 +59,9 @@ class CallLinkConnectedActionProcessor( Log.i(tag, "Updating pending list with ${peekInfo.pendingUsers.size} entries.") val pendingParticipants: List = peekInfo.pendingUsers.map { Recipient.externalPush(ServiceId.ACI.from(it)) } + Log.i(tag, "Storing peek-info in in-memory cache.") + AppDependencies.signalCallManager.emitCallLinkPeekInfoUpdate(callLink.recipientId, peekInfo) + return superState.builder() .changeCallInfoState() .setCallLinkPendingParticipants(pendingParticipants) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPeekInfo.kt b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPeekInfo.kt index e8b1f80bda..5e4ff78ad1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPeekInfo.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/CallLinkPeekInfo.kt @@ -7,20 +7,23 @@ package org.thoughtcrime.securesms.service.webrtc import org.signal.ringrtc.CallId import org.signal.ringrtc.PeekInfo +import org.thoughtcrime.securesms.recipients.Recipient /** * App-level peek info object for call links. */ data class CallLinkPeekInfo( val callId: CallId?, - val isActive: Boolean + val isActive: Boolean, + val isJoined: Boolean ) { companion object { @JvmStatic fun fromPeekInfo(peekInfo: PeekInfo): CallLinkPeekInfo { return CallLinkPeekInfo( callId = peekInfo.eraId?.let { CallId.fromEra(it) }, - isActive = peekInfo.joinedMembers.isNotEmpty() + isActive = peekInfo.joinedMembers.isNotEmpty(), + isJoined = peekInfo.joinedMembers.contains(Recipient.self().requireServiceId().rawUuid) ) } } 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 fad7d53457..66b7d6831a 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 @@ -435,11 +435,7 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. } } - linkPeekInfoStore.update(store -> { - Map newHashMap = new HashMap<>(store); - newHashMap.put(id, CallLinkPeekInfo.fromPeekInfo(info)); - return newHashMap; - }); + emitCallLinkPeekInfoUpdate(id, info); }); } catch (CallException | VerificationFailedException | InvalidInputException | IOException e) { Log.i(TAG, "error peeking call link", e); @@ -447,6 +443,14 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. }); } + public void emitCallLinkPeekInfoUpdate(@NonNull RecipientId recipientId, @NonNull PeekInfo peekInfo) { + linkPeekInfoStore.update(store -> { + Map newHashMap = new HashMap<>(store); + newHashMap.put(recipientId, CallLinkPeekInfo.fromPeekInfo(peekInfo)); + return newHashMap; + }); + } + public void peekGroupCall(@NonNull RecipientId id) { peekGroupCall(id, null); }