audio: fix speaker switch
Change-Id: I45ef4c1da798aab9039bffaa33219b40d86e4537
diff --git a/Ring/Ring/Calls/ButtonsContainerView.swift b/Ring/Ring/Calls/ButtonsContainerView.swift
index c994f0e..d2dd38b 100644
--- a/Ring/Ring/Calls/ButtonsContainerView.swift
+++ b/Ring/Ring/Calls/ButtonsContainerView.swift
@@ -172,7 +172,7 @@
if switchSpeakerButton.isEnabled && !switchSpeakerButton.isHidden {
self.optionsWithSpeaker()
} else if !switchSpeakerButton.isHidden {
- self.optionsWithSpeaker()
+ self.optionsWithoutSpeaker()
}
}
diff --git a/Ring/Ring/Calls/CallViewModel.swift b/Ring/Ring/Calls/CallViewModel.swift
index 4c3521b..299fc44 100644
--- a/Ring/Ring/Calls/CallViewModel.swift
+++ b/Ring/Ring/Calls/CallViewModel.swift
@@ -405,7 +405,13 @@
.filter({ serviceEvent in
serviceEvent.eventType == .audioActivated
}).subscribe(onNext: { [weak self] _ in
- self?.audioService.startAudio()
+ guard let self = self else {return}
+ self.audioService.startAudio()
+ //for outgoing calls ve create audio sesion with default parameters.
+ //for incoming call audio session is created, ve need to override it
+ let overrideOutput = self.call?.callTypeValue == CallType.incoming.rawValue
+ self.audioService.setDefaultOutput(toSpeaker: !self.isAudioOnly,
+ override: overrideOutput)
}).disposed(by: self.disposeBag)
}
@@ -433,22 +439,12 @@
}
}
}
- self.callService.hangUpCallOrConference(callId: rendererId)
- .subscribe(onCompleted: { [weak self] in
- // switch to either spk or headset (if connected) for loud ringtone
- // incase we were using rcv during the call
- self?.videoService.stopAudioDevice()
- self?.log.info("Call canceled")
- }, onError: { [weak self] error in
- self?.log.error("Failed to cancel the call")
- }).disposed(by: self.disposeBag)
+ self.callService
+ .hangUpCallOrConference(callId: rendererId)
+ .subscribe().disposed(by: self.disposeBag)
}
func answerCall() -> Completable {
- if !self.audioService.isHeadsetConnected.value {
- isAudioOnly ?
- self.audioService.overrideToReceiver() : self.audioService.overrideToSpeaker()
- }
return self.callService.accept(call: call)
}
@@ -456,10 +452,6 @@
guard let account = self.accountService.currentAccount else {
return
}
- if !self.audioService.isHeadsetConnected.value {
- isAudioOnly ?
- self.audioService.overrideToReceiver() : self.audioService.overrideToSpeaker()
- }
self.callService.placeCall(withAccount: account,
toRingId: uri,
userName: userName,
diff --git a/Ring/Ring/Services/AudioService.swift b/Ring/Ring/Services/AudioService.swift
index d18d96e..fe1caf8 100644
--- a/Ring/Ring/Services/AudioService.swift
+++ b/Ring/Ring/Services/AudioService.swift
@@ -44,6 +44,9 @@
init(withAudioAdapter audioAdapter: AudioAdapter) {
self.audioAdapter = audioAdapter
+ let bluetoothConnected = bluetoothAudioConnected()
+ let headphonesConnected = headphoneAudioConnected()
+ isHeadsetConnected.value = bluetoothConnected || headphonesConnected
// Listen for audio route changes
NotificationCenter.default.addObserver(
@@ -53,35 +56,31 @@
object: nil)
}
- // swiftlint:disable force_cast
@objc private func audioRouteChangeListener(_ notification: Notification) {
- let reasonRaw = notification.userInfo![AVAudioSessionRouteChangeReasonKey] as! UInt
- self.log.debug("Audio route change: \(reasonRaw)")
- guard let reason = AVAudioSession.RouteChangeReason(rawValue: reasonRaw) else {
- return
+ guard let userInfo = notification.userInfo,
+ let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt else {
+ return
}
- overrideAudioRoute(reason)
+ guard let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue),
+ (reason == .newDeviceAvailable || reason == .oldDeviceUnavailable || reason == .categoryChange) else {
+ return
+ }
+ overrideAudioRoute()
}
- // swiftlint:enable force_cast
- func overrideAudioRoute(_ reason: AVAudioSession.RouteChangeReason) {
- let wasHeadsetConnected = isHeadsetConnected.value
+ func overrideAudioRoute() {
let bluetoothConnected = bluetoothAudioConnected()
let headphonesConnected = headphoneAudioConnected()
- self.log.debug("Audio route override - reason: \(reason.rawValue), status: bluetooth: \(bluetoothConnected), headphones: \(headphonesConnected)")
isHeadsetConnected.value = bluetoothConnected || headphonesConnected
- if reason == .override && !isHeadsetConnected.value {
- setAudioOutputDevice(port: OutputPortType.builtinspk)
- } else if wasHeadsetConnected != isHeadsetConnected.value {
- if bluetoothConnected {
- setAudioOutputDevice(port: OutputPortType.bluetooth)
- } else if headphonesConnected {
- setAudioOutputDevice(port: OutputPortType.headphones)
- } else if wasHeadsetConnected {
- let outputPort = isOutputToSpeaker.value ? OutputPortType.builtinspk : OutputPortType.receiver
- setAudioOutputDevice(port: outputPort)
- }
+ if bluetoothConnected {
+ setAudioOutputDevice(port: OutputPortType.bluetooth)
+ return
+ } else if headphonesConnected {
+ setAudioOutputDevice(port: OutputPortType.headphones)
+ return
}
+ let outputPort = isOutputToSpeaker.value ? OutputPortType.builtinspk : OutputPortType.receiver
+ setAudioOutputDevice(port: outputPort)
}
func switchSpeaker() {
@@ -111,6 +110,13 @@
setAudioOutputDevice(port: OutputPortType.receiver)
}
+ func setDefaultOutput(toSpeaker: Bool, override: Bool = false) {
+ isOutputToSpeaker.value = toSpeaker
+ if override {
+ overrideAudioRoute()
+ }
+ }
+
func bluetoothAudioConnected() -> Bool {
let outputs = AVAudioSession.sharedInstance().currentRoute.outputs
for output in outputs {