Handle incoming GroupCallUpdate messages

This builds out infrastructure to fetch updated PeekInfo structs from
RingRTC on a GroupCallUpdate. There are still a bunch of TODOs to
resolve once RingRTC adds PeekInfo.
This commit is contained in:
Michelle Linington 2020-11-13 22:56:18 -08:00 committed by Nora Trapp
parent f6a252d274
commit daa28d413d
7 changed files with 113 additions and 1 deletions

View File

@ -548,7 +548,12 @@ extension CallService: CallObserver {
}
public func groupCallRemoteDeviceStatesChanged(_ call: SignalCall) {}
public func groupCallPeekChanged(_ call: SignalCall) {}
public func groupCallPeekChanged(_ call: SignalCall) {
// TODO: Fetch the real PeekInfo from call.groupCall.localDeviceState
let peekInfo = PeekInfo()
guard let groupThread = call.thread as? TSGroupThread else { return }
updateGroupCallMessageWithInfo(peekInfo, for: groupThread)
}
public func groupCallRequestMembershipProof(_ call: SignalCall) {
owsAssertDebug(call.isGroupCall)
@ -591,6 +596,63 @@ extension CallService: CallObserver {
}
}
// MARK: - Group call participant updates
extension CallService {
func peekCallAndUpdateThread(_ thread: TSGroupThread) {
let groupCall = (currentCall?.isGroupCall == true) ? currentCall?.groupCall : nil
let groupCallConnectionState = groupCall?.localDeviceState.connectionState
guard currentCall?.thread != thread || groupCallConnectionState != .connected else {
// If we're already connected to the group call that we want to peek, ignore
// We'll have PeekInfo updates handed to us directly from an observer callback
Logger.info("Ignoring peek request for currently connected call")
return
}
firstly {
// TODO: Fetch PeekInfo
return .value(PeekInfo())
}.done { info in
self.updateGroupCallMessageWithInfo(info, for: thread)
}.catch { error in
Logger.error("Failed to fetch PeekInfo for \(thread): \(error)")
}
}
fileprivate func updateGroupCallMessageWithInfo(_ info: PeekInfo, for thread: TSGroupThread) {
databaseStorage.write { writeTx in
// TODO: Build InteractionFinder method to find unended OWSGroupCallMessages for the current thread
let results: [OWSGroupCallMessage] = []
// Update everything that doesn't match the current call era to mark as ended
results
.filter { $0.conferenceId != info.eraId }
.forEach { toExpire in
toExpire.anyUpdateGroupCallMessage(transaction: writeTx) { $0.hasCallEnded = true }
}
// Update the message for the current era if it exists, or insert a new one.
let currentEraMessages = results.filter { $0.conferenceId == info.eraId }
owsAssertDebug(currentEraMessages.count <= 1)
if let currentMessage = results.first {
currentMessage.anyUpdateGroupCallMessage(transaction: writeTx) { (toUpdate) in
toUpdate.update(with: info, transaction: writeTx)
}
} else {
// TODO: Plumb through a more relevant timestamp if available
let timestamp = NSDate.ows_millisecondTimeStamp()
let newMessage = OWSGroupCallMessage(peekInfo: info, thread: thread, sentAtTimestamp: timestamp )
newMessage.anyInsert(transaction: writeTx)
}
}
}
}
extension CallService: UIDatabaseSnapshotDelegate {
public func uiDatabaseSnapshotWillUpdate() {}

View File

@ -36,6 +36,10 @@ class GroupCallUpdateMessageHandler: CallServiceObserver, CallObserver {
}
}
func handleUpdateMessage(_ message: SSKProtoDataMessageGroupCallUpdate, for thread: TSGroupThread) {
AppEnvironment.shared.callService.peekCallAndUpdateThread(thread)
}
// MARK: - CallServiceObserver
func didUpdateCall(call: SignalCall?) {

View File

@ -164,4 +164,11 @@ public class WebRTCCallMessageHandler: NSObject, OWSCallMessageHandler {
messageAgeSec: messageAgeSec
)
}
public func receivedGroupCallUpdateMessage(
_ update: SSKProtoDataMessageGroupCallUpdate,
for thread: TSGroupThread) {
self.callService.groupCallMessageHandler.handleUpdateMessage(update, for: thread)
}
}

View File

@ -30,4 +30,8 @@ public class NoopCallMessageHandler: NSObject, OWSCallMessageHandler {
public func receivedOpaque(_ opaque: SSKProtoCallMessageOpaque, from caller: SignalServiceAddress, sourceDevice device: UInt32, serverReceivedTimestamp: UInt64, serverDeliveryTimestamp: UInt64) {
owsFailDebug("")
}
public func receivedGroupCallUpdateMessage(_ update: SSKProtoDataMessageGroupCallUpdate, for thread: TSGroupThread) {
owsFailDebug("")
}
}

View File

@ -1699,6 +1699,19 @@ NS_ASSUME_NONNULL_BEGIN
associatedMessageAuthor:envelope.sourceAddress];
break;
}
} else if (dataMessage.groupCallUpdate != nil) {
TSGroupThread *_Nullable groupThread = nil;
NSData *_Nullable groupId = [self groupIdForDataMessage:dataMessage];
if (groupId) {
groupThread = [TSGroupThread fetchWithGroupId:groupId transaction:transaction];
}
if (groupThread) {
[self.callMessageHandler receivedGroupCallUpdateMessage:dataMessage.groupCallUpdate forThread:groupThread];
} else {
OWSLogError(@"Received GroupCallUpdate for unknown groupId: %@", groupId);
}
} else {
[OWSRecordTranscriptJob
processIncomingSentMessageTranscript:transcript
@ -2137,6 +2150,16 @@ NS_ASSUME_NONNULL_BEGIN
return nil;
}
if (dataMessage.groupCallUpdate) {
if (!thread.isGroupThread) {
OWSLogError(@"Invalid thread for GroupUpdateMessage: %@", thread);
return nil;
}
TSGroupThread *groupThread = (TSGroupThread *)thread;
[self.callMessageHandler receivedGroupCallUpdateMessage:dataMessage.groupCallUpdate
forThread:groupThread];
}
NSString *body = dataMessage.body;
MessageBodyRanges *_Nullable bodyRanges;

View File

@ -10,7 +10,9 @@ NS_ASSUME_NONNULL_BEGIN
@class SSKProtoCallMessageIceUpdate;
@class SSKProtoCallMessageOffer;
@class SSKProtoCallMessageOpaque;
@class SSKProtoDataMessageGroupCallUpdate;
@class SignalServiceAddress;
@class TSGroupThread;
@protocol OWSCallMessageHandler <NSObject>
@ -45,6 +47,10 @@ NS_ASSUME_NONNULL_BEGIN
serverReceivedTimestamp:(uint64_t)serverReceivedTimestamp
serverDeliveryTimestamp:(uint64_t)serverDeliveryTimestamp NS_SWIFT_NAME(receivedOpaque(_:from:sourceDevice:serverReceivedTimestamp:serverDeliveryTimestamp:));
- (void)receivedGroupCallUpdateMessage:(SSKProtoDataMessageGroupCallUpdate *)update
forThread:(TSGroupThread *)groupThread
NS_SWIFT_NAME(receivedGroupCallUpdateMessage(_:for:));
@end
NS_ASSUME_NONNULL_END

View File

@ -59,6 +59,12 @@ NS_ASSUME_NONNULL_BEGIN
OWSLogInfo(@"");
}
- (void)receivedGroupCallUpdateMessage:(SSKProtoDataMessageGroupCallUpdate *)update
forThread:(TSGroupThread *)groupThread
{
OWSLogInfo(@"");
}
@end
#endif