Calls Tab & Group Call Disposition
This commit is contained in:
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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>;
|
||||
|
Reference in New Issue
Block a user