From 93dd634561e2d6b60f763d0ec68cd3642883324c Mon Sep 17 00:00:00 2001 From: tkchin Date: Wed, 27 Jul 2016 10:17:14 -0700 Subject: [PATCH] Treat foreground event as interruption end. NOTRY=True BUG= Review-Url: https://codereview.webrtc.org/2181163005 Cr-Commit-Position: refs/heads/master@{#13543} --- .../ios/objc/RTCAudioSession+Private.h | 5 +++ .../audio_device/ios/objc/RTCAudioSession.mm | 34 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h b/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h index cb506c345a..36be014386 100644 --- a/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h +++ b/webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h @@ -31,6 +31,11 @@ NS_ASSUME_NONNULL_BEGIN /** Convenience BOOL that checks useManualAudio and isAudioEnebled. */ @property(readonly) BOOL canPlayOrRecord; +/** Tracks whether we have been sent an interruption event that hasn't been matched by either an + * interrupted end event or a foreground event. + */ +@property(nonatomic, assign) BOOL isInterrupted; + - (BOOL)checkLock:(NSError **)outError; /** Adds the delegate to the list of delegates, and places it at the front of diff --git a/webrtc/modules/audio_device/ios/objc/RTCAudioSession.mm b/webrtc/modules/audio_device/ios/objc/RTCAudioSession.mm index 159d34e993..b17c601270 100644 --- a/webrtc/modules/audio_device/ios/objc/RTCAudioSession.mm +++ b/webrtc/modules/audio_device/ios/objc/RTCAudioSession.mm @@ -10,6 +10,8 @@ #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h" +#import + #include "webrtc/base/atomicops.h" #include "webrtc/base/checks.h" #include "webrtc/base/criticalsection.h" @@ -36,6 +38,7 @@ NSInteger const kRTCAudioSessionErrorConfiguration = -2; BOOL _useManualAudio; BOOL _isAudioEnabled; BOOL _canPlayOrRecord; + BOOL _isInterrupted; } @synthesize session = _session; @@ -72,6 +75,11 @@ NSInteger const kRTCAudioSessionErrorConfiguration = -2; selector:@selector(handleMediaServicesWereReset:) name:AVAudioSessionMediaServicesWereResetNotification object:nil]; + // Also track foreground event in order to deal with interruption ended situation. + [center addObserver:self + selector:@selector(handleApplicationDidBecomeActive:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; } return self; } @@ -434,10 +442,12 @@ NSInteger const kRTCAudioSessionErrorConfiguration = -2; case AVAudioSessionInterruptionTypeBegan: RTCLog(@"Audio session interruption began."); self.isActive = NO; + self.isInterrupted = YES; [self notifyDidBeginInterruption]; break; case AVAudioSessionInterruptionTypeEnded: { RTCLog(@"Audio session interruption ended."); + self.isInterrupted = NO; [self updateAudioSessionAfterEvent]; NSNumber *optionsNumber = notification.userInfo[AVAudioSessionInterruptionOptionKey]; @@ -505,6 +515,15 @@ NSInteger const kRTCAudioSessionErrorConfiguration = -2; [self notifyMediaServicesWereReset]; } +- (void)handleApplicationDidBecomeActive:(NSNotification *)notification { + if (self.isInterrupted) { + RTCLog(@"Application became active after an interruption. Treating as interruption end."); + self.isInterrupted = NO; + [self updateAudioSessionAfterEvent]; + [self notifyDidEndInterruptionWithShouldResumeSession:YES]; + } +} + #pragma mark - Private + (NSError *)lockError { @@ -565,6 +584,21 @@ NSInteger const kRTCAudioSessionErrorConfiguration = -2; return !self.useManualAudio || self.isAudioEnabled; } +- (BOOL)isInterrupted { + @synchronized(self) { + return _isInterrupted; + } +} + +- (void)setIsInterrupted:(BOOL)isInterrupted { + @synchronized(self) { + if (_isInterrupted == isInterrupted) { + return; + } + _isInterrupted = isInterrupted; + } +} + - (BOOL)checkLock:(NSError **)outError { // Check ivar instead of trying to acquire lock so that we won't accidentally // acquire lock if it hasn't already been called.