diff --git a/sdk/objc/Framework/Classes/Audio/RTCAudioSession.mm b/sdk/objc/Framework/Classes/Audio/RTCAudioSession.mm index 43575b9652..67a70da800 100644 --- a/sdk/objc/Framework/Classes/Audio/RTCAudioSession.mm +++ b/sdk/objc/Framework/Classes/Audio/RTCAudioSession.mm @@ -56,8 +56,13 @@ NSString * const kRTCAudioSessionOutputVolumeSelector = @"outputVolume"; } - (instancetype)init { + return [self initWithAudioSession:[AVAudioSession sharedInstance]]; +} + +/** This initializer provides a way for unit tests to inject a fake/mock audio session. */ +- (instancetype)initWithAudioSession:(id)audioSession { if (self = [super init]) { - _session = [AVAudioSession sharedInstance]; + _session = audioSession; NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self @@ -91,7 +96,7 @@ NSString * const kRTCAudioSessionOutputVolumeSelector = @"outputVolume"; [_session addObserver:self forKeyPath:kRTCAudioSessionOutputVolumeSelector options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld - context:nil]; + context:(__bridge void*)RTCAudioSession.class]; RTCLog(@"RTCAudioSession (%p): init.", self); } @@ -100,7 +105,9 @@ NSString * const kRTCAudioSessionOutputVolumeSelector = @"outputVolume"; - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_session removeObserver:self forKeyPath:kRTCAudioSessionOutputVolumeSelector context:nil]; + [_session removeObserver:self + forKeyPath:kRTCAudioSessionOutputVolumeSelector + context:(__bridge void*)RTCAudioSession.class]; RTCLog(@"RTCAudioSession (%p): dealloc.", self); } @@ -815,10 +822,12 @@ NSString * const kRTCAudioSessionOutputVolumeSelector = @"outputVolume"; ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if (object == _session) { - NSNumber *newVolume = change[NSKeyValueChangeNewKey]; - RTCLog(@"OutputVolumeDidChange to %f", newVolume.floatValue); - [self notifyDidChangeOutputVolume:newVolume.floatValue]; + if (context == (__bridge void*)RTCAudioSession.class) { + if (object == _session) { + NSNumber *newVolume = change[NSKeyValueChangeNewKey]; + RTCLog(@"OutputVolumeDidChange to %f", newVolume.floatValue); + [self notifyDidChangeOutputVolume:newVolume.floatValue]; + } } else { [super observeValueForKeyPath:keyPath ofObject:object diff --git a/sdk/objc/Framework/UnitTests/RTCAudioSessionTest.mm b/sdk/objc/Framework/UnitTests/RTCAudioSessionTest.mm index d94c63535b..951b5ea260 100644 --- a/sdk/objc/Framework/UnitTests/RTCAudioSessionTest.mm +++ b/sdk/objc/Framework/UnitTests/RTCAudioSessionTest.mm @@ -18,6 +18,22 @@ #import "WebRTC/RTCAudioSession.h" #import "WebRTC/RTCAudioSessionConfiguration.h" +@interface RTCAudioSession (UnitTesting) + +- (instancetype)initWithAudioSession:(id)audioSession; + +@end + +@interface MockAVAudioSession : NSObject + +@property (nonatomic, readwrite, assign) float outputVolume; + +@end + +@implementation MockAVAudioSession +@synthesize outputVolume = _outputVolume; +@end + @interface RTCAudioSessionTestDelegate : NSObject @property (nonatomic, readonly) float outputVolume; @@ -265,20 +281,16 @@ OCMLocation *OCMMakeLocation(id testCase, const char *fileCString, int line){ } - (void)testAudioVolumeDidNotify { - RTCAudioSession *session = [RTCAudioSession sharedInstance]; + MockAVAudioSession *mockAVAudioSession = [[MockAVAudioSession alloc] init]; + RTCAudioSession *session = [[RTCAudioSession alloc] initWithAudioSession:mockAVAudioSession]; RTCAudioSessionTestDelegate *delegate = [[RTCAudioSessionTestDelegate alloc] init]; [session addDelegate:delegate]; - [session observeValueForKeyPath:@"outputVolume" - ofObject:[AVAudioSession sharedInstance] - change: - @{NSKeyValueChangeNewKey : - @([AVAudioSession sharedInstance].outputVolume) } - context:nil]; + float expectedVolume = 0.75; + mockAVAudioSession.outputVolume = expectedVolume; - EXPECT_NE(delegate.outputVolume, -1); - EXPECT_EQ([AVAudioSession sharedInstance].outputVolume, delegate.outputVolume); + EXPECT_EQ(expectedVolume, delegate.outputVolume); } @end