iOS AppRTC: First unit test.

Tests basic session ICE connection by stubbing out network components, which have been refactored to faciliate testing.

BUG=3994
R=jiayl@webrtc.org, kjellander@webrtc.org, phoglund@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/28349004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@8002 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
tkchin@webrtc.org 2015-01-06 07:21:34 +00:00
parent 4796cb93dc
commit 3a63a3c35d
26 changed files with 1244 additions and 366 deletions

1
.gitignore vendored
View File

@ -94,6 +94,7 @@
/third_party/modp_b64
/third_party/nss
/third_party/oauth2
/third_party/ocmock
/third_party/openmax_dl
/third_party/opus
/third_party/protobuf

View File

@ -55,6 +55,7 @@ DIRECTORIES = [
'third_party/libyuv',
'third_party/llvm-build',
'third_party/nss',
'third_party/ocmock',
'third_party/openmax_dl',
'third_party/opus',
'third_party/protobuf',

View File

@ -29,27 +29,20 @@
# used as an iOS or OS/X application.
{
'conditions': [
['OS=="ios"', {
'variables': {
'infoplist_file': './ios_test.plist',
},
'mac_bundle': 1,
'mac_bundle_resources': [
'<(infoplist_file)',
],
# The plist is listed above so that it appears in XCode's file list,
# but we don't actually want to bundle it.
'mac_bundle_resources!': [
'<(infoplist_file)',
],
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
# common.gypi enables this for mac but we want this to be disabled
# like it is for ios.
'CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS': 'NO',
'INFOPLIST_FILE': '<(infoplist_file)',
},
}],
], # conditions
'variables': {
'infoplist_file': './objc_app.plist',
},
'mac_bundle': 1,
'mac_bundle_resources': [
'<(infoplist_file)',
],
# The plist is listed above so that it appears in XCode's file list,
# but we don't actually want to bundle it.
'mac_bundle_resources!': [
'<(infoplist_file)',
],
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
'INFOPLIST_FILE': '<(infoplist_file)',
},
}

View File

@ -0,0 +1,68 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDAppClient.h"
#import "ARDRoomServerClient.h"
#import "ARDSignalingChannel.h"
#import "ARDTURNClient.h"
#import "RTCPeerConnection.h"
#import "RTCPeerConnectionDelegate.h"
#import "RTCPeerConnectionFactory.h"
#import "RTCSessionDescriptionDelegate.h"
@interface ARDAppClient () <ARDSignalingChannelDelegate,
RTCPeerConnectionDelegate, RTCSessionDescriptionDelegate>
@property(nonatomic, strong) id<ARDRoomServerClient> roomServerClient;
@property(nonatomic, strong) id<ARDSignalingChannel> channel;
@property(nonatomic, strong) id<ARDTURNClient> turnClient;
@property(nonatomic, strong) RTCPeerConnection *peerConnection;
@property(nonatomic, strong) RTCPeerConnectionFactory *factory;
@property(nonatomic, strong) NSMutableArray *messageQueue;
@property(nonatomic, assign) BOOL isTurnComplete;
@property(nonatomic, assign) BOOL hasReceivedSdp;
@property(nonatomic, readonly) BOOL isRegisteredWithRoomServer;
@property(nonatomic, strong) NSString *roomId;
@property(nonatomic, strong) NSString *clientId;
@property(nonatomic, assign) BOOL isInitiator;
@property(nonatomic, strong) NSMutableArray *iceServers;
@property(nonatomic, strong) NSURL *webSocketURL;
@property(nonatomic, strong) NSURL *webSocketRestURL;
@property(nonatomic, strong)
RTCMediaConstraints *defaultPeerConnectionConstraints;
- (instancetype)initWithRoomServerClient:(id<ARDRoomServerClient>)rsClient
signalingChannel:(id<ARDSignalingChannel>)channel
turnClient:(id<ARDTURNClient>)turnClient
delegate:(id<ARDAppClientDelegate>)delegate;
@end

View File

@ -44,6 +44,9 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
- (void)appClient:(ARDAppClient *)client
didChangeState:(ARDAppClientState)state;
- (void)appClient:(ARDAppClient *)client
didChangeConnectionState:(RTCICEConnectionState)state;
- (void)appClient:(ARDAppClient *)client
didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack;

View File

@ -25,38 +25,26 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDAppClient.h"
#import "ARDAppClient+Internal.h"
#import <AVFoundation/AVFoundation.h>
#import "ARDAppEngineClient.h"
#import "ARDCEODTURNClient.h"
#import "ARDMessageResponse.h"
#import "ARDRegisterResponse.h"
#import "ARDSignalingMessage.h"
#import "ARDUtilities.h"
#import "ARDWebSocketChannel.h"
#import "RTCICECandidate+JSON.h"
#import "RTCICEServer+JSON.h"
#import "RTCICEServer.h"
#import "RTCMediaConstraints.h"
#import "RTCMediaStream.h"
#import "RTCPair.h"
#import "RTCPeerConnection.h"
#import "RTCPeerConnectionDelegate.h"
#import "RTCPeerConnectionFactory.h"
#import "RTCSessionDescription+JSON.h"
#import "RTCSessionDescriptionDelegate.h"
#import "RTCVideoCapturer.h"
#import "RTCVideoTrack.h"
// TODO(tkchin): move these to a configuration object.
static NSString *kARDRoomServerHostUrl =
@"https://apprtc.appspot.com";
static NSString *kARDRoomServerRegisterFormat =
@"https://apprtc.appspot.com/register/%@";
static NSString *kARDRoomServerMessageFormat =
@"https://apprtc.appspot.com/message/%@/%@";
static NSString *kARDRoomServerByeFormat =
@"https://apprtc.appspot.com/bye/%@/%@";
static NSString *kARDDefaultSTUNServerUrl =
@"stun:stun.l.google.com:19302";
// TODO(tkchin): figure out a better username for CEOD statistics.
@ -69,34 +57,16 @@ static NSInteger kARDAppClientErrorUnknown = -1;
static NSInteger kARDAppClientErrorRoomFull = -2;
static NSInteger kARDAppClientErrorCreateSDP = -3;
static NSInteger kARDAppClientErrorSetSDP = -4;
static NSInteger kARDAppClientErrorNetwork = -5;
static NSInteger kARDAppClientErrorInvalidClient = -6;
static NSInteger kARDAppClientErrorInvalidRoom = -7;
@interface ARDAppClient () <ARDWebSocketChannelDelegate,
RTCPeerConnectionDelegate, RTCSessionDescriptionDelegate>
@property(nonatomic, strong) ARDWebSocketChannel *channel;
@property(nonatomic, strong) RTCPeerConnection *peerConnection;
@property(nonatomic, strong) RTCPeerConnectionFactory *factory;
@property(nonatomic, strong) NSMutableArray *messageQueue;
@property(nonatomic, assign) BOOL isTurnComplete;
@property(nonatomic, assign) BOOL hasReceivedSdp;
@property(nonatomic, readonly) BOOL isRegisteredWithRoomServer;
@property(nonatomic, strong) NSString *roomId;
@property(nonatomic, strong) NSString *clientId;
@property(nonatomic, assign) BOOL isInitiator;
@property(nonatomic, strong) NSMutableArray *iceServers;
@property(nonatomic, strong) NSURL *webSocketURL;
@property(nonatomic, strong) NSURL *webSocketRestURL;
@end
static NSInteger kARDAppClientErrorInvalidClient = -5;
static NSInteger kARDAppClientErrorInvalidRoom = -6;
@implementation ARDAppClient
@synthesize delegate = _delegate;
@synthesize state = _state;
@synthesize roomServerClient = _roomServerClient;
@synthesize channel = _channel;
@synthesize turnClient = _turnClient;
@synthesize peerConnection = _peerConnection;
@synthesize factory = _factory;
@synthesize messageQueue = _messageQueue;
@ -108,17 +78,46 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
@synthesize iceServers = _iceServers;
@synthesize webSocketURL = _websocketURL;
@synthesize webSocketRestURL = _websocketRestURL;
@synthesize defaultPeerConnectionConstraints =
_defaultPeerConnectionConstraints;
- (instancetype)initWithDelegate:(id<ARDAppClientDelegate>)delegate {
if (self = [super init]) {
_roomServerClient = [[ARDAppEngineClient alloc] init];
_delegate = delegate;
_factory = [[RTCPeerConnectionFactory alloc] init];
_messageQueue = [NSMutableArray array];
_iceServers = [NSMutableArray arrayWithObject:[self defaultSTUNServer]];
NSURL *turnRequestURL = [NSURL URLWithString:kARDTurnRequestUrl];
_turnClient = [[ARDCEODTURNClient alloc] initWithURL:turnRequestURL];
[self configure];
}
return self;
}
// TODO(tkchin): Provide signaling channel factory interface so we can recreate
// channel if we need to on network failure. Also, make this the default public
// constructor.
- (instancetype)initWithRoomServerClient:(id<ARDRoomServerClient>)rsClient
signalingChannel:(id<ARDSignalingChannel>)channel
turnClient:(id<ARDTURNClient>)turnClient
delegate:(id<ARDAppClientDelegate>)delegate {
NSParameterAssert(rsClient);
NSParameterAssert(channel);
NSParameterAssert(turnClient);
if (self = [super init]) {
_roomServerClient = rsClient;
_channel = channel;
_turnClient = turnClient;
_delegate = delegate;
[self configure];
}
return self;
}
- (void)configure {
_factory = [[RTCPeerConnectionFactory alloc] init];
_messageQueue = [NSMutableArray array];
_iceServers = [NSMutableArray arrayWithObject:[self defaultSTUNServer]];
}
- (void)dealloc {
[self disconnect];
}
@ -139,9 +138,11 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
// Request TURN.
__weak ARDAppClient *weakSelf = self;
NSURL *turnRequestURL = [NSURL URLWithString:kARDTurnRequestUrl];
[self requestTURNServersWithURL:turnRequestURL
completionHandler:^(NSArray *turnServers) {
[_turnClient requestServersWithCompletionHandler:^(NSArray *turnServers,
NSError *error) {
if (error) {
NSLog(@"Error retrieving TURN servers: %@", error);
}
ARDAppClient *strongSelf = weakSelf;
[strongSelf.iceServers addObjectsFromArray:turnServers];
strongSelf.isTurnComplete = YES;
@ -149,23 +150,21 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
}];
// Register with room server.
[self registerWithRoomServerForRoomId:roomId
completionHandler:^(ARDRegisterResponse *response) {
[_roomServerClient registerForRoomId:roomId
completionHandler:^(ARDRegisterResponse *response, NSError *error) {
ARDAppClient *strongSelf = weakSelf;
if (!response || response.result != kARDRegisterResultTypeSuccess) {
NSLog(@"Failed to register with room server. Result:%d",
(int)response.result);
[strongSelf disconnect];
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: @"Room is full.",
};
NSError *error =
[[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorRoomFull
userInfo:userInfo];
if (error) {
[strongSelf.delegate appClient:strongSelf didError:error];
return;
}
NSError *registerError =
[[strongSelf class] errorForRegisterResultType:response.result];
if (registerError) {
NSLog(@"Failed to register with room server.");
[strongSelf disconnect];
[strongSelf.delegate appClient:strongSelf didError:registerError];
return;
}
NSLog(@"Registered with room server.");
strongSelf.roomId = response.roomId;
strongSelf.clientId = response.clientId;
@ -191,14 +190,15 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
return;
}
if (self.isRegisteredWithRoomServer) {
[self unregisterWithRoomServer];
[_roomServerClient deregisterForRoomId:_roomId
clientId:_clientId
completionHandler:nil];
}
if (_channel) {
if (_channel.state == kARDWebSocketChannelStateRegistered) {
if (_channel.state == kARDSignalingChannelStateRegistered) {
// Tell the other client we're hanging up.
ARDByeMessage *byeMessage = [[ARDByeMessage alloc] init];
NSData *byeData = [byeMessage JSONData];
[_channel sendData:byeData];
[_channel sendMessage:byeMessage];
}
// Disconnect from collider.
_channel = nil;
@ -212,9 +212,9 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
self.state = kARDAppClientStateDisconnected;
}
#pragma mark - ARDWebSocketChannelDelegate
#pragma mark - ARDSignalingChannelDelegate
- (void)channel:(ARDWebSocketChannel *)channel
- (void)channel:(id<ARDSignalingChannel>)channel
didReceiveMessage:(ARDSignalingMessage *)message {
switch (message.type) {
case kARDSignalingMessageTypeOffer:
@ -232,15 +232,15 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
[self drainMessageQueueIfReady];
}
- (void)channel:(ARDWebSocketChannel *)channel
didChangeState:(ARDWebSocketChannelState)state {
- (void)channel:(id<ARDSignalingChannel>)channel
didChangeState:(ARDSignalingChannelState)state {
switch (state) {
case kARDWebSocketChannelStateOpen:
case kARDSignalingChannelStateOpen:
break;
case kARDWebSocketChannelStateRegistered:
case kARDSignalingChannelStateRegistered:
break;
case kARDWebSocketChannelStateClosed:
case kARDWebSocketChannelStateError:
case kARDSignalingChannelStateClosed:
case kARDSignalingChannelStateError:
// TODO(tkchin): reconnection scenarios. Right now we just disconnect
// completely if the websocket connection fails.
[self disconnect];
@ -281,6 +281,9 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
- (void)peerConnection:(RTCPeerConnection *)peerConnection
iceConnectionChanged:(RTCICEConnectionState)newState {
NSLog(@"ICE state changed: %d", newState);
dispatch_async(dispatch_get_main_queue(), ^{
[_delegate appClient:self didChangeConnectionState:newState];
});
}
- (void)peerConnection:(RTCPeerConnection *)peerConnection
@ -430,9 +433,26 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
- (void)sendSignalingMessage:(ARDSignalingMessage *)message {
if (_isInitiator) {
[self sendSignalingMessageToRoomServer:message completionHandler:nil];
__weak ARDAppClient *weakSelf = self;
[_roomServerClient sendMessage:message
forRoomId:_roomId
clientId:_clientId
completionHandler:^(ARDMessageResponse *response,
NSError *error) {
ARDAppClient *strongSelf = weakSelf;
if (error) {
[strongSelf.delegate appClient:strongSelf didError:error];
return;
}
NSError *messageError =
[[strongSelf class] errorForMessageResultType:response.result];
if (messageError) {
[strongSelf.delegate appClient:strongSelf didError:messageError];
return;
}
}];
} else {
[self sendSignalingMessageToCollider:message];
[_channel sendMessage:message];
}
}
@ -473,142 +493,6 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
return localStream;
}
- (void)requestTURNServersWithURL:(NSURL *)requestURL
completionHandler:(void (^)(NSArray *turnServers))completionHandler {
NSParameterAssert([requestURL absoluteString].length);
NSMutableURLRequest *request =
[NSMutableURLRequest requestWithURL:requestURL];
// We need to set origin because TURN provider whitelists requests based on
// origin.
[request addValue:@"Mozilla/5.0" forHTTPHeaderField:@"user-agent"];
[request addValue:kARDRoomServerHostUrl forHTTPHeaderField:@"origin"];
[NSURLConnection sendAsyncRequest:request
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error) {
NSArray *turnServers = [NSArray array];
if (error) {
NSLog(@"Unable to get TURN server.");
completionHandler(turnServers);
return;
}
NSDictionary *dict = [NSDictionary dictionaryWithJSONData:data];
turnServers = [RTCICEServer serversFromCEODJSONDictionary:dict];
completionHandler(turnServers);
}];
}
#pragma mark - Room server methods
- (void)registerWithRoomServerForRoomId:(NSString *)roomId
completionHandler:(void (^)(ARDRegisterResponse *))completionHandler {
NSString *urlString =
[NSString stringWithFormat:kARDRoomServerRegisterFormat, roomId];
NSURL *roomURL = [NSURL URLWithString:urlString];
NSLog(@"Registering with room server.");
__weak ARDAppClient *weakSelf = self;
[NSURLConnection sendAsyncPostToURL:roomURL
withData:nil
completionHandler:^(BOOL succeeded, NSData *data) {
ARDAppClient *strongSelf = weakSelf;
if (!succeeded) {
NSError *error = [self roomServerNetworkError];
[strongSelf.delegate appClient:strongSelf didError:error];
completionHandler(nil);
return;
}
ARDRegisterResponse *response =
[ARDRegisterResponse responseFromJSONData:data];
completionHandler(response);
}];
}
- (void)sendSignalingMessageToRoomServer:(ARDSignalingMessage *)message
completionHandler:(void (^)(ARDMessageResponse *))completionHandler {
NSData *data = [message JSONData];
NSString *urlString =
[NSString stringWithFormat:
kARDRoomServerMessageFormat, _roomId, _clientId];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(@"C->RS POST: %@", message);
__weak ARDAppClient *weakSelf = self;
[NSURLConnection sendAsyncPostToURL:url
withData:data
completionHandler:^(BOOL succeeded, NSData *data) {
ARDAppClient *strongSelf = weakSelf;
if (!succeeded) {
NSError *error = [self roomServerNetworkError];
[strongSelf.delegate appClient:strongSelf didError:error];
return;
}
ARDMessageResponse *response =
[ARDMessageResponse responseFromJSONData:data];
NSError *error = nil;
switch (response.result) {
case kARDMessageResultTypeSuccess:
break;
case kARDMessageResultTypeUnknown:
error =
[[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey: @"Unknown error.",
}];
case kARDMessageResultTypeInvalidClient:
error =
[[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorInvalidClient
userInfo:@{
NSLocalizedDescriptionKey: @"Invalid client.",
}];
break;
case kARDMessageResultTypeInvalidRoom:
error =
[[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorInvalidRoom
userInfo:@{
NSLocalizedDescriptionKey: @"Invalid room.",
}];
break;
};
if (error) {
[strongSelf.delegate appClient:strongSelf didError:error];
}
if (completionHandler) {
completionHandler(response);
}
}];
}
- (void)unregisterWithRoomServer {
NSString *urlString =
[NSString stringWithFormat:kARDRoomServerByeFormat, _roomId, _clientId];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
// We want a synchronous request so that we know that we're unregistered from
// room server before we do any further unregistration.
NSLog(@"C->RS: BYE");
NSError *error = nil;
[NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
NSLog(@"Error unregistering from room server: %@", error);
}
NSLog(@"Unregistered from room server.");
}
- (NSError *)roomServerNetworkError {
NSError *error =
[[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorNetwork
userInfo:@{
NSLocalizedDescriptionKey: @"Room server network error",
}];
return error;
}
#pragma mark - Collider methods
- (void)registerWithColliderIfReady {
@ -616,18 +500,15 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
return;
}
// Open WebSocket connection.
_channel =
[[ARDWebSocketChannel alloc] initWithURL:_websocketURL
restURL:_websocketRestURL
delegate:self];
if (!_channel) {
_channel =
[[ARDWebSocketChannel alloc] initWithURL:_websocketURL
restURL:_websocketRestURL
delegate:self];
}
[_channel registerForRoomId:_roomId clientId:_clientId];
}
- (void)sendSignalingMessageToCollider:(ARDSignalingMessage *)message {
NSData *data = [message JSONData];
[_channel sendData:data];
}
#pragma mark - Defaults
- (RTCMediaConstraints *)defaultMediaStreamConstraints {
@ -655,6 +536,9 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
}
- (RTCMediaConstraints *)defaultPeerConnectionConstraints {
if (_defaultPeerConnectionConstraints) {
return _defaultPeerConnectionConstraints;
}
NSArray *optionalConstraints = @[
[[RTCPair alloc] initWithKey:@"DtlsSrtpKeyAgreement" value:@"true"]
];
@ -672,4 +556,61 @@ static NSInteger kARDAppClientErrorInvalidRoom = -7;
password:@""];
}
#pragma mark - Errors
+ (NSError *)errorForRegisterResultType:(ARDRegisterResultType)resultType {
NSError *error = nil;
switch (resultType) {
case kARDRegisterResultTypeSuccess:
break;
case kARDRegisterResultTypeUnknown: {
error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey: @"Unknown error.",
}];
break;
}
case kARDRegisterResultTypeFull: {
error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorRoomFull
userInfo:@{
NSLocalizedDescriptionKey: @"Room is full.",
}];
break;
}
}
return error;
}
+ (NSError *)errorForMessageResultType:(ARDMessageResultType)resultType {
NSError *error = nil;
switch (resultType) {
case kARDMessageResultTypeSuccess:
break;
case kARDMessageResultTypeUnknown:
error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey: @"Unknown error.",
}];
break;
case kARDMessageResultTypeInvalidClient:
error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorInvalidClient
userInfo:@{
NSLocalizedDescriptionKey: @"Invalid client.",
}];
break;
case kARDMessageResultTypeInvalidRoom:
error = [[NSError alloc] initWithDomain:kARDAppClientErrorDomain
code:kARDAppClientErrorInvalidRoom
userInfo:@{
NSLocalizedDescriptionKey: @"Invalid room.",
}];
break;
}
return error;
}
@end

View File

@ -0,0 +1,31 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDRoomServerClient.h"
@interface ARDAppEngineClient : NSObject <ARDRoomServerClient>
@end

View File

@ -0,0 +1,178 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDAppEngineClient.h"
#import "ARDMessageResponse.h"
#import "ARDRegisterResponse.h"
#import "ARDSignalingMessage.h"
#import "ARDUtilities.h"
// TODO(tkchin): move these to a configuration object.
static NSString *kARDRoomServerHostUrl =
@"https://apprtc.appspot.com";
static NSString *kARDRoomServerRegisterFormat =
@"https://apprtc.appspot.com/register/%@";
static NSString *kARDRoomServerMessageFormat =
@"https://apprtc.appspot.com/message/%@/%@";
static NSString *kARDRoomServerByeFormat =
@"https://apprtc.appspot.com/bye/%@/%@";
static NSString *kARDAppEngineClientErrorDomain = @"ARDAppEngineClient";
static NSInteger kARDAppEngineClientErrorBadResponse = -1;
@implementation ARDAppEngineClient
#pragma mark - ARDRoomServerClient
- (void)registerForRoomId:(NSString *)roomId
completionHandler:(void (^)(ARDRegisterResponse *response,
NSError *error))completionHandler {
NSParameterAssert(roomId.length);
NSString *urlString =
[NSString stringWithFormat:kARDRoomServerRegisterFormat, roomId];
NSURL *roomURL = [NSURL URLWithString:urlString];
NSLog(@"Registering with room server.");
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:roomURL];
request.HTTPMethod = @"POST";
__weak ARDAppEngineClient *weakSelf = self;
[NSURLConnection sendAsyncRequest:request
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error) {
ARDAppEngineClient *strongSelf = weakSelf;
if (error) {
if (completionHandler) {
completionHandler(nil, error);
}
return;
}
ARDRegisterResponse *registerResponse =
[ARDRegisterResponse responseFromJSONData:data];
if (!registerResponse) {
if (completionHandler) {
NSError *error = [[self class] badResponseError];
completionHandler(nil, error);
}
return;
}
if (completionHandler) {
completionHandler(registerResponse, nil);
}
}];
}
- (void)sendMessage:(ARDSignalingMessage *)message
forRoomId:(NSString *)roomId
clientId:(NSString *)clientId
completionHandler:(void (^)(ARDMessageResponse *response,
NSError *error))completionHandler {
NSParameterAssert(message);
NSParameterAssert(roomId.length);
NSParameterAssert(clientId.length);
NSData *data = [message JSONData];
NSString *urlString =
[NSString stringWithFormat:
kARDRoomServerMessageFormat, roomId, clientId];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(@"C->RS POST: %@", message);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = data;
__weak ARDAppEngineClient *weakSelf = self;
[NSURLConnection sendAsyncRequest:request
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error) {
ARDAppEngineClient *strongSelf = weakSelf;
if (error) {
if (completionHandler) {
completionHandler(nil, error);
}
return;
}
ARDMessageResponse *messageResponse =
[ARDMessageResponse responseFromJSONData:data];
if (!messageResponse) {
if (completionHandler) {
NSError *error = [[self class] badResponseError];
completionHandler(nil, error);
}
return;
}
if (completionHandler) {
completionHandler(messageResponse, nil);
}
}];
}
- (void)deregisterForRoomId:(NSString *)roomId
clientId:(NSString *)clientId
completionHandler:(void (^)(NSError *error))completionHandler {
NSParameterAssert(roomId.length);
NSParameterAssert(clientId.length);
NSString *urlString =
[NSString stringWithFormat:kARDRoomServerByeFormat, roomId, clientId];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;
// We want a synchronous request so that we know that we're unregistered from
// room server before we do any further unregistration.
NSLog(@"C->RS: BYE");
[NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
NSLog(@"Error unregistering from room server: %@", error);
if (completionHandler) {
completionHandler(error);
}
return;
}
NSLog(@"Unregistered from room server.");
if (completionHandler) {
completionHandler(nil);
}
}
#pragma mark - Private
+ (NSError *)badResponseError {
NSError *error =
[[NSError alloc] initWithDomain:kARDAppEngineClientErrorDomain
code:kARDAppEngineClientErrorBadResponse
userInfo:@{
NSLocalizedDescriptionKey: @"Error parsing response.",
}];
return error;
}
@end

View File

@ -0,0 +1,35 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDTURNClient.h"
// Requests TURN server urls from compute engine on demand.
@interface ARDCEODTURNClient : NSObject <ARDTURNClient>
- (instancetype)initWithURL:(NSURL *)url;
@end

View File

@ -0,0 +1,83 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDCEODTURNClient.h"
#import "ARDUtilities.h"
#import "RTCICEServer+JSON.h"
// TODO(tkchin): move this to a configuration object.
static NSString *kTURNOriginURLString = @"https://apprtc.appspot.com";
static NSString *kARDCEODTURNClientErrorDomain = @"ARDCEODTURNClient";
static NSInteger kARDCEODTURNClientErrorBadResponse = -1;
@implementation ARDCEODTURNClient {
NSURL *_url;
}
- (instancetype)initWithURL:(NSURL *)url {
NSParameterAssert([url absoluteString].length);
if (self = [super init]) {
_url = url;
}
return self;
}
- (void)requestServersWithCompletionHandler:
(void (^)(NSArray *turnServers,
NSError *error))completionHandler {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url];
// We need to set origin because TURN provider whitelists requests based on
// origin.
[request addValue:@"Mozilla/5.0" forHTTPHeaderField:@"user-agent"];
[request addValue:kTURNOriginURLString forHTTPHeaderField:@"origin"];
[NSURLConnection sendAsyncRequest:request
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error) {
NSArray *turnServers = [NSArray array];
if (error) {
completionHandler(turnServers, error);
return;
}
NSDictionary *dict = [NSDictionary dictionaryWithJSONData:data];
turnServers = [RTCICEServer serversFromCEODJSONDictionary:dict];
if (!turnServers) {
NSError *responseError =
[[NSError alloc] initWithDomain:kARDCEODTURNClientErrorDomain
code:kARDCEODTURNClientErrorBadResponse
userInfo:@{
NSLocalizedDescriptionKey: @"Bad TURN response.",
}];
completionHandler(turnServers, responseError);
return;
}
completionHandler(turnServers, nil);
}];
}
@end

View File

@ -0,0 +1,34 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDMessageResponse.h"
@interface ARDMessageResponse ()
@property(nonatomic, assign) ARDMessageResultType result;
@end

View File

@ -25,18 +25,12 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDMessageResponse.h"
#import "ARDMessageResponse+Internal.h"
#import "ARDUtilities.h"
static NSString const *kARDMessageResultKey = @"result";
@interface ARDMessageResponse ()
@property(nonatomic, assign) ARDMessageResultType result;
@end
@implementation ARDMessageResponse
@synthesize result = _result;

View File

@ -0,0 +1,40 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDRegisterResponse.h"
@interface ARDRegisterResponse ()
@property(nonatomic, assign) ARDRegisterResultType result;
@property(nonatomic, assign) BOOL isInitiator;
@property(nonatomic, strong) NSString *roomId;
@property(nonatomic, strong) NSString *clientId;
@property(nonatomic, strong) NSArray *messages;
@property(nonatomic, strong) NSURL *webSocketURL;
@property(nonatomic, strong) NSURL *webSocketRestURL;
@end

View File

@ -25,7 +25,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "ARDRegisterResponse.h"
#import "ARDRegisterResponse+Internal.h"
#import "ARDSignalingMessage.h"
#import "ARDUtilities.h"
@ -40,18 +40,6 @@ static NSString const *kARDRegisterMessagesKey = @"messages";
static NSString const *kARDRegisterWebSocketURLKey = @"wss_url";
static NSString const *kARDRegisterWebSocketRestURLKey = @"wss_post_url";
@interface ARDRegisterResponse ()
@property(nonatomic, assign) ARDRegisterResultType result;
@property(nonatomic, assign) BOOL isInitiator;
@property(nonatomic, strong) NSString *roomId;
@property(nonatomic, strong) NSString *clientId;
@property(nonatomic, strong) NSArray *messages;
@property(nonatomic, strong) NSURL *webSocketURL;
@property(nonatomic, strong) NSURL *webSocketRestURL;
@end
@implementation ARDRegisterResponse
@synthesize result = _result;

View File

@ -0,0 +1,50 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
@class ARDMessageResponse;
@class ARDRegisterResponse;
@class ARDSignalingMessage;
@protocol ARDRoomServerClient <NSObject>
- (void)registerForRoomId:(NSString *)roomId
completionHandler:(void (^)(ARDRegisterResponse *response,
NSError *error))completionHandler;
- (void)sendMessage:(ARDSignalingMessage *)message
forRoomId:(NSString *)roomId
clientId:(NSString *)clientId
completionHandler:(void (^)(ARDMessageResponse *response,
NSError *error))completionHandler;
- (void)deregisterForRoomId:(NSString *)roomId
clientId:(NSString *)clientId
completionHandler:(void (^)(NSError *error))completionHandler;
@end

View File

@ -0,0 +1,69 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
#import "ARDSignalingMessage.h"
typedef NS_ENUM(NSInteger, ARDSignalingChannelState) {
// State when disconnected.
kARDSignalingChannelStateClosed,
// State when connection is established but not ready for use.
kARDSignalingChannelStateOpen,
// State when connection is established and registered.
kARDSignalingChannelStateRegistered,
// State when connection encounters a fatal error.
kARDSignalingChannelStateError
};
@protocol ARDSignalingChannel;
@protocol ARDSignalingChannelDelegate <NSObject>
- (void)channel:(id<ARDSignalingChannel>)channel
didChangeState:(ARDSignalingChannelState)state;
- (void)channel:(id<ARDSignalingChannel>)channel
didReceiveMessage:(ARDSignalingMessage *)message;
@end
@protocol ARDSignalingChannel <NSObject>
@property(nonatomic, readonly) NSString *roomId;
@property(nonatomic, readonly) NSString *clientId;
@property(nonatomic, readonly) ARDSignalingChannelState state;
@property(nonatomic, weak) id<ARDSignalingChannelDelegate> delegate;
// Registers the channel for the given room and client id.
- (void)registerForRoomId:(NSString *)roomId
clientId:(NSString *)clientId;
// Sends signaling message over the channel.
- (void)sendMessage:(ARDSignalingMessage *)message;
@end

View File

@ -0,0 +1,37 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
@protocol ARDTURNClient <NSObject>
// Returns TURN server urls if successful.
- (void)requestServersWithCompletionHandler:
(void (^)(NSArray *turnServers,
NSError *error))completionHandler;
@end

View File

@ -27,49 +27,22 @@
#import <Foundation/Foundation.h>
#import "ARDSignalingMessage.h"
typedef NS_ENUM(NSInteger, ARDWebSocketChannelState) {
// State when disconnected.
kARDWebSocketChannelStateClosed,
// State when connection is established but not ready for use.
kARDWebSocketChannelStateOpen,
// State when connection is established and registered.
kARDWebSocketChannelStateRegistered,
// State when connection encounters a fatal error.
kARDWebSocketChannelStateError
};
@class ARDWebSocketChannel;
@protocol ARDWebSocketChannelDelegate <NSObject>
- (void)channel:(ARDWebSocketChannel *)channel
didChangeState:(ARDWebSocketChannelState)state;
- (void)channel:(ARDWebSocketChannel *)channel
didReceiveMessage:(ARDSignalingMessage *)message;
@end
#import "ARDSignalingChannel.h"
// Wraps a WebSocket connection to the AppRTC WebSocket server.
@interface ARDWebSocketChannel : NSObject
@property(nonatomic, readonly) NSString *roomId;
@property(nonatomic, readonly) NSString *clientId;
@property(nonatomic, readonly) ARDWebSocketChannelState state;
@property(nonatomic, weak) id<ARDWebSocketChannelDelegate> delegate;
@interface ARDWebSocketChannel : NSObject <ARDSignalingChannel>
- (instancetype)initWithURL:(NSURL *)url
restURL:(NSURL *)restURL
delegate:(id<ARDWebSocketChannelDelegate>)delegate;
delegate:(id<ARDSignalingChannelDelegate>)delegate;
// Registers with the WebSocket server for the given room and client id once
// the web socket connection is open.
- (void)registerForRoomId:(NSString *)roomId
clientId:(NSString *)clientId;
// Sends data over the WebSocket connection if registered, otherwise POSTs to
// Sends message over the WebSocket connection if registered, otherwise POSTs to
// the web socket server instead.
- (void)sendData:(NSData *)data;
- (void)sendMessage:(ARDSignalingMessage *)message;
@end

View File

@ -50,7 +50,7 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
- (instancetype)initWithURL:(NSURL *)url
restURL:(NSURL *)restURL
delegate:(id<ARDWebSocketChannelDelegate>)delegate {
delegate:(id<ARDSignalingChannelDelegate>)delegate {
if (self = [super init]) {
_url = url;
_restURL = restURL;
@ -67,7 +67,7 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
[self disconnect];
}
- (void)setState:(ARDWebSocketChannelState)state {
- (void)setState:(ARDSignalingChannelState)state {
if (_state == state) {
return;
}
@ -81,15 +81,16 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
NSParameterAssert(clientId.length);
_roomId = roomId;
_clientId = clientId;
if (_state == kARDWebSocketChannelStateOpen) {
if (_state == kARDSignalingChannelStateOpen) {
[self registerWithCollider];
}
}
- (void)sendData:(NSData *)data {
- (void)sendMessage:(ARDSignalingMessage *)message {
NSParameterAssert(_clientId.length);
NSParameterAssert(_roomId.length);
if (_state == kARDWebSocketChannelStateRegistered) {
NSData *data = [message JSONData];
if (_state == kARDSignalingChannelStateRegistered) {
NSString *payload =
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *message = @{
@ -120,8 +121,8 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
}
- (void)disconnect {
if (_state == kARDWebSocketChannelStateClosed ||
_state == kARDWebSocketChannelStateError) {
if (_state == kARDSignalingChannelStateClosed ||
_state == kARDSignalingChannelStateError) {
return;
}
[_socket close];
@ -140,7 +141,7 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
NSLog(@"WebSocket connection opened.");
self.state = kARDWebSocketChannelStateOpen;
self.state = kARDSignalingChannelStateOpen;
if (_roomId.length && _clientId.length) {
[self registerWithCollider];
}
@ -171,7 +172,7 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
NSLog(@"WebSocket error: %@", error);
self.state = kARDWebSocketChannelStateError;
self.state = kARDSignalingChannelStateError;
}
- (void)webSocket:(SRWebSocket *)webSocket
@ -180,14 +181,14 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
wasClean:(BOOL)wasClean {
NSLog(@"WebSocket closed with code: %ld reason:%@ wasClean:%d",
(long)code, reason, wasClean);
NSParameterAssert(_state != kARDWebSocketChannelStateError);
self.state = kARDWebSocketChannelStateClosed;
NSParameterAssert(_state != kARDSignalingChannelStateError);
self.state = kARDSignalingChannelStateClosed;
}
#pragma mark - Private
- (void)registerWithCollider {
if (_state == kARDWebSocketChannelStateRegistered) {
if (_state == kARDSignalingChannelStateRegistered) {
return;
}
NSParameterAssert(_roomId.length);
@ -207,7 +208,7 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
// Registration can fail if server rejects it. For example, if the room is
// full.
[_socket send:messageString];
self.state = kARDWebSocketChannelStateRegistered;
self.state = kARDSignalingChannelStateRegistered;
}
@end

View File

@ -107,6 +107,10 @@ static CGFloat const kLocalViewPadding = 20;
}
}
- (void)appClient:(ARDAppClient *)client
didChangeConnectionState:(RTCICEConnectionState)state {
}
- (void)appClient:(ARDAppClient *)client
didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
_localVideoTrack = localVideoTrack;

View File

@ -266,6 +266,10 @@ static NSUInteger const kLogViewHeight = 280;
}
}
- (void)appClient:(ARDAppClient *)client
didChangeConnectionState:(RTCICEConnectionState)state {
}
- (void)appClient:(ARDAppClient *)client
didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
_localVideoTrack = localVideoTrack;

View File

@ -0,0 +1,323 @@
/*
* libjingle
* Copyright 2014, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import "ARDAppClient+Internal.h"
#import "ARDRegisterResponse+Internal.h"
#import "ARDMessageResponse+Internal.h"
#import "RTCMediaConstraints.h"
#import "RTCPeerConnectionFactory.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/ssladapter.h"
// These classes mimic XCTest APIs, to make eventual conversion to XCTest
// easier. Conversion will happen once XCTest is supported well on build bots.
@interface ARDTestExpectation : NSObject
@property(nonatomic, readonly) NSString *description;
@property(nonatomic, readonly) BOOL isFulfilled;
- (instancetype)initWithDescription:(NSString *)description;
- (void)fulfill;
@end
@implementation ARDTestExpectation
@synthesize description = _description;
@synthesize isFulfilled = _isFulfilled;
- (instancetype)initWithDescription:(NSString *)description {
if (self = [super init]) {
_description = description;
}
return self;
}
- (void)fulfill {
_isFulfilled = YES;
}
@end
@interface ARDTestCase : NSObject
- (ARDTestExpectation *)expectationWithDescription:(NSString *)description;
- (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
handler:(void (^)(NSError *error))handler;
@end
@implementation ARDTestCase {
NSMutableArray *_expectations;
}
- (instancetype)init {
if (self = [super init]) {
_expectations = [NSMutableArray array];
}
return self;
}
- (ARDTestExpectation *)expectationWithDescription:(NSString *)description {
ARDTestExpectation *expectation =
[[ARDTestExpectation alloc] initWithDescription:description];
[_expectations addObject:expectation];
return expectation;
}
- (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
handler:(void (^)(NSError *error))handler {
NSDate *startDate = [NSDate date];
while (![self areExpectationsFulfilled]) {
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate];
if (duration > timeout) {
NSAssert(NO, @"Expectation timed out.");
break;
}
[[NSRunLoop currentRunLoop]
runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
handler(nil);
}
- (BOOL)areExpectationsFulfilled {
for (ARDTestExpectation *expectation in _expectations) {
if (!expectation.isFulfilled) {
return NO;
}
}
return YES;
}
@end
@interface ARDAppClientTest : ARDTestCase
@end
@implementation ARDAppClientTest
#pragma mark - Mock helpers
- (id)mockRoomServerClientForRoomId:(NSString *)roomId
clientId:(NSString *)clientId
isInitiator:(BOOL)isInitiator
messages:(NSArray *)messages
messageHandler:
(void (^)(ARDSignalingMessage *))messageHandler {
id mockRoomServerClient =
[OCMockObject mockForProtocol:@protocol(ARDRoomServerClient)];
// Successful register response.
ARDRegisterResponse *registerResponse = [[ARDRegisterResponse alloc] init];
registerResponse.result = kARDRegisterResultTypeSuccess;
registerResponse.roomId = roomId;
registerResponse.clientId = clientId;
registerResponse.isInitiator = isInitiator;
registerResponse.messages = messages;
// Successful message response.
ARDMessageResponse *messageResponse = [[ARDMessageResponse alloc] init];
messageResponse.result = kARDMessageResultTypeSuccess;
// Return register response from above on register.
[[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
__unsafe_unretained void (^completionHandler)(ARDRegisterResponse *response,
NSError *error);
[invocation getArgument:&completionHandler atIndex:3];
completionHandler(registerResponse, nil);
}] registerForRoomId:roomId completionHandler:[OCMArg any]];
// Return message response from above on register.
[[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
__unsafe_unretained ARDSignalingMessage *message;
__unsafe_unretained void (^completionHandler)(ARDMessageResponse *response,
NSError *error);
[invocation getArgument:&message atIndex:2];
[invocation getArgument:&completionHandler atIndex:5];
messageHandler(message);
completionHandler(messageResponse, nil);
}] sendMessage:[OCMArg any]
forRoomId:roomId
clientId:clientId
completionHandler:[OCMArg any]];
// Do nothing on deregister.
[[[mockRoomServerClient stub] andDo:^(NSInvocation *invocation) {
__unsafe_unretained void (^completionHandler)(NSError *error);
[invocation getArgument:&completionHandler atIndex:4];
if (completionHandler) {
completionHandler(nil);
}
}] deregisterForRoomId:roomId
clientId:clientId
completionHandler:[OCMArg any]];
return mockRoomServerClient;
}
- (id)mockSignalingChannelForRoomId:(NSString *)roomId
clientId:(NSString *)clientId
messageHandler:
(void (^)(ARDSignalingMessage *message))messageHandler {
id mockSignalingChannel =
[OCMockObject niceMockForProtocol:@protocol(ARDSignalingChannel)];
[[mockSignalingChannel stub] registerForRoomId:roomId clientId:clientId];
[[[mockSignalingChannel stub] andDo:^(NSInvocation *invocation) {
__unsafe_unretained ARDSignalingMessage *message;
[invocation getArgument:&message atIndex:2];
messageHandler(message);
}] sendMessage:[OCMArg any]];
return mockSignalingChannel;
}
- (id)mockTURNClient {
id mockTURNClient =
[OCMockObject mockForProtocol:@protocol(ARDTURNClient)];
[[[mockTURNClient stub] andDo:^(NSInvocation *invocation) {
// Don't return anything in TURN response.
__unsafe_unretained void (^completionHandler)(NSArray *turnServers,
NSError *error);
[invocation getArgument:&completionHandler atIndex:2];
completionHandler([NSArray array], nil);
}] requestServersWithCompletionHandler:[OCMArg any]];
return mockTURNClient;
}
- (ARDAppClient *)createAppClientForRoomId:(NSString *)roomId
clientId:(NSString *)clientId
isInitiator:(BOOL)isInitiator
messages:(NSArray *)messages
messageHandler:
(void (^)(ARDSignalingMessage *message))messageHandler
connectedHandler:(void (^)(void))connectedHandler {
id turnClient = [self mockTURNClient];
id signalingChannel = [self mockSignalingChannelForRoomId:roomId
clientId:clientId
messageHandler:messageHandler];
id roomServerClient =
[self mockRoomServerClientForRoomId:roomId
clientId:clientId
isInitiator:isInitiator
messages:messages
messageHandler:messageHandler];
id delegate =
[OCMockObject niceMockForProtocol:@protocol(ARDAppClientDelegate)];
[[[delegate stub] andDo:^(NSInvocation *invocation) {
connectedHandler();
}] appClient:[OCMArg any] didChangeConnectionState:RTCICEConnectionConnected];
return [[ARDAppClient alloc] initWithRoomServerClient:roomServerClient
signalingChannel:signalingChannel
turnClient:turnClient
delegate:delegate];
}
// Tests that an ICE connection is established between two ARDAppClient objects
// where one is set up as a caller and the other the answerer. Network
// components are mocked out and messages are relayed directly from object to
// object. It's expected that both clients reach the RTCICEConnectionConnected
// state within a reasonable amount of time.
- (void)testSession {
// Need block arguments here because we're setting up a callbacks before we
// create the clients.
ARDAppClient *caller = nil;
ARDAppClient *answerer = nil;
__block __weak ARDAppClient *weakCaller = nil;
__block __weak ARDAppClient *weakAnswerer = nil;
NSString *roomId = @"testRoom";
NSString *callerId = @"testCallerId";
NSString *answererId = @"testAnswererId";
ARDTestExpectation *callerConnectionExpectation =
[self expectationWithDescription:@"Caller PC connected."];
ARDTestExpectation *answererConnectionExpectation =
[self expectationWithDescription:@"Answerer PC connected."];
caller = [self createAppClientForRoomId:roomId
clientId:callerId
isInitiator:YES
messages:[NSArray array]
messageHandler:^(ARDSignalingMessage *message) {
ARDAppClient *strongAnswerer = weakAnswerer;
[strongAnswerer channel:strongAnswerer.channel didReceiveMessage:message];
} connectedHandler:^{
[callerConnectionExpectation fulfill];
}];
// TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
// crash in Debug.
caller.defaultPeerConnectionConstraints = [[RTCMediaConstraints alloc] init];
weakCaller = caller;
answerer = [self createAppClientForRoomId:roomId
clientId:answererId
isInitiator:NO
messages:[NSArray array]
messageHandler:^(ARDSignalingMessage *message) {
ARDAppClient *strongCaller = weakCaller;
[strongCaller channel:strongCaller.channel didReceiveMessage:message];
} connectedHandler:^{
[answererConnectionExpectation fulfill];
}];
// TODO(tkchin): Figure out why DTLS-SRTP constraint causes thread assertion
// crash in Debug.
answerer.defaultPeerConnectionConstraints =
[[RTCMediaConstraints alloc] init];
weakAnswerer = answerer;
// Kick off connection.
[caller connectToRoomWithId:roomId options:nil];
[answerer connectToRoomWithId:roomId options:nil];
[self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
if (error) {
NSLog(@"Expectations error: %@", error);
}
}];
}
@end
class SignalingTest : public ::testing::Test {
protected:
static void SetUpTestCase() {
rtc::InitializeSSL();
}
static void TearDownTestCase() {
rtc::CleanupSSL();
}
};
TEST_F(SignalingTest, SessionTest) {
@autoreleasepool {
ARDAppClientTest *test = [[ARDAppClientTest alloc] init];
[test testSession];
}
}

View File

@ -278,6 +278,11 @@
'-lstdc++',
],
},
'all_dependent_settings': {
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
},
},
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
# common.gypi enables this for mac but we want this to be disabled

View File

@ -148,14 +148,70 @@
['OS=="ios" or (OS=="mac" and target_arch!="ia32" and mac_sdk>="10.8")', {
'targets': [
{ 'target_name': 'apprtc_signaling',
'type': 'static_library',
'dependencies': [
'libjingle.gyp:libjingle_peerconnection_objc',
'socketrocket',
],
'sources': [
'examples/objc/AppRTCDemo/ARDAppClient.h',
'examples/objc/AppRTCDemo/ARDAppClient.m',
'examples/objc/AppRTCDemo/ARDAppClient+Internal.h',
'examples/objc/AppRTCDemo/ARDAppEngineClient.h',
'examples/objc/AppRTCDemo/ARDAppEngineClient.m',
'examples/objc/AppRTCDemo/ARDCEODTURNClient.h',
'examples/objc/AppRTCDemo/ARDCEODTURNClient.m',
'examples/objc/AppRTCDemo/ARDMessageResponse.h',
'examples/objc/AppRTCDemo/ARDMessageResponse.m',
'examples/objc/AppRTCDemo/ARDMessageResponse+Internal.h',
'examples/objc/AppRTCDemo/ARDRegisterResponse.h',
'examples/objc/AppRTCDemo/ARDRegisterResponse.m',
'examples/objc/AppRTCDemo/ARDRegisterResponse+Internal.h',
'examples/objc/AppRTCDemo/ARDRoomServerClient.h',
'examples/objc/AppRTCDemo/ARDSignalingChannel.h',
'examples/objc/AppRTCDemo/ARDSignalingMessage.h',
'examples/objc/AppRTCDemo/ARDSignalingMessage.m',
'examples/objc/AppRTCDemo/ARDTURNClient.h',
'examples/objc/AppRTCDemo/ARDUtilities.h',
'examples/objc/AppRTCDemo/ARDUtilities.m',
'examples/objc/AppRTCDemo/ARDWebSocketChannel.h',
'examples/objc/AppRTCDemo/ARDWebSocketChannel.m',
'examples/objc/AppRTCDemo/RTCICECandidate+JSON.h',
'examples/objc/AppRTCDemo/RTCICECandidate+JSON.m',
'examples/objc/AppRTCDemo/RTCICEServer+JSON.h',
'examples/objc/AppRTCDemo/RTCICEServer+JSON.m',
'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h',
'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m',
'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h',
'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m',
],
'include_dirs': [
'examples/objc/APPRTCDemo',
],
'direct_dependent_settings': {
'include_dirs': [
'examples/objc/APPRTCDemo',
],
},
'export_dependent_settings': [
'libjingle.gyp:libjingle_peerconnection_objc',
],
'conditions': [
['OS=="mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET' : '10.8',
},
}],
],
},
{
'target_name': 'AppRTCDemo',
'type': 'executable',
'product_name': 'AppRTCDemo',
'mac_bundle': 1,
'dependencies': [
'libjingle.gyp:libjingle_peerconnection_objc',
'socketrocket',
'apprtc_signaling',
],
'conditions': [
['OS=="ios"', {
@ -199,34 +255,6 @@
],
}],
],
'include_dirs': [
'examples/objc/APPRTCDemo',
],
'sources': [
'examples/objc/AppRTCDemo/ARDAppClient.h',
'examples/objc/AppRTCDemo/ARDAppClient.m',
'examples/objc/AppRTCDemo/ARDMessageResponse.h',
'examples/objc/AppRTCDemo/ARDMessageResponse.m',
'examples/objc/AppRTCDemo/ARDRegisterResponse.h',
'examples/objc/AppRTCDemo/ARDRegisterResponse.m',
'examples/objc/AppRTCDemo/ARDSignalingMessage.h',
'examples/objc/AppRTCDemo/ARDSignalingMessage.m',
'examples/objc/AppRTCDemo/ARDUtilities.h',
'examples/objc/AppRTCDemo/ARDUtilities.m',
'examples/objc/AppRTCDemo/ARDWebSocketChannel.h',
'examples/objc/AppRTCDemo/ARDWebSocketChannel.m',
'examples/objc/AppRTCDemo/RTCICECandidate+JSON.h',
'examples/objc/AppRTCDemo/RTCICECandidate+JSON.m',
'examples/objc/AppRTCDemo/RTCICEServer+JSON.h',
'examples/objc/AppRTCDemo/RTCICEServer+JSON.m',
'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.h',
'examples/objc/AppRTCDemo/RTCMediaConstraints+JSON.m',
'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.h',
'examples/objc/AppRTCDemo/RTCSessionDescription+JSON.m',
],
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
},
}, # target AppRTCDemo
{
# TODO(tkchin): move this into the real third party location and

View File

@ -72,7 +72,7 @@
{
'target_name': 'libjingle_unittest',
'type': 'executable',
'includes': [ 'build/ios_tests.gypi', ],
'includes': [ 'build/objc_app.gypi', ],
'dependencies': [
'<(webrtc_root)/base/base.gyp:rtc_base',
'<(webrtc_root)/base/base_tests.gyp:rtc_base_tests_utils',
@ -341,7 +341,7 @@
{
'target_name': 'libjingle_peerconnection_objc_test',
'type': 'executable',
'includes': [ 'build/ios_tests.gypi', ],
'includes': [ 'build/objc_app.gypi' ],
'dependencies': [
'<(webrtc_root)/base/base_tests.gyp:rtc_base_tests_utils',
'libjingle.gyp:libjingle_peerconnection_objc',
@ -356,46 +356,40 @@
# needs a GUI driver.
'app/webrtc/objctests/mac/main.mm',
],
'FRAMEWORK_SEARCH_PATHS': [
'$(inherited)',
'$(SDKROOT)/Developer/Library/Frameworks',
'$(DEVELOPER_LIBRARY_DIR)/Frameworks',
],
# TODO(fischman): there is duplication here with
# build/ios_tests.gypi, because for historical reasons the
# mac x64 bots expect this unittest to be in a bundle
# directory (.app). Once the bots don't expect this
# anymore, remove this duplication.
'variables': {
'infoplist_file': 'build/ios_test.plist',
},
'mac_bundle': 1,
'mac_bundle_resources': [
'<(infoplist_file)',
],
# The plist is listed above so that it appears in XCode's file list,
# but we don't actually want to bundle it.
'mac_bundle_resources!': [
'<(infoplist_file)',
],
'xcode_settings': {
'CLANG_ENABLE_OBJC_ARC': 'YES',
# common.gypi enables this for mac but we want this to be disabled
# like it is for ios.
'CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS': 'NO',
'INFOPLIST_FILE': '<(infoplist_file)',
},
'conditions': [
['OS=="mac"', {
'xcode_settings': {
# Need to build against 10.7 framework for full ARC support
# on OSX.
'MACOSX_DEPLOYMENT_TARGET' : '10.7',
# common.gypi enables this for mac but we want this to be
# disabled like it is for ios.
'CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS': 'NO',
},
}],
],
}, # target libjingle_peerconnection_objc_test
{
'target_name': 'apprtc_signaling_gunit_test',
'type': 'executable',
'includes': [ 'build/objc_app.gypi' ],
'dependencies': [
'<(webrtc_root)/base/base_tests.gyp:rtc_base_tests_utils',
'<(DEPTH)/third_party/ocmock/ocmock.gyp:ocmock',
'libjingle_examples.gyp:apprtc_signaling',
],
'sources': [
'app/webrtc/objctests/mac/main.mm',
'examples/objc/AppRTCDemo/tests/ARDAppClientTest.mm',
],
'conditions': [
['OS=="mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET' : '10.8',
},
}],
],
}, # target apprtc_signaling_gunit_test
],
}],
['test_isolation_mode != "noop"', {