Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / app / webrtc / objctests / RTCPeerConnectionSyncObserver.m
1 /*
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;
38   NSMutableArray* _expectedSignalingChanges;
39   NSMutableArray* _expectedAddStreamLabels;
40   NSMutableArray* _expectedRemoveStreamLabels;
41   int _expectedICECandidates;
42   NSMutableArray* _receivedICECandidates;
43   NSMutableArray* _expectedICEConnectionChanges;
44   NSMutableArray* _expectedICEGatheringChanges;
45   NSMutableArray* _expectedDataChannels;
46   NSMutableArray* _expectedStateChanges;
47   NSMutableArray* _expectedMessages;
48 }
49
50 - (id)init {
51   self = [super init];
52   if (self) {
53     _expectedSignalingChanges = [NSMutableArray array];
54     _expectedSignalingChanges = [NSMutableArray array];
55     _expectedAddStreamLabels = [NSMutableArray array];
56     _expectedRemoveStreamLabels = [NSMutableArray array];
57     _receivedICECandidates = [NSMutableArray array];
58     _expectedICEConnectionChanges = [NSMutableArray array];
59     _expectedICEGatheringChanges = [NSMutableArray array];
60     _expectedDataChannels = [NSMutableArray array];
61     _expectedMessages = [NSMutableArray array];
62     _expectedStateChanges = [NSMutableArray array];
63   }
64   return self;
65 }
66
67 - (int)popFirstElementAsInt:(NSMutableArray*)array {
68   NSAssert([array count] > 0, @"Empty array");
69   NSNumber* boxedState = [array objectAtIndex:0];
70   [array removeObjectAtIndex:0];
71   return [boxedState intValue];
72 }
73
74 - (NSString*)popFirstElementAsNSString:(NSMutableArray*)array {
75   NSAssert([array count] > 0, @"Empty expectation array");
76   NSString* string = [array objectAtIndex:0];
77   [array removeObjectAtIndex:0];
78   return string;
79 }
80
81 - (BOOL)areAllExpectationsSatisfied {
82   return _expectedICECandidates <= 0 &&  // See comment in gotICECandidate.
83          _expectedErrors == 0 && [_expectedSignalingChanges count] == 0 &&
84          [_expectedICEConnectionChanges count] == 0 &&
85          [_expectedICEGatheringChanges count] == 0 &&
86          [_expectedAddStreamLabels count] == 0 &&
87          [_expectedRemoveStreamLabels count] == 0 &&
88          [_expectedDataChannels count] == 0 &&
89          [_expectedStateChanges count] == 0 &&
90          [_expectedMessages count] == 0;
91   // TODO(hughv): Test video state here too.
92 }
93
94 - (NSArray*)releaseReceivedICECandidates {
95   NSArray* ret = _receivedICECandidates;
96   _receivedICECandidates = [NSMutableArray array];
97   return ret;
98 }
99
100 - (void)expectError {
101   ++_expectedErrors;
102 }
103
104 - (void)expectSignalingChange:(RTCSignalingState)state {
105   [_expectedSignalingChanges addObject:@((int)state)];
106 }
107
108 - (void)expectAddStream:(NSString*)label {
109   [_expectedAddStreamLabels addObject:label];
110 }
111
112 - (void)expectRemoveStream:(NSString*)label {
113   [_expectedRemoveStreamLabels addObject:label];
114 }
115
116 - (void)expectICECandidates:(int)count {
117   _expectedICECandidates += count;
118 }
119
120 - (void)expectICEConnectionChange:(RTCICEConnectionState)state {
121   [_expectedICEConnectionChanges addObject:@((int)state)];
122 }
123
124 - (void)expectICEGatheringChange:(RTCICEGatheringState)state {
125   [_expectedICEGatheringChanges addObject:@((int)state)];
126 }
127
128 - (void)expectDataChannel:(NSString*)label {
129   [_expectedDataChannels addObject:label];
130 }
131
132 - (void)expectStateChange:(RTCDataChannelState)state {
133   [_expectedStateChanges addObject:@(state)];
134 }
135
136 - (void)expectMessage:(NSData*)message isBinary:(BOOL)isBinary {
137   RTCDataBuffer* buffer = [[RTCDataBuffer alloc] initWithData:message
138                                                      isBinary:isBinary];
139   [_expectedMessages addObject:buffer];
140 }
141
142 - (void)waitForAllExpectationsToBeSatisfied {
143   // TODO (fischman):  Revisit.  Keeping in sync with the Java version, but
144   // polling is not optimal.
145   // https://code.google.com/p/libjingle/source/browse/trunk/talk/app/webrtc/javatests/src/org/webrtc/PeerConnectionTest.java?line=212#212
146   while (![self areAllExpectationsSatisfied]) {
147     [[NSRunLoop currentRunLoop]
148         runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
149   }
150 }
151
152 #pragma mark - RTCPeerConnectionDelegate methods
153
154 - (void)peerConnection:(RTCPeerConnection*)peerConnection
155     signalingStateChanged:(RTCSignalingState)stateChanged {
156   int expectedState = [self popFirstElementAsInt:_expectedSignalingChanges];
157   NSString* message =
158       [NSString stringWithFormat:@"RTCPeerConnectionDelegate::"
159                                  @"onSignalingStateChange [%d] expected[%d]",
160                                  stateChanged,
161                                  expectedState];
162   NSAssert(expectedState == (int)stateChanged, message);
163 }
164
165 - (void)peerConnection:(RTCPeerConnection*)peerConnection
166            addedStream:(RTCMediaStream*)stream {
167   NSString* expectedLabel =
168       [self popFirstElementAsNSString:_expectedAddStreamLabels];
169   NSAssert([expectedLabel isEqual:stream.label], @"Stream not expected");
170 }
171
172 - (void)peerConnection:(RTCPeerConnection*)peerConnection
173          removedStream:(RTCMediaStream*)stream {
174   NSString* expectedLabel =
175       [self popFirstElementAsNSString:_expectedRemoveStreamLabels];
176   NSAssert([expectedLabel isEqual:stream.label], @"Stream not expected");
177 }
178
179 - (void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection*)peerConnection {
180 }
181
182 - (void)peerConnection:(RTCPeerConnection*)peerConnection
183        gotICECandidate:(RTCICECandidate*)candidate {
184   --_expectedICECandidates;
185   // We don't assert expectedICECandidates >= 0 because it's hard to know
186   // how many to expect, in general.  We only use expectICECandidates to
187   // assert a minimal count.
188   [_receivedICECandidates addObject:candidate];
189 }
190
191 - (void)peerConnection:(RTCPeerConnection*)peerConnection
192     iceGatheringChanged:(RTCICEGatheringState)newState {
193   // It's fine to get a variable number of GATHERING messages before
194   // COMPLETE fires (depending on how long the test runs) so we don't assert
195   // any particular count.
196   if (newState == RTCICEGatheringGathering) {
197     return;
198   }
199   int expectedState = [self popFirstElementAsInt:_expectedICEGatheringChanges];
200   NSAssert(expectedState == (int)newState, @"Empty expectation array");
201 }
202
203 - (void)peerConnection:(RTCPeerConnection*)peerConnection
204   iceConnectionChanged:(RTCICEConnectionState)newState {
205   // See TODO(fischman) in RTCPeerConnectionTest.mm about Completed.
206   if (newState == RTCICEConnectionCompleted)
207     return;
208   int expectedState = [self popFirstElementAsInt:_expectedICEConnectionChanges];
209   NSAssert(expectedState == (int)newState, @"Empty expectation array");
210 }
211
212 - (void)peerConnection:(RTCPeerConnection*)peerConnection
213     didOpenDataChannel:(RTCDataChannel*)dataChannel {
214   NSString* expectedLabel =
215       [self popFirstElementAsNSString:_expectedDataChannels];
216   NSAssert([expectedLabel isEqual:dataChannel.label],
217            @"Data channel not expected");
218   self.dataChannel = dataChannel;
219   dataChannel.delegate = self;
220   NSAssert(kRTCDataChannelStateConnecting == dataChannel.state,
221            @"Unexpected state");
222 }
223
224 #pragma mark - RTCDataChannelDelegate
225
226 - (void)channelDidChangeState:(RTCDataChannel*)channel {
227   NSAssert([_expectedStateChanges count] > 0,
228            @"Unexpected state change");
229   int expectedState = [self popFirstElementAsInt:_expectedStateChanges];
230   NSAssert(expectedState == channel.state, @"Channel state should match");
231 }
232
233 - (void)channel:(RTCDataChannel*)channel
234     didReceiveMessageWithBuffer:(RTCDataBuffer*)buffer {
235   NSAssert([_expectedMessages count] > 0,
236            @"Unexpected message received");
237   RTCDataBuffer* expectedBuffer = [_expectedMessages objectAtIndex:0];
238   NSAssert(expectedBuffer.isBinary == buffer.isBinary,
239            @"Buffer isBinary should match");
240   NSAssert([expectedBuffer.data isEqual:buffer.data],
241            @"Buffer data should match");
242   [_expectedMessages removeObjectAtIndex:0];
243 }
244
245 @end