By centralizing AudioSession management onto the AudioService, we can
avoid enabling the RTCAudioSession while we're mid-ring.
Also allows us to centralize and remove redundant audio session logic.
// FREEBIE
It's not clear why we were ever dispatching `sync` here.
Before this:
Place a call
See "connecting..."
Hang up
UI hangs for ~5 seconds
See "call failed" on CallKit screen
Press "cancel" on CallKit screen
returned to responsive app.
// FREEBIE
Now, by default, we only use TURN for incoming calls from unknown
contacts. We will potentially directly connect for outgoing calls and
for incoming calls from known contacts.
Optionally, the user can disable direct connection altogether, at the
cost of some call quality.
// FREEBIE
Distinguish between localHangup, remoteHangup, and call failure.
This allows us to put CallKit in the proper state, ready to receive new
calls without having a backlog of phantom calls which haven't been
properly removed.
Note the "call error" occurs at the point ICE fails, which takes a
while. Anecdotally, like 10 seconds, which feels like a long to be
talking into the ether.
I briefly considered failing at 'disconnected', which happens much
sooner, but that's actually a recoverable state. E.g. if you toggle
airplane mode you can see that you bounce into `disconnected` and then
back to `connected`, so I don't think we'd want to fail the call as long
as WebRTC considers it "recoverable".
// FREEBIE
We do this by manually managing the RTCAudioSession.
Unfortunately to do this we have to include a couple of RTC headers not
exported by the default build of WebRTC.framework (see: Libraries/WebRTC)
// FREEBIE
This makes sense as PeerConnectionClient is our interface to WebRTC
- Makes it easier to test PeerConnectionClient and CallService
- Allows us to shrink CallService class a bit (it's huge)
// FREEBIE
* Ensure NotificationsManager has dependencies
Otherwise it's easy to mess up the order of the required dependencies.
* move AccountManager into Environment, it's heavy to construct
// FREEBIE