react-native-webrtc / react-native-callkeep

iOS CallKit framework and Android ConnectionService for React Native
ISC License
897 stars 437 forks source link

[iOS] Declining Incoming Call to SIM number triggers `endCall` event #753

Open disco-panda opened 8 months ago

disco-panda commented 8 months ago

Bug report

Reproduced on:

Description

When using Callkeep to display an outbound call from our app and an incoming call comes in to the SIM on the phone, CallKit displays the incoming call with the option to decline or answer. Declining the call triggers the RNCallKeep endCall event with the callUUID from the outbound call instead.

This means that declining an inbound call to the phone will end the call in the app as it looks exactly like when a user presses the End Call button on CallKit.

Steps to Reproduce

Versions

- Callkeep: 4.3.12
- React Native: 0.72.6
- iOS: 17.1
- Android: N/A
- Phone model: iPhone 14 Pro 

Logs

N/A
Romick2005 commented 8 months ago

Are you using different callUUID for both calls? You should get proper callUUID on pressing specific call end button. Please check callUUID values there.

disco-panda commented 8 months ago

The call I am declining is not managed by the app, it is a call to the phone itself. @Romick2005

Romick2005 commented 8 months ago

But do you provide callUUID for the app call? And you are saying that you receive this callUUID on call end event? I will try to reproduce this tomorrow.

disco-panda commented 8 months ago

When working with calls in the app, I do use the callUUID. I create one when starting a call or receiving a call and use it to manage the call in callkit. All works well.

Only issue I am running into is that when a call to the phone is declined, it provides the callUUID of the currently active call in the app to the endCall event.

This makes it impossible to tell whether the user is actually wanting to end the call in the app, or is just declining a call that is incoming to the phone.

More than happy to provide any code / logs / screenshots that may be useful if that assists you. Really appreciate the quick responses @Romick2005 !

Romick2005 commented 8 months ago

I cannot confirm that. For me regular call decline does not fire endCall event with callUUID that was used for app internal call connection. It might be that I used my own forked version of this lib. So I cannot help you as it is working as expected for me and my assumption is that it could be working in older version of this lib.

disco-panda commented 8 months ago

@Romick2005 Thank you for taking the time to review, I will try using your forked version / and older version in the next few weeks and see if that helps.

If so, I will look for the cause and attempt to fix / submit back to this repo. Thanks again!

slootmaekersdirk commented 6 months ago

Hello,

any news on this one, we have the same issue, but unable to reproduce it

rncallkeep version 4.3.9 IOS 17.3

Dirk

slootmaekersdirk commented 6 months ago

One of our customers has the same issue. When running on AT&T and a GSM call enters, the endcall is triggered with the callUUID of the VOIP call. He did the same test abroad (other provider) and then it was ok, so no endcall was triggered.

any ideas on what can cause this issue?

thx Dirk

pinki-palacios commented 5 months ago

@Romick2005 any chance you're on an old ios version?

We're facing this issue as well and while testing with a coworker it turns out that it happens to me (being on latest ios) 17.3.1 while it doesn't happen for him being at 16.5

I'm wondering if that could be the reason behind you not being able to reproduce. I have not tried your fork yet but from briefly looking into it I wasn't able to find any change around ending calls.

@disco-panda any discoveries on your end regarding this? Any luck using the forked repo?

Romick2005 commented 5 months ago

No I am on the latest version of ios and do not have this issue. Have you tried to debug to print callUUID and where it is comes from just to find out the difference.

pinki-palacios commented 5 months ago

Yes, as I decline the other call this gets fired. https://github.com/react-native-webrtc/react-native-callkeep/blob/master/ios/RNCallKeep/RNCallKeep.m#L1085

I logged the action and the uuid of the action is the uuid of the call created from my app. The other interesting thing I noticed is that after that happens

await RNCallKeep.getCalls()

Goes from returning 2 items to return an empty array.

Here's a run of what I'm seeing. I added an interval to log out the current state of the calls

I start the call from my app with uuid: '85a7b3da-8bf8-430f-b675-61ffee20ea4a'

getCalls

  [ { hasEnded: false,
    callUUID: '85A7B3DA-8BF8-430F-B675-61FFEE20EA4A',
    outgoing: true,
    hasConnected: false,
    onHold: false } ]

I call myself from another phone we can see both calls

[ { hasEnded: false,
    callUUID: '85A7B3DA-8BF8-430F-B675-61FFEE20EA4A',
    outgoing: true,
    hasConnected: false,
    onHold: false },
  { hasEnded: false,
    callUUID: 'E9463951-0CCF-47D6-9461-D017ADF9BC0C', <-- incomming call uuid 
    outgoing: false,
    hasConnected: false,
    onHold: false } ]

I decline the incomming call. this is what the action looks like in the line I shared

[RNCallKeep][CXProviderDelegate][provider:performEndCallAction] action = <CXEndCallAction 0x280e24d20 UUID=007E3E11-CFFE-43DF-BA1B-BB88C12BE108 state=0 commitDate=2024-03-05 19:00:58 +0000 callUUID=85A7B3DA-8BF8-430F-B675-61FFEE20EA4A dateEnded=(null)>

Notice how the calluuid matches the call from my app instead of the incomming one

The next interval logs an empty array

pinki-palacios commented 5 months ago

If I do the same but using what's app to start the call from the other device it works as expected.

This is what I get. My app's call uuid

cee85f88-2117-4c2f-954a-4a4b40ce7788

While it rings I see both calls

 [ { hasEnded: false,
    callUUID: '631E123F-83C8-4877-A8DC-AF2F5866F7F2',
    outgoing: false,
    hasConnected: false,
    onHold: false },
  { hasEnded: false,
    callUUID: 'CEE85F88-2117-4C2F-954A-4A4B40CE7788',
    outgoing: true,
    hasConnected: false,
    onHold: false } ]

After I decline the whatsApp call my call stays there and performEndCallAction was never fired

[ { hasEnded: false,
    callUUID: 'CEE85F88-2117-4C2F-954A-4A4B40CE7788',
    outgoing: true,
    hasConnected: false,
    onHold: false } ]
pinki-palacios commented 5 months ago

Ok was able to fix it. It caught my atention the fact that my call was always returning hasConnected: false

I randomly tried to call

  RNCallKeep.answerIncomingCall(myCallUUID)

That ended up changing hasConnected to true and somehow that stopped the issue, now I'm able to decline incomming call. Not sure of how hacky this solution is given the fact that my call is "outgoing" but seems to be doing the trick so far...

  RNCallKeep.startCall(callId, contactNumber, contactDisplay)
  RNCallKeep.setCurrentCallActive(callId)
  RNCallKeep.answerIncomingCall(callId)

In retrospective setCurrentCallActive is only for android. I guess nothing was changing the state of my call to connected

disco-panda commented 5 months ago

@pinki-palacios Thank you so much for digging into this issue - your fix also appears to be working for my use case as well. Definitely hacky, but at least it works!

@manuquentin - may be worth digging deeper to see if there is a more permanent fix or a documentation update to be made. I will leave open for now, but happy to close if you wish to move it to a different issue.