Calls Tab & Group Call Disposition

This commit is contained in:
Jamie Kyle
2023-08-08 17:53:06 -07:00
committed by GitHub
parent 620e85ca01
commit 1eaabb6734
139 changed files with 9182 additions and 2721 deletions

View File

@@ -49,7 +49,7 @@ import { parseIntOrThrow } from '../util/parseIntOrThrow';
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
import { Zone } from '../util/Zone';
import { DurationInSeconds, SECOND } from '../util/durations';
import { bytesToUuid } from '../Crypto';
import { bytesToUuid } from '../util/uuidToBytes';
import type { DownloadedAttachmentType } from '../types/Attachment';
import { Address } from '../types/Address';
import { QualifiedAddress } from '../types/QualifiedAddress';
@@ -88,6 +88,7 @@ import type {
UnprocessedType,
} from './Types.d';
import {
CallEventSyncEvent,
EmptyEvent,
EnvelopeQueuedEvent,
EnvelopeUnsealedEvent,
@@ -113,7 +114,7 @@ import {
ViewSyncEvent,
ContactSyncEvent,
StoryRecipientUpdateEvent,
CallEventSyncEvent,
CallLogEventSyncEvent,
} from './messageReceiverEvents';
import * as log from '../logging/log';
import * as durations from '../util/durations';
@@ -128,6 +129,8 @@ import { isOlderThan } from '../util/timestamp';
import { inspectUnknownFieldTags } from '../util/inspectProtobufs';
import { incrementMessageCounter } from '../util/incrementMessageCounter';
import { filterAndClean } from '../types/BodyRange';
import { getCallEventForProto } from '../util/callDisposition';
import { CallLogEvent } from '../types/CallDisposition';
const GROUPV2_ID_LENGTH = 32;
const RETRY_TIMEOUT = 2 * 60 * 1000;
@@ -640,6 +643,11 @@ export default class MessageReceiver
handler: (ev: CallEventSyncEvent) => void
): void;
public override addEventListener(
name: 'callLogEventSync',
handler: (ev: CallLogEventSyncEvent) => void
): void;
public override addEventListener(name: string, handler: EventHandler): void {
return super.addEventListener(name, handler);
}
@@ -3041,6 +3049,9 @@ export default class MessageReceiver
if (syncMessage.callEvent) {
return this.handleCallEvent(envelope, syncMessage.callEvent);
}
if (syncMessage.callLogEvent) {
return this.handleCallLogEvent(envelope, syncMessage.callLogEvent);
}
this.removeFromCache(envelope);
const envelopeId = getEnvelopeId(envelope);
@@ -3353,57 +3364,16 @@ export default class MessageReceiver
): Promise<void> {
const logId = getEnvelopeId(envelope);
log.info('MessageReceiver.handleCallEvent', logId);
const { peerUuid, callId, type } = callEvent;
if (!peerUuid) {
throw new Error('MessageReceiver.handleCallEvent: missing peerUuid');
}
if (!callId) {
throw new Error('MessageReceiver.handleCallEvent: missing callId');
}
logUnexpectedUrgentValue(envelope, 'callEventSync');
if (
type !== Proto.SyncMessage.CallEvent.Type.VIDEO_CALL &&
type !== Proto.SyncMessage.CallEvent.Type.AUDIO_CALL
) {
log.warn('MessageReceiver.handleCallEvent: unknown call type');
return;
}
const { receivedAtCounter } = envelope;
const peerUuidStr = bytesToUuid(peerUuid);
strictAssert(
peerUuidStr != null,
'MessageReceiver.handleCallEvent: invalid peerUuid'
);
const { receivedAtCounter, timestamp } = envelope;
const wasIncoming =
callEvent.direction === Proto.SyncMessage.CallEvent.Direction.INCOMING;
const wasVideoCall =
callEvent.type === Proto.SyncMessage.CallEvent.Type.VIDEO_CALL;
const wasAccepted =
callEvent.event === Proto.SyncMessage.CallEvent.Event.ACCEPTED;
const wasDeclined =
callEvent.event === Proto.SyncMessage.CallEvent.Event.NOT_ACCEPTED;
const acceptedTime = wasAccepted ? timestamp : undefined;
const endedTime = wasDeclined ? timestamp : undefined;
const callEventDetails = getCallEventForProto(callEvent);
const callEventSync = new CallEventSyncEvent(
{
timestamp: envelope.timestamp,
peerUuid: peerUuidStr,
callId: callId.toString(),
wasIncoming,
wasVideoCall,
wasDeclined,
acceptedTime,
endedTime,
callEventDetails,
receivedAtCounter,
},
this.removeFromCache.bind(this, envelope)
@@ -3413,6 +3383,49 @@ export default class MessageReceiver
log.info('handleCallEvent: finished');
}
private async handleCallLogEvent(
envelope: ProcessedEnvelope,
callLogEvent: Proto.SyncMessage.ICallLogEvent
): Promise<void> {
const logId = getEnvelopeId(envelope);
log.info('MessageReceiver.handleCallLogEvent', logId);
logUnexpectedUrgentValue(envelope, 'callLogEventSync');
const { receivedAtCounter } = envelope;
let event: CallLogEvent;
if (callLogEvent.type == null) {
throw new Error('MessageReceiver.handleCallLogEvent: type was null');
} else if (
callLogEvent.type === Proto.SyncMessage.CallLogEvent.Type.CLEAR
) {
event = CallLogEvent.Clear;
} else {
throw new Error(
`MessageReceiver.handleCallLogEvent: unknown type ${callLogEvent.type}`
);
}
if (callLogEvent.timestamp == null) {
throw new Error('MessageReceiver.handleCallLogEvent: timestamp was null');
}
const timestamp = callLogEvent.timestamp.toNumber();
const callLogEventSync = new CallLogEventSyncEvent(
{
event,
timestamp,
receivedAtCounter,
},
this.removeFromCache.bind(this, envelope)
);
await this.dispatchAndWait(logId, callLogEventSync);
log.info('handleCallLogEvent: finished');
}
private async handleContacts(
envelope: ProcessedEnvelope,
contacts: Proto.SyncMessage.IContacts

View File

@@ -1663,52 +1663,6 @@ export default class MessageSender {
};
}
static getCallEventSync(
peerUuid: string,
callId: string,
isVideoCall: boolean,
isIncoming: boolean,
isAccepted: boolean
): SingleProtoJobData {
const myUuid = window.textsecure.storage.user.getCheckedUuid();
const syncMessage = MessageSender.createSyncMessage();
const type = isVideoCall
? Proto.SyncMessage.CallEvent.Type.VIDEO_CALL
: Proto.SyncMessage.CallEvent.Type.AUDIO_CALL;
const direction = isIncoming
? Proto.SyncMessage.CallEvent.Direction.INCOMING
: Proto.SyncMessage.CallEvent.Direction.OUTGOING;
const event = isAccepted
? Proto.SyncMessage.CallEvent.Event.ACCEPTED
: Proto.SyncMessage.CallEvent.Event.NOT_ACCEPTED;
syncMessage.callEvent = new Proto.SyncMessage.CallEvent({
peerUuid: uuidToBytes(peerUuid),
callId: Long.fromString(callId),
type,
direction,
event,
timestamp: Long.fromNumber(Date.now()),
});
const contentMessage = new Proto.Content();
contentMessage.syncMessage = syncMessage;
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
return {
contentHint: ContentHint.RESENDABLE,
identifier: myUuid.toString(),
isSyncMessage: true,
protoBase64: Bytes.toBase64(
Proto.Content.encode(contentMessage).finish()
),
type: 'callEventSync',
urgent: false,
};
}
static getVerificationSync(
destinationE164: string | undefined,
destinationUuid: string | undefined,

View File

@@ -11,7 +11,7 @@ import type { LoggerType } from '../../types/Logging';
import { strictAssert } from '../../util/assert';
import { UUID_BYTE_SIZE } from '../../types/UUID';
import * as Bytes from '../../Bytes';
import { uuidToBytes, bytesToUuid } from '../../Crypto';
import { uuidToBytes, bytesToUuid } from '../../util/uuidToBytes';
import { SignalService as Proto } from '../../protobuf';
import type {
CDSRequestOptionsType,

View File

@@ -12,6 +12,7 @@ import type {
ProcessedSent,
} from './Types.d';
import type { ModifiedContactDetails } from './ContactsParser';
import type { CallEventDetails, CallLogEvent } from '../types/CallDisposition';
export class EmptyEvent extends Event {
constructor() {
@@ -404,14 +405,7 @@ export class ViewSyncEvent extends ConfirmableEvent {
}
export type CallEventSyncEventData = Readonly<{
timestamp: number;
peerUuid: string;
callId: string;
wasVideoCall: boolean;
wasIncoming: boolean;
wasDeclined: boolean;
acceptedTime: number | undefined;
endedTime: number | undefined;
callEventDetails: CallEventDetails;
receivedAtCounter: number;
}>;
@@ -424,6 +418,21 @@ export class CallEventSyncEvent extends ConfirmableEvent {
}
}
export type CallLogEventSyncEventData = Readonly<{
event: CallLogEvent;
timestamp: number;
receivedAtCounter: number;
}>;
export class CallLogEventSyncEvent extends ConfirmableEvent {
constructor(
public readonly callLogEvent: CallLogEventSyncEventData,
confirm: ConfirmCallback
) {
super('callLogEventSync', confirm);
}
}
export type StoryRecipientUpdateData = Readonly<{
destinationUuid: string;
storyMessageRecipients: Array<Proto.SyncMessage.Sent.IStoryMessageRecipient>;