iOS: Add ability to specify audio constraints.

NOTRY=True
BUG=

Review-Url: https://codereview.webrtc.org/2290583003
Cr-Commit-Position: refs/heads/master@{#13976}
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCAudioSource+Private.h b/webrtc/sdk/objc/Framework/Classes/RTCAudioSource+Private.h
new file mode 100644
index 0000000..43aff02
--- /dev/null
+++ b/webrtc/sdk/objc/Framework/Classes/RTCAudioSource+Private.h
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import "WebRTC/RTCAudioSource.h"
+
+#import "RTCMediaSource+Private.h"
+
+@interface RTCAudioSource ()
+
+/**
+ * The AudioSourceInterface object passed to this RTCAudioSource during
+ * construction.
+ */
+@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::AudioSourceInterface> nativeAudioSource;
+
+/** Initialize an RTCAudioSource from a native AudioSourceInterface. */
+- (instancetype)initWithNativeAudioSource:
+    (rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource
+    NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)initWithNativeMediaSource:
+    (rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
+                                     type:(RTCMediaSourceType)type NS_UNAVAILABLE;
+
+@end
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCAudioSource.mm b/webrtc/sdk/objc/Framework/Classes/RTCAudioSource.mm
new file mode 100644
index 0000000..8975652
--- /dev/null
+++ b/webrtc/sdk/objc/Framework/Classes/RTCAudioSource.mm
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import "RTCAudioSource+Private.h"
+
+#include "webrtc/base/checks.h"
+
+@implementation RTCAudioSource {
+  rtc::scoped_refptr<webrtc::AudioSourceInterface> _nativeAudioSource;
+}
+
+- (instancetype)initWithNativeAudioSource:
+    (rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource {
+  RTC_DCHECK(nativeAudioSource);
+  if (self = [super initWithNativeMediaSource:nativeAudioSource
+                                         type:RTCMediaSourceTypeAudio]) {
+    _nativeAudioSource = nativeAudioSource;
+  }
+  return self;
+}
+
+- (instancetype)initWithNativeMediaSource:
+    (rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
+                                     type:(RTCMediaSourceType)type {
+  RTC_NOTREACHED();
+  return nil;
+}
+
+- (NSString *)description {
+  NSString *stateString = [[self class] stringForState:self.state];
+  return [NSString stringWithFormat:@"RTCAudioSource( %p ): %@", self, stateString];
+}
+
+#pragma mark - Private
+
+- (rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource {
+  return _nativeAudioSource;
+}
+
+@end
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack+Private.h b/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack+Private.h
index cb5f186..ea14fb3 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack+Private.h
+++ b/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack+Private.h
@@ -23,6 +23,7 @@
 
 /** Initialize an RTCAudioTrack with an id. */
 - (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
+                         source:(RTCAudioSource *)source
                         trackId:(NSString *)trackId;
 
 @end
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack.mm b/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack.mm
index 42542b8..5fa2d46 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack.mm
+++ b/webrtc/sdk/objc/Framework/Classes/RTCAudioTrack.mm
@@ -11,19 +11,30 @@
 #import "RTCAudioTrack+Private.h"
 
 #import "NSString+StdString.h"
+#import "RTCAudioSource+Private.h"
 #import "RTCMediaStreamTrack+Private.h"
 #import "RTCPeerConnectionFactory+Private.h"
 
+#include "webrtc/base/checks.h"
+
 @implementation RTCAudioTrack
 
+@synthesize source = _source;
+
 - (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
+                         source:(RTCAudioSource *)source
                         trackId:(NSString *)trackId {
-  NSParameterAssert(factory);
-  NSParameterAssert(trackId.length);
+  RTC_DCHECK(factory);
+  RTC_DCHECK(source);
+  RTC_DCHECK(trackId.length);
+
   std::string nativeId = [NSString stdStringForString:trackId];
   rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
-      factory.nativeFactory->CreateAudioTrack(nativeId, nullptr);
-  return [self initWithNativeTrack:track type:RTCMediaStreamTrackTypeAudio];
+      factory.nativeFactory->CreateAudioTrack(nativeId, source.nativeAudioSource);
+  if ([self initWithNativeTrack:track type:RTCMediaStreamTrackTypeAudio]) {
+    _source = source;
+  }
+  return self;
 }
 
 - (instancetype)initWithNativeTrack:
@@ -34,6 +45,18 @@
   return [super initWithNativeTrack:nativeTrack type:type];
 }
 
+
+- (RTCAudioSource *)source {
+  if (!_source) {
+    rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
+        self.nativeAudioTrack->GetSource();
+    if (source) {
+      _source = [[RTCAudioSource alloc] initWithNativeAudioSource:source.get()];
+    }
+  }
+  return _source;
+}
+
 #pragma mark - Private
 
 - (rtc::scoped_refptr<webrtc::AudioTrackInterface>)nativeAudioTrack {
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCMediaSource+Private.h b/webrtc/sdk/objc/Framework/Classes/RTCMediaSource+Private.h
new file mode 100644
index 0000000..55d268a
--- /dev/null
+++ b/webrtc/sdk/objc/Framework/Classes/RTCMediaSource+Private.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import "WebRTC/RTCMediaSource.h"
+
+#include "webrtc/api/mediastreaminterface.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSInteger, RTCMediaSourceType) {
+  RTCMediaSourceTypeAudio,
+  RTCMediaSourceTypeVideo,
+};
+
+@interface RTCMediaSource ()
+
+@property(nonatomic, readonly)
+    rtc::scoped_refptr<webrtc::MediaSourceInterface> nativeMediaSource;
+
+- (instancetype)initWithNativeMediaSource:
+   (rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
+                                     type:(RTCMediaSourceType)type
+    NS_DESIGNATED_INITIALIZER;
+
++ (webrtc::MediaSourceInterface::SourceState)nativeSourceStateForState:
+    (RTCSourceState)state;
+
++ (RTCSourceState)sourceStateForNativeState:
+    (webrtc::MediaSourceInterface::SourceState)nativeState;
+
++ (NSString *)stringForState:(RTCSourceState)state;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCMediaSource.mm b/webrtc/sdk/objc/Framework/Classes/RTCMediaSource.mm
new file mode 100644
index 0000000..996563b
--- /dev/null
+++ b/webrtc/sdk/objc/Framework/Classes/RTCMediaSource.mm
@@ -0,0 +1,79 @@
+/*
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import "RTCMediaSource+Private.h"
+
+#include "webrtc/base/checks.h"
+
+@implementation RTCMediaSource {
+  RTCMediaSourceType _type;
+}
+
+@synthesize nativeMediaSource = _nativeMediaSource;
+
+- (instancetype)initWithNativeMediaSource:
+   (rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
+                                     type:(RTCMediaSourceType)type {
+  RTC_DCHECK(nativeMediaSource);
+  if (self = [super init]) {
+    _nativeMediaSource = nativeMediaSource;
+    _type = type;
+  }
+  return self;
+}
+
+- (RTCSourceState)state {
+  return [[self class] sourceStateForNativeState:_nativeMediaSource->state()];
+}
+
+#pragma mark - Private
+
++ (webrtc::MediaSourceInterface::SourceState)nativeSourceStateForState:
+    (RTCSourceState)state {
+  switch (state) {
+    case RTCSourceStateInitializing:
+      return webrtc::MediaSourceInterface::kInitializing;
+    case RTCSourceStateLive:
+      return webrtc::MediaSourceInterface::kLive;
+    case RTCSourceStateEnded:
+      return webrtc::MediaSourceInterface::kEnded;
+    case RTCSourceStateMuted:
+      return webrtc::MediaSourceInterface::kMuted;
+  }
+}
+
++ (RTCSourceState)sourceStateForNativeState:
+    (webrtc::MediaSourceInterface::SourceState)nativeState {
+  switch (nativeState) {
+    case webrtc::MediaSourceInterface::kInitializing:
+      return RTCSourceStateInitializing;
+    case webrtc::MediaSourceInterface::kLive:
+      return RTCSourceStateLive;
+    case webrtc::MediaSourceInterface::kEnded:
+      return RTCSourceStateEnded;
+    case webrtc::MediaSourceInterface::kMuted:
+      return RTCSourceStateMuted;
+  }
+}
+
++ (NSString *)stringForState:(RTCSourceState)state {
+  switch (state) {
+    case RTCSourceStateInitializing:
+      return @"Initializing";
+    case RTCSourceStateLive:
+      return @"Live";
+    case RTCSourceStateEnded:
+      return @"Ended";
+    case RTCSourceStateMuted:
+      return @"Muted";
+  }
+}
+
+@end
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCPeerConnectionFactory.mm b/webrtc/sdk/objc/Framework/Classes/RTCPeerConnectionFactory.mm
index 0ac2ec4..d5fd1df 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCPeerConnectionFactory.mm
+++ b/webrtc/sdk/objc/Framework/Classes/RTCPeerConnectionFactory.mm
@@ -12,7 +12,9 @@
 
 #import "NSString+StdString.h"
 #import "RTCAVFoundationVideoSource+Private.h"
+#import "RTCAudioSource+Private.h"
 #import "RTCAudioTrack+Private.h"
+#import "RTCMediaConstraints+Private.h"
 #import "RTCMediaStream+Private.h"
 #import "RTCPeerConnection+Private.h"
 #import "RTCVideoSource+Private.h"
@@ -61,17 +63,34 @@
   _nativeFactory->StopAecDump();
 }
 
+- (RTCAudioSource *)audioSourceWithConstraints:(nullable RTCMediaConstraints *)constraints {
+  std::unique_ptr<webrtc::MediaConstraints> nativeConstraints;
+  if (constraints) {
+    nativeConstraints = constraints.nativeConstraints;
+  }
+  rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
+      _nativeFactory->CreateAudioSource(nativeConstraints.get());
+  return [[RTCAudioSource alloc] initWithNativeAudioSource:source];
+}
+
+- (RTCAudioTrack *)audioTrackWithTrackId:(NSString *)trackId {
+  RTCAudioSource *audioSource = [self audioSourceWithConstraints:nil];
+  return [self audioTrackWithSource:audioSource trackId:trackId];
+}
+
+- (RTCAudioTrack *)audioTrackWithSource:(RTCAudioSource *)source
+                                trackId:(NSString *)trackId {
+  return [[RTCAudioTrack alloc] initWithFactory:self
+                                         source:source
+                                        trackId:trackId];
+}
+
 - (RTCAVFoundationVideoSource *)avFoundationVideoSourceWithConstraints:
     (nullable RTCMediaConstraints *)constraints {
   return [[RTCAVFoundationVideoSource alloc] initWithFactory:self
                                                  constraints:constraints];
 }
 
-- (RTCAudioTrack *)audioTrackWithTrackId:(NSString *)trackId {
-  return [[RTCAudioTrack alloc] initWithFactory:self
-                                        trackId:trackId];
-}
-
 - (RTCVideoTrack *)videoTrackWithSource:(RTCVideoSource *)source
                                 trackId:(NSString *)trackId {
   return [[RTCVideoTrack alloc] initWithFactory:self
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCVideoSource+Private.h b/webrtc/sdk/objc/Framework/Classes/RTCVideoSource+Private.h
index 757c174..f6e202c 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCVideoSource+Private.h
+++ b/webrtc/sdk/objc/Framework/Classes/RTCVideoSource+Private.h
@@ -10,6 +10,8 @@
 
 #import "WebRTC/RTCVideoSource.h"
 
+#import "RTCMediaSource+Private.h"
+
 #include "webrtc/api/mediastreaminterface.h"
 
 NS_ASSUME_NONNULL_BEGIN
@@ -29,13 +31,9 @@
     (rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource
     NS_DESIGNATED_INITIALIZER;
 
-+ (webrtc::MediaSourceInterface::SourceState)nativeSourceStateForState:
-    (RTCSourceState)state;
-
-+ (RTCSourceState)sourceStateForNativeState:
-    (webrtc::MediaSourceInterface::SourceState)nativeState;
-
-+ (NSString *)stringForState:(RTCSourceState)state;
+- (instancetype)initWithNativeMediaSource:
+    (rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
+                                     type:(RTCMediaSourceType)type NS_UNAVAILABLE;
 
 @end
 
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCVideoSource.mm b/webrtc/sdk/objc/Framework/Classes/RTCVideoSource.mm
index eddf5e0..83a8b79 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCVideoSource.mm
+++ b/webrtc/sdk/objc/Framework/Classes/RTCVideoSource.mm
@@ -10,17 +10,32 @@
 
 #import "RTCVideoSource+Private.h"
 
+#include "webrtc/base/checks.h"
+
 @implementation RTCVideoSource {
   rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> _nativeVideoSource;
 }
 
-- (RTCSourceState)state {
-  return [[self class] sourceStateForNativeState:_nativeVideoSource->state()];
+- (instancetype)initWithNativeVideoSource:
+    (rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource {
+  RTC_DCHECK(nativeVideoSource);
+  if (self = [super initWithNativeMediaSource:nativeVideoSource
+                                         type:RTCMediaSourceTypeVideo]) {
+    _nativeVideoSource = nativeVideoSource;
+  }
+  return self;
+}
+
+- (instancetype)initWithNativeMediaSource:
+    (rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
+                                     type:(RTCMediaSourceType)type {
+  RTC_NOTREACHED();
+  return nil;
 }
 
 - (NSString *)description {
-  return [NSString stringWithFormat:@"RTCVideoSource:\n%@",
-                                    [[self class] stringForState:self.state]];
+  NSString *stateString = [[self class] stringForState:self.state];
+  return [NSString stringWithFormat:@"RTCVideoSource( %p ): %@", self, stateString];
 }
 
 #pragma mark - Private
@@ -29,54 +44,4 @@
   return _nativeVideoSource;
 }
 
-- (instancetype)initWithNativeVideoSource:
-    (rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource {
-  NSParameterAssert(nativeVideoSource);
-  if (self = [super init]) {
-    _nativeVideoSource = nativeVideoSource;
-  }
-  return self;
-}
-
-+ (webrtc::MediaSourceInterface::SourceState)nativeSourceStateForState:
-    (RTCSourceState)state {
-  switch (state) {
-    case RTCSourceStateInitializing:
-      return webrtc::MediaSourceInterface::kInitializing;
-    case RTCSourceStateLive:
-      return webrtc::MediaSourceInterface::kLive;
-    case RTCSourceStateEnded:
-      return webrtc::MediaSourceInterface::kEnded;
-    case RTCSourceStateMuted:
-      return webrtc::MediaSourceInterface::kMuted;
-  }
-}
-
-+ (RTCSourceState)sourceStateForNativeState:
-    (webrtc::MediaSourceInterface::SourceState)nativeState {
-  switch (nativeState) {
-    case webrtc::MediaSourceInterface::kInitializing:
-      return RTCSourceStateInitializing;
-    case webrtc::MediaSourceInterface::kLive:
-      return RTCSourceStateLive;
-    case webrtc::MediaSourceInterface::kEnded:
-      return RTCSourceStateEnded;
-    case webrtc::MediaSourceInterface::kMuted:
-      return RTCSourceStateMuted;
-  }
-}
-
-+ (NSString *)stringForState:(RTCSourceState)state {
-  switch (state) {
-    case RTCSourceStateInitializing:
-      return @"Initializing";
-    case RTCSourceStateLive:
-      return @"Live";
-    case RTCSourceStateEnded:
-      return @"Ended";
-    case RTCSourceStateMuted:
-      return @"Muted";
-  }
-}
-
 @end