mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Add support for group call disposition.
Co-authored-by: Cody Henthorne <cody@signal.org>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
package org.thoughtcrime.securesms.service
|
||||
|
||||
import android.app.Application
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.annotation.WorkerThread
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Manages deleting call events 8 hours after they've been marked deleted.
|
||||
*/
|
||||
class DeletedCallEventManager(
|
||||
application: Application
|
||||
) : TimedEventManager<DeletedCallEventManager.Event>(application, "ExpiringCallEventsManager") {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(DeletedCallEventManager::class.java)
|
||||
|
||||
private val CALL_EVENT_DELETION_LIFESPAN = TimeUnit.HOURS.toMillis(8)
|
||||
}
|
||||
|
||||
init {
|
||||
scheduleIfNecessary()
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun getNextClosestEvent(): Event? {
|
||||
val oldestTimestamp = SignalDatabase.calls.getOldestDeletionTimestamp()
|
||||
if (oldestTimestamp <= 0) return null
|
||||
|
||||
val timeSinceSend = System.currentTimeMillis() - oldestTimestamp
|
||||
val delay = (CALL_EVENT_DELETION_LIFESPAN - timeSinceSend).coerceAtLeast(0)
|
||||
Log.i(TAG, "The oldest call event needs to be deleted in $delay ms.")
|
||||
|
||||
return Event(delay)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun executeEvent(event: Event) {
|
||||
val threshold = System.currentTimeMillis() - CALL_EVENT_DELETION_LIFESPAN
|
||||
val deletes = SignalDatabase.calls.deleteCallEventsDeletedBefore(threshold)
|
||||
Log.i(TAG, "Deleted $deletes call events before $threshold")
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun getDelayForEvent(event: Event): Long = event.delay
|
||||
|
||||
@WorkerThread
|
||||
override fun scheduleAlarm(application: Application, event: Event, delay: Long) {
|
||||
setAlarm(application, delay, DeleteCallEventsAlarm::class.java)
|
||||
}
|
||||
|
||||
data class Event(val delay: Long)
|
||||
|
||||
class DeleteCallEventsAlarm : BroadcastReceiver() {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(DeleteCallEventsAlarm::class.java)
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
Log.d(TAG, "onReceive()")
|
||||
ApplicationDependencies.getDeletedCallEventManager().scheduleIfNecessary()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.thoughtcrime.securesms.service.webrtc
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.thoughtcrime.securesms.database.model.toProtoByteString
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.SyncMessage.CallEvent
|
||||
|
||||
@@ -10,27 +13,70 @@ import org.whispersystems.signalservice.internal.push.SignalServiceProtos.SyncMe
|
||||
object CallEventSyncMessageUtil {
|
||||
@JvmStatic
|
||||
fun createAcceptedSyncMessage(remotePeer: RemotePeer, timestamp: Long, isOutgoing: Boolean, isVideoCall: Boolean): CallEvent {
|
||||
return CallEvent
|
||||
.newBuilder()
|
||||
.setPeerUuid(Recipient.resolved(remotePeer.id).requireServiceId().toByteString())
|
||||
.setId(remotePeer.callId.longValue())
|
||||
.setTimestamp(timestamp)
|
||||
.setType(if (isVideoCall) CallEvent.Type.VIDEO_CALL else CallEvent.Type.AUDIO_CALL)
|
||||
.setDirection(if (isOutgoing) CallEvent.Direction.OUTGOING else CallEvent.Direction.INCOMING)
|
||||
.setEvent(CallEvent.Event.ACCEPTED)
|
||||
.build()
|
||||
return createCallEvent(
|
||||
remotePeer.id,
|
||||
remotePeer.callId.longValue(),
|
||||
timestamp,
|
||||
isOutgoing,
|
||||
isVideoCall,
|
||||
CallEvent.Event.ACCEPTED
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createNotAcceptedSyncMessage(remotePeer: RemotePeer, timestamp: Long, isOutgoing: Boolean, isVideoCall: Boolean): CallEvent {
|
||||
return createCallEvent(
|
||||
remotePeer.id,
|
||||
remotePeer.callId.longValue(),
|
||||
timestamp,
|
||||
isOutgoing,
|
||||
isVideoCall,
|
||||
CallEvent.Event.NOT_ACCEPTED
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createDeleteCallEvent(remotePeer: RemotePeer, timestamp: Long, isOutgoing: Boolean, isVideoCall: Boolean): CallEvent {
|
||||
return createCallEvent(
|
||||
remotePeer.id,
|
||||
remotePeer.callId.longValue(),
|
||||
timestamp,
|
||||
isOutgoing,
|
||||
isVideoCall,
|
||||
CallEvent.Event.DELETE
|
||||
)
|
||||
}
|
||||
|
||||
private fun createCallEvent(
|
||||
recipientId: RecipientId,
|
||||
callId: Long,
|
||||
timestamp: Long,
|
||||
isOutgoing: Boolean,
|
||||
isVideoCall: Boolean,
|
||||
event: CallEvent.Event
|
||||
): CallEvent {
|
||||
val recipient = Recipient.resolved(recipientId)
|
||||
val isGroupCall = recipient.isGroup
|
||||
val conversationId: ByteString = if (isGroupCall) {
|
||||
recipient.requireGroupId().decodedId.toProtoByteString()
|
||||
} else {
|
||||
recipient.requireServiceId().toByteString()
|
||||
}
|
||||
|
||||
return CallEvent
|
||||
.newBuilder()
|
||||
.setPeerUuid(Recipient.resolved(remotePeer.id).requireServiceId().toByteString())
|
||||
.setId(remotePeer.callId.longValue())
|
||||
.setConversationId(conversationId)
|
||||
.setId(callId)
|
||||
.setTimestamp(timestamp)
|
||||
.setType(if (isVideoCall) CallEvent.Type.VIDEO_CALL else CallEvent.Type.AUDIO_CALL)
|
||||
.setType(
|
||||
when {
|
||||
isGroupCall -> CallEvent.Type.GROUP_CALL
|
||||
isVideoCall -> CallEvent.Type.VIDEO_CALL
|
||||
else -> CallEvent.Type.AUDIO_CALL
|
||||
}
|
||||
)
|
||||
.setDirection(if (isOutgoing) CallEvent.Direction.OUTGOING else CallEvent.Direction.INCOMING)
|
||||
.setEvent(CallEvent.Event.NOT_ACCEPTED)
|
||||
.setEvent(event)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.events.CallParticipant;
|
||||
import org.thoughtcrime.securesms.events.CallParticipantId;
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.ringrtc.Camera;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.webrtc.state.WebRtcEphemeralState;
|
||||
@@ -148,8 +149,9 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
String eraId = WebRtcUtil.getGroupCallEraId(groupCall);
|
||||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId);
|
||||
boolean remoteUserRangTheCall = currentState.getCallSetupState(RemotePeer.GROUP_CALL_ID).getRingerRecipient() != Recipient.self();
|
||||
String eraId = WebRtcUtil.getGroupCallEraId(groupCall);
|
||||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId, remoteUserRangTheCall, true);
|
||||
|
||||
List<UUID> members = new ArrayList<>(peekInfo.getJoinedMembers());
|
||||
if (!members.contains(SignalStore.account().requireAci().uuid())) {
|
||||
@@ -176,7 +178,7 @@ public class GroupConnectedActionProcessor extends GroupActionProcessor {
|
||||
}
|
||||
|
||||
String eraId = WebRtcUtil.getGroupCallEraId(groupCall);
|
||||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId);
|
||||
webRtcInteractor.sendGroupCallMessage(currentState.getCallInfoState().getCallRecipient(), eraId, false, false);
|
||||
|
||||
List<UUID> members = Stream.of(currentState.getCallInfoState().getRemoteCallParticipants()).map(p -> p.getRecipient().requireServiceId().uuid()).toList();
|
||||
webRtcInteractor.updateGroupCallUpdateMessage(currentState.getCallInfoState().getCallRecipient().getId(), eraId, members, false);
|
||||
|
||||
@@ -102,9 +102,9 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||
}
|
||||
|
||||
if (ringUpdate != CallManager.RingUpdate.REQUESTED) {
|
||||
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(ringId, remotePeerGroup.getId(), sender, System.currentTimeMillis(), ringUpdate);
|
||||
return currentState;
|
||||
} else if (SignalDatabase.groupCallRings().isCancelled(ringId)) {
|
||||
} else if (SignalDatabase.calls().isRingCancelled(ringId)) {
|
||||
try {
|
||||
Log.i(TAG, "Incoming ring request for already cancelled ring: " + ringId);
|
||||
webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, null);
|
||||
@@ -118,7 +118,7 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||
if (activeProfile != null && !(activeProfile.isRecipientAllowed(remotePeerGroup.getId()) || activeProfile.getAllowAllCalls())) {
|
||||
try {
|
||||
Log.i(TAG, "Incoming ring request for profile restricted recipient");
|
||||
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), CallManager.RingUpdate.EXPIRED_REQUEST);
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(ringId, remotePeerGroup.getId(), sender, System.currentTimeMillis(), CallManager.RingUpdate.EXPIRED_REQUEST);
|
||||
webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, CallManager.RingCancelReason.DeclinedByUser);
|
||||
} catch (CallException e) {
|
||||
Log.w(TAG, "Error while trying to cancel ring: " + ringId, e);
|
||||
@@ -135,7 +135,7 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||
protected @NonNull WebRtcServiceState handleReceivedGroupCallPeekForRingingCheck(@NonNull WebRtcServiceState currentState, @NonNull GroupCallRingCheckInfo info, @NonNull PeekInfo peekInfo) {
|
||||
Log.i(tag, "handleReceivedGroupCallPeekForRingingCheck(): recipient: " + info.getRecipientId() + " ring: " + info.getRingId());
|
||||
|
||||
if (SignalDatabase.groupCallRings().isCancelled(info.getRingId())) {
|
||||
if (SignalDatabase.calls().isRingCancelled(info.getRingId())) {
|
||||
try {
|
||||
Log.i(TAG, "Ring was cancelled while getting peek info ring: " + info.getRingId());
|
||||
webRtcInteractor.getCallManager().cancelGroupRing(info.getGroupId().getDecodedId(), info.getRingId(), null);
|
||||
@@ -147,11 +147,11 @@ public class IdleActionProcessor extends WebRtcActionProcessor {
|
||||
|
||||
if (peekInfo.getDeviceCount() == 0) {
|
||||
Log.i(TAG, "No one in the group call, mark as expired and do not ring");
|
||||
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(info.getRingId(), System.currentTimeMillis(), CallManager.RingUpdate.EXPIRED_REQUEST);
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(info.getRingId(), info.getRecipientId(), info.getRingerUuid(), System.currentTimeMillis(), CallManager.RingUpdate.EXPIRED_REQUEST);
|
||||
return currentState;
|
||||
} else if (peekInfo.getJoinedMembers().contains(Recipient.self().requireServiceId().uuid())) {
|
||||
Log.i(TAG, "We are already in the call, mark accepted on another device and do not ring");
|
||||
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(info.getRingId(), System.currentTimeMillis(), CallManager.RingUpdate.ACCEPTED_ON_ANOTHER_DEVICE);
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(info.getRingId(), info.getRecipientId(), info.getRingerUuid(), System.currentTimeMillis(), CallManager.RingUpdate.ACCEPTED_ON_ANOTHER_DEVICE);
|
||||
return currentState;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,12 +176,12 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor {
|
||||
|
||||
activePeer.localRinging();
|
||||
|
||||
SignalDatabase.calls().insertCall(remotePeer.getCallId().longValue(),
|
||||
System.currentTimeMillis(),
|
||||
remotePeer.getId(),
|
||||
SignalDatabase.calls().insertOneToOneCall(remotePeer.getCallId().longValue(),
|
||||
System.currentTimeMillis(),
|
||||
remotePeer.getId(),
|
||||
currentState.getCallSetupState(activePeer).isRemoteVideoOffer() ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL,
|
||||
CallTable.Direction.INCOMING,
|
||||
CallTable.Event.ONGOING);
|
||||
CallTable.Direction.INCOMING,
|
||||
CallTable.Event.ONGOING);
|
||||
|
||||
webRtcInteractor.updatePhoneState(LockManager.PhoneState.INTERACTIVE);
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
boolean updateForCurrentRingId = ringId == currentState.getCallSetupState(RemotePeer.GROUP_CALL_ID).getRingId();
|
||||
boolean isCurrentlyRinging = currentState.getCallInfoState().getGroupCallState().isRinging();
|
||||
|
||||
if (SignalDatabase.groupCallRings().isCancelled(ringId)) {
|
||||
if (SignalDatabase.calls().isRingCancelled(ringId)) {
|
||||
try {
|
||||
Log.i(TAG, "Ignoring incoming ring request for already cancelled ring: " + ringId);
|
||||
webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, null);
|
||||
@@ -69,7 +69,11 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
}
|
||||
|
||||
if (ringUpdate != CallManager.RingUpdate.REQUESTED) {
|
||||
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(ringId,
|
||||
remotePeerGroup.getId(),
|
||||
sender,
|
||||
System.currentTimeMillis(),
|
||||
ringUpdate);
|
||||
|
||||
if (updateForCurrentRingId && isCurrentlyRinging) {
|
||||
Log.i(TAG, "Cancelling current ring: " + ringId);
|
||||
@@ -104,7 +108,14 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
|
||||
Log.i(TAG, "Requesting new ring: " + ringId);
|
||||
|
||||
SignalDatabase.groupCallRings().insertGroupRing(ringId, System.currentTimeMillis(), ringUpdate);
|
||||
Recipient ringerRecipient = Recipient.externalPush(ServiceId.from(sender));
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(
|
||||
ringId,
|
||||
remotePeerGroup.getId(),
|
||||
ringerRecipient.getId(),
|
||||
System.currentTimeMillis(),
|
||||
ringUpdate
|
||||
);
|
||||
|
||||
currentState = WebRtcVideoUtil.initializeVideo(context, webRtcInteractor.getCameraEventListener(), currentState, RemotePeer.GROUP_CALL_ID.longValue());
|
||||
|
||||
@@ -138,7 +149,7 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
.changeCallSetupState(RemotePeer.GROUP_CALL_ID)
|
||||
.isRemoteVideoOffer(true)
|
||||
.ringId(ringId)
|
||||
.ringerRecipient(Recipient.externalPush(ServiceId.from(sender)))
|
||||
.ringerRecipient(ringerRecipient)
|
||||
.commit()
|
||||
.changeCallInfoState()
|
||||
.activePeer(new RemotePeer(currentState.getCallInfoState().getCallRecipient().getId(), RemotePeer.GROUP_CALL_ID))
|
||||
@@ -226,10 +237,13 @@ public final class IncomingGroupCallActionProcessor extends DeviceAwareActionPro
|
||||
Recipient recipient = currentState.getCallInfoState().getCallRecipient();
|
||||
Optional<GroupId> groupId = recipient.getGroupId();
|
||||
long ringId = currentState.getCallSetupState(RemotePeer.GROUP_CALL_ID).getRingId();
|
||||
Recipient ringer = currentState.getCallSetupState(RemotePeer.GROUP_CALL_ID).getRingerRecipient();
|
||||
|
||||
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId,
|
||||
System.currentTimeMillis(),
|
||||
CallManager.RingUpdate.DECLINED_ON_ANOTHER_DEVICE);
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(ringId,
|
||||
recipient.getId(),
|
||||
ringer.getId(),
|
||||
System.currentTimeMillis(),
|
||||
CallManager.RingUpdate.DECLINED_ON_ANOTHER_DEVICE);
|
||||
|
||||
try {
|
||||
webRtcInteractor.getCallManager().cancelGroupRing(groupId.get().getDecodedId(),
|
||||
|
||||
@@ -85,12 +85,12 @@ public class OutgoingCallActionProcessor extends DeviceAwareActionProcessor {
|
||||
|
||||
RecipientUtil.setAndSendUniversalExpireTimerIfNecessary(context, Recipient.resolved(remotePeer.getId()), SignalDatabase.threads().getThreadIdIfExistsFor(remotePeer.getId()));
|
||||
|
||||
SignalDatabase.calls().insertCall(remotePeer.getCallId().longValue(),
|
||||
System.currentTimeMillis(),
|
||||
remotePeer.getId(),
|
||||
SignalDatabase.calls().insertOneToOneCall(remotePeer.getCallId().longValue(),
|
||||
System.currentTimeMillis(),
|
||||
remotePeer.getId(),
|
||||
isVideoCall ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL,
|
||||
CallTable.Direction.OUTGOING,
|
||||
CallTable.Event.ONGOING);
|
||||
CallTable.Direction.OUTGOING,
|
||||
CallTable.Event.ONGOING);
|
||||
|
||||
EglBaseWrapper.replaceHolder(EglBaseWrapper.OUTGOING_PLACEHOLDER, remotePeer.getCallId().longValue());
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ import org.thoughtcrime.securesms.events.GroupCallPeekEvent;
|
||||
import org.thoughtcrime.securesms.events.WebRtcViewModel;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.GroupManager;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.jobs.CallSyncEventJob;
|
||||
import org.thoughtcrime.securesms.jobs.GroupCallUpdateSendJob;
|
||||
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
@@ -349,8 +351,8 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
Long threadId = SignalDatabase.threads().getThreadIdFor(group.getId());
|
||||
|
||||
if (threadId != null) {
|
||||
SignalDatabase.messages()
|
||||
.updatePreviousGroupCall(threadId,
|
||||
SignalDatabase.calls()
|
||||
.updateGroupCallFromPeek(threadId,
|
||||
peekInfo.getEraId(),
|
||||
peekInfo.getJoinedMembers(),
|
||||
WebRtcUtil.isCallFull(peekInfo));
|
||||
@@ -831,25 +833,25 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
|
||||
public void insertMissedCall(@NonNull RemotePeer remotePeer, long timestamp, boolean isVideoOffer) {
|
||||
CallTable.Call call = SignalDatabase.calls()
|
||||
.updateCall(remotePeer.getCallId().longValue(), CallTable.Event.MISSED);
|
||||
.updateOneToOneCall(remotePeer.getCallId().longValue(), CallTable.Event.MISSED);
|
||||
|
||||
if (call == null) {
|
||||
CallTable.Type type = isVideoOffer ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL;
|
||||
|
||||
SignalDatabase.calls()
|
||||
.insertCall(remotePeer.getCallId().longValue(), timestamp, remotePeer.getId(), type, CallTable.Direction.INCOMING, CallTable.Event.MISSED);
|
||||
.insertOneToOneCall(remotePeer.getCallId().longValue(), timestamp, remotePeer.getId(), type, CallTable.Direction.INCOMING, CallTable.Event.MISSED);
|
||||
}
|
||||
}
|
||||
|
||||
public void insertReceivedCall(@NonNull RemotePeer remotePeer, boolean isVideoOffer) {
|
||||
CallTable.Call call = SignalDatabase.calls()
|
||||
.updateCall(remotePeer.getCallId().longValue(), CallTable.Event.ACCEPTED);
|
||||
.updateOneToOneCall(remotePeer.getCallId().longValue(), CallTable.Event.ACCEPTED);
|
||||
|
||||
if (call == null) {
|
||||
CallTable.Type type = isVideoOffer ? CallTable.Type.VIDEO_CALL : CallTable.Type.AUDIO_CALL;
|
||||
|
||||
SignalDatabase.calls()
|
||||
.insertCall(remotePeer.getCallId().longValue(), System.currentTimeMillis(), remotePeer.getId(), type, CallTable.Direction.INCOMING, CallTable.Event.ACCEPTED);
|
||||
.insertOneToOneCall(remotePeer.getCallId().longValue(), System.currentTimeMillis(), remotePeer.getId(), type, CallTable.Direction.INCOMING, CallTable.Event.ACCEPTED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,17 +889,32 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
});
|
||||
}
|
||||
|
||||
public void sendGroupCallUpdateMessage(@NonNull Recipient recipient, @Nullable String groupCallEraId) {
|
||||
SignalExecutors.BOUNDED.execute(() -> ApplicationDependencies.getJobManager().add(GroupCallUpdateSendJob.create(recipient.getId(), groupCallEraId)));
|
||||
public void sendGroupCallUpdateMessage(@NonNull Recipient recipient, @Nullable String groupCallEraId, boolean isIncoming, boolean isJoinEvent) {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
GroupCallUpdateSendJob updateSendJob = GroupCallUpdateSendJob.create(recipient.getId(), groupCallEraId);
|
||||
JobManager.Chain chain = ApplicationDependencies.getJobManager().startChain(updateSendJob);
|
||||
|
||||
if (isJoinEvent && groupCallEraId != null) {
|
||||
chain.then(CallSyncEventJob.createForJoin(
|
||||
recipient.getId(),
|
||||
CallId.fromEra(groupCallEraId).longValue(),
|
||||
isIncoming
|
||||
));
|
||||
} else if (isJoinEvent) {
|
||||
Log.w(TAG, "Can't send join event sync message without an era id.");
|
||||
}
|
||||
|
||||
chain.enqueue();
|
||||
});
|
||||
}
|
||||
|
||||
public void updateGroupCallUpdateMessage(@NonNull RecipientId groupId, @Nullable String groupCallEraId, @NonNull Collection<UUID> joinedMembers, boolean isCallFull) {
|
||||
SignalExecutors.BOUNDED.execute(() -> SignalDatabase.messages().insertOrUpdateGroupCall(groupId,
|
||||
Recipient.self().getId(),
|
||||
System.currentTimeMillis(),
|
||||
groupCallEraId,
|
||||
joinedMembers,
|
||||
isCallFull));
|
||||
SignalExecutors.BOUNDED.execute(() -> SignalDatabase.calls().insertOrUpdateGroupCallFromLocalEvent(groupId,
|
||||
Recipient.self().getId(),
|
||||
System.currentTimeMillis(),
|
||||
groupCallEraId,
|
||||
joinedMembers,
|
||||
isCallFull));
|
||||
}
|
||||
|
||||
public void sendCallMessage(@NonNull final RemotePeer remotePeer,
|
||||
@@ -935,7 +952,7 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
public void sendAcceptedCallEventSyncMessage(@NonNull RemotePeer remotePeer, boolean isOutgoing, boolean isVideoCall) {
|
||||
SignalDatabase
|
||||
.calls()
|
||||
.updateCall(remotePeer.getCallId().longValue(), CallTable.Event.ACCEPTED);
|
||||
.updateOneToOneCall(remotePeer.getCallId().longValue(), CallTable.Event.ACCEPTED);
|
||||
|
||||
if (TextSecurePreferences.isMultiDevice(context)) {
|
||||
networkExecutor.execute(() -> {
|
||||
@@ -952,7 +969,7 @@ private void processStateless(@NonNull Function1<WebRtcEphemeralState, WebRtcEph
|
||||
public void sendNotAcceptedCallEventSyncMessage(@NonNull RemotePeer remotePeer, boolean isOutgoing, boolean isVideoCall) {
|
||||
SignalDatabase
|
||||
.calls()
|
||||
.updateCall(remotePeer.getCallId().longValue(), CallTable.Event.NOT_ACCEPTED);
|
||||
.updateOneToOneCall(remotePeer.getCallId().longValue(), CallTable.Event.NOT_ACCEPTED);
|
||||
|
||||
if (TextSecurePreferences.isMultiDevice(context)) {
|
||||
networkExecutor.execute(() -> {
|
||||
|
||||
@@ -54,6 +54,7 @@ import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.IceUpdateMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
|
||||
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -798,9 +799,11 @@ public abstract class WebRtcActionProcessor {
|
||||
if (ringUpdate != RingUpdate.BUSY_LOCALLY && ringUpdate != RingUpdate.BUSY_ON_ANOTHER_DEVICE) {
|
||||
webRtcInteractor.getCallManager().cancelGroupRing(groupId.getDecodedId(), ringId, CallManager.RingCancelReason.Busy);
|
||||
}
|
||||
SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId,
|
||||
System.currentTimeMillis(),
|
||||
ringUpdate == RingUpdate.REQUESTED ? RingUpdate.BUSY_LOCALLY : ringUpdate);
|
||||
SignalDatabase.calls().insertOrUpdateGroupCallFromRingState(ringId,
|
||||
remotePeerGroup.getId(),
|
||||
sender,
|
||||
System.currentTimeMillis(),
|
||||
ringUpdate == RingUpdate.REQUESTED ? RingUpdate.BUSY_LOCALLY : ringUpdate);
|
||||
} catch (CallException e) {
|
||||
Log.w(tag, "Unable to cancel ring", e);
|
||||
}
|
||||
@@ -826,7 +829,7 @@ public abstract class WebRtcActionProcessor {
|
||||
Recipient recipient = currentState.getCallInfoState().getCallRecipient();
|
||||
|
||||
if (recipient != null && currentState.getCallInfoState().getGroupCallState().isConnected()) {
|
||||
webRtcInteractor.sendGroupCallMessage(recipient, WebRtcUtil.getGroupCallEraId(groupCall));
|
||||
webRtcInteractor.sendGroupCallMessage(recipient, WebRtcUtil.getGroupCallEraId(groupCall), false, false);
|
||||
}
|
||||
|
||||
currentState = currentState.builder()
|
||||
|
||||
@@ -84,8 +84,8 @@ public class WebRtcInteractor {
|
||||
signalCallManager.sendCallMessage(remotePeer, callMessage);
|
||||
}
|
||||
|
||||
void sendGroupCallMessage(@NonNull Recipient recipient, @Nullable String groupCallEraId) {
|
||||
signalCallManager.sendGroupCallUpdateMessage(recipient, groupCallEraId);
|
||||
void sendGroupCallMessage(@NonNull Recipient recipient, @Nullable String groupCallEraId, boolean isIncoming, boolean isJoinEvent) {
|
||||
signalCallManager.sendGroupCallUpdateMessage(recipient, groupCallEraId, isIncoming, isJoinEvent);
|
||||
}
|
||||
|
||||
void updateGroupCallUpdateMessage(@NonNull RecipientId groupId, @Nullable String groupCallEraId, @NonNull Collection<UUID> joinedMembers, boolean isCallFull) {
|
||||
|
||||
Reference in New Issue
Block a user