blob: 645fb778e7ec67bb9d21c9f846c90e6ac04fbc8d [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2013, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#if !defined(__has_feature) || !__has_feature(objc_arc)
29#error "This file requires ARC support."
30#endif
31
32#import "RTCPeerConnectionSyncObserver.h"
33
34#import "RTCMediaStream.h"
35
36@implementation RTCPeerConnectionSyncObserver {
37 int _expectedErrors;
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000038 NSMutableArray* _expectedSignalingChanges;
39 NSMutableArray* _expectedAddStreamLabels;
40 NSMutableArray* _expectedRemoveStreamLabels;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041 int _expectedICECandidates;
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000042 NSMutableArray* _receivedICECandidates;
43 NSMutableArray* _expectedICEConnectionChanges;
44 NSMutableArray* _expectedICEGatheringChanges;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045}
46
47- (id)init {
48 self = [super init];
49 if (self) {
50 _expectedSignalingChanges = [NSMutableArray array];
51 _expectedSignalingChanges = [NSMutableArray array];
52 _expectedAddStreamLabels = [NSMutableArray array];
53 _expectedRemoveStreamLabels = [NSMutableArray array];
54 _receivedICECandidates = [NSMutableArray array];
55 _expectedICEConnectionChanges = [NSMutableArray array];
56 _expectedICEGatheringChanges = [NSMutableArray array];
57 }
58 return self;
59}
60
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000061- (int)popFirstElementAsInt:(NSMutableArray*)array {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 NSAssert([array count] > 0, @"Empty array");
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000063 NSNumber* boxedState = [array objectAtIndex:0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 [array removeObjectAtIndex:0];
65 return [boxedState intValue];
66}
67
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000068- (NSString*)popFirstElementAsNSString:(NSMutableArray*)array {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069 NSAssert([array count] > 0, @"Empty expectation array");
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000070 NSString* string = [array objectAtIndex:0];
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071 [array removeObjectAtIndex:0];
72 return string;
73}
74
75- (BOOL)areAllExpectationsSatisfied {
76 return _expectedICECandidates <= 0 && // See comment in gotICECandidate.
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000077 _expectedErrors == 0 && [_expectedSignalingChanges count] == 0 &&
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078 [_expectedICEConnectionChanges count] == 0 &&
79 [_expectedICEGatheringChanges count] == 0 &&
80 [_expectedAddStreamLabels count] == 0 &&
81 [_expectedRemoveStreamLabels count] == 0;
82 // TODO(hughv): Test video state here too.
83}
84
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000085- (NSArray*)releaseReceivedICECandidates {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 NSArray* ret = _receivedICECandidates;
87 _receivedICECandidates = [NSMutableArray array];
88 return ret;
89}
90
91- (void)expectError {
92 ++_expectedErrors;
93}
94
95- (void)expectSignalingChange:(RTCSignalingState)state {
96 [_expectedSignalingChanges addObject:@((int)state)];
97}
98
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +000099- (void)expectAddStream:(NSString*)label {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100 [_expectedAddStreamLabels addObject:label];
101}
102
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000103- (void)expectRemoveStream:(NSString*)label {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104 [_expectedRemoveStreamLabels addObject:label];
105}
106
107- (void)expectICECandidates:(int)count {
108 _expectedICECandidates += count;
109}
110
111- (void)expectICEConnectionChange:(RTCICEConnectionState)state {
112 [_expectedICEConnectionChanges addObject:@((int)state)];
113}
114
115- (void)expectICEGatheringChange:(RTCICEGatheringState)state {
116 [_expectedICEGatheringChanges addObject:@((int)state)];
117}
118
119- (void)waitForAllExpectationsToBeSatisfied {
120 // TODO (fischman): Revisit. Keeping in sync with the Java version, but
121 // polling is not optimal.
122 // https://code.google.com/p/libjingle/source/browse/trunk/talk/app/webrtc/javatests/src/org/webrtc/PeerConnectionTest.java?line=212#212
123 while (![self areAllExpectationsSatisfied]) {
124 [[NSRunLoop currentRunLoop]
125 runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
126 }
127}
128
129#pragma mark - RTCPeerConnectionDelegate methods
130
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000131- (void)peerConnectionOnError:(RTCPeerConnection*)peerConnection {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132 NSLog(@"RTCPeerConnectionDelegate::onError");
133 NSAssert(--_expectedErrors >= 0, @"Unexpected error");
134}
135
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000136- (void)peerConnection:(RTCPeerConnection*)peerConnection
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 signalingStateChanged:(RTCSignalingState)stateChanged {
138 int expectedState = [self popFirstElementAsInt:_expectedSignalingChanges];
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000139 NSString* message =
140 [NSString stringWithFormat:@"RTCPeerConnectionDelegate::"
141 @"onSignalingStateChange [%d] expected[%d]",
142 stateChanged,
143 expectedState];
144 NSAssert(expectedState == (int)stateChanged, message);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145}
146
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000147- (void)peerConnection:(RTCPeerConnection*)peerConnection
148 addedStream:(RTCMediaStream*)stream {
149 NSString* expectedLabel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150 [self popFirstElementAsNSString:_expectedAddStreamLabels];
151 NSAssert([expectedLabel isEqual:stream.label], @"Stream not expected");
152}
153
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000154- (void)peerConnection:(RTCPeerConnection*)peerConnection
155 removedStream:(RTCMediaStream*)stream {
156 NSString* expectedLabel =
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157 [self popFirstElementAsNSString:_expectedRemoveStreamLabels];
158 NSAssert([expectedLabel isEqual:stream.label], @"Stream not expected");
159}
160
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000161- (void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection*)peerConnection {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162}
163
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000164- (void)peerConnection:(RTCPeerConnection*)peerConnection
165 gotICECandidate:(RTCICECandidate*)candidate {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 --_expectedICECandidates;
167 // We don't assert expectedICECandidates >= 0 because it's hard to know
168 // how many to expect, in general. We only use expectICECandidates to
169 // assert a minimal count.
170 [_receivedICECandidates addObject:candidate];
171}
172
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000173- (void)peerConnection:(RTCPeerConnection*)peerConnection
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 iceGatheringChanged:(RTCICEGatheringState)newState {
175 // It's fine to get a variable number of GATHERING messages before
176 // COMPLETE fires (depending on how long the test runs) so we don't assert
177 // any particular count.
178 if (newState == RTCICEGatheringGathering) {
179 return;
180 }
181 int expectedState = [self popFirstElementAsInt:_expectedICEGatheringChanges];
182 NSAssert(expectedState == (int)newState, @"Empty expectation array");
183}
184
fischman@webrtc.org7fa1fcb2014-03-25 00:11:56 +0000185- (void)peerConnection:(RTCPeerConnection*)peerConnection
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000186 iceConnectionChanged:(RTCICEConnectionState)newState {
fischman@webrtc.orga01daf02014-03-08 03:17:55 +0000187 // See TODO(fischman) in RTCPeerConnectionTest.mm about Completed.
188 if (newState == RTCICEConnectionCompleted)
189 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 int expectedState = [self popFirstElementAsInt:_expectedICEConnectionChanges];
191 NSAssert(expectedState == (int)newState, @"Empty expectation array");
192}
193
194@end