blob: 7cbd2a982a95d48a4b6f97e7cfa19b29a3902c7c [file] [log] [blame]
tkchin0ce3bf92016-03-12 16:52:04 -08001/*
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import <Foundation/Foundation.h>
12
13#include "testing/gtest/include/gtest/gtest.h"
14
15#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h"
tkchine54467f2016-03-15 16:54:03 -070016#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession+Private.h"
17
18@interface RTCAudioSessionTestDelegate : NSObject <RTCAudioSessionDelegate>
19@end
20
21@implementation RTCAudioSessionTestDelegate
22
23- (void)audioSessionDidBeginInterruption:(RTCAudioSession *)session {
24}
25
26- (void)audioSessionDidEndInterruption:(RTCAudioSession *)session
27 shouldResumeSession:(BOOL)shouldResumeSession {
28}
29
30- (void)audioSessionDidChangeRoute:(RTCAudioSession *)session
31 reason:(AVAudioSessionRouteChangeReason)reason
32 previousRoute:(AVAudioSessionRouteDescription *)previousRoute {
33}
34
35- (void)audioSessionMediaServicesWereLost:(RTCAudioSession *)session {
36}
37
38- (void)audioSessionMediaServicesWereReset:(RTCAudioSession *)session {
39}
40
41- (void)audioSessionShouldConfigure:(RTCAudioSession *)session {
42}
43
44- (void)audioSessionShouldUnconfigure:(RTCAudioSession *)session {
45}
46
47@end
48
tkchinefdd9302016-04-11 12:00:59 -070049// A delegate that adds itself to the audio session on init and removes itself
50// in its dealloc.
51@interface RTCTestRemoveOnDeallocDelegate : RTCAudioSessionTestDelegate
52@end
53
54@implementation RTCTestRemoveOnDeallocDelegate
55
56- (instancetype)init {
57 if (self = [super init]) {
58 RTCAudioSession *session = [RTCAudioSession sharedInstance];
59 [session addDelegate:self];
60 }
61 return self;
62}
63
64- (void)dealloc {
65 RTCAudioSession *session = [RTCAudioSession sharedInstance];
66 [session removeDelegate:self];
67}
68
69@end
70
tkchin0ce3bf92016-03-12 16:52:04 -080071
72@interface RTCAudioSessionTest : NSObject
73
74- (void)testLockForConfiguration;
75
76@end
77
78@implementation RTCAudioSessionTest
79
80- (void)testLockForConfiguration {
81 RTCAudioSession *session = [RTCAudioSession sharedInstance];
82
83 for (size_t i = 0; i < 2; i++) {
84 [session lockForConfiguration];
85 EXPECT_TRUE(session.isLocked);
86 }
87 for (size_t i = 0; i < 2; i++) {
88 EXPECT_TRUE(session.isLocked);
89 [session unlockForConfiguration];
90 }
91 EXPECT_FALSE(session.isLocked);
92}
93
tkchine54467f2016-03-15 16:54:03 -070094- (void)testAddAndRemoveDelegates {
95 RTCAudioSession *session = [RTCAudioSession sharedInstance];
96 NSMutableArray *delegates = [NSMutableArray array];
97 const size_t count = 5;
98 for (size_t i = 0; i < count; ++i) {
99 RTCAudioSessionTestDelegate *delegate =
100 [[RTCAudioSessionTestDelegate alloc] init];
101 [session addDelegate:delegate];
102 [delegates addObject:delegate];
103 EXPECT_EQ(i + 1, session.delegates.size());
104 }
105 [delegates enumerateObjectsUsingBlock:^(RTCAudioSessionTestDelegate *obj,
106 NSUInteger idx,
107 BOOL *stop) {
108 [session removeDelegate:obj];
109 }];
110 EXPECT_EQ(0u, session.delegates.size());
111}
112
113- (void)testPushDelegate {
114 RTCAudioSession *session = [RTCAudioSession sharedInstance];
115 NSMutableArray *delegates = [NSMutableArray array];
116 const size_t count = 2;
117 for (size_t i = 0; i < count; ++i) {
118 RTCAudioSessionTestDelegate *delegate =
119 [[RTCAudioSessionTestDelegate alloc] init];
120 [session addDelegate:delegate];
121 [delegates addObject:delegate];
122 }
123 // Test that it gets added to the front of the list.
124 RTCAudioSessionTestDelegate *pushedDelegate =
125 [[RTCAudioSessionTestDelegate alloc] init];
126 [session pushDelegate:pushedDelegate];
127 EXPECT_TRUE(pushedDelegate == session.delegates[0]);
128
129 // Test that it stays at the front of the list.
130 for (size_t i = 0; i < count; ++i) {
131 RTCAudioSessionTestDelegate *delegate =
132 [[RTCAudioSessionTestDelegate alloc] init];
133 [session addDelegate:delegate];
134 [delegates addObject:delegate];
135 }
136 EXPECT_TRUE(pushedDelegate == session.delegates[0]);
137
138 // Test that the next one goes to the front too.
139 pushedDelegate = [[RTCAudioSessionTestDelegate alloc] init];
140 [session pushDelegate:pushedDelegate];
141 EXPECT_TRUE(pushedDelegate == session.delegates[0]);
142}
143
144// Tests that delegates added to the audio session properly zero out. This is
145// checking an implementation detail (that vectors of __weak work as expected).
146- (void)testZeroingWeakDelegate {
147 RTCAudioSession *session = [RTCAudioSession sharedInstance];
148 @autoreleasepool {
149 // Add a delegate to the session. There should be one delegate at this
150 // point.
151 RTCAudioSessionTestDelegate *delegate =
152 [[RTCAudioSessionTestDelegate alloc] init];
153 [session addDelegate:delegate];
154 EXPECT_EQ(1u, session.delegates.size());
155 EXPECT_TRUE(session.delegates[0]);
156 }
157 // The previously created delegate should've de-alloced, leaving a nil ptr.
158 EXPECT_FALSE(session.delegates[0]);
159 RTCAudioSessionTestDelegate *delegate =
160 [[RTCAudioSessionTestDelegate alloc] init];
161 [session addDelegate:delegate];
162 // On adding a new delegate, nil ptrs should've been cleared.
163 EXPECT_EQ(1u, session.delegates.size());
164 EXPECT_TRUE(session.delegates[0]);
165}
166
tkchinefdd9302016-04-11 12:00:59 -0700167// Tests that we don't crash when removing delegates in dealloc.
168// Added as a regression test.
169- (void)testRemoveDelegateOnDealloc {
170 @autoreleasepool {
171 RTCTestRemoveOnDeallocDelegate *delegate =
172 [[RTCTestRemoveOnDeallocDelegate alloc] init];
173 EXPECT_TRUE(delegate);
174 }
175 RTCAudioSession *session = [RTCAudioSession sharedInstance];
176 EXPECT_EQ(0u, session.delegates.size());
177}
178
tkchin0ce3bf92016-03-12 16:52:04 -0800179@end
180
tkchine54467f2016-03-15 16:54:03 -0700181namespace webrtc {
182
183class AudioSessionTest : public ::testing::Test {
184 protected:
185 void TearDown() {
186 RTCAudioSession *session = [RTCAudioSession sharedInstance];
187 for (id<RTCAudioSessionDelegate> delegate : session.delegates) {
188 [session removeDelegate:delegate];
189 }
190 }
191};
192
193TEST_F(AudioSessionTest, LockForConfiguration) {
tkchin0ce3bf92016-03-12 16:52:04 -0800194 RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init];
195 [test testLockForConfiguration];
196}
tkchine54467f2016-03-15 16:54:03 -0700197
198TEST_F(AudioSessionTest, AddAndRemoveDelegates) {
199 RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init];
200 [test testAddAndRemoveDelegates];
201}
202
203TEST_F(AudioSessionTest, PushDelegate) {
204 RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init];
205 [test testPushDelegate];
206}
207
208TEST_F(AudioSessionTest, ZeroingWeakDelegate) {
209 RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init];
210 [test testZeroingWeakDelegate];
211}
212
tkchinefdd9302016-04-11 12:00:59 -0700213TEST_F(AudioSessionTest, RemoveDelegateOnDealloc) {
214 RTCAudioSessionTest *test = [[RTCAudioSessionTest alloc] init];
215 [test testRemoveDelegateOnDealloc];
216}
217
tkchine54467f2016-03-15 16:54:03 -0700218} // namespace webrtc