expo-callkit-telecom 0.2.0 → 0.2.2

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.
Files changed (19) hide show
  1. package/README.md +11 -0
  2. package/android/src/main/java/expo/modules/callkittelecom/ExpoCallKitTelecomModule.kt +254 -282
  3. package/android/src/main/java/expo/modules/callkittelecom/IncomingCallActivity.kt +27 -34
  4. package/android/src/main/java/expo/modules/callkittelecom/events/CallEventEmitter.kt +21 -32
  5. package/android/src/main/java/expo/modules/callkittelecom/managers/CallAudioManager.kt +53 -74
  6. package/android/src/main/java/expo/modules/callkittelecom/managers/CallManager.kt +95 -156
  7. package/android/src/main/java/expo/modules/callkittelecom/managers/CallNotificationManager.kt +71 -84
  8. package/android/src/main/java/expo/modules/callkittelecom/managers/CaptureSessionManager.kt +1 -3
  9. package/android/src/main/java/expo/modules/callkittelecom/managers/DialtonePlayer.kt +6 -4
  10. package/android/src/main/java/expo/modules/callkittelecom/managers/FulfillRequestManager.kt +21 -21
  11. package/android/src/main/java/expo/modules/callkittelecom/managers/VoIPPushManager.kt +3 -5
  12. package/android/src/main/java/expo/modules/callkittelecom/models/CallModels.kt +28 -36
  13. package/android/src/main/java/expo/modules/callkittelecom/services/CallNotificationReceiver.kt +7 -8
  14. package/android/src/main/java/expo/modules/callkittelecom/services/ExpoCallKitTelecomMessagingService.kt +9 -16
  15. package/android/src/main/java/expo/modules/callkittelecom/store/CallStore.kt +32 -68
  16. package/android/src/main/java/expo/modules/callkittelecom/utils/CallKitTelecomLog.kt +6 -17
  17. package/android/src/main/java/expo/modules/callkittelecom/utils/PermissionUtils.kt +7 -7
  18. package/ios/Managers/CaptureSessionManager.swift +1 -1
  19. package/package.json +1 -1
@@ -27,6 +27,9 @@ import expo.modules.callkittelecom.models.CallSessionStatus
27
27
  import expo.modules.callkittelecom.models.IncomingCallEvent
28
28
  import expo.modules.callkittelecom.store.CallStore
29
29
  import expo.modules.callkittelecom.utils.CallKitTelecomLog
30
+ import java.time.Instant
31
+ import java.util.UUID
32
+ import java.util.concurrent.ConcurrentHashMap
30
33
  import kotlinx.coroutines.CancellationException
31
34
  import kotlinx.coroutines.CoroutineName
32
35
  import kotlinx.coroutines.CoroutineScope
@@ -39,9 +42,6 @@ import kotlinx.coroutines.delay
39
42
  import kotlinx.coroutines.isActive
40
43
  import kotlinx.coroutines.launch
41
44
  import kotlinx.coroutines.selects.select
42
- import java.time.Instant
43
- import java.util.UUID
44
- import java.util.concurrent.ConcurrentHashMap
45
45
 
46
46
  /**
47
47
  * Central Android call lifecycle manager using Core-Telecom Jetpack.
@@ -70,8 +70,8 @@ class CallManager private constructor() {
70
70
  /**
71
71
  * Channels for dispatching actions into active Core-Telecom call scopes.
72
72
  *
73
- * Scope methods are called from within the addCall block via channel-based
74
- * dispatch rather than storing and calling CallControlScope references externally.
73
+ * Scope methods are called from within the addCall block via channel-based dispatch rather than
74
+ * storing and calling CallControlScope references externally.
75
75
  */
76
76
  private class CallActions {
77
77
  val setActive = Channel<Unit>(Channel.CONFLATED)
@@ -81,8 +81,8 @@ class CallManager private constructor() {
81
81
  }
82
82
 
83
83
  /**
84
- * Encapsulates the coroutine job, action channels, and timeout for a single call.
85
- * Consolidates what was previously three separate maps.
84
+ * Encapsulates the coroutine job, action channels, and timeout for a single call. Consolidates
85
+ * what was previously three separate maps.
86
86
  */
87
87
  private class CallController(
88
88
  val job: Job,
@@ -116,12 +116,15 @@ class CallManager private constructor() {
116
116
 
117
117
  callsManager = CallsManager(context)
118
118
  callsManager.registerAppWithTelecom(
119
- CallsManager.CAPABILITY_BASELINE or CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING,
119
+ CallsManager.CAPABILITY_BASELINE or CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING
120
120
  )
121
121
 
122
- incomingCallTimeoutMs = readTimeoutMs("ExpoCallKitTelecomIncomingCallTimeout", incomingCallTimeoutMs)
123
- outgoingCallTimeoutMs = readTimeoutMs("ExpoCallKitTelecomOutgoingCallTimeout", outgoingCallTimeoutMs)
124
- fulfillAnswerTimeoutMs = readTimeoutMs("ExpoCallKitTelecomFulfillAnswerCallTimeout", fulfillAnswerTimeoutMs)
122
+ incomingCallTimeoutMs =
123
+ readTimeoutMs("ExpoCallKitTelecomIncomingCallTimeout", incomingCallTimeoutMs)
124
+ outgoingCallTimeoutMs =
125
+ readTimeoutMs("ExpoCallKitTelecomOutgoingCallTimeout", outgoingCallTimeoutMs)
126
+ fulfillAnswerTimeoutMs =
127
+ readTimeoutMs("ExpoCallKitTelecomFulfillAnswerCallTimeout", fulfillAnswerTimeoutMs)
125
128
 
126
129
  CallAudioManager.initialize(context)
127
130
  CallAudioManager.onRequestEndpointChange = { endpoint ->
@@ -139,10 +142,7 @@ class CallManager private constructor() {
139
142
  }
140
143
 
141
144
  /** Reads a timeout from Android manifest metadata (seconds) and returns milliseconds. */
142
- private fun readTimeoutMs(
143
- key: String,
144
- defaultMs: Long,
145
- ): Long =
145
+ private fun readTimeoutMs(key: String, defaultMs: Long): Long =
146
146
  try {
147
147
  val defaultSeconds = (defaultMs / 1000).toInt()
148
148
  val appInfo =
@@ -159,10 +159,7 @@ class CallManager private constructor() {
159
159
  // region Call Timeout
160
160
 
161
161
  /** Starts a call timeout that marks non-connected calls as unanswered. */
162
- private fun startCallTimeout(
163
- id: UUID,
164
- timeoutMs: Long,
165
- ) {
162
+ private fun startCallTimeout(id: UUID, timeoutMs: Long) {
166
163
  cancelCallTimeout(id)
167
164
  CallKitTelecomLog.d(TAG) { "Starting call timeout - id: $id, timeout: ${timeoutMs}ms" }
168
165
 
@@ -203,7 +200,11 @@ class CallManager private constructor() {
203
200
  return Uri.fromParts(PhoneAccount.SCHEME_SIP, email, null)
204
201
  }
205
202
 
206
- return Uri.fromParts(PhoneAccount.SCHEME_SIP, "${participant.id}@callkit-telecom.local", null)
203
+ return Uri.fromParts(
204
+ PhoneAccount.SCHEME_SIP,
205
+ "${participant.id}@callkit-telecom.local",
206
+ null,
207
+ )
207
208
  }
208
209
 
209
210
  // region Start Outgoing Call
@@ -217,13 +218,12 @@ class CallManager private constructor() {
217
218
  * - preps audio for call
218
219
  * - calls addCall with DIRECTION_OUTGOING
219
220
  */
220
- fun startOutgoingCall(
221
- recipient: CallParticipant,
222
- options: CallOptions,
223
- ): String {
221
+ fun startOutgoingCall(recipient: CallParticipant, options: CallOptions): String {
224
222
  val existingSession = CallStore.firstSession()
225
223
  if (existingSession != null) {
226
- CallKitTelecomLog.w(TAG) { "Cannot start outgoing call - session already exists: ${existingSession.id}" }
224
+ CallKitTelecomLog.w(TAG) {
225
+ "Cannot start outgoing call - session already exists: ${existingSession.id}"
226
+ }
227
227
  throw IllegalStateException("A call session already exists")
228
228
  }
229
229
 
@@ -314,7 +314,9 @@ class CallManager private constructor() {
314
314
  fun reportIncomingCall(event: IncomingCallEvent) {
315
315
  val existingSession = CallStore.firstSession()
316
316
  if (existingSession != null) {
317
- CallKitTelecomLog.w(TAG) { "Cannot report incoming call - session already exists: ${existingSession.id}" }
317
+ CallKitTelecomLog.w(TAG) {
318
+ "Cannot report incoming call - session already exists: ${existingSession.id}"
319
+ }
318
320
  throw IllegalStateException("A call session already exists")
319
321
  }
320
322
 
@@ -418,15 +420,12 @@ class CallManager private constructor() {
418
420
 
419
421
  activeCalls[callId]?.actions?.setActive?.trySend(Unit)
420
422
 
421
- val callerName =
422
- CallStore
423
- .session(callId)
424
- ?.remoteParticipants
425
- ?.firstOrNull()
426
- ?.displayName
423
+ val callerName = CallStore.session(callId)?.remoteParticipants?.firstOrNull()?.displayName
427
424
  CallNotificationManager.showOngoingCall(context, callId, callerName, now.toEpochMilli())
428
425
 
429
- CallKitTelecomLog.d(TAG) { "Fulfilled incoming call - callId: $callId, requestId: $requestId" }
426
+ CallKitTelecomLog.d(TAG) {
427
+ "Fulfilled incoming call - callId: $callId, requestId: $requestId"
428
+ }
430
429
  return true
431
430
  }
432
431
 
@@ -443,12 +442,7 @@ class CallManager private constructor() {
443
442
 
444
443
  activeCalls[id]?.actions?.setActive?.trySend(Unit)
445
444
 
446
- val callerName =
447
- CallStore
448
- .session(id)
449
- ?.remoteParticipants
450
- ?.firstOrNull()
451
- ?.displayName
445
+ val callerName = CallStore.session(id)?.remoteParticipants?.firstOrNull()?.displayName
452
446
  CallNotificationManager.showOngoingCall(context, id, callerName, now.toEpochMilli())
453
447
  }
454
448
 
@@ -463,17 +457,13 @@ class CallManager private constructor() {
463
457
  }
464
458
 
465
459
  /** Reports externally-ended call with explicit reason (`onCallReportedEnded` path). */
466
- fun reportCallEnded(
467
- id: UUID,
468
- reason: CallEndedReason,
469
- ) {
460
+ fun reportCallEnded(id: UUID, reason: CallEndedReason) {
470
461
  CallKitTelecomLog.d(TAG) { "Reporting call ended - id: $id, reason: ${reason.value}" }
471
462
  finishCall(id, emitEnded = false, reportedReason = reason)
472
463
  }
473
464
 
474
465
  /**
475
466
  * Shared call-finalization routine.
476
- *
477
467
  * - Cancels timeouts and pending fulfill requests
478
468
  * - Disconnects Core-Telecom scope (which causes addCall to return)
479
469
  * - Emits ended/reported-ended events as requested
@@ -499,11 +489,7 @@ class CallManager private constructor() {
499
489
  // so the DisconnectCause is properly delivered to the Telecom framework.
500
490
  // The finally block provides safety-net cleanup if needed.
501
491
  if (sendDisconnect) {
502
- activeCalls
503
- .remove(id)
504
- ?.actions
505
- ?.disconnect
506
- ?.trySend(disconnectCauseFor(reportedReason))
492
+ activeCalls.remove(id)?.actions?.disconnect?.trySend(disconnectCauseFor(reportedReason))
507
493
  }
508
494
 
509
495
  if (existingSession.status != CallSessionStatus.ENDED) {
@@ -517,10 +503,7 @@ class CallManager private constructor() {
517
503
  if (reportedReason != null) {
518
504
  CallEventEmitter.send(
519
505
  CallEvents.CALL_REPORTED_ENDED,
520
- mapOf(
521
- "id" to id.toString(),
522
- "reason" to reportedReason.value,
523
- ),
506
+ mapOf("id" to id.toString(), "reason" to reportedReason.value),
524
507
  )
525
508
  }
526
509
 
@@ -531,20 +514,24 @@ class CallManager private constructor() {
531
514
  CallAudioManager.onAudioDeactivated(remainingSessions)
532
515
  }
533
516
 
534
- CallKitTelecomLog.d(TAG) { "Call finished - id: $id, emitEnded: $emitEnded, reason: ${reportedReason?.value}" }
517
+ CallKitTelecomLog.d(TAG) {
518
+ "Call finished - id: $id, emitEnded: $emitEnded, reason: ${reportedReason?.value}"
519
+ }
535
520
  }
536
521
 
537
522
  /**
538
523
  * Safety-net cleanup called from the addCall finally block.
539
524
  *
540
- * Ensures all resources are released even if finishCall didn't run due to
541
- * an unexpected exception or cancellation.
525
+ * Ensures all resources are released even if finishCall didn't run due to an unexpected
526
+ * exception or cancellation.
542
527
  */
543
528
  private fun cleanupCallIfNeeded(id: UUID) {
544
529
  activeCalls.remove(id)
545
530
 
546
531
  val session = CallStore.session(id) ?: return
547
- CallKitTelecomLog.w(TAG) { "Safety-net cleanup for call - id: $id, status: ${session.status.value}" }
532
+ CallKitTelecomLog.w(TAG) {
533
+ "Safety-net cleanup for call - id: $id, status: ${session.status.value}"
534
+ }
548
535
 
549
536
  DialtonePlayer.stop()
550
537
  FulfillRequestManager.cancelForCall(id)
@@ -569,12 +556,10 @@ class CallManager private constructor() {
569
556
  CallEndedReason.UNANSWERED -> DisconnectCause(DisconnectCause.MISSED)
570
557
 
571
558
  CallEndedReason.ANSWERED_ELSEWHERE,
572
- CallEndedReason.DECLINED_ELSEWHERE,
573
- -> DisconnectCause(DisconnectCause.REMOTE)
559
+ CallEndedReason.DECLINED_ELSEWHERE -> DisconnectCause(DisconnectCause.REMOTE)
574
560
 
575
561
  CallEndedReason.FAILED,
576
- CallEndedReason.UNKNOWN,
577
- -> DisconnectCause(DisconnectCause.LOCAL)
562
+ CallEndedReason.UNKNOWN -> DisconnectCause(DisconnectCause.LOCAL)
578
563
 
579
564
  null -> DisconnectCause(DisconnectCause.LOCAL)
580
565
  }
@@ -584,18 +569,12 @@ class CallManager private constructor() {
584
569
  // region Mute Support
585
570
 
586
571
  /** Sets local mute state and emits `onSetMutedAction`. */
587
- fun setMuted(
588
- id: UUID,
589
- muted: Boolean,
590
- ) {
572
+ fun setMuted(id: UUID, muted: Boolean) {
591
573
  CallKitTelecomLog.d(TAG) { "Setting mute state - id: $id, muted: $muted" }
592
574
  CallStore.updateMuted(id, muted)
593
575
  CallEventEmitter.send(
594
576
  CallEvents.SET_MUTED_ACTION,
595
- mapOf(
596
- "id" to id.toString(),
597
- "isMuted" to muted,
598
- ),
577
+ mapOf("id" to id.toString(), "isMuted" to muted),
599
578
  )
600
579
  }
601
580
 
@@ -604,10 +583,7 @@ class CallManager private constructor() {
604
583
  // region Video Support
605
584
 
606
585
  /** Reports video enabled state change and emits `onVideoChanged`. */
607
- fun reportVideo(
608
- id: UUID,
609
- enabled: Boolean,
610
- ) {
586
+ fun reportVideo(id: UUID, enabled: Boolean) {
611
587
  CallKitTelecomLog.d(TAG) { "Setting video state - id: $id, enabled: $enabled" }
612
588
  CallStore.update(id) { session ->
613
589
  session.copy(options = session.options.copy(hasVideo = enabled))
@@ -617,10 +593,7 @@ class CallManager private constructor() {
617
593
 
618
594
  CallEventEmitter.send(
619
595
  CallEvents.VIDEO_CHANGED,
620
- mapOf(
621
- "id" to id.toString(),
622
- "hasVideo" to enabled,
623
- ),
596
+ mapOf("id" to id.toString(), "hasVideo" to enabled),
624
597
  )
625
598
  }
626
599
 
@@ -629,10 +602,7 @@ class CallManager private constructor() {
629
602
  // region Hold Support
630
603
 
631
604
  /** Sets hold state, updates Core-Telecom scope state, and emits `onSetHeldAction`. */
632
- fun setHeld(
633
- id: UUID,
634
- onHold: Boolean,
635
- ) {
605
+ fun setHeld(id: UUID, onHold: Boolean) {
636
606
  CallKitTelecomLog.d(TAG) { "Setting hold state - id: $id, onHold: $onHold" }
637
607
  CallStore.updateHeld(id, onHold)
638
608
 
@@ -644,10 +614,7 @@ class CallManager private constructor() {
644
614
 
645
615
  CallEventEmitter.send(
646
616
  CallEvents.SET_HELD_ACTION,
647
- mapOf(
648
- "id" to id.toString(),
649
- "isOnHold" to onHold,
650
- ),
617
+ mapOf("id" to id.toString(), "isOnHold" to onHold),
651
618
  )
652
619
  }
653
620
 
@@ -656,22 +623,11 @@ class CallManager private constructor() {
656
623
  // region DTMF Support
657
624
 
658
625
  /** Records requested DTMF digits and emits `onDTMF`. */
659
- fun playDTMF(
660
- id: UUID,
661
- digits: String,
662
- ) {
626
+ fun playDTMF(id: UUID, digits: String) {
663
627
  CallKitTelecomLog.d(TAG) { "Playing DTMF - id: $id, length: ${digits.length}" }
664
- CallStore.update(id) { session ->
665
- session.copy(dtmfDigits = digits)
666
- }
628
+ CallStore.update(id) { session -> session.copy(dtmfDigits = digits) }
667
629
 
668
- CallEventEmitter.send(
669
- CallEvents.DTMF,
670
- mapOf(
671
- "id" to id.toString(),
672
- "digits" to digits,
673
- ),
674
- )
630
+ CallEventEmitter.send(CallEvents.DTMF, mapOf("id" to id.toString(), "digits" to digits))
675
631
  }
676
632
 
677
633
  // endregion
@@ -681,8 +637,8 @@ class CallManager private constructor() {
681
637
  /**
682
638
  * Launches a Core-Telecom call scope with shared lifecycle management.
683
639
  *
684
- * Handles channel setup, action dispatch via select, flow collectors,
685
- * and safety-net cleanup in a single place.
640
+ * Handles channel setup, action dispatch via select, flow collectors, and safety-net cleanup in
641
+ * a single place.
686
642
  *
687
643
  * @param id Call UUID
688
644
  * @param attributes Core-Telecom call attributes
@@ -704,15 +660,18 @@ class CallManager private constructor() {
704
660
  callAttributes = attributes,
705
661
  onAnswer = onAnswer,
706
662
  onDisconnect = { cause ->
707
- CallKitTelecomLog.d(TAG) { "Call onDisconnect - id: $id, cause: ${cause.code}" }
708
- finishCall(id, emitEnded = true, reportedReason = null, sendDisconnect = false)
709
- },
710
- onSetActive = {
711
- setHeld(id, false)
712
- },
713
- onSetInactive = {
714
- setHeld(id, true)
663
+ CallKitTelecomLog.d(TAG) {
664
+ "Call onDisconnect - id: $id, cause: ${cause.code}"
665
+ }
666
+ finishCall(
667
+ id,
668
+ emitEnded = true,
669
+ reportedReason = null,
670
+ sendDisconnect = false,
671
+ )
715
672
  },
673
+ onSetActive = { setHeld(id, false) },
674
+ onSetInactive = { setHeld(id, true) },
716
675
  ) {
717
676
  val callScope: CallControlScope = this
718
677
 
@@ -729,7 +688,12 @@ class CallManager private constructor() {
729
688
  CallKitTelecomLog.d(TAG) { "Call coroutine cancelled - id: $id" }
730
689
  } catch (e: Exception) {
731
690
  CallKitTelecomLog.e(TAG) { "Call addCall failed - id: $id, error: ${e.message}" }
732
- finishCall(id, emitEnded = true, reportedReason = CallEndedReason.FAILED, sendDisconnect = false)
691
+ finishCall(
692
+ id,
693
+ emitEnded = true,
694
+ reportedReason = CallEndedReason.FAILED,
695
+ sendDisconnect = false,
696
+ )
733
697
  } finally {
734
698
  cleanupCallIfNeeded(id)
735
699
  CallKitTelecomLog.d(TAG) { "Call addCall block exited - id: $id" }
@@ -739,26 +703,17 @@ class CallManager private constructor() {
739
703
  /**
740
704
  * Processes call action channels using a single select loop.
741
705
  *
742
- * Runs until the coroutine is cancelled (when addCall returns).
743
- * Using select ensures actions are processed sequentially, preventing
744
- * concurrent scope method calls from racing.
706
+ * Runs until the coroutine is cancelled (when addCall returns). Using select ensures actions
707
+ * are processed sequentially, preventing concurrent scope method calls from racing.
745
708
  */
746
- private suspend fun handleCallActions(
747
- id: UUID,
748
- actions: CallActions,
749
- scope: CallControlScope,
750
- ) {
709
+ private suspend fun handleCallActions(id: UUID, actions: CallActions, scope: CallControlScope) {
751
710
  while (currentCoroutineContext().isActive) {
752
711
  select<Unit> {
753
712
  actions.setActive.onReceive {
754
713
  handleControlResult(id, "setActive", scope.setActive())
755
714
  }
756
- actions.setInactive.onReceive {
757
- logIfError(id, "setInactive", scope.setInactive())
758
- }
759
- actions.disconnect.onReceive { cause ->
760
- scope.disconnect(cause)
761
- }
715
+ actions.setInactive.onReceive { logIfError(id, "setInactive", scope.setInactive()) }
716
+ actions.disconnect.onReceive { cause -> scope.disconnect(cause) }
762
717
  actions.endpointChange.onReceive { endpoint ->
763
718
  logIfError(id, "requestEndpointChange", scope.requestEndpointChange(endpoint))
764
719
  }
@@ -769,14 +724,10 @@ class CallManager private constructor() {
769
724
  /**
770
725
  * Handles CallControlResult for critical actions like setActive.
771
726
  *
772
- * When a critical action fails, the call cannot continue in a valid state
773
- * and is ended with a FAILED reason.
727
+ * When a critical action fails, the call cannot continue in a valid state and is ended with a
728
+ * FAILED reason.
774
729
  */
775
- private fun handleControlResult(
776
- id: UUID,
777
- action: String,
778
- result: CallControlResult,
779
- ) {
730
+ private fun handleControlResult(id: UUID, action: String, result: CallControlResult) {
780
731
  if (result is CallControlResult.Error) {
781
732
  CallKitTelecomLog.e(TAG) { "$action failed - id: $id, error: ${result.errorCode}" }
782
733
  reportCallEnded(id, CallEndedReason.FAILED)
@@ -784,11 +735,7 @@ class CallManager private constructor() {
784
735
  }
785
736
 
786
737
  /** Logs Core-Telecom control action failures at error level. */
787
- private fun logIfError(
788
- id: UUID,
789
- action: String,
790
- result: CallControlResult,
791
- ) {
738
+ private fun logIfError(id: UUID, action: String, result: CallControlResult) {
792
739
  if (result is CallControlResult.Error) {
793
740
  CallKitTelecomLog.e(TAG) { "$action failed - id: $id, error: ${result.errorCode}" }
794
741
  }
@@ -797,17 +744,16 @@ class CallManager private constructor() {
797
744
  /**
798
745
  * Collects Core-Telecom endpoint and mute flows within the CallControlScope.
799
746
  *
800
- * These coroutines keep the addCall block alive and forward audio state
801
- * changes to CallAudioManager and CallStore.
747
+ * These coroutines keep the addCall block alive and forward audio state changes to
748
+ * CallAudioManager and CallStore.
802
749
  */
803
- private fun CoroutineScope.collectCallFlows(
804
- id: UUID,
805
- callScope: CallControlScope,
806
- ) {
750
+ private fun CoroutineScope.collectCallFlows(id: UUID, callScope: CallControlScope) {
807
751
  launch {
808
752
  callScope.availableEndpoints.collect { endpoints ->
809
753
  CallStore.session(id) ?: return@collect
810
- CallKitTelecomLog.d(TAG) { "Available endpoints changed - id: $id, count: ${endpoints.size}" }
754
+ CallKitTelecomLog.d(TAG) {
755
+ "Available endpoints changed - id: $id, count: ${endpoints.size}"
756
+ }
811
757
  CallAudioManager.onAvailableEndpointsChanged(endpoints)
812
758
  }
813
759
  }
@@ -815,7 +761,9 @@ class CallManager private constructor() {
815
761
  launch {
816
762
  callScope.currentCallEndpoint.collect { endpoint ->
817
763
  CallStore.session(id) ?: return@collect
818
- CallKitTelecomLog.d(TAG) { "Endpoint changed - id: $id, type: ${endpoint.type}, name: ${endpoint.name}" }
764
+ CallKitTelecomLog.d(TAG) {
765
+ "Endpoint changed - id: $id, type: ${endpoint.type}, name: ${endpoint.name}"
766
+ }
819
767
  CallAudioManager.onEndpointChanged(endpoint)
820
768
  }
821
769
  }
@@ -828,10 +776,7 @@ class CallManager private constructor() {
828
776
  CallStore.updateMuted(id, muted)
829
777
  CallEventEmitter.send(
830
778
  CallEvents.SET_MUTED_ACTION,
831
- mapOf(
832
- "id" to id.toString(),
833
- "isMuted" to muted,
834
- ),
779
+ mapOf("id" to id.toString(), "isMuted" to muted),
835
780
  )
836
781
  }
837
782
  }
@@ -865,10 +810,7 @@ class CallManager private constructor() {
865
810
  }
866
811
 
867
812
  val request =
868
- FulfillRequestManager.createRequest(
869
- callId = id,
870
- timeoutMs = fulfillAnswerTimeoutMs,
871
- ) {
813
+ FulfillRequestManager.createRequest(callId = id, timeoutMs = fulfillAnswerTimeoutMs) {
872
814
  reportCallEnded(it, CallEndedReason.FAILED)
873
815
  }
874
816
 
@@ -876,10 +818,7 @@ class CallManager private constructor() {
876
818
 
877
819
  CallEventEmitter.send(
878
820
  CallEvents.CALL_ANSWERED,
879
- mapOf(
880
- "id" to id.toString(),
881
- "requestId" to request.requestId.toString(),
882
- ),
821
+ mapOf("id" to id.toString(), "requestId" to request.requestId.toString()),
883
822
  )
884
823
  }
885
824