Replace bluetoothEnabled and speakerEnabled flags in the CallManager by isBluetoothEnabled and isSpeakerEnabled function, which will give real time state of the API based on what the linphone core getAudioDevice functions returns

This commit is contained in:
QuentinArguillere 2021-05-10 11:52:08 +02:00
parent 5e6329e40d
commit 88970c0e04
9 changed files with 51 additions and 105 deletions

View file

@ -39,8 +39,6 @@ import AVFoundation
let callController: CXCallController! // to support callkit
var lc: Core?
@objc var speakerBeforePause : Bool = false
@objc var speakerEnabled : Bool = false
@objc var bluetoothEnabled : Bool = false
@objc var nextCallIsTransfer: Bool = false
@objc var alreadyRegisteredForNotification: Bool = false
var referedFromCall: String?
@ -126,26 +124,8 @@ import AVFoundation
#endif
return false
}
/*
@objc func allowSpeaker() -> Bool {
if (UIDevice.current.userInterfaceIdiom == .pad) {
// For now, ipad support only speaker.
return true
}
return true
var allow = true
let newRoute = AVAudioSession.sharedInstance().currentRoute
if (newRoute.outputs.count > 0) {
let route = newRoute.outputs[0].portType
allow = !( route == .lineOut || route == .headphones || (AudioHelper.bluetoothRoutes() as Array).contains(where: {($0 as! AVAudioSession.Port) == route}))
}
return allow
}
*/
@objc func changeRouteToSpeaker() {
speakerEnabled = true
for device in lc!.audioDevices {
if (device.type == AudioDeviceType.Speaker) {
lc!.outputAudioDevice = device
@ -153,46 +133,46 @@ import AVFoundation
}
}
UIDevice.current.isProximityMonitoringEnabled = false
bluetoothEnabled = false
}
@objc func changeRouteToBluetooth() {
bluetoothEnabled = true
for device in lc!.audioDevices {
if (device.type == AudioDeviceType.Bluetooth || device.type == AudioDeviceType.BluetoothA2DP) {
lc!.outputAudioDevice = device
break
}
}
speakerEnabled = false
UIDevice.current.isProximityMonitoringEnabled = (lc!.callsNb > 0)
}
@objc func changeRouteToDefault() {
bluetoothEnabled = false
speakerEnabled = false
lc!.outputAudioDevice = lc!.defaultOutputAudioDevice
}
/*
@objc func enableSpeaker(enable: Bool) {
speakerEnabled = enable
do {
if (enable && allowSpeaker()) {
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
UIDevice.current.isProximityMonitoringEnabled = false
bluetoothEnabled = false
} else {
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
let buildinPort = AudioHelper.builtinAudioDevice()
try AVAudioSession.sharedInstance().setPreferredInput(buildinPort)
UIDevice.current.isProximityMonitoringEnabled = (lc!.callsNb > 0)
@objc func isBluetoothAvailable() -> Bool {
for device in lc!.audioDevices {
if (device.type == AudioDeviceType.Bluetooth || device.type == AudioDeviceType.BluetoothA2DP) {
let name = device.deviceName
return true;
}
} catch {
Log.directLog(BCTBX_LOG_ERROR, text: "Failed to change audio route: err \(error)")
}
return false;
}
*/
@objc func isSpeakerEnabled() -> Bool {
if let outputDevice = lc!.outputAudioDevice {
return outputDevice.type == AudioDeviceType.Speaker
}
return false
}
@objc func isBluetoothEnabled() -> Bool {
if let outputDevice = lc!.outputAudioDevice {
return (outputDevice.type == AudioDeviceType.Bluetooth || outputDevice.type == AudioDeviceType.BluetoothA2DP)
}
return false
}
func requestTransaction(_ transaction: CXTransaction, action: String) {
callController.request(transaction) { error in
if let error = error {
@ -575,7 +555,7 @@ import AVFoundation
// disable this because I don't find anygood reason for it: _bluetoothAvailable = FALSE;
// furthermore it introduces a bug when calling multiple times since route may not be
// reconfigured between cause leading to bluetooth being disabled while it should not
CallManager.instance().bluetoothEnabled = false
//CallManager.instance().bluetoothEnabled = false
}
if UIApplication.shared.applicationState != .active && (callLog == nil || callLog?.status == .Missed || callLog?.status == .Aborted || callLog?.status == .EarlyAborted) {
@ -636,7 +616,8 @@ import AVFoundation
}
if (cstate == .IncomingReceived || cstate == .OutgoingInit || cstate == .Connected || cstate == .StreamsRunning) {
if ((call.currentParams?.videoEnabled ?? false) && !CallManager.speaker_already_enabled && !CallManager.instance().bluetoothEnabled) {
// if ((call.currentParams?.videoEnabled ?? false) && !CallManager.speaker_already_enabled && !CallManager.instance().bluetoothEnabled) {
if ((call.currentParams?.videoEnabled ?? false) && !CallManager.speaker_already_enabled && !CallManager.instance().isBluetoothEnabled()) {
CallManager.instance().changeRouteToSpeaker()
CallManager.speaker_already_enabled = true
}

View file

@ -185,8 +185,8 @@ static UICompositeViewDescription *compositeDescription = nil;
[_routesButton setOn];
}
_routesBluetoothButton.selected = CallManager.instance.bluetoothEnabled;
_routesSpeakerButton.selected = CallManager.instance.speakerEnabled;
_routesBluetoothButton.selected = [CallManager.instance isBluetoothEnabled];
_routesSpeakerButton.selected = [CallManager.instance isSpeakerEnabled];
_routesEarpieceButton.selected = !_routesBluetoothButton.selected && !_routesSpeakerButton.selected;
if (hidden != _routesView.hidden) {

View file

@ -493,8 +493,8 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[_routesButton setOn];
}
_routesBluetoothButton.selected = CallManager.instance.bluetoothEnabled;
_routesSpeakerButton.selected = CallManager.instance.speakerEnabled;
_routesBluetoothButton.selected = [CallManager.instance isBluetoothEnabled];
_routesSpeakerButton.selected = [CallManager.instance isSpeakerEnabled];
_routesEarpieceButton.selected = !_routesBluetoothButton.selected && !_routesSpeakerButton.selected;
if (hidden != _routesView.hidden) {

View file

@ -190,7 +190,6 @@ typedef struct _LinphoneManagerSounds {
- (void)migrationPerAccount;
- (void)setupGSMInteraction;
//- (void)setBluetoothEnabled:(BOOL)enable;
- (BOOL)isCTCallCenterExist;
@property (readonly) BOOL isTesting;

View file

@ -1732,58 +1732,15 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
if (IPAD)
return;
// there is at least one bug when you disconnect an audio bluetooth headset
// since we only get notification of route having changed, we cannot tell if that is due to:
// -bluetooth headset disconnected or
// -user wanted to use earpiece
// the only thing we can assume is that when we lost a device, it must be a bluetooth one (strong hypothesis though)
if ([[notif.userInfo valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue] == AVAudioSessionRouteChangeReasonOldDeviceUnavailable)
_bluetoothAvailable = NO;
AVAudioSessionRouteDescription *newRoute = [AVAudioSession sharedInstance].currentRoute;
if (newRoute && newRoute.outputs.count > 0) {
NSString *route = newRoute.outputs[0].portType;
LOGI(@"Current audio route is [%s]", [route UTF8String]);
linphone_core_audio_route_changed(theLinphoneCore);
CallManager.instance.speakerEnabled = [route isEqualToString:AVAudioSessionPortBuiltInSpeaker];
if (([[AudioHelper bluetoothRoutes] containsObject:route]) && !CallManager.instance.speakerEnabled) {
_bluetoothAvailable = TRUE;
CallManager.instance.bluetoothEnabled = TRUE;
} else
CallManager.instance.bluetoothEnabled = FALSE;
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:_bluetoothAvailable], @"available", nil];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneBluetoothAvailabilityUpdate
object:self
userInfo:dict];
}
_bluetoothAvailable = [CallManager.instance isBluetoothAvailable];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:_bluetoothAvailable], @"available", nil];
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneBluetoothAvailabilityUpdate
object:self
userInfo:dict];
}
/*
- (void)setBluetoothEnabled:(BOOL)enable {
if (_bluetoothAvailable) {
// The change of route will be done in enableSpeaker
CallManager.instance.bluetoothEnabled = enable;
if (CallManager.instance.bluetoothEnabled) {
NSError *err = nil;
AVAudioSessionPortDescription *_bluetoothPort = [AudioHelper bluetoothAudioDevice];
[[AVAudioSession sharedInstance] setPreferredInput:_bluetoothPort error:&err];
// if setting bluetooth failed, it must be because the device is not available
// anymore (disconnected), so deactivate bluetooth.
if (err) {
CallManager.instance.bluetoothEnabled = FALSE;
LOGE(@"Failed to enable bluetooth: err %@", err.localizedDescription);
err = nil;
} else {
CallManager.instance.speakerEnabled = FALSE;
return;
}
}
}
[CallManager.instance enableSpeakerWithEnable:CallManager.instance.speakerEnabled];
}
*/
#pragma mark - Call Functions
- (void)send:(NSString *)replyText toChatRoom:(LinphoneChatRoom *)room {
LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String);
@ -2108,7 +2065,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
if ([ct currentCalls] != nil) {
if (call) {
LOGI(@"Pausing SIP call because GSM call");
CallManager.instance.speakerBeforePause = CallManager.instance.speakerEnabled;
CallManager.instance.speakerBeforePause = [CallManager.instance isSpeakerEnabled];
linphone_call_pause(call);
[self startCallPausedLongRunningTask];
} else if (linphone_core_is_in_conference(theLinphoneCore)) {

View file

@ -85,7 +85,7 @@
if ([CallManager callKitEnabled]) {
[CallManager.instance setHeldWithCall:call hold:true];
} else {
CallManager.instance.speakerBeforePause = CallManager.instance.speakerEnabled;
CallManager.instance.speakerBeforePause = [CallManager.instance isSpeakerEnabled];
linphone_call_pause(call);
}
} else {
@ -106,7 +106,7 @@
if ([CallManager callKitEnabled]) {
[CallManager.instance setHeldWithCall:currentCall hold:true];
} else {
CallManager.instance.speakerBeforePause = CallManager.instance.speakerEnabled;
CallManager.instance.speakerBeforePause = [CallManager.instance isSpeakerEnabled];
linphone_call_pause(currentCall);
}
} else {

View file

@ -34,6 +34,15 @@ INIT_WITH_COMMON_CF {
return self;
}
- (void)onOn {
[CallManager.instance changeRouteToSpeaker];
}
- (void)onOff {
[CallManager.instance changeRouteToDefault];
}
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
}
@ -46,7 +55,7 @@ INIT_WITH_COMMON_CF {
}
- (bool)onUpdate {
return CallManager.instance.speakerEnabled;
return [CallManager.instance isSpeakerEnabled];
}
@end

View file

@ -381,7 +381,7 @@ static RootViewManager *rootViewManagerInstance = nil;
if (![LinphoneManager.instance isCTCallCenterExist]) {
/*only register CT call center CB for connected call*/
[LinphoneManager.instance setupGSMInteraction];
[[UIDevice currentDevice] setProximityMonitoringEnabled:!(CallManager.instance.speakerEnabled || CallManager.instance.bluetoothEnabled)];
[[UIDevice currentDevice] setProximityMonitoringEnabled:!([CallManager.instance isSpeakerEnabled] || [CallManager.instance isBluetoothEnabled])];
}
break;
}

View file

@ -205,7 +205,7 @@ extension ProviderDelegate: CXProviderDelegate {
if (call!.params?.localConferenceMode ?? false) {
return
}
CallManager.instance().speakerBeforePause = CallManager.instance().speakerEnabled
CallManager.instance().speakerBeforePause = CallManager.instance().isSpeakerEnabled()
try call!.pause()
} else {
if (call?.conference != nil && CallManager.instance().lc?.callsNb ?? 0 > 1) {