[iOS] CXSetHeldCallAction handler re-requests the same hold action, so unholding a call flips it between held and active until it ends
I maintainer di solito rispondono entro 2 giorni
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 72/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Ambito
- audio-video-rtc, mobile
Direzione di ricerca
Inizia nel package iOS stream_video_push_notification e segui StreamVideoCallkitManager.provider(_:perform:) insieme a StreamCallKitCallController.setHold(call:onHold:). Controlla i chiamanti di setHold e confronta il gestore della messa in attesa con quello dell’azione di silenziamento. Il lavoro è completato quando la ripresa genera un evento di messa in attesa, ripristina la sessione audio e non accoda un’altra transazione di messa in attesa.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Package: stream_video_push_notification (iOS)
Version: seen at 164832a0f29d1c0f6dd1edb9f2458bc568ad56ad, also in 1.7.x
Platform: iOS only
Device: iPhone, iOS 26.6
Description
StreamVideoCallkitManager.provider(_:perform: CXSetHeldCallAction) asks CallKit for a new CXSetHeldCallAction with the same value while it is still handling the current one:
public func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {
guard let call = self.callController.callWithUUID(uuid: action.callUUID) else {
action.fail()
return
}
call.isOnHold = action.isOnHold
call.isMuted = action.isOnHold
self.callController.setHold(call: call, onHold: action.isOnHold) // <- requests a new transaction
sendHoldEvent(action.callUUID.uuidString, action.isOnHold)
action.fulfill()
}
StreamCallKitCallController.setHold(call:onHold:) builds a new CXSetHeldCallAction and sends it to CXCallController.request. So every hold action CallKit performs queues one more just like it.
- A system hold (for example accepting a cellular call with "Hold & Accept") leaves an extra "hold" transaction queued.
- When the call is unheld (from the app via
holdCall(uuid, isOnHold: false), or by the system), the unhold queues an extra "unhold" transaction too. - From then on, each pending transaction re-queues itself when performed, so CallKit keeps alternating hold and unhold.
The loop stops only when the CallKit call ends. After that the handler's callWithUUID guard fails and nothing is requested again.
The CXSetMutedCallAction handler doesn't do this. It updates state, sends the event and fulfills.
Steps to reproduce
- Start or join a call with CallKit (
startOutgoingCall+setCallConnected, or an incoming call that is accepted). - Receive a cellular call and choose Hold & Accept. The app gets
ActionCallToggleHold(isOnHold: true). - End the cellular call.
- Resume the held call: call
pushNotificationManager.holdCall(uuid, isOnHold: false), or resume it from the native call UI.
Expected behavior
One ActionCallToggleHold(isOnHold: false). The call becomes active and its audio session is activated again.
Actual behavior
ActionCallToggleHold events for the call alternate between true and false every few milliseconds, with repeated ActionCallToggleAudioSession(isActive: false) events, until the call ends. Audio doesn't come back, and any UI driven by the hold state flickers.
Logs from the app (one holdCall(uuid, isOnHold: false) at 14:09:50.884):
14:09:30.495 ActionCallToggleHold BCDFA02E-… isOnHold: true
14:09:50.884 app: holdCall(bcdfa02e-…, isOnHold: false)
14:09:50.887 ActionCallToggleHold BCDFA02E-… isOnHold: false
14:09:50.888 ActionCallToggleHold BCDFA02E-… isOnHold: true
14:09:50.888 ActionCallToggleHold BCDFA02E-… isOnHold: false
14:09:50.894 ActionCallToggleHold BCDFA02E-… isOnHold: true
14:09:50.894 ActionCallToggleHold BCDFA02E-… isOnHold: false
…
14:09:51.241 ActionCallToggleAudioSession isActive: false
… (400+ hold events in 8 s)
14:09:58.420 app leaves the call, CallKit call ends, events stop
Suggested fix
Don't request a transaction from the perform handler. CallKit is already performing this action, so the handler only needs to update local state, notify Dart and fulfill:
public func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {
guard let call = self.callController.callWithUUID(uuid: action.callUUID) else {
action.fail()
return
}
call.isOnHold = action.isOnHold
call.isMuted = action.isOnHold
sendHoldEvent(call.data.uuid, action.isOnHold)
action.fulfill()
}
If setHold(call:onHold:) has no other callers, it can be removed. holdCall(call:onHold:) already covers holds the app requests.
Workaround
Don't unhold the CallKit call. To resume, end it with endCallByCid(cid, silent: true) and report the call again with a new uuid (startOutgoingCall + setCallConnected). Ending the call breaks the loop.
- Lingua principale
- Dart
- Stelle
- 79
- Fork
- 55
- Merge medio
- 2g 10h
- PR unite (30g)
- 132
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di GetStream/stream-video-flutter
-
consumeAndAcceptActiveCall calls connect() without includeUserDetails, ignoring includeUserDetailsForAutoConnectForse già presa @Brazol l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
GetStream/stream-video-flutter#1537 ·
I maintainer di solito rispondono entro 2 giorni
-
[iOS] Remote screen share stays blank after returning from Picture-in-PictureForse già presa @Brazol l’ha presa 1 giorno fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 45/100
GetStream/stream-video-flutter#1538 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 52/100
GetStream/stream-video-flutter#1535 · 2 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 42/100
GetStream/stream-video-flutter#1430 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
GetStream/stream-video-flutter#1293 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di GetStream/stream-video-flutter
Issue simili
-
documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
patarapolw/lingua_srs#103 ·
I maintainer di solito rispondono entro 1 giorno
-
[Feature]Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 5 giorni
-
desktop linux photos
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
lichess-org/mobile#3944 ·
I maintainer di solito rispondono entro 2 giorni
-
auto-implement
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
bannzai/medicalarm#538 ·
I maintainer di solito rispondono entro 1 giorno