Create a peer connection factory builder

Similar to the builder on android: https://cs.chromium.org/chromium/src/third_party/webrtc/sdk/android/api/org/webrtc/PeerConnectionFactory.java?rcl=b90e63c620877712e45ee320cfa25cb825bf5373&l=134

1. A builder will allow us to choose what module factories to provide and use default for the others.
2. A helper category is added to provide helpers functions for creating common builders.

Bug: None
Change-Id: I5889bdd7dc2a2aeded62ef5f2c2381edd07089b3
Reviewed-on: https://webrtc-review.googlesource.com/83280
Commit-Queue: Anders Carlsson <andersc@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23696}
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 822c3c2..1e3bd62 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -706,6 +706,10 @@
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Private.h",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory.mm",
+        "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h",
+        "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.mm",
+        "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.h",
+        "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.mm",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryOptions+Private.h",
         "objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryOptions.mm",
         "objc/Framework/Classes/PeerConnection/RTCRtcpParameters+Private.h",
@@ -786,12 +790,16 @@
         ":videorendereradapter_objc",
         ":videosource_objc",
         "../api:libjingle_peerconnection_api",
+        "../api/audio_codecs:audio_codecs_api",
         "../api/audio_codecs:builtin_audio_decoder_factory",
+        "../api/audio_codecs:builtin_audio_encoder_factory",
         "../api/video:video_frame",
         "../api/video_codecs:video_codecs_api",
         "../common_video",
         "../media:rtc_media_base",
         "../modules:module_api",
+        "../modules/audio_device:audio_device_api",
+        "../modules/audio_processing:audio_processing",
         "../modules/video_coding:video_codec_interface",
         "../pc:create_pc_factory",
         "../pc:peerconnection",
@@ -926,6 +934,7 @@
           "objc/Framework/UnitTests/RTCIceServerTest.mm",
           "objc/Framework/UnitTests/RTCIntervalRangeTests.mm",
           "objc/Framework/UnitTests/RTCMediaConstraintsTest.mm",
+          "objc/Framework/UnitTests/RTCPeerConnectionFactoryBuilderTest.mm",
           "objc/Framework/UnitTests/RTCPeerConnectionTest.mm",
           "objc/Framework/UnitTests/RTCSessionDescriptionTest.mm",
           "objc/Framework/UnitTests/RTCTracingTest.mm",
@@ -957,9 +966,14 @@
           ":videosource_objc",
           ":videotoolbox_objc",
           "../../system_wrappers:system_wrappers_default",
+          "../api/audio_codecs:audio_codecs_api",
+          "../api/audio_codecs:builtin_audio_decoder_factory",
+          "../api/audio_codecs:builtin_audio_encoder_factory",
           "../api/video_codecs:video_codecs_api",
           "../media:rtc_media_base",
           "../modules:module_api",
+          "../modules/audio_device:audio_device_api",
+          "../modules/audio_processing:audio_processing",
           "../modules/video_coding:video_codec_interface",
           "../rtc_base:rtc_base_tests_utils",
           "//test:test_support",
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h
new file mode 100644
index 0000000..070a0e7
--- /dev/null
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright 2018 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 "RTCPeerConnectionFactoryBuilder.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCPeerConnectionFactoryBuilder (DefaultComponents)
+
++ (RTCPeerConnectionFactoryBuilder *)defaultBuilder;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.mm
new file mode 100644
index 0000000..9fb50de
--- /dev/null
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.mm
@@ -0,0 +1,48 @@
+/*
+ *  Copyright 2018 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 "RTCPeerConnectionFactory+Native.h"
+#import "RTCPeerConnectionFactoryBuilder+DefaultComponents.h"
+
+#import "WebRTC/RTCVideoCodecH264.h"
+#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/audio_codecs/builtin_audio_encoder_factory.h"
+#include "sdk/objc/Framework/Native/api/video_decoder_factory.h"
+#include "sdk/objc/Framework/Native/api/video_encoder_factory.h"
+
+#if defined(WEBRTC_IOS)
+#import "sdk/objc/Framework/Native/api/audio_device_module.h"
+#endif
+
+@implementation RTCPeerConnectionFactoryBuilder (DefaultComponents)
+
++ (RTCPeerConnectionFactoryBuilder *)defaultBuilder {
+  RTCPeerConnectionFactoryBuilder *builder = [[RTCPeerConnectionFactoryBuilder alloc] init];
+  auto audioEncoderFactory = webrtc::CreateBuiltinAudioEncoderFactory();
+  [builder setAudioEncoderFactory:audioEncoderFactory];
+
+  auto audioDecoderFactory = webrtc::CreateBuiltinAudioDecoderFactory();
+  [builder setAudioDecoderFactory:audioDecoderFactory];
+
+  auto videoEncoderFactory =
+      webrtc::ObjCToNativeVideoEncoderFactory([[RTCVideoEncoderFactoryH264 alloc] init]);
+  [builder setVideoEncoderFactory:std::move(videoEncoderFactory)];
+
+  auto videoDecoderFactory =
+      webrtc::ObjCToNativeVideoDecoderFactory([[RTCVideoDecoderFactoryH264 alloc] init]);
+  [builder setVideoDecoderFactory:std::move(videoDecoderFactory)];
+
+#if defined(WEBRTC_IOS)
+  [builder setAudioDeviceModule:webrtc::CreateAudioDeviceModule()];
+#endif
+  return builder;
+}
+
+@end
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.h b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.h
new file mode 100644
index 0000000..27bdcd9
--- /dev/null
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.h
@@ -0,0 +1,48 @@
+/*
+ *  Copyright 2018 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/RTCPeerConnectionFactory.h"
+
+#include "rtc_base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+class AudioDeviceModule;
+class AudioEncoderFactory;
+class AudioDecoderFactory;
+class VideoEncoderFactory;
+class VideoDecoderFactory;
+class AudioProcessing;
+
+}  // namespace webrtc
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RTCPeerConnectionFactoryBuilder : NSObject
+
++ (RTCPeerConnectionFactoryBuilder *)builder;
+
+- (RTCPeerConnectionFactory *)createPeerConnectionFactory;
+
+- (void)setVideoEncoderFactory:(std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory;
+
+- (void)setVideoDecoderFactory:(std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory;
+
+- (void)setAudioEncoderFactory:(rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory;
+
+- (void)setAudioDecoderFactory:(rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory;
+
+- (void)setAudioDeviceModule:(rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule;
+
+- (void)setAudioProcessingModule:(rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.mm
new file mode 100644
index 0000000..a26a639
--- /dev/null
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.mm
@@ -0,0 +1,71 @@
+/*
+ *  Copyright 2018 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 "RTCPeerConnectionFactoryBuilder.h"
+#import "RTCPeerConnectionFactory+Native.h"
+
+#include "api/audio_codecs/audio_decoder_factory.h"
+#include "api/audio_codecs/audio_encoder_factory.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "modules/audio_device/include/audio_device.h"
+#include "modules/audio_processing/include/audio_processing.h"
+
+@implementation RTCPeerConnectionFactoryBuilder {
+  std::unique_ptr<webrtc::VideoEncoderFactory> _videoEncoderFactory;
+  std::unique_ptr<webrtc::VideoDecoderFactory> _videoDecoderFactory;
+  rtc::scoped_refptr<webrtc::AudioEncoderFactory> _audioEncoderFactory;
+  rtc::scoped_refptr<webrtc::AudioDecoderFactory> _audioDecoderFactory;
+  rtc::scoped_refptr<webrtc::AudioDeviceModule> _audioDeviceModule;
+  rtc::scoped_refptr<webrtc::AudioProcessing> _audioProcessingModule;
+}
+
++ (RTCPeerConnectionFactoryBuilder *)builder {
+  return [[RTCPeerConnectionFactoryBuilder alloc] init];
+}
+
+- (RTCPeerConnectionFactory *)createPeerConnectionFactory {
+  RTCPeerConnectionFactory *factory = [RTCPeerConnectionFactory alloc];
+  return [factory initWithNativeAudioEncoderFactory:_audioEncoderFactory
+                          nativeAudioDecoderFactory:_audioDecoderFactory
+                          nativeVideoEncoderFactory:std::move(_videoEncoderFactory)
+                          nativeVideoDecoderFactory:std::move(_videoDecoderFactory)
+                                  audioDeviceModule:_audioDeviceModule
+                              audioProcessingModule:_audioProcessingModule];
+}
+
+- (void)setVideoEncoderFactory:(std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory {
+  _videoEncoderFactory = std::move(videoEncoderFactory);
+}
+
+- (void)setVideoDecoderFactory:(std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory {
+  _videoDecoderFactory = std::move(videoDecoderFactory);
+}
+
+- (void)setAudioEncoderFactory:
+        (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory {
+  _audioEncoderFactory = audioEncoderFactory;
+}
+
+- (void)setAudioDecoderFactory:
+        (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory {
+  _audioDecoderFactory = audioDecoderFactory;
+}
+
+- (void)setAudioDeviceModule:(rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule {
+  _audioDeviceModule = audioDeviceModule;
+}
+
+- (void)setAudioProcessingModule:
+        (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule {
+  _audioProcessingModule = audioProcessingModule;
+}
+
+@end
diff --git a/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactoryBuilderTest.mm b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactoryBuilderTest.mm
new file mode 100644
index 0000000..fa78aed
--- /dev/null
+++ b/sdk/objc/Framework/UnitTests/RTCPeerConnectionFactoryBuilderTest.mm
@@ -0,0 +1,92 @@
+/*
+ *  Copyright 2015 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 <Foundation/Foundation.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+#import <OCMock/OCMock.h>
+#ifdef __cplusplus
+}
+#endif
+#import "sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactory+Native.h"
+#import "sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder+DefaultComponents.h"
+#import "sdk/objc/Framework/Classes/PeerConnection/RTCPeerConnectionFactoryBuilder.h"
+
+#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/audio_codecs/builtin_audio_encoder_factory.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
+#include "modules/audio_device/include/audio_device.h"
+#include "modules/audio_processing/include/audio_processing.h"
+
+#include "rtc_base/gunit.h"
+
+@interface RTCPeerConnectionFactoryBuilderTest : NSObject
+- (void)testBuilder;
+- (void)testDefaultComponentsBuilder;
+@end
+
+@implementation RTCPeerConnectionFactoryBuilderTest
+
+- (void)testBuilder {
+  id factoryMock = OCMStrictClassMock([RTCPeerConnectionFactory class]);
+  OCMExpect([factoryMock alloc]).andReturn(factoryMock);
+#ifdef HAVE_NO_MEDIA
+  RTC_UNUSED([[[factoryMock expect] andReturn:factoryMock] initWithNoMedia]);
+#else
+  RTC_UNUSED([[[[factoryMock expect] andReturn:factoryMock] ignoringNonObjectArgs]
+      initWithNativeAudioEncoderFactory:nullptr
+              nativeAudioDecoderFactory:nullptr
+              nativeVideoEncoderFactory:nullptr
+              nativeVideoDecoderFactory:nullptr
+                      audioDeviceModule:nullptr
+                  audioProcessingModule:nullptr]);
+#endif
+  RTCPeerConnectionFactoryBuilder* builder = [[RTCPeerConnectionFactoryBuilder alloc] init];
+  RTCPeerConnectionFactory* peerConnectionFactory = [builder createPeerConnectionFactory];
+  EXPECT_TRUE(peerConnectionFactory != nil);
+  OCMVerifyAll(factoryMock);
+}
+
+- (void)testDefaultComponentsBuilder {
+  id factoryMock = OCMStrictClassMock([RTCPeerConnectionFactory class]);
+  OCMExpect([factoryMock alloc]).andReturn(factoryMock);
+#ifdef HAVE_NO_MEDIA
+  RTC_UNUSED([[[factoryMock expect] andReturn:factoryMock] initWithNoMedia]);
+#else
+  RTC_UNUSED([[[[factoryMock expect] andReturn:factoryMock] ignoringNonObjectArgs]
+      initWithNativeAudioEncoderFactory:nullptr
+              nativeAudioDecoderFactory:nullptr
+              nativeVideoEncoderFactory:nullptr
+              nativeVideoDecoderFactory:nullptr
+                      audioDeviceModule:nullptr
+                  audioProcessingModule:nullptr]);
+#endif
+  RTCPeerConnectionFactoryBuilder* builder = [RTCPeerConnectionFactoryBuilder defaultBuilder];
+  RTCPeerConnectionFactory* peerConnectionFactory = [builder createPeerConnectionFactory];
+  EXPECT_TRUE(peerConnectionFactory != nil);
+  OCMVerifyAll(factoryMock);
+}
+@end
+
+TEST(RTCPeerConnectionFactoryBuilderTest, BuilderTest) {
+  @autoreleasepool {
+    RTCPeerConnectionFactoryBuilderTest* test = [[RTCPeerConnectionFactoryBuilderTest alloc] init];
+    [test testBuilder];
+  }
+}
+
+TEST(RTCPeerConnectionFactoryBuilderTest, DefaultComponentsBuilderTest) {
+  @autoreleasepool {
+    RTCPeerConnectionFactoryBuilderTest* test = [[RTCPeerConnectionFactoryBuilderTest alloc] init];
+    [test testDefaultComponentsBuilder];
+  }
+}