From 47217364f541165b96344749fc18ccbb7bd8fb7c Mon Sep 17 00:00:00 2001 From: Peter Hanspers Date: Thu, 5 Oct 2017 11:39:15 +0200 Subject: [PATCH] Adding a KVO context to avoid issues with future super/sub-classing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:8342 Change-Id: I457858056ffc7f33bbfb261153301ea2ccd71a51 Reviewed-on: https://webrtc-review.googlesource.com/6440 Commit-Queue: Peter Hanspers Reviewed-by: Anders Carlsson Reviewed-by: Daniela Jovanoska Petrenko Reviewed-by: Kári Helgason Cr-Commit-Position: refs/heads/master@{#20389} --- .../Classes/Audio/RTCAudioSession.mm | 23 +++++++++----- .../UnitTests/RTCAudioSessionTest.mm | 30 +++++++++++++------ 2 files changed, 37 insertions(+), 16 deletions(-) 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