diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index ee87cf12a..c63a76ca6 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -80,7 +80,6 @@ typedef struct _LinphoneManagerSounds { Connectivity connectivity; BOOL stopWaitingRegisters; NSMutableArray *inhibitedEvent; - @public CallContext currentCallContextBeforeGoingBackground; @@ -112,9 +111,6 @@ typedef struct _LinphoneManagerSounds { - (void)refreshRegisters; -- (void)enableSpeaker:(BOOL)enable; -- (BOOL)isSpeakerEnabled; - - (void)addInhibitedEvent:(NSString*)event; - (BOOL)removeInhibitedEvent:(NSString*)event; @@ -133,8 +129,6 @@ typedef struct _LinphoneManagerSounds { -(void)lpConfigSetBool:(BOOL) value forKey:(NSString*) key; -(BOOL)lpConfigBoolForKey:(NSString*) key; - - @property (readonly) FastAddressBook* fastAddressBook; @property Connectivity connectivity; @property (readonly) const char* frontCamId; @@ -143,6 +137,7 @@ typedef struct _LinphoneManagerSounds { @property (nonatomic, retain) NSData *pushNotificationToken; @property (readonly) LinphoneManagerSounds sounds; @property (readonly) NSMutableArray *logs; +@property (nonatomic, assign) BOOL speakerEnabled; @end diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 6cc0405f3..8917def89 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -78,6 +78,7 @@ extern void libmsbcg729_init(); @synthesize pushNotificationToken; @synthesize sounds; @synthesize logs; +@synthesize speakerEnabled; struct codec_name_pref_table{ const char *name; @@ -179,8 +180,13 @@ struct codec_name_pref_table codec_pref_table[]={ - (id)init { if ((self = [super init])) { + AudioSessionInitialize(NULL, NULL, NULL, NULL); + OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); + if (lStatus) { + [LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus]; + } - + // Sounds { NSString *path = [[NSBundle mainBundle] pathForResource:@"ring" ofType:@"wav"]; sounds.call = 0; @@ -197,9 +203,11 @@ struct codec_name_pref_table codec_pref_table[]={ [LinphoneLogger log:LinphoneLoggerWarning format:@"Can't set \"message\" system sound"]; } } + inhibitedEvent = [[NSMutableArray alloc] init]; logs = [[NSMutableArray alloc] init]; database = NULL; + speakerEnabled = FALSE; [self openDatabase]; [self copyDefaultSettings]; lastRemoteNotificationTime=0; @@ -220,6 +228,11 @@ struct codec_name_pref_table codec_pref_table[]={ [self closeDatabase]; [logs release]; + OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); + if (lStatus) { + [LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus]; + } + [super dealloc]; } @@ -347,7 +360,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char // Disable speaker when no more call if ((state == LinphoneCallEnd || state == LinphoneCallError)) { if(linphone_core_get_calls_nb([LinphoneManager getLc]) == 0) - [self enableSpeaker:FALSE]; + [self setSpeakerEnabled:FALSE]; } // Enable speaker when video @@ -357,7 +370,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char state == LinphoneCallStreamsRunning || state == LinphoneCallUpdated) { if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - [self enableSpeaker:TRUE]; + [self setSpeakerEnabled:TRUE]; } } @@ -835,10 +848,36 @@ static LinphoneCoreVTable linphonec_vtable = { [LinphoneManager copyFile:src destination:dst override:FALSE]; } + #pragma mark - Speaker Functions -- (void)enableSpeaker:(BOOL)enable { - //redirect audio to speaker +static void audioRouteChangeListenerCallback ( + void *inUserData, // 1 + AudioSessionPropertyID inPropertyID, // 2 + UInt32 inPropertyValueSize, // 3 + const void *inPropertyValue // 4 + ) { + if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; // 5 + LinphoneManager* lm = (LinphoneManager*)inUserData; + + bool enabled = false; + CFStringRef lNewRoute = CFSTR("Unknown"); + UInt32 lNewRouteSize = sizeof(lNewRoute); + OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute); + if (!lStatus && lNewRouteSize > 0) { + NSString *route = (NSString *) lNewRoute; + [LinphoneLogger logc:LinphoneLoggerLog format:"Current audio route is [%s]", [route cStringUsingEncoding:[NSString defaultCStringEncoding]]]; + enabled = [route isEqualToString: @"Speaker"] || [route isEqualToString: @"SpeakerAndMicrophone"]; + CFRelease(lNewRoute); + } + + if(enabled != lm.speakerEnabled) { // Reforce value + lm.speakerEnabled = lm.speakerEnabled; + } +} + +- (void)setSpeakerEnabled:(BOOL)enable { + speakerEnabled = enable; if(enable) { UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute @@ -852,21 +891,6 @@ static LinphoneCoreVTable linphonec_vtable = { } } -- (BOOL)isSpeakerEnabled { - bool enabled = false; - CFStringRef lNewRoute = CFSTR("Unknown"); - UInt32 lNewRouteSize = sizeof(lNewRoute); - OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute); - if (!lStatus && lNewRouteSize > 0) { - NSString *route = (NSString *) lNewRoute; - [LinphoneLogger logc:LinphoneLoggerLog format:"Current audio route is [%s]", [route cStringUsingEncoding:[NSString defaultCStringEncoding]]]; - enabled = [route isEqualToString: @"Speaker"] || [route isEqualToString: @"SpeakerAndMicrophone"]; - CFRelease(lNewRoute); - } - return enabled; -} - - #pragma mark - Call Functions - (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer { diff --git a/Classes/LinphoneUI/UISpeakerButton.m b/Classes/LinphoneUI/UISpeakerButton.m index faeba9ad7..474bd6f8c 100644 --- a/Classes/LinphoneUI/UISpeakerButton.m +++ b/Classes/LinphoneUI/UISpeakerButton.m @@ -29,8 +29,6 @@ #pragma mark - Static Functions -static AudioSessionPropertyID routeChangeID = kAudioSessionProperty_AudioRouteChange; - static void audioRouteChangeListenerCallback ( void *inUserData, // 1 AudioSessionPropertyID inPropertyID, // 2 @@ -38,27 +36,13 @@ static void audioRouteChangeListenerCallback ( const void *inPropertyValue // 4 ) { if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return; // 5 - UISpeakerButton* button=(UISpeakerButton*)inUserData; - UInt32 routeSize = sizeof (CFStringRef); - CFStringRef route; - AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, - &routeSize, - &route); - - if (route && - button.selected && - !( [(NSString*)route isEqualToString: @"Speaker"] || [(NSString*)route isEqualToString: @"SpeakerAndMicrophone"])) { - [LinphoneLogger logc:LinphoneLoggerLog format:"Audio route change to [%s] rejected by speaker button", [(NSString*)route cStringUsingEncoding:[NSString defaultCStringEncoding]]]; - // reject change - [button onOn]; - } else - [(UISpeakerButton*)inUserData update]; - + UISpeakerButton* button = (UISpeakerButton*)inUserData; + [button update]; } - (void)initUISpeakerButton { AudioSessionInitialize(NULL, NULL, NULL, NULL); - OSStatus lStatus = AudioSessionAddPropertyListener(routeChangeID, audioRouteChangeListenerCallback, self); + OSStatus lStatus = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); if (lStatus) { [LinphoneLogger logc:LinphoneLoggerError format:"cannot register route change handler [%ld]",lStatus]; } @@ -89,25 +73,26 @@ static void audioRouteChangeListenerCallback ( } - (void)dealloc { - OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(routeChangeID, audioRouteChangeListenerCallback, self); + OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self); if (lStatus) { - [LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]",lStatus]; + [LinphoneLogger logc:LinphoneLoggerError format:"cannot un register route change handler [%ld]", lStatus]; } [super dealloc]; } + #pragma mark - UIToggleButtonDelegate Functions - (void)onOn { - [[LinphoneManager instance] enableSpeaker:TRUE]; + [[LinphoneManager instance] setSpeakerEnabled:TRUE]; } - (void)onOff { - [[LinphoneManager instance] enableSpeaker:FALSE]; + [[LinphoneManager instance] setSpeakerEnabled:FALSE]; } - (bool)onUpdate { - return [[LinphoneManager instance] isSpeakerEnabled]; + return [[LinphoneManager instance] speakerEnabled]; } @end