From e425d351c72aafb7f29acde22faa53c520fd797a Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 30 Jan 2017 15:10:47 -0500 Subject: [PATCH 1/3] WIP: incoming non-signal call while in outgoing signal call Marking Signal-Call as started, changes the incoming call screen for subsequent calls to show "Accept & End", "Send to VoiceMail" and "Accept & Hold" instead of just "Accept" & "Decline" Though - we don't support Holding. What we really want to see is just "Accept & End" and "Decline | Send to Voicemail" // FREEBIE --- .../Speakerbox/CallKitCallUIAdaptee.swift | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift index f427d6032..4cbbc9732 100644 --- a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift +++ b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift @@ -138,8 +138,7 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { func recipientAcceptedCall(_ call: SignalCall) { AssertIsOnMainThread() - // no - op - // TODO provider update call connected? + self.provider.reportOutgoingCall(with: call.localId, connectedAt: nil) } func localHangupCall(_ call: SignalCall) { @@ -213,27 +212,15 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { } CallService.signalingQueue.async { - self.callService.handleOutgoingCall(call).then { + self.callService.handleOutgoingCall(call).then { () -> Void in action.fulfill() + self.provider.reportOutgoingCall(with: call.localId, startedConnectingAt: nil) }.catch { error in Logger.error("\(self.TAG) error \(error) in \(#function)") self.callManager.removeCall(call) action.fail() } } - - // TODO FIXME - // /* - // Set callback blocks for significant events in the call's lifecycle, so that the CXProvider may be updated - // to reflect the updated state. - // */ - // call.hasStartedConnectingDidChange = { [weak self] in - // self?.provider.reportOutgoingCall(with: call.uuid, startedConnectingAt: call.connectingDate) - // } - // call.hasConnectedDidChange = { [weak self] in - // self?.provider.reportOutgoingCall(with: call.uuid, connectedAt: call.connectDate) - // } - } func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) { From 969b73cad8ed3fb542848e398a4620a9f1d40f9e Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 30 Jan 2017 15:40:40 -0500 Subject: [PATCH 2/3] Implement call holding (call swapping still broken). - Alice calls Bob on Signal and they start talking - Charlie calls Alice on Not-Signal. - Alice chooses to "Hold & Accept" putting Bob on Hold while the call with Charlie connects. - If Alice ends the call with Charlie, we're back in Signal-iOS and talking to Bob, no problem. - However, if, before ending the call with Charlie, Alice tries to swap *back* to bob, bob won't hear any audio in the callkit screen. Alice has to switch back to the Signal screen before the audio is transmitted. // FREEBIE --- Signal/src/call/SignalCall.swift | 2 ++ .../Speakerbox/CallKitCallUIAdaptee.swift | 25 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Signal/src/call/SignalCall.swift b/Signal/src/call/SignalCall.swift index 13f1bd4ff..c7e8b8f23 100644 --- a/Signal/src/call/SignalCall.swift +++ b/Signal/src/call/SignalCall.swift @@ -133,6 +133,8 @@ protocol CallObserver: class { } } + var isOnHold = false + var connectedDate: NSDate? var error: CallError? diff --git a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift index 4cbbc9732..222b952b8 100644 --- a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift +++ b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift @@ -285,20 +285,19 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { action.fail() return } - Logger.warn("TODO, unimplemented set held call: \(call)") - // TODO FIXME - // // Update the SpeakerboxCall's underlying hold state. - // call.isOnHold = action.isOnHold - // - // // Stop or start audio in response to holding or unholding the call. - // if call.isOnHold { - // // stopAudio() <-- SpeakerBox - // PeerConnectionClient.stopAudioSession() - // } else { - // // startAudio() <-- SpeakerBox - // PeerConnectionClient.startAudioSession() - // } + // Update the SignalCall's underlying hold state. + call.isOnHold = action.isOnHold + + // Stop or start audio in response to holding or unholding the call. + if call.isOnHold { + // stopAudio() <-- SpeakerBox + PeerConnectionClient.stopAudioSession() + } else { + // startAudio() <-- SpeakerBox + // This is redundant with what happens in `provider(_:didActivate:)` + //PeerConnectionClient.startAudioSession() + } // Signal to the system that the action has been successfully performed. action.fulfill() From 141a1bd176b560008bc7b1f610c6dfd687a36fc6 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 30 Jan 2017 16:11:39 -0500 Subject: [PATCH 3/3] Disable half-working call-holding feature all together consolidated feature-disable logic for incoming/outgoing calls to make it easier to document, and less likely to break when we *do* implement CallHolding // FREEBIE --- .../Speakerbox/CallKitCallUIAdaptee.swift | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift index 222b952b8..42d4cc831 100644 --- a/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift +++ b/Signal/src/call/Speakerbox/CallKitCallUIAdaptee.swift @@ -91,10 +91,7 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { let update = CXCallUpdate() update.remoteHandle = CXHandle(type: .phoneNumber, value: call.remotePhoneNumber) update.hasVideo = call.hasLocalVideo - update.supportsHolding = false - update.supportsGrouping = false - update.supportsUngrouping = false - update.supportsDTMF = false + disableUnsupportedFeatures(callUpdate: update) // Report the incoming call to the system provider.reportNewIncomingCall(with: call.localId, update: update) { error in @@ -139,6 +136,11 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { AssertIsOnMainThread() self.provider.reportOutgoingCall(with: call.localId, connectedAt: nil) + + let update = CXCallUpdate() + disableUnsupportedFeatures(callUpdate: update) + + provider.reportCall(with: call.localId, updated: update) } func localHangupCall(_ call: SignalCall) { @@ -358,4 +360,19 @@ final class CallKitCallUIAdaptee: NSObject, CallUIAdaptee, CXProviderDelegate { de-activated after having its priority restored to normal. */ } + + // MARK: - Util + + private func disableUnsupportedFeatures(callUpdate: CXCallUpdate) { + // Call Holding is failing to restart audio when "swapping" calls on the CallKit screen + // until user returns to in-app call screen. + callUpdate.supportsHolding = false + + // Not yet supported + callUpdate.supportsGrouping = false + callUpdate.supportsUngrouping = false + + // Is there any reason to support this? + callUpdate.supportsDTMF = false + } }