@signalapp/ringrtc 2.25.1 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,22 +36,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
36
36
  });
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.CallLogLevel = exports.CallEndedReason = exports.CallState = exports.RingCancelReason = exports.BandwidthMode = exports.HangupType = exports.OpaqueMessage = exports.HangupMessage = exports.BusyMessage = exports.IceCandidateMessage = exports.AnswerMessage = exports.OfferType = exports.OfferMessage = exports.CallingMessage = exports.GroupCall = exports.VideoRequest = exports.GroupMemberInfo = exports.RemoteDeviceState = exports.LocalDeviceState = exports.HttpMethod = exports.RingUpdate = exports.CallMessageUrgency = exports.GroupCallEndReason = exports.JoinState = exports.ConnectionState = exports.Call = exports.RingRTCType = exports.ReceivedAudioLevel = exports.NetworkRoute = exports.PeekInfo = exports.PeekDeviceInfo = void 0;
40
- /* tslint:disable max-classes-per-file */
39
+ exports.CallLogLevel = exports.CallEndedReason = exports.CallState = exports.RingCancelReason = exports.BandwidthMode = exports.HangupType = exports.OpaqueMessage = exports.HangupMessage = exports.BusyMessage = exports.IceCandidateMessage = exports.AnswerMessage = exports.OfferType = exports.OfferMessage = exports.CallingMessage = exports.GroupCall = exports.VideoRequest = exports.GroupMemberInfo = exports.RemoteDeviceState = exports.LocalDeviceState = exports.HttpMethod = exports.RingUpdate = exports.CallMessageUrgency = exports.GroupCallEndReason = exports.JoinState = exports.ConnectionState = exports.Call = exports.RingRTCType = exports.ReceivedAudioLevel = exports.NetworkRoute = exports.PeekInfo = exports.PeekDeviceInfo = exports.callIdFromRingId = exports.callIdFromEra = void 0;
40
+ /* eslint-disable max-classes-per-file */
41
41
  const os = __importStar(require("os"));
42
42
  const process = __importStar(require("process"));
43
- // tslint:disable-next-line no-var-requires no-require-imports
44
- const Native = require('../../build/' +
45
- os.platform() +
46
- '/libringrtc-' +
47
- process.arch +
48
- '.node');
43
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require
44
+ const Native = require(`../../build/${os.platform()}/libringrtc-${process.arch}.node`);
45
+ exports.callIdFromEra = Native.callIdFromEra;
46
+ function callIdFromRingId(ringId) {
47
+ return {
48
+ low: Number(BigInt.asIntN(32, ringId)),
49
+ high: Number(BigInt.asIntN(32, ringId >> BigInt(32))),
50
+ unsigned: true,
51
+ };
52
+ }
53
+ exports.callIdFromRingId = callIdFromRingId;
49
54
  class Config {
50
55
  constructor() {
51
56
  this.use_new_audio_device_module = false;
52
57
  }
53
58
  }
54
- // tslint:disable-next-line no-unnecessary-class
55
59
  class NativeCallManager {
56
60
  constructor(observer) {
57
61
  this.observer = observer;
@@ -61,9 +65,11 @@ class NativeCallManager {
61
65
  this.createCallEndpoint(config);
62
66
  }
63
67
  createCallEndpoint(config) {
68
+ /* eslint-disable prefer-template */
64
69
  const fieldTrialsString = Object.entries(config.field_trials || {})
65
70
  .map(([k, v]) => `${k}/${v}`)
66
71
  .join('/') + '/';
72
+ /* eslint-enable prefer-template */
67
73
  Object.defineProperty(this, Native.callEndpointPropertyKey, {
68
74
  configurable: true,
69
75
  get() {
@@ -71,12 +77,13 @@ class NativeCallManager {
71
77
  if (process.platform === 'darwin') {
72
78
  // Preload devices to work around
73
79
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1287628
74
- window.navigator.mediaDevices.enumerateDevices();
80
+ void window.navigator.mediaDevices.enumerateDevices();
75
81
  }
76
82
  Object.defineProperty(this, Native.callEndpointPropertyKey, {
77
83
  configurable: true,
78
84
  value: callEndpoint,
79
85
  });
86
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
80
87
  return callEndpoint;
81
88
  },
82
89
  });
@@ -242,7 +249,10 @@ class CallInfo {
242
249
  class RingRTCType {
243
250
  getCallInfoKey(callId) {
244
251
  // CallId is u64 so use a string key instead.
245
- return callId.high.toString() + callId.low.toString();
252
+ // Note that the representation is not padded, so we include a separator.
253
+ // Otherwise {1, 123} and {11, 23} would have the same key.
254
+ // (We could use Long.toString as well, but it doesn't matter what the key is.)
255
+ return `${callId.high} ${callId.low}`;
246
256
  }
247
257
  constructor() {
248
258
  // Set by UX
@@ -281,7 +291,7 @@ class RingRTCType {
281
291
  }
282
292
  // Called by UX
283
293
  cancelGroupRing(groupId, ringId, reason) {
284
- silly_deadlock_protection(() => {
294
+ sillyDeadlockProtection(() => {
285
295
  this.callManager.cancelGroupRing(groupId, ringId.toString(), reason);
286
296
  });
287
297
  }
@@ -305,7 +315,7 @@ class RingRTCType {
305
315
  }
306
316
  })
307
317
  .catch(e => {
308
- this.logError('RingRTC.handleStartCall exception: ' + e.toString());
318
+ this.logError(`RingRTC.handleStartCall exception: ${e}`);
309
319
  call.ignore();
310
320
  });
311
321
  }
@@ -331,8 +341,7 @@ class RingRTCType {
331
341
  }
332
342
  const isIncoming = true;
333
343
  const call = new Call(this.callManager, remoteUserId, callId, isIncoming, isVideoCall, CallState.Prering);
334
- const handleIncomingCall = this.handleIncomingCall;
335
- const handleStartCall = this.handleStartCall;
344
+ const { handleIncomingCall, handleStartCall } = this;
336
345
  if (!handleIncomingCall || !handleStartCall) {
337
346
  call.ignore();
338
347
  return;
@@ -346,25 +355,25 @@ class RingRTCType {
346
355
  }
347
356
  else {
348
357
  handleStartCall(call)
349
- .then(success => {
350
- if (!success) {
358
+ .then(innerSuccess => {
359
+ if (!innerSuccess) {
351
360
  this.logWarn('RingRTC.handleStartCall failed for incoming call. Call ignored.');
352
361
  call.ignore();
353
362
  }
354
363
  })
355
364
  .catch(e => {
356
- this.logError('RingRTC.handleStartCall exception: ' + e.toString());
365
+ this.logError(`RingRTC.handleStartCall exception: ${e}`);
357
366
  call.ignore();
358
367
  });
359
368
  }
360
369
  })
361
370
  .catch(e => {
362
- this.logError('RingRTC.handleIncomingCall exception: ' + e.toString());
371
+ this.logError(`RingRTC.handleIncomingCall exception: ${e}`);
363
372
  call.ignore();
364
373
  });
365
374
  }
366
375
  proceed(callId, settings) {
367
- silly_deadlock_protection(() => {
376
+ sillyDeadlockProtection(() => {
368
377
  this.callManager.proceed(callId, settings.iceServer.username || '', settings.iceServer.password || '', settings.iceServer.urls, settings.hideIp, settings.bandwidthMode, settings.audioLevelsIntervalMillis || 0);
369
378
  });
370
379
  }
@@ -378,7 +387,7 @@ class RingRTCType {
378
387
  }
379
388
  // Called by Rust
380
389
  onCallEnded(remoteUserId, callId, reason, ageSec) {
381
- let callInfo = this._callInfoByCallId.get(this.getCallInfoKey(callId));
390
+ const callInfo = this._callInfoByCallId.get(this.getCallInfoKey(callId));
382
391
  const { isVideoCall, receivedAtCounter } = callInfo || {
383
392
  isVideoCall: false,
384
393
  receivedAtCounter: undefined,
@@ -472,7 +481,7 @@ class RingRTCType {
472
481
  if (!call) {
473
482
  return;
474
483
  }
475
- if (!!((_a = this._call) === null || _a === void 0 ? void 0 : _a.renderVideoFrame)) {
484
+ if ((_a = this._call) === null || _a === void 0 ? void 0 : _a.renderVideoFrame) {
476
485
  (_b = this._call) === null || _b === void 0 ? void 0 : _b.renderVideoFrame(width, height, buffer);
477
486
  }
478
487
  }
@@ -522,10 +531,12 @@ class RingRTCType {
522
531
  this.sendSignaling(remoteUserId, remoteDeviceId, callId, broadcast, message);
523
532
  }
524
533
  sendSignaling(remoteUserId, remoteDeviceId, callId, broadcast, message) {
534
+ /* eslint-disable no-param-reassign */
525
535
  message.supportsMultiRing = true;
526
536
  if (!broadcast) {
527
537
  message.destinationDeviceId = remoteDeviceId;
528
538
  }
539
+ /* eslint-enable no-param-reassign */
529
540
  (() => __awaiter(this, void 0, void 0, function* () {
530
541
  if (this.handleOutgoingSignaling) {
531
542
  const signalingResult = yield this.handleOutgoingSignaling(remoteUserId, message);
@@ -539,10 +550,10 @@ class RingRTCType {
539
550
  else {
540
551
  this.callManager.signalingMessageSendFailed(callId);
541
552
  }
542
- }))();
553
+ }))().catch(e => this.logError(e.toString()));
543
554
  }
544
555
  receivedHttpResponse(requestId, status, body) {
545
- silly_deadlock_protection(() => {
556
+ sillyDeadlockProtection(() => {
546
557
  try {
547
558
  this.callManager.receivedHttpResponse(requestId, status, body);
548
559
  }
@@ -553,7 +564,7 @@ class RingRTCType {
553
564
  });
554
565
  }
555
566
  httpRequestFailed(requestId, debugInfo) {
556
- silly_deadlock_protection(() => {
567
+ sillyDeadlockProtection(() => {
557
568
  try {
558
569
  this.callManager.httpRequestFailed(requestId, debugInfo);
559
570
  }
@@ -573,19 +584,18 @@ class RingRTCType {
573
584
  // Called by UX
574
585
  // Returns a list of user IDs
575
586
  peekGroupCall(sfuUrl, membershipProof, groupMembers) {
576
- let [requestId, promise] = this._peekRequests.add();
587
+ const [requestId, promise] = this._peekRequests.add();
577
588
  // Response comes back via handlePeekResponse
578
- silly_deadlock_protection(() => {
589
+ sillyDeadlockProtection(() => {
579
590
  this.callManager.peekGroupCall(requestId, sfuUrl, membershipProof, groupMembers);
580
591
  });
581
592
  return promise;
582
593
  }
583
594
  // Called by Rust
584
595
  requestMembershipProof(clientId) {
585
- silly_deadlock_protection(() => {
586
- let groupCall = this._groupCallByClientId.get(clientId);
596
+ sillyDeadlockProtection(() => {
597
+ const groupCall = this._groupCallByClientId.get(clientId);
587
598
  if (!groupCall) {
588
- let error = new Error();
589
599
  this.logError('requestMembershipProof(): GroupCall not found in map!');
590
600
  return;
591
601
  }
@@ -594,10 +604,9 @@ class RingRTCType {
594
604
  }
595
605
  // Called by Rust
596
606
  requestGroupMembers(clientId) {
597
- silly_deadlock_protection(() => {
598
- let groupCall = this._groupCallByClientId.get(clientId);
607
+ sillyDeadlockProtection(() => {
608
+ const groupCall = this._groupCallByClientId.get(clientId);
599
609
  if (!groupCall) {
600
- let error = new Error();
601
610
  this.logError('requestGroupMembers(): GroupCall not found in map!');
602
611
  return;
603
612
  }
@@ -606,10 +615,9 @@ class RingRTCType {
606
615
  }
607
616
  // Called by Rust
608
617
  handleConnectionStateChanged(clientId, connectionState) {
609
- silly_deadlock_protection(() => {
610
- let groupCall = this._groupCallByClientId.get(clientId);
618
+ sillyDeadlockProtection(() => {
619
+ const groupCall = this._groupCallByClientId.get(clientId);
611
620
  if (!groupCall) {
612
- let error = new Error();
613
621
  this.logError('handleConnectionStateChanged(): GroupCall not found in map!');
614
622
  return;
615
623
  }
@@ -618,10 +626,9 @@ class RingRTCType {
618
626
  }
619
627
  // Called by Rust
620
628
  handleJoinStateChanged(clientId, joinState, demuxId) {
621
- silly_deadlock_protection(() => {
622
- let groupCall = this._groupCallByClientId.get(clientId);
629
+ sillyDeadlockProtection(() => {
630
+ const groupCall = this._groupCallByClientId.get(clientId);
623
631
  if (!groupCall) {
624
- let error = new Error();
625
632
  this.logError('handleJoinStateChanged(): GroupCall not found in map!');
626
633
  return;
627
634
  }
@@ -630,8 +637,8 @@ class RingRTCType {
630
637
  }
631
638
  // Called by Rust
632
639
  handleNetworkRouteChanged(clientId, localNetworkAdapterType) {
633
- silly_deadlock_protection(() => {
634
- let groupCall = this._groupCallByClientId.get(clientId);
640
+ sillyDeadlockProtection(() => {
641
+ const groupCall = this._groupCallByClientId.get(clientId);
635
642
  if (!groupCall) {
636
643
  this.logError('handleNetworkRouteChanged(): GroupCall not found in map!');
637
644
  return;
@@ -641,19 +648,18 @@ class RingRTCType {
641
648
  }
642
649
  // Called by Rust
643
650
  handleAudioLevels(clientId, capturedLevel, receivedLevels) {
644
- silly_deadlock_protection(() => {
645
- let groupCall = this._groupCallByClientId.get(clientId);
646
- if (!!groupCall) {
651
+ sillyDeadlockProtection(() => {
652
+ const groupCall = this._groupCallByClientId.get(clientId);
653
+ if (groupCall) {
647
654
  groupCall.handleAudioLevels(capturedLevel, receivedLevels);
648
655
  }
649
656
  });
650
657
  }
651
658
  // Called by Rust
652
659
  handleRemoteDevicesChanged(clientId, remoteDeviceStates) {
653
- silly_deadlock_protection(() => {
654
- let groupCall = this._groupCallByClientId.get(clientId);
660
+ sillyDeadlockProtection(() => {
661
+ const groupCall = this._groupCallByClientId.get(clientId);
655
662
  if (!groupCall) {
656
- let error = new Error();
657
663
  this.logError('handleRemoteDevicesChanged(): GroupCall not found in map!');
658
664
  return;
659
665
  }
@@ -662,10 +668,9 @@ class RingRTCType {
662
668
  }
663
669
  // Called by Rust
664
670
  handlePeekChanged(clientId, info) {
665
- silly_deadlock_protection(() => {
666
- let groupCall = this._groupCallByClientId.get(clientId);
671
+ sillyDeadlockProtection(() => {
672
+ const groupCall = this._groupCallByClientId.get(clientId);
667
673
  if (!groupCall) {
668
- let error = new Error();
669
674
  this.logError('handlePeekChanged(): GroupCall not found in map!');
670
675
  return;
671
676
  }
@@ -673,19 +678,18 @@ class RingRTCType {
673
678
  });
674
679
  }
675
680
  // Called by Rust
676
- handlePeekResponse(request_id, info) {
677
- silly_deadlock_protection(() => {
678
- if (!this._peekRequests.resolve(request_id, info)) {
679
- this.logWarn(`Invalid request ID for handlePeekResponse: ${request_id}`);
681
+ handlePeekResponse(requestId, info) {
682
+ sillyDeadlockProtection(() => {
683
+ if (!this._peekRequests.resolve(requestId, info)) {
684
+ this.logWarn(`Invalid request ID for handlePeekResponse: ${requestId}`);
680
685
  }
681
686
  });
682
687
  }
683
688
  // Called by Rust
684
689
  handleEnded(clientId, reason) {
685
- silly_deadlock_protection(() => {
686
- let groupCall = this._groupCallByClientId.get(clientId);
690
+ sillyDeadlockProtection(() => {
691
+ const groupCall = this._groupCallByClientId.get(clientId);
687
692
  if (!groupCall) {
688
- let error = new Error();
689
693
  this.logError('handleEnded(): GroupCall not found in map!');
690
694
  return;
691
695
  }
@@ -695,7 +699,7 @@ class RingRTCType {
695
699
  }
696
700
  // Called by Rust
697
701
  groupCallRingUpdate(groupId, ringIdString, sender, state) {
698
- silly_deadlock_protection(() => {
702
+ sillyDeadlockProtection(() => {
699
703
  if (this.handleGroupCallRingUpdate) {
700
704
  const ringId = BigInt(ringIdString);
701
705
  this.handleGroupCallRingUpdate(groupId, ringId, sender, state);
@@ -724,16 +728,16 @@ class RingRTCType {
724
728
  this.onLogMessage(CallLogLevel.Info, 'Service.ts', 0, message);
725
729
  }
726
730
  // Called by MessageReceiver
727
- // tslint:disable-next-line cyclomatic-complexity
728
731
  handleCallingMessage(remoteUserId, remoteUuid, remoteDeviceId, localDeviceId, messageAgeSec, messageReceivedAtCounter, message, senderIdentityKey, receiverIdentityKey) {
732
+ var _a, _b, _c, _d, _e;
729
733
  if (message.destinationDeviceId &&
730
734
  message.destinationDeviceId !== localDeviceId) {
731
735
  // Drop the message as it isn't for this device, handleIgnoredCall() is not needed.
732
736
  return;
733
737
  }
734
- if (message.offer && message.offer.callId) {
738
+ if ((_a = message.offer) === null || _a === void 0 ? void 0 : _a.callId) {
735
739
  const callId = message.offer.callId;
736
- const opaque = to_buffer(message.offer.opaque);
740
+ const opaque = toBuffer(message.offer.opaque);
737
741
  // opaque is required. sdp is obsolete, but it might still come with opaque.
738
742
  if (!opaque) {
739
743
  // TODO: Remove once the proto is updated to only support opaque and require it.
@@ -742,13 +746,13 @@ class RingRTCType {
742
746
  }
743
747
  const offerType = message.offer.type || OfferType.AudioCall;
744
748
  // Save the call details for later when the call is ended.
745
- let callInfo = new CallInfo(offerType === OfferType.VideoCall, messageReceivedAtCounter);
749
+ const callInfo = new CallInfo(offerType === OfferType.VideoCall, messageReceivedAtCounter);
746
750
  this._callInfoByCallId.set(this.getCallInfoKey(callId), callInfo);
747
751
  this.callManager.receivedOffer(remoteUserId, remoteDeviceId, localDeviceId, messageAgeSec, callId, offerType, opaque, senderIdentityKey, receiverIdentityKey);
748
752
  }
749
- if (message.answer && message.answer.callId) {
753
+ if ((_b = message.answer) === null || _b === void 0 ? void 0 : _b.callId) {
750
754
  const callId = message.answer.callId;
751
- const opaque = to_buffer(message.answer.opaque);
755
+ const opaque = toBuffer(message.answer.opaque);
752
756
  // opaque is required. sdp is obsolete, but it might still come with opaque.
753
757
  if (!opaque) {
754
758
  // TODO: Remove once the proto is updated to only support opaque and require it.
@@ -759,11 +763,11 @@ class RingRTCType {
759
763
  }
760
764
  if (message.iceCandidates && message.iceCandidates.length > 0) {
761
765
  // We assume they all have the same .callId
762
- let callId = message.iceCandidates[0].callId;
766
+ const callId = message.iceCandidates[0].callId;
763
767
  // We have to copy them to do the .toArrayBuffer() thing.
764
768
  const candidates = [];
765
769
  for (const candidate of message.iceCandidates) {
766
- const copy = to_buffer(candidate.opaque);
770
+ const copy = toBuffer(candidate.opaque);
767
771
  if (copy) {
768
772
  candidates.push(copy);
769
773
  }
@@ -777,21 +781,25 @@ class RingRTCType {
777
781
  this.logWarn('handleCallingMessage(): No ice candidates in ice message, remote should update');
778
782
  return;
779
783
  }
784
+ if (!callId) {
785
+ this.logWarn('handleCallingMessage(): No call ID in ice message');
786
+ return;
787
+ }
780
788
  this.callManager.receivedIceCandidates(remoteUserId, remoteDeviceId, callId, candidates);
781
789
  }
782
- if (message.hangup && message.hangup.callId) {
790
+ if ((_c = message.hangup) === null || _c === void 0 ? void 0 : _c.callId) {
783
791
  const callId = message.hangup.callId;
784
792
  const hangupType = message.hangup.type || HangupType.Normal;
785
793
  const hangupDeviceId = message.hangup.deviceId || null;
786
794
  this.callManager.receivedHangup(remoteUserId, remoteDeviceId, callId, hangupType, hangupDeviceId);
787
795
  }
788
- if (message.legacyHangup && message.legacyHangup.callId) {
796
+ if ((_d = message.legacyHangup) === null || _d === void 0 ? void 0 : _d.callId) {
789
797
  const callId = message.legacyHangup.callId;
790
798
  const hangupType = message.legacyHangup.type || HangupType.Normal;
791
799
  const hangupDeviceId = message.legacyHangup.deviceId || null;
792
800
  this.callManager.receivedHangup(remoteUserId, remoteDeviceId, callId, hangupType, hangupDeviceId);
793
801
  }
794
- if (message.busy && message.busy.callId) {
802
+ if ((_e = message.busy) === null || _e === void 0 ? void 0 : _e.callId) {
795
803
  const callId = message.busy.callId;
796
804
  this.callManager.receivedBusy(remoteUserId, remoteDeviceId, callId);
797
805
  }
@@ -800,7 +808,7 @@ class RingRTCType {
800
808
  this.logError('handleCallingMessage(): opaque message received without UUID!');
801
809
  return;
802
810
  }
803
- const data = to_buffer(message.opaque.data);
811
+ const data = toBuffer(message.opaque.data);
804
812
  if (data == undefined) {
805
813
  this.logError('handleCallingMessage(): opaque message received without data!');
806
814
  return;
@@ -840,10 +848,10 @@ class RingRTCType {
840
848
  return this._call;
841
849
  }
842
850
  getCall(callId) {
843
- const { call } = this;
851
+ const call = this.call;
844
852
  if (call &&
845
853
  call.callId.high === callId.high &&
846
- call.callId.low === call.callId.low) {
854
+ call.callId.low === callId.low) {
847
855
  return call;
848
856
  }
849
857
  return null;
@@ -965,7 +973,7 @@ class Call {
965
973
  this._state = state;
966
974
  this.enableOrDisableCapturer();
967
975
  this.enableOrDisableRenderer();
968
- if (!!this.handleStateChanged) {
976
+ if (this.handleStateChanged) {
969
977
  this.handleStateChanged();
970
978
  }
971
979
  }
@@ -999,7 +1007,7 @@ class Call {
999
1007
  this._videoRenderer.disable();
1000
1008
  }
1001
1009
  // This assumes we only have one active call.
1002
- silly_deadlock_protection(() => {
1010
+ sillyDeadlockProtection(() => {
1003
1011
  this._callManager.hangup();
1004
1012
  });
1005
1013
  }
@@ -1009,7 +1017,7 @@ class Call {
1009
1017
  set outgoingAudioEnabled(enabled) {
1010
1018
  this._outgoingAudioEnabled = enabled;
1011
1019
  // This assumes we only have one active call.
1012
- silly_deadlock_protection(() => {
1020
+ sillyDeadlockProtection(() => {
1013
1021
  this._callManager.setOutgoingAudioEnabled(enabled);
1014
1022
  });
1015
1023
  }
@@ -1023,7 +1031,7 @@ class Call {
1023
1031
  set outgoingVideoIsScreenShare(isScreenShare) {
1024
1032
  // This assumes we only have one active call.
1025
1033
  this._outgoingVideoIsScreenShare = isScreenShare;
1026
- silly_deadlock_protection(() => {
1034
+ sillyDeadlockProtection(() => {
1027
1035
  this._callManager.setOutgoingVideoIsScreenShare(isScreenShare);
1028
1036
  });
1029
1037
  }
@@ -1079,7 +1087,7 @@ class Call {
1079
1087
  }
1080
1088
  }
1081
1089
  setOutgoingVideoEnabled(enabled) {
1082
- silly_deadlock_protection(() => {
1090
+ sillyDeadlockProtection(() => {
1083
1091
  try {
1084
1092
  this._callManager.setOutgoingVideoEnabled(enabled);
1085
1093
  }
@@ -1090,7 +1098,7 @@ class Call {
1090
1098
  });
1091
1099
  }
1092
1100
  updateBandwidthMode(bandwidthMode) {
1093
- silly_deadlock_protection(() => {
1101
+ sillyDeadlockProtection(() => {
1094
1102
  try {
1095
1103
  this._callManager.updateBandwidthMode(bandwidthMode);
1096
1104
  }
@@ -1354,7 +1362,7 @@ class GroupCall {
1354
1362
  this._localDeviceState.audioLevel = normalizeAudioLevel(capturedLevel);
1355
1363
  if (this._remoteDeviceStates != undefined) {
1356
1364
  for (const received of receivedLevels) {
1357
- for (let remoteDeviceState of this._remoteDeviceStates) {
1365
+ for (const remoteDeviceState of this._remoteDeviceStates) {
1358
1366
  if (remoteDeviceState.demuxId == received.demuxId) {
1359
1367
  remoteDeviceState.audioLevel = normalizeAudioLevel(received.level);
1360
1368
  }
@@ -1415,14 +1423,14 @@ class GroupCallVideoFrameSource {
1415
1423
  receiveVideoFrame(buffer, maxWidth, maxHeight) {
1416
1424
  // This assumes we only have one active call.
1417
1425
  const frame = this._callManager.receiveGroupCallVideoFrame(this._groupCall.clientId, this._remoteDemuxId, buffer, maxWidth, maxHeight);
1418
- if (!!frame) {
1426
+ if (frame) {
1419
1427
  const [width, height] = frame;
1420
1428
  this._groupCall.setRemoteAspectRatio(this._remoteDemuxId, width / height);
1421
1429
  }
1422
1430
  return frame;
1423
1431
  }
1424
1432
  }
1425
- function to_buffer(pbab) {
1433
+ function toBuffer(pbab) {
1426
1434
  if (!pbab) {
1427
1435
  return pbab;
1428
1436
  }
@@ -1516,12 +1524,12 @@ var CallLogLevel;
1516
1524
  CallLogLevel[CallLogLevel["Debug"] = 4] = "Debug";
1517
1525
  CallLogLevel[CallLogLevel["Trace"] = 5] = "Trace";
1518
1526
  })(CallLogLevel = exports.CallLogLevel || (exports.CallLogLevel = {}));
1519
- function silly_deadlock_protection(f) {
1520
- // tslint:disable no-floating-promises
1521
- (() => __awaiter(this, void 0, void 0, function* () {
1527
+ function sillyDeadlockProtection(f) {
1528
+ void (() => __awaiter(this, void 0, void 0, function* () {
1522
1529
  // This is a silly way of preventing a deadlock.
1523
- // tslint:disable-next-line await-promise
1530
+ // eslint-disable-next-line @typescript-eslint/await-thenable
1524
1531
  yield 0;
1525
1532
  f();
1526
1533
  }))();
1527
1534
  }
1535
+ //# sourceMappingURL=Service.js.map
@@ -46,7 +46,7 @@ export declare class GumVideoCapturer {
46
46
  enableCaptureAndSend(sender: VideoFrameSender, options?: GumVideoCaptureOptions): void;
47
47
  disable(): void;
48
48
  setPreferredDevice(deviceId: string): Promise<void>;
49
- enumerateDevices(): Promise<MediaDeviceInfo[]>;
49
+ enumerateDevices(): Promise<Array<MediaDeviceInfo>>;
50
50
  private getUserMedia;
51
51
  private startCapturing;
52
52
  private stopCapturing;
@@ -22,6 +22,7 @@ var VideoPixelFormatEnum;
22
22
  VideoPixelFormatEnum[VideoPixelFormatEnum["Nv12"] = 1] = "Nv12";
23
23
  VideoPixelFormatEnum[VideoPixelFormatEnum["Rgba"] = 2] = "Rgba";
24
24
  })(VideoPixelFormatEnum = exports.VideoPixelFormatEnum || (exports.VideoPixelFormatEnum = {}));
25
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
26
  function videoPixelFormatFromEnum(format) {
26
27
  switch (format) {
27
28
  case VideoPixelFormatEnum.I420: {
@@ -82,11 +83,11 @@ class GumVideoCapturer {
82
83
  this.updateLocalPreviewIntervalId = setInterval(this.updateLocalPreviewSourceObject.bind(this), 1000);
83
84
  }
84
85
  enableCapture() {
85
- // tslint:disable no-floating-promises
86
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
86
87
  this.startCapturing(this.defaultCaptureOptions);
87
88
  }
88
89
  enableCaptureAndSend(sender, options) {
89
- // tslint:disable no-floating-promises
90
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
90
91
  this.startCapturing(options !== null && options !== void 0 ? options : this.defaultCaptureOptions);
91
92
  this.startSending(sender);
92
93
  }
@@ -98,13 +99,14 @@ class GumVideoCapturer {
98
99
  }
99
100
  this.updateLocalPreviewIntervalId = undefined;
100
101
  }
102
+ // eslint-disable-next-line @typescript-eslint/require-await
101
103
  setPreferredDevice(deviceId) {
102
104
  return __awaiter(this, void 0, void 0, function* () {
103
105
  this.preferredDeviceId = deviceId;
104
106
  if (this.captureOptions) {
105
- const captureOptions = this.captureOptions;
106
- const sender = this.sender;
107
+ const { captureOptions, sender } = this;
107
108
  this.disable();
109
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
108
110
  this.startCapturing(captureOptions);
109
111
  if (sender) {
110
112
  this.startSending(sender);
@@ -122,7 +124,7 @@ class GumVideoCapturer {
122
124
  getUserMedia(options) {
123
125
  var _a;
124
126
  // TODO: Figure out a better way to make typescript accept "mandatory".
125
- let constraints = {
127
+ const constraints = {
126
128
  audio: false,
127
129
  video: {
128
130
  deviceId: (_a = options.preferredDeviceId) !== null && _a !== void 0 ? _a : this.preferredDeviceId,
@@ -203,7 +205,7 @@ class GumVideoCapturer {
203
205
  }
204
206
  index_1.RingRTC.logInfo('stopCapturing()');
205
207
  this.captureOptions = undefined;
206
- if (!!this.mediaStream) {
208
+ if (this.mediaStream) {
207
209
  for (const track of this.mediaStream.getVideoTracks()) {
208
210
  // Make the light turn off faster
209
211
  track.stop();
@@ -216,7 +218,7 @@ class GumVideoCapturer {
216
218
  if (this.sender === sender) {
217
219
  return;
218
220
  }
219
- if (!!this.sender) {
221
+ if (this.sender) {
220
222
  // If we're replacing an existing sender, make sure we stop the
221
223
  // current setInterval loop before starting another one.
222
224
  this.stopSending();
@@ -233,7 +235,7 @@ class GumVideoCapturer {
233
235
  }
234
236
  if (track.readyState === 'ended') {
235
237
  this.stopCapturing();
236
- index_1.RingRTC.logError(`spawnSender(): Video track ended before spawning sender`);
238
+ index_1.RingRTC.logError('spawnSender(): Video track ended before spawning sender');
237
239
  return;
238
240
  }
239
241
  const reader = new MediaStreamTrackProcessor({
@@ -241,10 +243,11 @@ class GumVideoCapturer {
241
243
  }).readable.getReader();
242
244
  const buffer = Buffer.alloc(exports.MAX_VIDEO_CAPTURE_BUFFER_SIZE);
243
245
  this.spawnedSenderRunning = true;
246
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
244
247
  (() => __awaiter(this, void 0, void 0, function* () {
245
248
  var _a;
246
249
  try {
247
- while (sender === this.sender && mediaStream == this.mediaStream) {
250
+ while (mediaStream == this.mediaStream) {
248
251
  const { done, value: frame } = yield reader.read();
249
252
  if (done) {
250
253
  break;
@@ -258,7 +261,10 @@ class GumVideoCapturer {
258
261
  index_1.RingRTC.logWarn(`Unsupported video frame format: ${frame.format}`);
259
262
  break;
260
263
  }
261
- frame.copyTo(buffer);
264
+ yield frame.copyTo(buffer);
265
+ if (sender !== this.sender) {
266
+ break;
267
+ }
262
268
  sender.sendVideoFrame(frame.codedWidth, frame.codedHeight, format, buffer);
263
269
  }
264
270
  catch (e) {
@@ -295,7 +301,7 @@ class GumVideoCapturer {
295
301
  if (localPreview.srcObject === mediaStream) {
296
302
  return;
297
303
  }
298
- if (mediaStream) {
304
+ if (mediaStream && this.captureOptions) {
299
305
  localPreview.srcObject = mediaStream;
300
306
  if (localPreview.width === 0) {
301
307
  localPreview.width = this.captureOptions.maxWidth;
@@ -327,7 +333,7 @@ class CanvasVideoRenderer {
327
333
  if (this.source === source) {
328
334
  return;
329
335
  }
330
- if (!!this.source) {
336
+ if (this.source) {
331
337
  // If we're replacing an existing source, make sure we stop the
332
338
  // current rAF loop before starting another one.
333
339
  if (this.rafId) {
@@ -420,3 +426,4 @@ class CanvasVideoRenderer {
420
426
  }
421
427
  }
422
428
  exports.CanvasVideoRenderer = CanvasVideoRenderer;
429
+ //# sourceMappingURL=VideoSupport.js.map