@@ -116,6 +116,7 @@ import io.getstream.video.android.core.notifications.IncomingNotificationData
116116import io.getstream.video.android.core.notifications.NotificationType
117117import io.getstream.video.android.core.notifications.internal.service.CallServiceConfig
118118import io.getstream.video.android.core.notifications.internal.telecom.jetpack.JetpackTelecomRepository
119+ import io.getstream.video.android.core.notifications.internal.telecom.jetpack.TelecomCall
119120import io.getstream.video.android.core.permission.PermissionRequest
120121import io.getstream.video.android.core.pinning.PinType
121122import io.getstream.video.android.core.pinning.PinUpdateAtTime
@@ -130,6 +131,7 @@ import io.getstream.video.android.core.utils.toUser
130131import io.getstream.video.android.model.StreamCallId
131132import io.getstream.video.android.model.User
132133import kotlinx.coroutines.CoroutineScope
134+ import kotlinx.coroutines.Dispatchers
133135import kotlinx.coroutines.Job
134136import kotlinx.coroutines.channels.awaitClose
135137import kotlinx.coroutines.currentCoroutineContext
@@ -145,6 +147,7 @@ import kotlinx.coroutines.flow.combine
145147import kotlinx.coroutines.flow.debounce
146148import kotlinx.coroutines.flow.distinctUntilChanged
147149import kotlinx.coroutines.flow.flow
150+ import kotlinx.coroutines.flow.map
148151import kotlinx.coroutines.flow.stateIn
149152import kotlinx.coroutines.flow.transform
150153import kotlinx.coroutines.isActive
@@ -720,8 +723,14 @@ public class CallState(
720723 @InternalStreamVideoApi
721724 public val notificationIdFlow: StateFlow <Int ?> = _notificationIdFlow
722725
726+ private var telecomHoldObserverJob: Job ? = null
727+
723728 @InternalStreamVideoApi
724729 internal var jetpackTelecomRepository: JetpackTelecomRepository ? = null
730+ set(value) {
731+ field = value
732+ value?.let { observeTelecomHold(it) }
733+ }
725734
726735 internal var incomingNotificationData = IncomingNotificationData (emptyMap())
727736
@@ -1749,6 +1758,28 @@ public class CallState(
17491758 this ._notificationIdFlow .value = notificationId
17501759 this .atomicNotification.set(notification)
17511760 }
1761+
1762+ /* *
1763+ * [RingingState.Incoming] and [RingingState.Outgoing] are intentionally not observed.
1764+ * In Android Telecom, hold states are only applicable once a call is active (answered).
1765+ */
1766+ private fun observeTelecomHold (repo : JetpackTelecomRepository ) {
1767+ telecomHoldObserverJob?.cancel()
1768+
1769+ telecomHoldObserverJob = scope.launch(Dispatchers .Default ) {
1770+ repo.currentCall
1771+ .map { (it as ? TelecomCall .Registered )?.isOnHold == true }
1772+ .distinctUntilChanged()
1773+ .collect { telecomCall ->
1774+ when (ringingState.value) {
1775+ is RingingState .Active -> {
1776+ call.leave(" call-on-hold" )
1777+ }
1778+ else -> {}
1779+ }
1780+ }
1781+ }
1782+ }
17521783}
17531784
17541785private fun MemberResponse.toMemberState (): MemberState {
0 commit comments