Add file capturer to AppRTCMobile on simulator.

To achieve this, the CL does the following
- Adds sample mp4 video
- Refactors the existing RTCFileVideoCapturer to achieve continious
capture and adds tests.

Bug: webrtc:8406
Change-Id: Ibc0891176c58ec9053b42e340d2113036e7199ec
Reviewed-on: https://webrtc-review.googlesource.com/12180
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Commit-Queue: Daniela Jovanoska Petrenko <denicija@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20598}
diff --git a/examples/objc/AppRTCMobile/ARDAppClient.h b/examples/objc/AppRTCMobile/ARDAppClient.h
index 8c27b34..5054c28 100644
--- a/examples/objc/AppRTCMobile/ARDAppClient.h
+++ b/examples/objc/AppRTCMobile/ARDAppClient.h
@@ -9,8 +9,6 @@
  */
 
 #import <Foundation/Foundation.h>
-
-#import "WebRTC/RTCCameraVideoCapturer.h"
 #import "WebRTC/RTCPeerConnection.h"
 #import "WebRTC/RTCVideoTrack.h"
 
@@ -26,6 +24,8 @@
 @class ARDAppClient;
 @class ARDSettingsModel;
 @class RTCMediaConstraints;
+@class RTCCameraVideoCapturer;
+@class RTCFileVideoCapturer;
 
 // The delegate is informed of pertinent events and will be called on the
 // main queue.
@@ -52,6 +52,10 @@
 - (void)appClient:(ARDAppClient *)client
       didGetStats:(NSArray *)stats;
 
+@optional
+- (void)appClient:(ARDAppClient *)client
+didCreateLocalFileCapturer:(RTCFileVideoCapturer *)fileCapturer;
+
 @end
 
 // Handles connections to the AppRTC server for a given room. Methods on this
diff --git a/examples/objc/AppRTCMobile/ARDAppClient.m b/examples/objc/AppRTCMobile/ARDAppClient.m
index f753828..1c41a72 100644
--- a/examples/objc/AppRTCMobile/ARDAppClient.m
+++ b/examples/objc/AppRTCMobile/ARDAppClient.m
@@ -15,6 +15,7 @@
 #import "WebRTC/RTCCameraVideoCapturer.h"
 #import "WebRTC/RTCConfiguration.h"
 #import "WebRTC/RTCFileLogger.h"
+#import "WebRTC/RTCFileVideoCapturer.h"
 #import "WebRTC/RTCIceServer.h"
 #import "WebRTC/RTCLogging.h"
 #import "WebRTC/RTCMediaConstraints.h"
@@ -690,21 +691,24 @@
 }
 
 - (RTCVideoTrack *)createLocalVideoTrack {
-  RTCVideoTrack* localVideoTrack = nil;
-  // The iOS simulator doesn't provide any sort of camera capture
-  // support or emulation (http://goo.gl/rHAnC1) so don't bother
-  // trying to open a local stream.
+  if ([_settings currentAudioOnlySettingFromStore]) {
+    return nil;
+  }
+
+  RTCVideoSource *source = [_factory videoSource];
+
 #if !TARGET_IPHONE_SIMULATOR
-  if (![_settings currentAudioOnlySettingFromStore]) {
-    RTCVideoSource *source = [_factory videoSource];
-    RTCCameraVideoCapturer *capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:source];
-    [_delegate appClient:self didCreateLocalCapturer:capturer];
-    localVideoTrack =
-        [_factory videoTrackWithSource:source
-                               trackId:kARDVideoTrackId];
+  RTCCameraVideoCapturer *capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:source];
+  [_delegate appClient:self didCreateLocalCapturer:capturer];
+
+#else
+  if (@available(iOS 10, *)) {
+    RTCFileVideoCapturer *fileCapturer = [[RTCFileVideoCapturer alloc] initWithDelegate:source];
+    [_delegate appClient:self didCreateLocalFileCapturer:fileCapturer];
   }
 #endif
-  return localVideoTrack;
+
+  return [_factory videoTrackWithSource:source trackId:kARDVideoTrackId];
 }
 
 #pragma mark - Collider methods
diff --git a/examples/objc/AppRTCMobile/ARDSettingsModel.m b/examples/objc/AppRTCMobile/ARDSettingsModel.m
index 0a2bee6..a4eea73 100644
--- a/examples/objc/AppRTCMobile/ARDSettingsModel.m
+++ b/examples/objc/AppRTCMobile/ARDSettingsModel.m
@@ -169,20 +169,12 @@
 
 - (void)registerStoreDefaults {
   NSString *defaultVideoResolutionSetting = [self defaultVideoResolutionSetting];
-  BOOL audioOnly = (defaultVideoResolutionSetting.length == 0);
-
-// The iOS simulator doesn't provide any sort of camera capture
-// support or emulation (http://goo.gl/rHAnC1) so don't bother
-// trying to open a local stream.
-#if TARGET_IPHONE_SIMULATOR
-  audioOnly = YES;
-#endif
 
   NSData *codecData = [NSKeyedArchiver archivedDataWithRootObject:[self defaultVideoCodecSetting]];
   [ARDSettingsStore setDefaultsForVideoResolution:[self defaultVideoResolutionSetting]
                                        videoCodec:codecData
                                           bitrate:nil
-                                        audioOnly:audioOnly
+                                        audioOnly:NO
                                     createAecDump:NO
                                useLevelController:NO
                              useManualAudioConfig:YES];
diff --git a/examples/objc/AppRTCMobile/ios/ARDFileCaptureController.h b/examples/objc/AppRTCMobile/ios/ARDFileCaptureController.h
new file mode 100644
index 0000000..7e0387d
--- /dev/null
+++ b/examples/objc/AppRTCMobile/ios/ARDFileCaptureController.h
@@ -0,0 +1,40 @@
+/*
+ *  Copyright 2017 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>
+
+@class RTCFileVideoCapturer;
+
+/**
+ * Controls a file capturer.
+ */
+NS_CLASS_AVAILABLE_IOS(10)
+@interface ARDFileCaptureController : NSObject
+
+/**
+ * Creates instance of the controller.
+ *
+ * @param capturer The capturer to be controlled.
+ */
+- (instancetype)initWithCapturer:(RTCFileVideoCapturer *)capturer;
+
+/**
+ * Starts the file capturer.
+ *
+ * Possible errors produced by the capturer will be logged.
+ */
+- (void)startCapture;
+
+/**
+ * Immediately stops capturer.
+ */
+- (void)stopCapture;
+
+@end
diff --git a/examples/objc/AppRTCMobile/ios/ARDFileCaptureController.m b/examples/objc/AppRTCMobile/ios/ARDFileCaptureController.m
new file mode 100644
index 0000000..d61bfe2
--- /dev/null
+++ b/examples/objc/AppRTCMobile/ios/ARDFileCaptureController.m
@@ -0,0 +1,45 @@
+/*
+ *  Copyright 2017 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 "ARDFileCaptureController.h"
+
+#import "WebRTC/RTCFileVideoCapturer.h"
+
+@interface ARDFileCaptureController ()
+
+@property(nonatomic, strong) RTCFileVideoCapturer *fileCapturer;
+
+@end
+
+@implementation ARDFileCaptureController
+@synthesize fileCapturer = _fileCapturer;
+
+- (instancetype)initWithCapturer:(RTCFileVideoCapturer *)capturer {
+  if (self = [super init]) {
+    _fileCapturer = capturer;
+  }
+  return self;
+}
+
+- (void)startCapture {
+  [self startFileCapture];
+}
+
+- (void)startFileCapture {
+  [self.fileCapturer startCapturingFromFileNamed:@"foreman.mp4"
+                                         onError:^(NSError *_Nonnull error) {
+                                           NSLog(@"Error %@", error.userInfo);
+                                         }];
+}
+
+- (void)stopCapture {
+  [self.fileCapturer stopCapture];
+}
+@end
diff --git a/examples/objc/AppRTCMobile/ios/ARDVideoCallViewController.m b/examples/objc/AppRTCMobile/ios/ARDVideoCallViewController.m
index ad5bc80..e5c9e64 100644
--- a/examples/objc/AppRTCMobile/ios/ARDVideoCallViewController.m
+++ b/examples/objc/AppRTCMobile/ios/ARDVideoCallViewController.m
@@ -11,9 +11,11 @@
 #import "ARDVideoCallViewController.h"
 
 #import "WebRTC/RTCAudioSession.h"
+#import "WebRTC/RTCCameraVideoCapturer.h"
 
 #import "ARDAppClient.h"
 #import "ARDCaptureController.h"
+#import "ARDFileCaptureController.h"
 #import "ARDSettingsModel.h"
 #import "ARDVideoCallView.h"
 #import "WebRTC/RTCAVFoundationVideoSource.h"
@@ -32,6 +34,7 @@
   ARDAppClient *_client;
   RTCVideoTrack *_remoteVideoTrack;
   ARDCaptureController *_captureController;
+  ARDFileCaptureController *_fileCaptureController NS_AVAILABLE_IOS(10);
   AVAudioSessionPortOverride _portOverride;
 }
 
@@ -102,6 +105,14 @@
 }
 
 - (void)appClient:(ARDAppClient *)client
+    didCreateLocalFileCapturer:(RTCFileVideoCapturer *)fileCapturer {
+  if (@available(iOS 10, *)) {
+    _fileCaptureController = [[ARDFileCaptureController alloc] initWithCapturer:fileCapturer];
+    [_fileCaptureController startCapture];
+  }
+}
+
+- (void)appClient:(ARDAppClient *)client
     didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
 }
 
@@ -187,6 +198,8 @@
   _videoCallView.localVideoView.captureSession = nil;
   [_captureController stopCapture];
   _captureController = nil;
+  [_fileCaptureController stopCapture];
+  _fileCaptureController = nil;
   [_client disconnect];
   [_delegate viewControllerDidFinish:self];
 }
diff --git a/examples/objc/AppRTCMobile/ios/resources/foreman.mp4 b/examples/objc/AppRTCMobile/ios/resources/foreman.mp4
new file mode 100644
index 0000000..ccffbf4
--- /dev/null
+++ b/examples/objc/AppRTCMobile/ios/resources/foreman.mp4
Binary files differ
diff --git a/examples/objc/AppRTCMobile/tests/ARDFileCaptureController_xctest.mm b/examples/objc/AppRTCMobile/tests/ARDFileCaptureController_xctest.mm
new file mode 100644
index 0000000..e734f10
--- /dev/null
+++ b/examples/objc/AppRTCMobile/tests/ARDFileCaptureController_xctest.mm
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 2017 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>
+#import <OCMock/OCMock.h>
+#import <XCTest/XCTest.h>
+
+#import "ARDFileCaptureController.h"
+
+#import "WebRTC/RTCFileVideoCapturer.h"
+
+NS_CLASS_AVAILABLE_IOS(10)
+@interface ARDFileCaptureControllerTests : XCTestCase
+
+@property(nonatomic, strong) ARDFileCaptureController *fileCaptureController;
+@property(nonatomic, strong) id fileCapturerMock;
+
+@end
+
+@implementation ARDFileCaptureControllerTests
+
+@synthesize fileCaptureController = _fileCaptureController;
+@synthesize fileCapturerMock = _fileCapturerMock;
+
+- (void)setUp {
+  [super setUp];
+  self.fileCapturerMock = OCMClassMock([RTCFileVideoCapturer class]);
+  self.fileCaptureController =
+      [[ARDFileCaptureController alloc] initWithCapturer:self.fileCapturerMock];
+}
+
+- (void)tearDown {
+  self.fileCaptureController = nil;
+  [self.fileCapturerMock stopMocking];
+  self.fileCapturerMock = nil;
+  [super tearDown];
+}
+
+- (void)testCaptureIsStarted {
+  [[self.fileCapturerMock expect] startCapturingFromFileNamed:[OCMArg any] onError:[OCMArg any]];
+
+  [self.fileCaptureController startCapture];
+
+  [self.fileCapturerMock verify];
+}
+
+- (void)testCaptureIsStoped {
+  [[self.fileCapturerMock expect] stopCapture];
+
+  [self.fileCaptureController stopCapture];
+
+  [self.fileCapturerMock verify];
+}
+
+@end