| /* |
| * Copyright 2016 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #import <Foundation/Foundation.h> |
| |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h" |
| #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h" |
| |
| @interface RTCAudioSessionTestDelegate : NSObject <RTCAudioSessionDelegate> |
| @end |
| |
| @implementation RTCAudioSessionTestDelegate |
| |
| - (void)audioSessionDidBeginInterruption:(RTCAudioSession *)session { |
| } |
| |
| - (void)audioSessionDidEndInterruption:(RTCAudioSession *)session |
| shouldResumeSession:(BOOL)shouldResumeSession { |
| } |
| |
| - (void)audioSessionDidChangeRoute:(RTCAudioSession *)session |
| reason:(AVAudioSessionRouteChangeReason)reason |
| previousRoute:(AVAudioSessionRouteDescription *)previousRoute { |
| } |
| |
| - (void)audioSessionMediaServicesWereLost:(RTCAudioSession *)session { |
| } |
| |
| - (void)audioSessionMediaServicesWereReset:(RTCAudioSession *)session { |
| } |
| |
| - (void)audioSessionShouldConfigure:(RTCAudioSession *)session { |
| } |
| |
| - (void)audioSessionShouldUnconfigure:(RTCAudioSession *)session { |
| } |
| |
| @end |
| |
| // A delegate that adds itself to the audio session on init and removes itself |
| // in its dealloc. |
| @interface RTCTestRemoveOnDeallocDelegate : RTCAudioSessionTestDelegate |
| @end |
| |
| @implementation RTCTestRemoveOnDeallocDelegate |
| |
| - (instancetype)init { |
| if (self = [super init]) { |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| [session addDelegate:self]; |
| } |
| return self; |
| } |
| |
| - (void)dealloc { |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| [session removeDelegate:self]; |
| } |
| |
| @end |
| |
| |
| @interface RTCAudioSessionTest : NSObject |
| |
| - (void)testLockForConfiguration; |
| |
| @end |
| |
| @implementation RTCAudioSessionTest |
| |
| - (void)testLockForConfiguration { |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| |
| for (size_t i = 0; i < 2; i++) { |
| [session lockForConfiguration]; |
| EXPECT_TRUE(session.isLocked); |
| } |
| for (size_t i = 0; i < 2; i++) { |
| EXPECT_TRUE(session.isLocked); |
| [session unlockForConfiguration]; |
| } |
| EXPECT_FALSE(session.isLocked); |
| } |
| |
| - (void)testAddAndRemoveDelegates { |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| NSMutableArray *delegates = [NSMutableArray array]; |
| const size_t count = 5; |
| for (size_t i = 0; i < count; ++i) { |
| RTCAudioSessionTestDelegate *delegate = |
| [[RTCAudioSessionTestDelegate alloc] init]; |
| [session addDelegate:delegate]; |
| [delegates addObject:delegate]; |
| EXPECT_EQ(i + 1, session.delegates.size()); |
| } |
| [delegates enumerateObjectsUsingBlock:^(RTCAudioSessionTestDelegate *obj, |
| NSUInteger idx, |
| BOOL *stop) { |
| [session removeDelegate:obj]; |
| }]; |
| EXPECT_EQ(0u, session.delegates.size()); |
| } |
| |
| - (void)testPushDelegate { |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| NSMutableArray *delegates = [NSMutableArray array]; |
| const size_t count = 2; |
| for (size_t i = 0; i < count; ++i) { |
| RTCAudioSessionTestDelegate *delegate = |
| [[RTCAudioSessionTestDelegate alloc] init]; |
| [session addDelegate:delegate]; |
| [delegates addObject:delegate]; |
| } |
| // Test that it gets added to the front of the list. |
| RTCAudioSessionTestDelegate *pushedDelegate = |
| [[RTCAudioSessionTestDelegate alloc] init]; |
| [session pushDelegate:pushedDelegate]; |
| EXPECT_TRUE(pushedDelegate == session.delegates[0]); |
| |
| // Test that it stays at the front of the list. |
| for (size_t i = 0; i < count; ++i) { |
| RTCAudioSessionTestDelegate *delegate = |
| [[RTCAudioSessionTestDelegate alloc] init]; |
| [session addDelegate:delegate]; |
| [delegates addObject:delegate]; |
| } |
| EXPECT_TRUE(pushedDelegate == session.delegates[0]); |
| |
| // Test that the next one goes to the front too. |
| pushedDelegate = [[RTCAudioSessionTestDelegate alloc] init]; |
| [session pushDelegate:pushedDelegate]; |
| EXPECT_TRUE(pushedDelegate == session.delegates[0]); |
| } |
| |
| // Tests that delegates added to the audio session properly zero out. This is |
| // checking an implementation detail (that vectors of __weak work as expected). |
| - (void)testZeroingWeakDelegate { |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| @autoreleasepool { |
| // Add a delegate to the session. There should be one delegate at this |
| // point. |
| RTCAudioSessionTestDelegate *delegate = |
| [[RTCAudioSessionTestDelegate alloc] init]; |
| [session addDelegate:delegate]; |
| EXPECT_EQ(1u, session.delegates.size()); |
| EXPECT_TRUE(session.delegates[0]); |
| } |
| // The previously created delegate should've de-alloced, leaving a nil ptr. |
| EXPECT_FALSE(session.delegates[0]); |
| RTCAudioSessionTestDelegate *delegate = |
| [[RTCAudioSessionTestDelegate alloc] init]; |
| [session addDelegate:delegate]; |
| // On adding a new delegate, nil ptrs should've been cleared. |
| EXPECT_EQ(1u, session.delegates.size()); |
| EXPECT_TRUE(session.delegates[0]); |
| } |
| |
| // Tests that we don't crash when removing delegates in dealloc. |
| // Added as a regression test. |
| - (void)testRemoveDelegateOnDealloc { |
| @autoreleasepool { |
| RTCTestRemoveOnDeallocDelegate *delegate = |
| [[RTCTestRemoveOnDeallocDelegate alloc] init]; |
| EXPECT_TRUE(delegate); |
| } |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| EXPECT_EQ(0u, session.delegates.size()); |
| } |
| |
| @end |
| |
| namespace webrtc { |
| |
| class AudioSessionTest : public ::testing::Test { |
| protected: |
| void TearDown() { |
| RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| for (id<RTCAudioSessionDelegate> delegate : session.delegates) { |
| [session removeDelegate:delegate]; |
| } |
| } |
| }; |
| |
| TEST_F(AudioSessionTest, LockForConfiguration) { |
| RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init]; |
| [test testLockForConfiguration]; |
| } |
| |
| TEST_F(AudioSessionTest, AddAndRemoveDelegates) { |
| RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init]; |
| [test testAddAndRemoveDelegates]; |
| } |
| |
| TEST_F(AudioSessionTest, PushDelegate) { |
| RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init]; |
| [test testPushDelegate]; |
| } |
| |
| TEST_F(AudioSessionTest, ZeroingWeakDelegate) { |
| RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init]; |
| [test testZeroingWeakDelegate]; |
| } |
| |
| TEST_F(AudioSessionTest, RemoveDelegateOnDealloc) { |
| RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init]; |
| [test testRemoveDelegateOnDealloc]; |
| } |
| |
| } // namespace webrtc |