From c69a6095424abdff194b80ea56a32a5d2898f114 Mon Sep 17 00:00:00 2001 From: Khaled Alshehri <39571180+i5xx@users.noreply.github.com> Date: Wed, 8 Aug 2018 02:34:41 +0300 Subject: [PATCH] Add files via upload --- ManagedCapturer/SCCaptureImageState.h | 22 +++ ManagedCapturer/SCCaptureImageState.m | 65 +++++++ .../SCCaptureImageStateTransitionPayload.h | 29 +++ .../SCCaptureImageStateTransitionPayload.m | 27 +++ .../SCCaptureImageWhileRecordingState.h | 22 +++ .../SCCaptureImageWhileRecordingState.m | 85 +++++++++ ...mageWhileRecordingStateTransitionPayload.h | 29 +++ ...mageWhileRecordingStateTransitionPayload.m | 27 +++ ManagedCapturer/SCCaptureInitializedState.h | 22 +++ ManagedCapturer/SCCaptureInitializedState.m | 68 +++++++ ManagedCapturer/SCCaptureRecordingState.h | 22 +++ ManagedCapturer/SCCaptureRecordingState.m | 114 ++++++++++++ ...SCCaptureRecordingStateTransitionPayload.h | 41 ++++ ...SCCaptureRecordingStateTransitionPayload.m | 33 ++++ ManagedCapturer/SCCaptureRunningState.h | 22 +++ ManagedCapturer/SCCaptureRunningState.m | 176 ++++++++++++++++++ ManagedCapturer/SCCaptureScanningState.h | 18 ++ ManagedCapturer/SCCaptureScanningState.m | 75 ++++++++ ManagedCapturer/SCCaptureUninitializedState.h | 26 +++ ManagedCapturer/SCCaptureUninitializedState.m | 70 +++++++ ManagedCapturer/SCStateTransitionPayload.h | 22 +++ ManagedCapturer/SCStateTransitionPayload.m | 27 +++ ManagedCapturer/States/SCCaptureImageState.h | 22 +++ ManagedCapturer/States/SCCaptureImageState.m | 65 +++++++ .../SCCaptureImageStateTransitionPayload.h | 29 +++ .../SCCaptureImageStateTransitionPayload.m | 27 +++ .../SCCaptureImageWhileRecordingState.h | 22 +++ .../SCCaptureImageWhileRecordingState.m | 85 +++++++++ ...mageWhileRecordingStateTransitionPayload.h | 29 +++ ...mageWhileRecordingStateTransitionPayload.m | 27 +++ .../States/SCCaptureInitializedState.h | 22 +++ .../States/SCCaptureInitializedState.m | 68 +++++++ .../States/SCCaptureRecordingState.h | 22 +++ .../States/SCCaptureRecordingState.m | 114 ++++++++++++ ...SCCaptureRecordingStateTransitionPayload.h | 41 ++++ ...SCCaptureRecordingStateTransitionPayload.m | 33 ++++ .../States/SCCaptureRunningState.h | 22 +++ .../States/SCCaptureRunningState.m | 176 ++++++++++++++++++ .../States/SCCaptureScanningState.h | 18 ++ .../States/SCCaptureScanningState.m | 75 ++++++++ .../States/SCCaptureUninitializedState.h | 26 +++ .../States/SCCaptureUninitializedState.m | 70 +++++++ .../States/SCStateTransitionPayload.h | 22 +++ .../States/SCStateTransitionPayload.m | 27 +++ ManagedCapturer/UIScreen+Debug.h | 13 ++ ManagedCapturer/UIScreen+Debug.m | 28 +++ 46 files changed, 2125 insertions(+) create mode 100644 ManagedCapturer/SCCaptureImageState.h create mode 100644 ManagedCapturer/SCCaptureImageState.m create mode 100644 ManagedCapturer/SCCaptureImageStateTransitionPayload.h create mode 100644 ManagedCapturer/SCCaptureImageStateTransitionPayload.m create mode 100644 ManagedCapturer/SCCaptureImageWhileRecordingState.h create mode 100644 ManagedCapturer/SCCaptureImageWhileRecordingState.m create mode 100644 ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.h create mode 100644 ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.m create mode 100644 ManagedCapturer/SCCaptureInitializedState.h create mode 100644 ManagedCapturer/SCCaptureInitializedState.m create mode 100644 ManagedCapturer/SCCaptureRecordingState.h create mode 100644 ManagedCapturer/SCCaptureRecordingState.m create mode 100644 ManagedCapturer/SCCaptureRecordingStateTransitionPayload.h create mode 100644 ManagedCapturer/SCCaptureRecordingStateTransitionPayload.m create mode 100644 ManagedCapturer/SCCaptureRunningState.h create mode 100644 ManagedCapturer/SCCaptureRunningState.m create mode 100644 ManagedCapturer/SCCaptureScanningState.h create mode 100644 ManagedCapturer/SCCaptureScanningState.m create mode 100644 ManagedCapturer/SCCaptureUninitializedState.h create mode 100644 ManagedCapturer/SCCaptureUninitializedState.m create mode 100644 ManagedCapturer/SCStateTransitionPayload.h create mode 100644 ManagedCapturer/SCStateTransitionPayload.m create mode 100644 ManagedCapturer/States/SCCaptureImageState.h create mode 100644 ManagedCapturer/States/SCCaptureImageState.m create mode 100644 ManagedCapturer/States/SCCaptureImageStateTransitionPayload.h create mode 100644 ManagedCapturer/States/SCCaptureImageStateTransitionPayload.m create mode 100644 ManagedCapturer/States/SCCaptureImageWhileRecordingState.h create mode 100644 ManagedCapturer/States/SCCaptureImageWhileRecordingState.m create mode 100644 ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.h create mode 100644 ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.m create mode 100644 ManagedCapturer/States/SCCaptureInitializedState.h create mode 100644 ManagedCapturer/States/SCCaptureInitializedState.m create mode 100644 ManagedCapturer/States/SCCaptureRecordingState.h create mode 100644 ManagedCapturer/States/SCCaptureRecordingState.m create mode 100644 ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.h create mode 100644 ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.m create mode 100644 ManagedCapturer/States/SCCaptureRunningState.h create mode 100644 ManagedCapturer/States/SCCaptureRunningState.m create mode 100644 ManagedCapturer/States/SCCaptureScanningState.h create mode 100644 ManagedCapturer/States/SCCaptureScanningState.m create mode 100644 ManagedCapturer/States/SCCaptureUninitializedState.h create mode 100644 ManagedCapturer/States/SCCaptureUninitializedState.m create mode 100644 ManagedCapturer/States/SCStateTransitionPayload.h create mode 100644 ManagedCapturer/States/SCStateTransitionPayload.m create mode 100644 ManagedCapturer/UIScreen+Debug.h create mode 100644 ManagedCapturer/UIScreen+Debug.m diff --git a/ManagedCapturer/SCCaptureImageState.h b/ManagedCapturer/SCCaptureImageState.h new file mode 100644 index 0000000..561b43f --- /dev/null +++ b/ManagedCapturer/SCCaptureImageState.h @@ -0,0 +1,22 @@ +// +// SCCaptureImageState.h +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureImageState : SCCaptureBaseState + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/SCCaptureImageState.m b/ManagedCapturer/SCCaptureImageState.m new file mode 100644 index 0000000..d26a0f4 --- /dev/null +++ b/ManagedCapturer/SCCaptureImageState.m @@ -0,0 +1,65 @@ +// +// SCCaptureImageState.m +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCCaptureImageState.h" + +#import "SCCaptureImageStateTransitionPayload.h" +#import "SCManagedCapturerV1_Private.h" +#import "SCStateTransitionPayload.h" + +#import +#import + +@interface SCCaptureImageState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} +@end + +@implementation SCCaptureImageState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCAssert(payload.toState == [self stateId], @""); + if (![payload isKindOfClass:[SCCaptureImageStateTransitionPayload class]]) { + SCAssertFail(@"wrong payload pass in"); + [_delegate currentState:self requestToTransferToNewState:payload.fromState payload:nil context:context]; + return; + } + SCCaptureImageStateTransitionPayload *captureImagePayload = (SCCaptureImageStateTransitionPayload *)payload; + + [SCCaptureWorker + captureStillImageWithCaptureResource:resource + aspectRatio:captureImagePayload.aspectRatio + captureSessionID:captureImagePayload.captureSessionID + shouldCaptureFromVideo:[SCCaptureWorker shouldCaptureImageFromVideoWithResource:resource] + completionHandler:captureImagePayload.block + context:context]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureImageStateId; +} +@end diff --git a/ManagedCapturer/SCCaptureImageStateTransitionPayload.h b/ManagedCapturer/SCCaptureImageStateTransitionPayload.h new file mode 100644 index 0000000..ea82816 --- /dev/null +++ b/ManagedCapturer/SCCaptureImageStateTransitionPayload.h @@ -0,0 +1,29 @@ +// +// SCCaptureImageStateTransitionPayload.h +// Snapchat +// +// Created by Lin Jia on 1/9/18. +// + +#import "SCCaptureCommon.h" +#import "SCStateTransitionPayload.h" + +#import + +@interface SCCaptureImageStateTransitionPayload : SCStateTransitionPayload + +@property (nonatomic, readonly, strong) NSString *captureSessionID; + +@property (nonatomic, readonly, copy) sc_managed_capturer_capture_still_image_completion_handler_t block; + +@property (nonatomic, readonly, assign) CGFloat aspectRatio; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block; + +@end diff --git a/ManagedCapturer/SCCaptureImageStateTransitionPayload.m b/ManagedCapturer/SCCaptureImageStateTransitionPayload.m new file mode 100644 index 0000000..45ba345 --- /dev/null +++ b/ManagedCapturer/SCCaptureImageStateTransitionPayload.m @@ -0,0 +1,27 @@ +// +// SCCaptureImageStateTransitionPayload.m +// Snapchat +// +// Created by Lin Jia on 1/9/18. +// + +#import "SCCaptureImageStateTransitionPayload.h" + +@implementation SCCaptureImageStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block +{ + self = [super initWithFromState:fromState toState:toState]; + if (self) { + _captureSessionID = captureSessionID; + _aspectRatio = aspectRatio; + _block = block; + } + return self; +} + +@end diff --git a/ManagedCapturer/SCCaptureImageWhileRecordingState.h b/ManagedCapturer/SCCaptureImageWhileRecordingState.h new file mode 100644 index 0000000..281b0a4 --- /dev/null +++ b/ManagedCapturer/SCCaptureImageWhileRecordingState.h @@ -0,0 +1,22 @@ +// +// SCCaptureImageWhileRecordingState.h +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureImageWhileRecordingState : SCCaptureBaseState + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/SCCaptureImageWhileRecordingState.m b/ManagedCapturer/SCCaptureImageWhileRecordingState.m new file mode 100644 index 0000000..eb1e4e1 --- /dev/null +++ b/ManagedCapturer/SCCaptureImageWhileRecordingState.m @@ -0,0 +1,85 @@ +// +// SCCaptureImageWhileRecordingState.m +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureImageWhileRecordingState.h" + +#import "SCCaptureImageWhileRecordingStateTransitionPayload.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import + +@interface SCCaptureImageWhileRecordingState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} +@end + +@implementation SCCaptureImageWhileRecordingState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureImageWhileRecordingStateId; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCAssert(payload.fromState == SCCaptureRecordingStateId, @""); + SCAssert(payload.toState == [self stateId], @""); + SCAssert([payload isKindOfClass:[SCCaptureImageWhileRecordingStateTransitionPayload class]], @""); + ; + SCCaptureImageWhileRecordingStateTransitionPayload *captureImagePayload = + (SCCaptureImageWhileRecordingStateTransitionPayload *)payload; + + @weakify(self); + sc_managed_capturer_capture_still_image_completion_handler_t block = + ^(UIImage *fullScreenImage, NSDictionary *metadata, NSError *error, SCManagedCapturerState *state) { + captureImagePayload.block(fullScreenImage, metadata, error, state); + [_performer perform:^{ + @strongify(self); + [self _cancelRecordingWithContext:context resource:resource]; + }]; + }; + + [SCCaptureWorker + captureStillImageWithCaptureResource:resource + aspectRatio:captureImagePayload.aspectRatio + captureSessionID:captureImagePayload.captureSessionID + shouldCaptureFromVideo:[SCCaptureWorker shouldCaptureImageFromVideoWithResource:resource] + completionHandler:block + context:context]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; +} + +- (void)_cancelRecordingWithContext:(NSString *)context resource:(SCCaptureResource *)resource +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + [SCCaptureWorker cancelRecordingWithCaptureResource:resource]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} +@end diff --git a/ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.h b/ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.h new file mode 100644 index 0000000..7079a10 --- /dev/null +++ b/ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.h @@ -0,0 +1,29 @@ +// +// SCCaptureImageWhileRecordingStateTransitionPayload.h +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureCommon.h" +#import "SCStateTransitionPayload.h" + +#import + +@interface SCCaptureImageWhileRecordingStateTransitionPayload : SCStateTransitionPayload + +@property (nonatomic, readonly, strong) NSString *captureSessionID; + +@property (nonatomic, readonly, copy) sc_managed_capturer_capture_still_image_completion_handler_t block; + +@property (nonatomic, readonly, assign) CGFloat aspectRatio; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block; + +@end diff --git a/ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.m b/ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.m new file mode 100644 index 0000000..ae4f271 --- /dev/null +++ b/ManagedCapturer/SCCaptureImageWhileRecordingStateTransitionPayload.m @@ -0,0 +1,27 @@ +// +// SCCaptureImageWhileRecordingStateTransitionPayload.m +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureImageWhileRecordingStateTransitionPayload.h" + +@implementation SCCaptureImageWhileRecordingStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block +{ + self = [super initWithFromState:fromState toState:toState]; + if (self) { + _captureSessionID = captureSessionID; + _aspectRatio = aspectRatio; + _block = block; + } + return self; +} + +@end diff --git a/ManagedCapturer/SCCaptureInitializedState.h b/ManagedCapturer/SCCaptureInitializedState.h new file mode 100644 index 0000000..5d5876c --- /dev/null +++ b/ManagedCapturer/SCCaptureInitializedState.h @@ -0,0 +1,22 @@ +// +// SCCaptureInitializedState.h +// Snapchat +// +// Created by Jingtian Yang on 20/12/2017. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureInitializedState : SCCaptureBaseState + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/SCCaptureInitializedState.m b/ManagedCapturer/SCCaptureInitializedState.m new file mode 100644 index 0000000..7a687a6 --- /dev/null +++ b/ManagedCapturer/SCCaptureInitializedState.m @@ -0,0 +1,68 @@ +// +// SCCaptureInitializedState.m +// Snapchat +// +// Created by Jingtian Yang on 20/12/2017. +// + +#import "SCCaptureInitializedState.h" + +#import "SCCapturerToken.h" +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import + +@interface SCCaptureInitializedState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureInitializedState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureInitializedStateId; +} + +- (void)startRunningWithCapturerToken:(SCCapturerToken *)token + resource:(SCCaptureResource *)resource + completionHandler:(dispatch_block_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"startRunningAsynchronouslyWithCompletionHandler called. token: %@", token); + + [SCCaptureWorker startRunningWithCaptureResource:resource token:token completionHandler:completionHandler]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/SCCaptureRecordingState.h b/ManagedCapturer/SCCaptureRecordingState.h new file mode 100644 index 0000000..a6bbbf0 --- /dev/null +++ b/ManagedCapturer/SCCaptureRecordingState.h @@ -0,0 +1,22 @@ +// +// SCCaptureRecordingState.h +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureRecordingState : SCCaptureBaseState + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/SCCaptureRecordingState.m b/ManagedCapturer/SCCaptureRecordingState.m new file mode 100644 index 0000000..fb7513c --- /dev/null +++ b/ManagedCapturer/SCCaptureRecordingState.m @@ -0,0 +1,114 @@ +// +// SCCaptureRecordingState.m +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureRecordingState.h" + +#import "SCCaptureImageWhileRecordingStateTransitionPayload.h" +#import "SCCaptureRecordingStateTransitionPayload.h" +#import "SCManagedCapturerV1_Private.h" +#import "SCStateTransitionPayload.h" + +#import +#import + +@interface SCCaptureRecordingState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} +@end + +@implementation SCCaptureRecordingState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(resource.queuePerformer); + SCAssert(payload.toState == [self stateId], @""); + if (![payload isKindOfClass:[SCCaptureRecordingStateTransitionPayload class]]) { + SCAssertFail(@"wrong payload pass in"); + [_delegate currentState:self requestToTransferToNewState:payload.fromState payload:nil context:context]; + return; + } + + SCCaptureRecordingStateTransitionPayload *recordingPayload = (SCCaptureRecordingStateTransitionPayload *)payload; + [SCCaptureWorker startRecordingWithCaptureResource:resource + outputSettings:recordingPayload.outputSettings + audioConfiguration:recordingPayload.configuration + maxDuration:recordingPayload.maxDuration + fileURL:recordingPayload.fileURL + captureSessionID:recordingPayload.captureSessionID + completionHandler:recordingPayload.block]; +} + +- (void)stopRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + [SCCaptureWorker stopRecordingWithCaptureResource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)cancelRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + [SCCaptureWorker cancelRecordingWithCaptureResource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureRecordingStateId; +} + +- (void)captureStillImageWithResource:(SCCaptureResource *)resource + aspectRatio:(CGFloat)aspectRatio + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCCaptureImageWhileRecordingStateTransitionPayload *payload = [ + [SCCaptureImageWhileRecordingStateTransitionPayload alloc] initWithFromState:SCCaptureRecordingStateId + toState:SCCaptureImageWhileRecordingStateId + captureSessionId:captureSessionID + aspectRatio:aspectRatio + completionHandler:completionHandler]; + [_delegate currentState:self + requestToTransferToNewState:SCCaptureImageWhileRecordingStateId + payload:payload + context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/SCCaptureRecordingStateTransitionPayload.h b/ManagedCapturer/SCCaptureRecordingStateTransitionPayload.h new file mode 100644 index 0000000..4995daa --- /dev/null +++ b/ManagedCapturer/SCCaptureRecordingStateTransitionPayload.h @@ -0,0 +1,41 @@ +// +// SCCaptureRecordingStateTransitionPayload.h +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureCommon.h" +#import "SCManagedVideoCapturerOutputSettings.h" +#import "SCStateTransitionPayload.h" + +#import + +#import + +@interface SCCaptureRecordingStateTransitionPayload : SCStateTransitionPayload + +@property (nonatomic, readonly, strong) SCManagedVideoCapturerOutputSettings *outputSettings; + +@property (nonatomic, readonly, strong) SCAudioConfiguration *configuration; + +@property (nonatomic, readonly, assign) NSTimeInterval maxDuration; + +@property (nonatomic, readonly, strong) NSURL *fileURL; + +@property (nonatomic, readonly, strong) NSString *captureSessionID; + +@property (nonatomic, readonly, copy) sc_managed_capturer_start_recording_completion_handler_t block; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + outputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings + audioConfiguration:(SCAudioConfiguration *)configuration + maxDuration:(NSTimeInterval)maxDuration + fileURL:(NSURL *)fileURL + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_start_recording_completion_handler_t)block; + +@end diff --git a/ManagedCapturer/SCCaptureRecordingStateTransitionPayload.m b/ManagedCapturer/SCCaptureRecordingStateTransitionPayload.m new file mode 100644 index 0000000..167031a --- /dev/null +++ b/ManagedCapturer/SCCaptureRecordingStateTransitionPayload.m @@ -0,0 +1,33 @@ +// +// SCCaptureRecordingStateTransitionPayload.m +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureRecordingStateTransitionPayload.h" + +@implementation SCCaptureRecordingStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + outputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings + audioConfiguration:configuration + maxDuration:(NSTimeInterval)maxDuration + fileURL:(NSURL *)fileURL + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_start_recording_completion_handler_t)block +{ + self = [super initWithFromState:fromState toState:toState]; + if (self) { + _outputSettings = outputSettings; + _configuration = configuration; + _maxDuration = maxDuration; + _fileURL = fileURL; + _captureSessionID = captureSessionID; + _block = block; + } + return self; +} + +@end diff --git a/ManagedCapturer/SCCaptureRunningState.h b/ManagedCapturer/SCCaptureRunningState.h new file mode 100644 index 0000000..4912a4a --- /dev/null +++ b/ManagedCapturer/SCCaptureRunningState.h @@ -0,0 +1,22 @@ +// +// SCCaptureRunningState.h +// Snapchat +// +// Created by Jingtian Yang on 08/01/2018. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureRunningState : SCCaptureBaseState + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/SCCaptureRunningState.m b/ManagedCapturer/SCCaptureRunningState.m new file mode 100644 index 0000000..3fd665e --- /dev/null +++ b/ManagedCapturer/SCCaptureRunningState.m @@ -0,0 +1,176 @@ +// +// SCCaptureRunningState.m +// Snapchat +// +// Created by Jingtian Yang on 08/01/2018. +// + +#import "SCCaptureRunningState.h" + +#import "SCCaptureImageStateTransitionPayload.h" +#import "SCCaptureRecordingStateTransitionPayload.h" +#import "SCCaptureWorker.h" +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" +#import "SCScanConfiguration.h" + +#import +#import +#import + +@interface SCCaptureRunningState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureRunningState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (void)captureStillImageWithResource:(SCCaptureResource *)resource + aspectRatio:(CGFloat)aspectRatio + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCCaptureImageStateTransitionPayload *payload = + [[SCCaptureImageStateTransitionPayload alloc] initWithFromState:SCCaptureRunningStateId + toState:SCCaptureImageStateId + captureSessionId:captureSessionID + aspectRatio:aspectRatio + completionHandler:completionHandler]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureImageStateId payload:payload context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureRunningStateId; +} + +- (void)startRunningWithCapturerToken:(SCCapturerToken *)token + resource:(SCCaptureResource *)resource + completionHandler:(dispatch_block_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"startRunningAsynchronouslyWithCompletionHandler called. token: %@", token); + [SCCaptureWorker startRunningWithCaptureResource:resource token:token completionHandler:completionHandler]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)stopRunningWithCapturerToken:(SCCapturerToken *)token + resource:(SCCaptureResource *)resource + completionHandler:(sc_managed_capturer_stop_running_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + SCLogCapturerInfo(@"Stop running asynchronously. token:%@", token); + if ([[SCManagedCapturerV1 sharedInstance] stopRunningWithCaptureToken:token + completionHandler:completionHandler + context:context]) { + [_delegate currentState:self + requestToTransferToNewState:SCCaptureInitializedStateId + payload:nil + context:context]; + } + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)startScanWithScanConfiguration:(SCScanConfiguration *)configuration + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"Start scan on preview asynchronously. configuration:%@", configuration); + SCAssertPerformer(_performer); + [SCCaptureWorker startScanWithScanConfiguration:configuration resource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureScanningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)prepareForRecordingWithResource:(SCCaptureResource *)resource + audioConfiguration:(SCAudioConfiguration *)configuration + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + [SCCaptureWorker prepareForRecordingWithAudioConfiguration:configuration resource:resource]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)startRecordingWithResource:(SCCaptureResource *)resource + audioConfiguration:(SCAudioConfiguration *)configuration + outputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings + maxDuration:(NSTimeInterval)maxDuration + fileURL:(NSURL *)fileURL + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_start_recording_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + SCCaptureRecordingStateTransitionPayload *payload = + [[SCCaptureRecordingStateTransitionPayload alloc] initWithFromState:SCCaptureRunningStateId + toState:SCCaptureRecordingStateId + outputSettings:outputSettings + audioConfiguration:configuration + maxDuration:maxDuration + fileURL:fileURL + captureSessionID:captureSessionID + completionHandler:completionHandler]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRecordingStateId payload:payload context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)cancelRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + // Intentionally No Op, this will be removed once CCAM-13851 gets resolved. + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/SCCaptureScanningState.h b/ManagedCapturer/SCCaptureScanningState.h new file mode 100644 index 0000000..0e60f79 --- /dev/null +++ b/ManagedCapturer/SCCaptureScanningState.h @@ -0,0 +1,18 @@ +// +// SCCaptureScanningState.h +// Snapchat +// +// Created by Xiaokang Liu on 09/01/2018. +// + +#import "SCCaptureBaseState.h" + +@class SCQueuePerformer; + +@interface SCCaptureScanningState : SCCaptureBaseState +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; +@end diff --git a/ManagedCapturer/SCCaptureScanningState.m b/ManagedCapturer/SCCaptureScanningState.m new file mode 100644 index 0000000..7b6f0e7 --- /dev/null +++ b/ManagedCapturer/SCCaptureScanningState.m @@ -0,0 +1,75 @@ +// +// SCCaptureScanningState.m +// Snapchat +// +// Created by Xiaokang Liu on 09/01/2018. +// + +#import "SCCaptureScanningState.h" + +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import +#import + +@interface SCCaptureScanningState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureScanningState +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + SCAssert(delegate, @""); + SCAssert(performer, @""); + SCAssert(bookKeeper, @""); + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureScanningStateId; +} + +- (void)stopScanWithCompletionHandler:(dispatch_block_t)completionHandler + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"stop scan asynchronously."); + [SCCaptureWorker stopScanWithCompletionHandler:completionHandler resource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)cancelRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + // Intentionally No Op, this will be removed once CCAM-13851 gets resolved. + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/SCCaptureUninitializedState.h b/ManagedCapturer/SCCaptureUninitializedState.h new file mode 100644 index 0000000..0809581 --- /dev/null +++ b/ManagedCapturer/SCCaptureUninitializedState.h @@ -0,0 +1,26 @@ +// +// SCCaptureUninitializedState.h +// Snapchat +// +// Created by Lin Jia on 10/19/17. +// +// + +#import "SCCaptureBaseState.h" + +#import + +/* + State which handles capture initialialization, which should be used only once for every app life span. +*/ +@class SCQueuePerformer; + +@interface SCCaptureUninitializedState : SCCaptureBaseState + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/SCCaptureUninitializedState.m b/ManagedCapturer/SCCaptureUninitializedState.m new file mode 100644 index 0000000..ffe99bf --- /dev/null +++ b/ManagedCapturer/SCCaptureUninitializedState.m @@ -0,0 +1,70 @@ +// +// SCCaptureUninitializedState.m +// Snapchat +// +// Created by Lin Jia on 10/19/17. +// +// + +#import "SCCaptureUninitializedState.h" + +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import +#import + +@interface SCCaptureUninitializedState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureUninitializedState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureUninitializedStateId; +} + +- (void)initializeCaptureWithDevicePosition:(SCManagedCaptureDevicePosition)devicePosition + resource:(SCCaptureResource *)resource + completionHandler:(dispatch_block_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"Setting up with devicePosition:%lu", (unsigned long)devicePosition); + + // TODO: we need to push completionHandler to a payload and let intializedState handle. + [[SCManagedCapturerV1 sharedInstance] setupWithDevicePosition:devicePosition completionHandler:completionHandler]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureInitializedStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/SCStateTransitionPayload.h b/ManagedCapturer/SCStateTransitionPayload.h new file mode 100644 index 0000000..8fca174 --- /dev/null +++ b/ManagedCapturer/SCStateTransitionPayload.h @@ -0,0 +1,22 @@ +// +// SCStateTransitionPayload.h +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCCaptureStateUtil.h" + +#import + +@interface SCStateTransitionPayload : NSObject + +@property (nonatomic, readonly, assign) SCCaptureStateMachineStateId fromState; + +@property (nonatomic, readonly, assign) SCCaptureStateMachineStateId toState; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState toState:(SCCaptureStateMachineStateId)toState; + +@end diff --git a/ManagedCapturer/SCStateTransitionPayload.m b/ManagedCapturer/SCStateTransitionPayload.m new file mode 100644 index 0000000..d4df2bd --- /dev/null +++ b/ManagedCapturer/SCStateTransitionPayload.m @@ -0,0 +1,27 @@ +// +// SCStateTransitionPayload.m +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCStateTransitionPayload.h" + +#import + +@implementation SCStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState toState:(SCCaptureStateMachineStateId)toState +{ + self = [super init]; + if (self) { + SCAssert(fromState != toState, @""); + SCAssert(fromState > SCCaptureBaseStateId && fromState < SCCaptureStateMachineStateIdCount, @""); + SCAssert(toState > SCCaptureBaseStateId && toState < SCCaptureStateMachineStateIdCount, @""); + _fromState = fromState; + _toState = toState; + } + return self; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureImageState.h b/ManagedCapturer/States/SCCaptureImageState.h new file mode 100644 index 0000000..561b43f --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageState.h @@ -0,0 +1,22 @@ +// +// SCCaptureImageState.h +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureImageState : SCCaptureBaseState + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/States/SCCaptureImageState.m b/ManagedCapturer/States/SCCaptureImageState.m new file mode 100644 index 0000000..d26a0f4 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageState.m @@ -0,0 +1,65 @@ +// +// SCCaptureImageState.m +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCCaptureImageState.h" + +#import "SCCaptureImageStateTransitionPayload.h" +#import "SCManagedCapturerV1_Private.h" +#import "SCStateTransitionPayload.h" + +#import +#import + +@interface SCCaptureImageState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} +@end + +@implementation SCCaptureImageState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCAssert(payload.toState == [self stateId], @""); + if (![payload isKindOfClass:[SCCaptureImageStateTransitionPayload class]]) { + SCAssertFail(@"wrong payload pass in"); + [_delegate currentState:self requestToTransferToNewState:payload.fromState payload:nil context:context]; + return; + } + SCCaptureImageStateTransitionPayload *captureImagePayload = (SCCaptureImageStateTransitionPayload *)payload; + + [SCCaptureWorker + captureStillImageWithCaptureResource:resource + aspectRatio:captureImagePayload.aspectRatio + captureSessionID:captureImagePayload.captureSessionID + shouldCaptureFromVideo:[SCCaptureWorker shouldCaptureImageFromVideoWithResource:resource] + completionHandler:captureImagePayload.block + context:context]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureImageStateId; +} +@end diff --git a/ManagedCapturer/States/SCCaptureImageStateTransitionPayload.h b/ManagedCapturer/States/SCCaptureImageStateTransitionPayload.h new file mode 100644 index 0000000..ea82816 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageStateTransitionPayload.h @@ -0,0 +1,29 @@ +// +// SCCaptureImageStateTransitionPayload.h +// Snapchat +// +// Created by Lin Jia on 1/9/18. +// + +#import "SCCaptureCommon.h" +#import "SCStateTransitionPayload.h" + +#import + +@interface SCCaptureImageStateTransitionPayload : SCStateTransitionPayload + +@property (nonatomic, readonly, strong) NSString *captureSessionID; + +@property (nonatomic, readonly, copy) sc_managed_capturer_capture_still_image_completion_handler_t block; + +@property (nonatomic, readonly, assign) CGFloat aspectRatio; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block; + +@end diff --git a/ManagedCapturer/States/SCCaptureImageStateTransitionPayload.m b/ManagedCapturer/States/SCCaptureImageStateTransitionPayload.m new file mode 100644 index 0000000..45ba345 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageStateTransitionPayload.m @@ -0,0 +1,27 @@ +// +// SCCaptureImageStateTransitionPayload.m +// Snapchat +// +// Created by Lin Jia on 1/9/18. +// + +#import "SCCaptureImageStateTransitionPayload.h" + +@implementation SCCaptureImageStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block +{ + self = [super initWithFromState:fromState toState:toState]; + if (self) { + _captureSessionID = captureSessionID; + _aspectRatio = aspectRatio; + _block = block; + } + return self; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureImageWhileRecordingState.h b/ManagedCapturer/States/SCCaptureImageWhileRecordingState.h new file mode 100644 index 0000000..281b0a4 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageWhileRecordingState.h @@ -0,0 +1,22 @@ +// +// SCCaptureImageWhileRecordingState.h +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureImageWhileRecordingState : SCCaptureBaseState + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/States/SCCaptureImageWhileRecordingState.m b/ManagedCapturer/States/SCCaptureImageWhileRecordingState.m new file mode 100644 index 0000000..eb1e4e1 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageWhileRecordingState.m @@ -0,0 +1,85 @@ +// +// SCCaptureImageWhileRecordingState.m +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureImageWhileRecordingState.h" + +#import "SCCaptureImageWhileRecordingStateTransitionPayload.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import + +@interface SCCaptureImageWhileRecordingState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} +@end + +@implementation SCCaptureImageWhileRecordingState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureImageWhileRecordingStateId; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCAssert(payload.fromState == SCCaptureRecordingStateId, @""); + SCAssert(payload.toState == [self stateId], @""); + SCAssert([payload isKindOfClass:[SCCaptureImageWhileRecordingStateTransitionPayload class]], @""); + ; + SCCaptureImageWhileRecordingStateTransitionPayload *captureImagePayload = + (SCCaptureImageWhileRecordingStateTransitionPayload *)payload; + + @weakify(self); + sc_managed_capturer_capture_still_image_completion_handler_t block = + ^(UIImage *fullScreenImage, NSDictionary *metadata, NSError *error, SCManagedCapturerState *state) { + captureImagePayload.block(fullScreenImage, metadata, error, state); + [_performer perform:^{ + @strongify(self); + [self _cancelRecordingWithContext:context resource:resource]; + }]; + }; + + [SCCaptureWorker + captureStillImageWithCaptureResource:resource + aspectRatio:captureImagePayload.aspectRatio + captureSessionID:captureImagePayload.captureSessionID + shouldCaptureFromVideo:[SCCaptureWorker shouldCaptureImageFromVideoWithResource:resource] + completionHandler:block + context:context]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; +} + +- (void)_cancelRecordingWithContext:(NSString *)context resource:(SCCaptureResource *)resource +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + [SCCaptureWorker cancelRecordingWithCaptureResource:resource]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} +@end diff --git a/ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.h b/ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.h new file mode 100644 index 0000000..7079a10 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.h @@ -0,0 +1,29 @@ +// +// SCCaptureImageWhileRecordingStateTransitionPayload.h +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureCommon.h" +#import "SCStateTransitionPayload.h" + +#import + +@interface SCCaptureImageWhileRecordingStateTransitionPayload : SCStateTransitionPayload + +@property (nonatomic, readonly, strong) NSString *captureSessionID; + +@property (nonatomic, readonly, copy) sc_managed_capturer_capture_still_image_completion_handler_t block; + +@property (nonatomic, readonly, assign) CGFloat aspectRatio; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block; + +@end diff --git a/ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.m b/ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.m new file mode 100644 index 0000000..ae4f271 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureImageWhileRecordingStateTransitionPayload.m @@ -0,0 +1,27 @@ +// +// SCCaptureImageWhileRecordingStateTransitionPayload.m +// Snapchat +// +// Created by Sun Lei on 22/02/2018. +// + +#import "SCCaptureImageWhileRecordingStateTransitionPayload.h" + +@implementation SCCaptureImageWhileRecordingStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + captureSessionId:(NSString *)captureSessionID + aspectRatio:(CGFloat)aspectRatio + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)block +{ + self = [super initWithFromState:fromState toState:toState]; + if (self) { + _captureSessionID = captureSessionID; + _aspectRatio = aspectRatio; + _block = block; + } + return self; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureInitializedState.h b/ManagedCapturer/States/SCCaptureInitializedState.h new file mode 100644 index 0000000..5d5876c --- /dev/null +++ b/ManagedCapturer/States/SCCaptureInitializedState.h @@ -0,0 +1,22 @@ +// +// SCCaptureInitializedState.h +// Snapchat +// +// Created by Jingtian Yang on 20/12/2017. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureInitializedState : SCCaptureBaseState + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/States/SCCaptureInitializedState.m b/ManagedCapturer/States/SCCaptureInitializedState.m new file mode 100644 index 0000000..7a687a6 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureInitializedState.m @@ -0,0 +1,68 @@ +// +// SCCaptureInitializedState.m +// Snapchat +// +// Created by Jingtian Yang on 20/12/2017. +// + +#import "SCCaptureInitializedState.h" + +#import "SCCapturerToken.h" +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import + +@interface SCCaptureInitializedState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureInitializedState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureInitializedStateId; +} + +- (void)startRunningWithCapturerToken:(SCCapturerToken *)token + resource:(SCCaptureResource *)resource + completionHandler:(dispatch_block_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"startRunningAsynchronouslyWithCompletionHandler called. token: %@", token); + + [SCCaptureWorker startRunningWithCaptureResource:resource token:token completionHandler:completionHandler]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureRecordingState.h b/ManagedCapturer/States/SCCaptureRecordingState.h new file mode 100644 index 0000000..a6bbbf0 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureRecordingState.h @@ -0,0 +1,22 @@ +// +// SCCaptureRecordingState.h +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureRecordingState : SCCaptureBaseState + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/States/SCCaptureRecordingState.m b/ManagedCapturer/States/SCCaptureRecordingState.m new file mode 100644 index 0000000..fb7513c --- /dev/null +++ b/ManagedCapturer/States/SCCaptureRecordingState.m @@ -0,0 +1,114 @@ +// +// SCCaptureRecordingState.m +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureRecordingState.h" + +#import "SCCaptureImageWhileRecordingStateTransitionPayload.h" +#import "SCCaptureRecordingStateTransitionPayload.h" +#import "SCManagedCapturerV1_Private.h" +#import "SCStateTransitionPayload.h" + +#import +#import + +@interface SCCaptureRecordingState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} +@end + +@implementation SCCaptureRecordingState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(resource.queuePerformer); + SCAssert(payload.toState == [self stateId], @""); + if (![payload isKindOfClass:[SCCaptureRecordingStateTransitionPayload class]]) { + SCAssertFail(@"wrong payload pass in"); + [_delegate currentState:self requestToTransferToNewState:payload.fromState payload:nil context:context]; + return; + } + + SCCaptureRecordingStateTransitionPayload *recordingPayload = (SCCaptureRecordingStateTransitionPayload *)payload; + [SCCaptureWorker startRecordingWithCaptureResource:resource + outputSettings:recordingPayload.outputSettings + audioConfiguration:recordingPayload.configuration + maxDuration:recordingPayload.maxDuration + fileURL:recordingPayload.fileURL + captureSessionID:recordingPayload.captureSessionID + completionHandler:recordingPayload.block]; +} + +- (void)stopRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + [SCCaptureWorker stopRecordingWithCaptureResource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)cancelRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + [SCCaptureWorker cancelRecordingWithCaptureResource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureRecordingStateId; +} + +- (void)captureStillImageWithResource:(SCCaptureResource *)resource + aspectRatio:(CGFloat)aspectRatio + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCCaptureImageWhileRecordingStateTransitionPayload *payload = [ + [SCCaptureImageWhileRecordingStateTransitionPayload alloc] initWithFromState:SCCaptureRecordingStateId + toState:SCCaptureImageWhileRecordingStateId + captureSessionId:captureSessionID + aspectRatio:aspectRatio + completionHandler:completionHandler]; + [_delegate currentState:self + requestToTransferToNewState:SCCaptureImageWhileRecordingStateId + payload:payload + context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.h b/ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.h new file mode 100644 index 0000000..4995daa --- /dev/null +++ b/ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.h @@ -0,0 +1,41 @@ +// +// SCCaptureRecordingStateTransitionPayload.h +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureCommon.h" +#import "SCManagedVideoCapturerOutputSettings.h" +#import "SCStateTransitionPayload.h" + +#import + +#import + +@interface SCCaptureRecordingStateTransitionPayload : SCStateTransitionPayload + +@property (nonatomic, readonly, strong) SCManagedVideoCapturerOutputSettings *outputSettings; + +@property (nonatomic, readonly, strong) SCAudioConfiguration *configuration; + +@property (nonatomic, readonly, assign) NSTimeInterval maxDuration; + +@property (nonatomic, readonly, strong) NSURL *fileURL; + +@property (nonatomic, readonly, strong) NSString *captureSessionID; + +@property (nonatomic, readonly, copy) sc_managed_capturer_start_recording_completion_handler_t block; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + outputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings + audioConfiguration:(SCAudioConfiguration *)configuration + maxDuration:(NSTimeInterval)maxDuration + fileURL:(NSURL *)fileURL + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_start_recording_completion_handler_t)block; + +@end diff --git a/ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.m b/ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.m new file mode 100644 index 0000000..167031a --- /dev/null +++ b/ManagedCapturer/States/SCCaptureRecordingStateTransitionPayload.m @@ -0,0 +1,33 @@ +// +// SCCaptureRecordingStateTransitionPayload.m +// Snapchat +// +// Created by Jingtian Yang on 12/01/2018. +// + +#import "SCCaptureRecordingStateTransitionPayload.h" + +@implementation SCCaptureRecordingStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState + toState:(SCCaptureStateMachineStateId)toState + outputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings + audioConfiguration:configuration + maxDuration:(NSTimeInterval)maxDuration + fileURL:(NSURL *)fileURL + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_start_recording_completion_handler_t)block +{ + self = [super initWithFromState:fromState toState:toState]; + if (self) { + _outputSettings = outputSettings; + _configuration = configuration; + _maxDuration = maxDuration; + _fileURL = fileURL; + _captureSessionID = captureSessionID; + _block = block; + } + return self; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureRunningState.h b/ManagedCapturer/States/SCCaptureRunningState.h new file mode 100644 index 0000000..4912a4a --- /dev/null +++ b/ManagedCapturer/States/SCCaptureRunningState.h @@ -0,0 +1,22 @@ +// +// SCCaptureRunningState.h +// Snapchat +// +// Created by Jingtian Yang on 08/01/2018. +// + +#import "SCCaptureBaseState.h" + +#import + +@class SCQueuePerformer; + +@interface SCCaptureRunningState : SCCaptureBaseState + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/States/SCCaptureRunningState.m b/ManagedCapturer/States/SCCaptureRunningState.m new file mode 100644 index 0000000..3fd665e --- /dev/null +++ b/ManagedCapturer/States/SCCaptureRunningState.m @@ -0,0 +1,176 @@ +// +// SCCaptureRunningState.m +// Snapchat +// +// Created by Jingtian Yang on 08/01/2018. +// + +#import "SCCaptureRunningState.h" + +#import "SCCaptureImageStateTransitionPayload.h" +#import "SCCaptureRecordingStateTransitionPayload.h" +#import "SCCaptureWorker.h" +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" +#import "SCScanConfiguration.h" + +#import +#import +#import + +@interface SCCaptureRunningState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureRunningState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (void)captureStillImageWithResource:(SCCaptureResource *)resource + aspectRatio:(CGFloat)aspectRatio + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_capture_still_image_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCCaptureImageStateTransitionPayload *payload = + [[SCCaptureImageStateTransitionPayload alloc] initWithFromState:SCCaptureRunningStateId + toState:SCCaptureImageStateId + captureSessionId:captureSessionID + aspectRatio:aspectRatio + completionHandler:completionHandler]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureImageStateId payload:payload context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureRunningStateId; +} + +- (void)startRunningWithCapturerToken:(SCCapturerToken *)token + resource:(SCCaptureResource *)resource + completionHandler:(dispatch_block_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"startRunningAsynchronouslyWithCompletionHandler called. token: %@", token); + [SCCaptureWorker startRunningWithCaptureResource:resource token:token completionHandler:completionHandler]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)stopRunningWithCapturerToken:(SCCapturerToken *)token + resource:(SCCaptureResource *)resource + completionHandler:(sc_managed_capturer_stop_running_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + SCLogCapturerInfo(@"Stop running asynchronously. token:%@", token); + if ([[SCManagedCapturerV1 sharedInstance] stopRunningWithCaptureToken:token + completionHandler:completionHandler + context:context]) { + [_delegate currentState:self + requestToTransferToNewState:SCCaptureInitializedStateId + payload:nil + context:context]; + } + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)startScanWithScanConfiguration:(SCScanConfiguration *)configuration + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"Start scan on preview asynchronously. configuration:%@", configuration); + SCAssertPerformer(_performer); + [SCCaptureWorker startScanWithScanConfiguration:configuration resource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureScanningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)prepareForRecordingWithResource:(SCCaptureResource *)resource + audioConfiguration:(SCAudioConfiguration *)configuration + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + [SCCaptureWorker prepareForRecordingWithAudioConfiguration:configuration resource:resource]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)startRecordingWithResource:(SCCaptureResource *)resource + audioConfiguration:(SCAudioConfiguration *)configuration + outputSettings:(SCManagedVideoCapturerOutputSettings *)outputSettings + maxDuration:(NSTimeInterval)maxDuration + fileURL:(NSURL *)fileURL + captureSessionID:(NSString *)captureSessionID + completionHandler:(sc_managed_capturer_start_recording_completion_handler_t)completionHandler + context:(NSString *)context +{ + SCTraceODPCompatibleStart(2); + SCAssertPerformer(_performer); + + SCCaptureRecordingStateTransitionPayload *payload = + [[SCCaptureRecordingStateTransitionPayload alloc] initWithFromState:SCCaptureRunningStateId + toState:SCCaptureRecordingStateId + outputSettings:outputSettings + audioConfiguration:configuration + maxDuration:maxDuration + fileURL:fileURL + captureSessionID:captureSessionID + completionHandler:completionHandler]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRecordingStateId payload:payload context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)cancelRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + // Intentionally No Op, this will be removed once CCAM-13851 gets resolved. + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureScanningState.h b/ManagedCapturer/States/SCCaptureScanningState.h new file mode 100644 index 0000000..0e60f79 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureScanningState.h @@ -0,0 +1,18 @@ +// +// SCCaptureScanningState.h +// Snapchat +// +// Created by Xiaokang Liu on 09/01/2018. +// + +#import "SCCaptureBaseState.h" + +@class SCQueuePerformer; + +@interface SCCaptureScanningState : SCCaptureBaseState +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; +@end diff --git a/ManagedCapturer/States/SCCaptureScanningState.m b/ManagedCapturer/States/SCCaptureScanningState.m new file mode 100644 index 0000000..7b6f0e7 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureScanningState.m @@ -0,0 +1,75 @@ +// +// SCCaptureScanningState.m +// Snapchat +// +// Created by Xiaokang Liu on 09/01/2018. +// + +#import "SCCaptureScanningState.h" + +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import +#import + +@interface SCCaptureScanningState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureScanningState +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + SCAssert(delegate, @""); + SCAssert(performer, @""); + SCAssert(bookKeeper, @""); + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureScanningStateId; +} + +- (void)stopScanWithCompletionHandler:(dispatch_block_t)completionHandler + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"stop scan asynchronously."); + [SCCaptureWorker stopScanWithCompletionHandler:completionHandler resource:resource]; + [_delegate currentState:self requestToTransferToNewState:SCCaptureRunningStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +- (void)cancelRecordingWithResource:(SCCaptureResource *)resource context:(NSString *)context +{ + // Intentionally No Op, this will be removed once CCAM-13851 gets resolved. + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/States/SCCaptureUninitializedState.h b/ManagedCapturer/States/SCCaptureUninitializedState.h new file mode 100644 index 0000000..0809581 --- /dev/null +++ b/ManagedCapturer/States/SCCaptureUninitializedState.h @@ -0,0 +1,26 @@ +// +// SCCaptureUninitializedState.h +// Snapchat +// +// Created by Lin Jia on 10/19/17. +// +// + +#import "SCCaptureBaseState.h" + +#import + +/* + State which handles capture initialialization, which should be used only once for every app life span. +*/ +@class SCQueuePerformer; + +@interface SCCaptureUninitializedState : SCCaptureBaseState + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate; + +@end diff --git a/ManagedCapturer/States/SCCaptureUninitializedState.m b/ManagedCapturer/States/SCCaptureUninitializedState.m new file mode 100644 index 0000000..ffe99bf --- /dev/null +++ b/ManagedCapturer/States/SCCaptureUninitializedState.m @@ -0,0 +1,70 @@ +// +// SCCaptureUninitializedState.m +// Snapchat +// +// Created by Lin Jia on 10/19/17. +// +// + +#import "SCCaptureUninitializedState.h" + +#import "SCManagedCapturerLogging.h" +#import "SCManagedCapturerV1_Private.h" + +#import +#import +#import + +@interface SCCaptureUninitializedState () { + __weak id _delegate; + SCQueuePerformer *_performer; +} + +@end + +@implementation SCCaptureUninitializedState + +- (instancetype)initWithPerformer:(SCQueuePerformer *)performer + bookKeeper:(SCCaptureStateMachineBookKeeper *)bookKeeper + delegate:(id)delegate +{ + self = [super initWithPerformer:performer bookKeeper:bookKeeper delegate:delegate]; + if (self) { + _delegate = delegate; + _performer = performer; + } + return self; +} + +- (void)didBecomeCurrentState:(SCStateTransitionPayload *)payload + resource:(SCCaptureResource *)resource + context:(NSString *)context +{ + // No op. +} + +- (SCCaptureStateMachineStateId)stateId +{ + return SCCaptureUninitializedStateId; +} + +- (void)initializeCaptureWithDevicePosition:(SCManagedCaptureDevicePosition)devicePosition + resource:(SCCaptureResource *)resource + completionHandler:(dispatch_block_t)completionHandler + context:(NSString *)context +{ + SCAssertPerformer(_performer); + SCTraceODPCompatibleStart(2); + SCLogCapturerInfo(@"Setting up with devicePosition:%lu", (unsigned long)devicePosition); + + // TODO: we need to push completionHandler to a payload and let intializedState handle. + [[SCManagedCapturerV1 sharedInstance] setupWithDevicePosition:devicePosition completionHandler:completionHandler]; + + [_delegate currentState:self requestToTransferToNewState:SCCaptureInitializedStateId payload:nil context:context]; + + NSString *apiName = + [NSString sc_stringWithFormat:@"%@/%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + [self.bookKeeper logAPICalled:apiName context:context]; +} + +@end diff --git a/ManagedCapturer/States/SCStateTransitionPayload.h b/ManagedCapturer/States/SCStateTransitionPayload.h new file mode 100644 index 0000000..8fca174 --- /dev/null +++ b/ManagedCapturer/States/SCStateTransitionPayload.h @@ -0,0 +1,22 @@ +// +// SCStateTransitionPayload.h +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCCaptureStateUtil.h" + +#import + +@interface SCStateTransitionPayload : NSObject + +@property (nonatomic, readonly, assign) SCCaptureStateMachineStateId fromState; + +@property (nonatomic, readonly, assign) SCCaptureStateMachineStateId toState; + +SC_INIT_AND_NEW_UNAVAILABLE + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState toState:(SCCaptureStateMachineStateId)toState; + +@end diff --git a/ManagedCapturer/States/SCStateTransitionPayload.m b/ManagedCapturer/States/SCStateTransitionPayload.m new file mode 100644 index 0000000..d4df2bd --- /dev/null +++ b/ManagedCapturer/States/SCStateTransitionPayload.m @@ -0,0 +1,27 @@ +// +// SCStateTransitionPayload.m +// Snapchat +// +// Created by Lin Jia on 1/8/18. +// + +#import "SCStateTransitionPayload.h" + +#import + +@implementation SCStateTransitionPayload + +- (instancetype)initWithFromState:(SCCaptureStateMachineStateId)fromState toState:(SCCaptureStateMachineStateId)toState +{ + self = [super init]; + if (self) { + SCAssert(fromState != toState, @""); + SCAssert(fromState > SCCaptureBaseStateId && fromState < SCCaptureStateMachineStateIdCount, @""); + SCAssert(toState > SCCaptureBaseStateId && toState < SCCaptureStateMachineStateIdCount, @""); + _fromState = fromState; + _toState = toState; + } + return self; +} + +@end diff --git a/ManagedCapturer/UIScreen+Debug.h b/ManagedCapturer/UIScreen+Debug.h new file mode 100644 index 0000000..58d54a1 --- /dev/null +++ b/ManagedCapturer/UIScreen+Debug.h @@ -0,0 +1,13 @@ +// +// UIScreen+Debug.h +// Snapchat +// +// Created by Derek Peirce on 6/1/17. +// Copyright © 2017 Snapchat, Inc. All rights reserved. +// + +#import + +@interface UIScreen (Debug) + +@end diff --git a/ManagedCapturer/UIScreen+Debug.m b/ManagedCapturer/UIScreen+Debug.m new file mode 100644 index 0000000..26a121c --- /dev/null +++ b/ManagedCapturer/UIScreen+Debug.m @@ -0,0 +1,28 @@ + +#import "UIScreen+Debug.h" + +#import +#import + +#import + +@implementation UIScreen (Debug) ++ (void)load +{ + if (SCIsPerformanceLoggingEnabled()) { + static dispatch_once_t once_token; + dispatch_once(&once_token, ^{ + SEL setBrightnessSelector = @selector(setBrightness:); + SEL setBrightnessLoggerSelector = @selector(logged_setBrightness:); + Method originalMethod = class_getInstanceMethod(self, setBrightnessSelector); + Method extendedMethod = class_getInstanceMethod(self, setBrightnessLoggerSelector); + method_exchangeImplementations(originalMethod, extendedMethod); + }); + } +} +- (void)logged_setBrightness:(CGFloat)brightness +{ + SCLogGeneralInfo(@"Setting brightness from %f to %f", self.brightness, brightness); + [self logged_setBrightness:brightness]; +} +@end