diff --git a/Podfile.lock b/Podfile.lock index e64e5201c..bae2bb60e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -70,4 +70,4 @@ SPEC CHECKSUMS: UICKeyChainStore: eef407137f0397e95a3df32cdf05f7e2ddd99647 UnionFind: 45777a8b6878d3a602af3654cc3a09b87389d356 -COCOAPODS: 0.34.1 +COCOAPODS: 0.34.4 diff --git a/Signal/src/audio/AppAudioManager.h b/Signal/src/audio/AppAudioManager.h index 19f8cc0a9..952ce809f 100644 --- a/Signal/src/audio/AppAudioManager.h +++ b/Signal/src/audio/AppAudioManager.h @@ -2,6 +2,7 @@ #import "CallProgress.h" #import "CallTermination.h" +#import "SoundPlayer.h" /** * The AppAudioManager is a Singleton object used to control audio settings / updates @@ -13,7 +14,7 @@ * which speaker to use or if all sounds should be muted. **/ -@interface AppAudioManager : NSObject +@interface AppAudioManager : NSObject enum AudioProfile { AudioProfile_Default, @@ -37,4 +38,7 @@ enum AudioProfile { -(BOOL) setAudioEnabled:(BOOL) enable; -(void) awake; + +- (void)didCompleteSoundInstanceOfType:(SoundInstanceType)instanceType; + @end diff --git a/Signal/src/audio/AppAudioManager.m b/Signal/src/audio/AppAudioManager.m index 40b415b9e..85a3f27e5 100644 --- a/Signal/src/audio/AppAudioManager.m +++ b/Signal/src/audio/AppAudioManager.m @@ -28,7 +28,7 @@ AppAudioManager* sharedAppAudioManager; if( nil == sharedAppAudioManager){ sharedAppAudioManager = [AppAudioManager new]; sharedAppAudioManager.soundPlayer = [SoundPlayer new]; - [sharedAppAudioManager setAudioEnabled:YES]; + [[sharedAppAudioManager soundPlayer] setDelegate:sharedAppAudioManager]; } } return sharedAppAudioManager; @@ -74,9 +74,11 @@ AppAudioManager* sharedAppAudioManager; } #pragma mark AudioControl; --(void) respondToProgressChange:(enum CallProgressType) progressType forLocallyInitiatedCall:(BOOL) initiatedLocally { +-(void) respondToProgressChange:(enum CallProgressType) progressType + forLocallyInitiatedCall:(BOOL) initiatedLocally { switch (progressType){ case CallProgressType_Connecting: + [sharedAppAudioManager setAudioEnabled:YES]; [_soundPlayer stopAllAudio]; case CallProgressType_Ringing: (initiatedLocally) ? [self handleOutboundRing] : [self handleInboundRing]; @@ -106,12 +108,13 @@ AppAudioManager* sharedAppAudioManager; -(BOOL) shouldErrorSoundBePlayedForCallTerminationType:(enum CallTerminationType) type{ [_soundPlayer stopAllAudio]; - if (CallTerminationType_RejectedLocal) {return NO;} - else if (CallTerminationType_RejectedRemote) {return NO;} - else if (CallTerminationType_HangupLocal) {return NO;} - else if (CallTerminationType_HangupRemote) {return NO;} - else if (CallTerminationType_RecipientUnavailable) {return NO;} - + if (type == CallTerminationType_RejectedLocal || + type == CallTerminationType_RejectedRemote || + type == CallTerminationType_HangupLocal || + type == CallTerminationType_HangupRemote || + type == CallTerminationType_RecipientUnavailable) { + return NO; + } return YES; } @@ -174,14 +177,31 @@ AppAudioManager* sharedAppAudioManager; -(BOOL) setAudioEnabled:(BOOL) enable { NSError* e; - [AVAudioSession.sharedInstance setActive:enable error:&e]; - [_soundPlayer awake]; + if (enable) { + [[AVAudioSession sharedInstance] setActive:enable error:&e]; + [_soundPlayer awake]; + } + else { + [[AVAudioSession sharedInstance] setActive:enable + withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation + error:&e]; + } return ( nil !=e ); } -(void) awake { [_soundPlayer awake]; } + +#pragma mark Sound Player Delegate + +- (void)didCompleteSoundInstanceOfType:(SoundInstanceType)instanceType { + if (instanceType == SoundInstanceTypeBusySound || + instanceType == SoundInstanceTypeErrorAlert || + instanceType == SoundInstanceTypeAlert) { + [sharedAppAudioManager setAudioEnabled:NO]; + } +} @end diff --git a/Signal/src/audio/SoundBoard.m b/Signal/src/audio/SoundBoard.m index c7a6d8b32..5d30af88d 100644 --- a/Signal/src/audio/SoundBoard.m +++ b/Signal/src/audio/SoundBoard.m @@ -10,42 +10,49 @@ static NSString* SoundFile_Ringtone =@"r.caf"; @implementation SoundBoard -+(SoundInstance*) instanceOfInboundRingtone{ ++(SoundInstance*) instanceOfInboundRingtone { SoundInstance* soundInstance = [SoundInstance soundInstanceForFile:SoundFile_Ringtone]; [soundInstance setAudioToLoopIndefinitely]; + [soundInstance setInstanceType:SoundInstanceTypeInboundRingtone]; return soundInstance; } -+(SoundInstance*) instanceOfOutboundRingtone{ ++(SoundInstance*) instanceOfOutboundRingtone { SoundInstance* soundInstance = [SoundInstance soundInstanceForFile:SoundFile_Outbound]; [soundInstance setAudioToLoopIndefinitely]; + [soundInstance setInstanceType:SoundInstanceTypeBusySound]; return soundInstance; } -+(SoundInstance*) instanceOfHandshakeSound { ++(SoundInstance*) instanceOfHandshakeSound { SoundInstance* soundInstance = [SoundInstance soundInstanceForFile:SoundFile_Handshake]; [soundInstance setAudioToLoopIndefinitely]; + [soundInstance setInstanceType:SoundInstanceTypeHandshakeSound]; return soundInstance; } +(SoundInstance*) instanceOfCompletedSound { SoundInstance* soundInstance = [SoundInstance soundInstanceForFile:SoundFile_Completed]; + [soundInstance setInstanceType:SoundInstanceTypeCompletedSound]; return soundInstance; } +(SoundInstance*) instanceOfBusySound { SoundInstance* soundInstance = [SoundInstance soundInstanceForFile:SoundFile_Busy]; [soundInstance setAudioLoopCount:10]; + [soundInstance setInstanceType:SoundInstanceTypeBusySound]; return soundInstance; } +(SoundInstance*) instanceOfErrorAlert { SoundInstance* soundInstance = [SoundInstance soundInstanceForFile:SoundFile_Failure]; + [soundInstance setInstanceType:SoundInstanceTypeErrorAlert]; return soundInstance; } +(SoundInstance*) instanceOfAlert { SoundInstance* soundInstance = [SoundInstance soundInstanceForFile:SoundFile_Alert]; + [soundInstance setInstanceType:SoundInstanceTypeAlert]; return soundInstance; } diff --git a/Signal/src/audio/SoundInstance.h b/Signal/src/audio/SoundInstance.h index c8bec5681..80299e552 100644 --- a/Signal/src/audio/SoundInstance.h +++ b/Signal/src/audio/SoundInstance.h @@ -6,10 +6,26 @@ @interface SoundInstance : NSObject +typedef enum { + SoundInstanceTypeNothing, + SoundInstanceTypeInboundRingtone, + SoundInstanceTypeOutboundRingtone, + SoundInstanceTypeHandshakeSound, + SoundInstanceTypeCompletedSound, + SoundInstanceTypeBusySound, + SoundInstanceTypeErrorAlert, + SoundInstanceTypeAlert +} SoundInstanceType; + +@property (nonatomic) SoundInstanceType instanceType; + +(SoundInstance*) soundInstanceForFile:(NSString*) audioFile; -(NSString*) getId; -(void) setAudioToLoopIndefinitely; -(void) setAudioLoopCount:(NSInteger) loopCount; -(void) setCompeletionBlock:(void (^)(SoundInstance*)) block; + +- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player + successfully:(BOOL)flag; @end diff --git a/Signal/src/audio/SoundInstance.m b/Signal/src/audio/SoundInstance.m index 571b5876a..87caf0ee4 100644 --- a/Signal/src/audio/SoundInstance.m +++ b/Signal/src/audio/SoundInstance.m @@ -5,6 +5,7 @@ } @property (retain) AVAudioPlayer *audioPlayer; + @end @implementation SoundInstance @@ -26,6 +27,7 @@ -(void) stop { [self.audioPlayer stop]; + [self audioPlayerDidFinishPlaying:self.audioPlayer successfully:YES]; } -(void) setAudioToLoopIndefinitely { @@ -36,6 +38,13 @@ self.audioPlayer.numberOfLoops = loopCount; } +- (SoundInstanceType)instanceType { + if (!_instanceType) { + _instanceType = SoundInstanceTypeNothing; + } + return _instanceType; +} + +(NSURL*) urlToFile:(NSString*) file { return [NSURL fileURLWithPath: [NSString stringWithFormat:@"%@/%@", NSBundle.mainBundle.resourcePath,file]]; @@ -50,7 +59,6 @@ return audioPlayer; } - -(void) setCompeletionBlock:(void (^)(SoundInstance* )) block { completionBlock = block; } diff --git a/Signal/src/audio/SoundPlayer.h b/Signal/src/audio/SoundPlayer.h index a098836d4..b5ca76921 100644 --- a/Signal/src/audio/SoundPlayer.h +++ b/Signal/src/audio/SoundPlayer.h @@ -7,12 +7,23 @@ * sound is ignored. Multiple different sound instances can be played concurrently. */ +@protocol SoundPlayerDelegate; + @interface SoundPlayer : NSObject +@property (strong, nonatomic) id delegate; + -(void) playSound:(SoundInstance*) player; -(void) stopSound:(SoundInstance*) player; -(void) stopAllAudio; -(void) awake; + @end +@protocol SoundPlayerDelegate + +@optional +- (void)didCompleteSoundInstanceOfType:(SoundInstanceType)instanceType; + +@end diff --git a/Signal/src/audio/SoundPlayer.m b/Signal/src/audio/SoundPlayer.m index eadbbd789..f3d18a299 100644 --- a/Signal/src/audio/SoundPlayer.m +++ b/Signal/src/audio/SoundPlayer.m @@ -22,6 +22,9 @@ NSMutableDictionary* currentActiveAudioPlayers; @synchronized(currentActiveAudioPlayers){ [sound setCompeletionBlock:^(SoundInstance* soundInst) { [self removeSoundFromManifest:soundInst]; + if (self.delegate) { + [self.delegate didCompleteSoundInstanceOfType:soundInst.instanceType]; + } }]; [currentActiveAudioPlayers setValue:sound forKey:sound.getId]; } diff --git a/Signal/src/view controllers/InCallViewController.m b/Signal/src/view controllers/InCallViewController.m index 8cf6bcafb..2e76fb24a 100644 --- a/Signal/src/view controllers/InCallViewController.m +++ b/Signal/src/view controllers/InCallViewController.m @@ -7,8 +7,6 @@ #import "CallAudioManager.h" #import "PhoneManager.h" -#import - #define BUTTON_BORDER_WIDTH 1.0f #define CONTACT_IMAGE_BORDER_WIDTH 2.0f #define RINGING_ROTATION_DURATION 0.375f @@ -24,7 +22,6 @@ static NSInteger connectingFlashCounter = 0; @interface InCallViewController () { - BOOL _isMusicPaused; CallAudioManager *_callAudioManager; NSTimer *_connectingFlashTimer; NSTimer *_ringingAnimationTimer; @@ -47,7 +44,6 @@ static NSInteger connectingFlashCounter = 0; - (void)viewDidLoad { [super viewDidLoad]; [self showCallState]; - [self pauseMusicIfPlaying]; [self setupButtonBorders]; [self localizeButtons]; [UIDevice.currentDevice setProximityMonitoringEnabled:YES]; @@ -75,13 +71,6 @@ static NSInteger connectingFlashCounter = 0; [self handleIncomingDetails]; } -- (void)pauseMusicIfPlaying { - if ([[MPMusicPlayerController iPodMusicPlayer] playbackState] == MPMusicPlaybackStatePlaying) { - _isMusicPaused = YES; - [[MPMusicPlayerController iPodMusicPlayer] pause]; - } -} - - (void)startConnectingFlashAnimation { if(!_ringingAnimationTimer.isValid){ _connectingFlashTimer = [NSTimer scheduledTimerWithTimeInterval:CONNECTING_FLASH_DURATION @@ -207,7 +196,7 @@ static NSInteger connectingFlashCounter = 0; BOOL showAcceptRejectButtons = !_callState.initiatedLocally && [latestProgress type] <= CallProgressType_Ringing; [self displayAcceptRejectButtons:showAcceptRejectButtons]; [AppAudioManager.sharedInstance respondToProgressChange:[latestProgress type] - forLocallyInitiatedCall:_callState.initiatedLocally]; + forLocallyInitiatedCall:_callState.initiatedLocally]; if ([latestProgress type] == CallProgressType_Ringing) { [self startRingingAnimation]; @@ -228,10 +217,6 @@ static NSInteger connectingFlashCounter = 0; [Environment.phoneManager hangupOrDenyCall]; [self dismissViewWithOptionalDelay: [termination type] != CallTerminationType_ReplacedByNext ]; - - if (_isMusicPaused) { - [[MPMusicPlayerController iPodMusicPlayer] play]; - } } - (void)endCallTapped {