Obj-C SDK Cleanup
This CL separates the files under sdk/objc into logical directories, replacing the previous file layout under Framework/. A long term goal is to have some system set up to generate the files under sdk/objc/api (the PeerConnection API wrappers) from the C++ code. In the shorter term the goal is to abstract out shared concepts from these classes in order to make them as uniform as possible. The separation into base/, components/, and helpers/ are to differentiate between the base layer's common protocols, various utilities and the actual platform specific components. The old directory layout that resembled a framework's internal layout is not necessary, since it is generated by the framework target when building it. Bug: webrtc:9627 Change-Id: Ib084fd83f050ae980649ca99e841f4fb0580bd8f Reviewed-on: https://webrtc-review.googlesource.com/94142 Reviewed-by: Kári Helgason <kthelgason@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Commit-Queue: Anders Carlsson <andersc@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24493}
This commit is contained in:
committed by
Commit Bot
parent
9ea5765f78
commit
7bca8ca4e2
23
sdk/objc/helpers/AVCaptureSession+DevicePosition.h
Normal file
23
sdk/objc/helpers/AVCaptureSession+DevicePosition.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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 <AVFoundation/AVFoundation.h>
|
||||
#import <CoreMedia/CoreMedia.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AVCaptureSession (DevicePosition)
|
||||
|
||||
// Check the image's EXIF for the camera the image came from.
|
||||
+ (AVCaptureDevicePosition)devicePositionForSampleBuffer:(CMSampleBufferRef)sampleBuffer;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
51
sdk/objc/helpers/AVCaptureSession+DevicePosition.mm
Normal file
51
sdk/objc/helpers/AVCaptureSession+DevicePosition.mm
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 "AVCaptureSession+DevicePosition.h"
|
||||
|
||||
BOOL CFStringContainsString(CFStringRef theString, CFStringRef stringToFind) {
|
||||
return CFStringFindWithOptions(theString,
|
||||
stringToFind,
|
||||
CFRangeMake(0, CFStringGetLength(theString)),
|
||||
kCFCompareCaseInsensitive,
|
||||
nil);
|
||||
}
|
||||
|
||||
@implementation AVCaptureSession (DevicePosition)
|
||||
|
||||
+ (AVCaptureDevicePosition)devicePositionForSampleBuffer:(CMSampleBufferRef)sampleBuffer {
|
||||
// Check the image's EXIF for the camera the image came from.
|
||||
AVCaptureDevicePosition cameraPosition = AVCaptureDevicePositionUnspecified;
|
||||
CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(
|
||||
kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate);
|
||||
if (attachments) {
|
||||
int size = CFDictionaryGetCount(attachments);
|
||||
if (size > 0) {
|
||||
CFDictionaryRef cfExifDictVal = nil;
|
||||
if (CFDictionaryGetValueIfPresent(
|
||||
attachments, (const void *)CFSTR("{Exif}"), (const void **)&cfExifDictVal)) {
|
||||
CFStringRef cfLensModelStrVal;
|
||||
if (CFDictionaryGetValueIfPresent(cfExifDictVal,
|
||||
(const void *)CFSTR("LensModel"),
|
||||
(const void **)&cfLensModelStrVal)) {
|
||||
if (CFStringContainsString(cfLensModelStrVal, CFSTR("front"))) {
|
||||
cameraPosition = AVCaptureDevicePositionFront;
|
||||
} else if (CFStringContainsString(cfLensModelStrVal, CFSTR("back"))) {
|
||||
cameraPosition = AVCaptureDevicePositionBack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CFRelease(attachments);
|
||||
}
|
||||
return cameraPosition;
|
||||
}
|
||||
|
||||
@end
|
||||
26
sdk/objc/helpers/NSString+StdString.h
Normal file
26
sdk/objc/helpers/NSString+StdString.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#include <string>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NSString (StdString)
|
||||
|
||||
@property(nonatomic, readonly) std::string stdString;
|
||||
|
||||
+ (std::string)stdStringForString:(NSString *)nsString;
|
||||
+ (NSString *)stringForStdString:(const std::string &)stdString;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
33
sdk/objc/helpers/NSString+StdString.mm
Normal file
33
sdk/objc/helpers/NSString+StdString.mm
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 "NSString+StdString.h"
|
||||
|
||||
@implementation NSString (StdString)
|
||||
|
||||
- (std::string)stdString {
|
||||
return [NSString stdStringForString:self];
|
||||
}
|
||||
|
||||
+ (std::string)stdStringForString:(NSString *)nsString {
|
||||
NSData *charData = [nsString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
return std::string(reinterpret_cast<const char *>(charData.bytes),
|
||||
charData.length);
|
||||
}
|
||||
|
||||
+ (NSString *)stringForStdString:(const std::string&)stdString {
|
||||
// std::string may contain null termination character so we construct
|
||||
// using length.
|
||||
return [[NSString alloc] initWithBytes:stdString.data()
|
||||
length:stdString.length()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@end
|
||||
30
sdk/objc/helpers/RTCCameraPreviewView.h
Normal file
30
sdk/objc/helpers/RTCCameraPreviewView.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RTCMacros.h"
|
||||
|
||||
@class AVCaptureSession;
|
||||
|
||||
/** RTCCameraPreviewView is a view that renders local video from an
|
||||
* AVCaptureSession.
|
||||
*/
|
||||
RTC_EXPORT
|
||||
@interface RTCCameraPreviewView : UIView
|
||||
|
||||
/** The capture session being rendered in the view. Capture session
|
||||
* is assigned to AVCaptureVideoPreviewLayer async in the same
|
||||
* queue that the AVCaptureSession is started/stopped.
|
||||
*/
|
||||
@property(nonatomic, strong) AVCaptureSession* captureSession;
|
||||
|
||||
@end
|
||||
120
sdk/objc/helpers/RTCCameraPreviewView.m
Normal file
120
sdk/objc/helpers/RTCCameraPreviewView.m
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 "RTCCameraPreviewView.h"
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RTCDispatcher+Private.h"
|
||||
|
||||
@implementation RTCCameraPreviewView
|
||||
|
||||
@synthesize captureSession = _captureSession;
|
||||
|
||||
+ (Class)layerClass {
|
||||
return [AVCaptureVideoPreviewLayer class];
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)aRect {
|
||||
self = [super initWithFrame:aRect];
|
||||
if (self) {
|
||||
[self addOrientationObserver];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder*)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
[self addOrientationObserver];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self removeOrientationObserver];
|
||||
}
|
||||
|
||||
- (void)setCaptureSession:(AVCaptureSession *)captureSession {
|
||||
if (_captureSession == captureSession) {
|
||||
return;
|
||||
}
|
||||
[RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
|
||||
block:^{
|
||||
_captureSession = captureSession;
|
||||
AVCaptureVideoPreviewLayer *previewLayer = [self previewLayer];
|
||||
[RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeCaptureSession
|
||||
block:^{
|
||||
previewLayer.session = captureSession;
|
||||
[RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
|
||||
block:^{
|
||||
[self setCorrectVideoOrientation];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
|
||||
// Update the video orientation based on the device orientation.
|
||||
[self setCorrectVideoOrientation];
|
||||
}
|
||||
|
||||
-(void)orientationChanged:(NSNotification *)notification {
|
||||
[self setCorrectVideoOrientation];
|
||||
}
|
||||
|
||||
- (void)setCorrectVideoOrientation {
|
||||
// Get current device orientation.
|
||||
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
|
||||
AVCaptureVideoPreviewLayer *previewLayer = [self previewLayer];
|
||||
|
||||
// First check if we are allowed to set the video orientation.
|
||||
if (previewLayer.connection.isVideoOrientationSupported) {
|
||||
// Set the video orientation based on device orientation.
|
||||
if (deviceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
|
||||
previewLayer.connection.videoOrientation =
|
||||
AVCaptureVideoOrientationPortraitUpsideDown;
|
||||
} else if (deviceOrientation == UIInterfaceOrientationLandscapeRight) {
|
||||
previewLayer.connection.videoOrientation =
|
||||
AVCaptureVideoOrientationLandscapeRight;
|
||||
} else if (deviceOrientation == UIInterfaceOrientationLandscapeLeft) {
|
||||
previewLayer.connection.videoOrientation =
|
||||
AVCaptureVideoOrientationLandscapeLeft;
|
||||
} else if (deviceOrientation == UIInterfaceOrientationPortrait) {
|
||||
previewLayer.connection.videoOrientation =
|
||||
AVCaptureVideoOrientationPortrait;
|
||||
}
|
||||
// If device orientation switches to FaceUp or FaceDown, don't change video orientation.
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)addOrientationObserver {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(orientationChanged:)
|
||||
name:UIDeviceOrientationDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)removeOrientationObserver {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:UIDeviceOrientationDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (AVCaptureVideoPreviewLayer *)previewLayer {
|
||||
return (AVCaptureVideoPreviewLayer *)self.layer;
|
||||
}
|
||||
|
||||
@end
|
||||
17
sdk/objc/helpers/RTCDispatcher+Private.h
Normal file
17
sdk/objc/helpers/RTCDispatcher+Private.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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 "RTCDispatcher.h"
|
||||
|
||||
@interface RTCDispatcher ()
|
||||
|
||||
+ (dispatch_queue_t)dispatchQueueForType:(RTCDispatcherQueueType)dispatchType;
|
||||
|
||||
@end
|
||||
44
sdk/objc/helpers/RTCDispatcher.h
Normal file
44
sdk/objc/helpers/RTCDispatcher.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#import "RTCMacros.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, RTCDispatcherQueueType) {
|
||||
// Main dispatcher queue.
|
||||
RTCDispatcherTypeMain,
|
||||
// Used for starting/stopping AVCaptureSession, and assigning
|
||||
// capture session to AVCaptureVideoPreviewLayer.
|
||||
RTCDispatcherTypeCaptureSession,
|
||||
// Used for operations on AVAudioSession.
|
||||
RTCDispatcherTypeAudioSession,
|
||||
};
|
||||
|
||||
/** Dispatcher that asynchronously dispatches blocks to a specific
|
||||
* shared dispatch queue.
|
||||
*/
|
||||
RTC_EXPORT
|
||||
@interface RTCDispatcher : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/** Dispatch the block asynchronously on the queue for dispatchType.
|
||||
* @param dispatchType The queue type to dispatch on.
|
||||
* @param block The block to dispatch asynchronously.
|
||||
*/
|
||||
+ (void)dispatchAsyncOnType:(RTCDispatcherQueueType)dispatchType block:(dispatch_block_t)block;
|
||||
|
||||
/** Returns YES if run on queue for the dispatchType otherwise NO.
|
||||
* Useful for asserting that a method is run on a correct queue.
|
||||
*/
|
||||
+ (BOOL)isOnQueueForType:(RTCDispatcherQueueType)dispatchType;
|
||||
|
||||
@end
|
||||
60
sdk/objc/helpers/RTCDispatcher.m
Normal file
60
sdk/objc/helpers/RTCDispatcher.m
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 "RTCDispatcher+Private.h"
|
||||
|
||||
static dispatch_queue_t kAudioSessionQueue = nil;
|
||||
static dispatch_queue_t kCaptureSessionQueue = nil;
|
||||
|
||||
@implementation RTCDispatcher
|
||||
|
||||
+ (void)initialize {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
kAudioSessionQueue = dispatch_queue_create(
|
||||
"org.webrtc.RTCDispatcherAudioSession",
|
||||
DISPATCH_QUEUE_SERIAL);
|
||||
kCaptureSessionQueue = dispatch_queue_create(
|
||||
"org.webrtc.RTCDispatcherCaptureSession",
|
||||
DISPATCH_QUEUE_SERIAL);
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)dispatchAsyncOnType:(RTCDispatcherQueueType)dispatchType
|
||||
block:(dispatch_block_t)block {
|
||||
dispatch_queue_t queue = [self dispatchQueueForType:dispatchType];
|
||||
dispatch_async(queue, block);
|
||||
}
|
||||
|
||||
+ (BOOL)isOnQueueForType:(RTCDispatcherQueueType)dispatchType {
|
||||
dispatch_queue_t targetQueue = [self dispatchQueueForType:dispatchType];
|
||||
const char* targetLabel = dispatch_queue_get_label(targetQueue);
|
||||
const char* currentLabel = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL);
|
||||
|
||||
NSAssert(strlen(targetLabel) > 0, @"Label is required for the target queue.");
|
||||
NSAssert(strlen(currentLabel) > 0, @"Label is required for the current queue.");
|
||||
|
||||
return strcmp(targetLabel, currentLabel) == 0;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
+ (dispatch_queue_t)dispatchQueueForType:(RTCDispatcherQueueType)dispatchType {
|
||||
switch (dispatchType) {
|
||||
case RTCDispatcherTypeMain:
|
||||
return dispatch_get_main_queue();
|
||||
case RTCDispatcherTypeCaptureSession:
|
||||
return kCaptureSessionQueue;
|
||||
case RTCDispatcherTypeAudioSession:
|
||||
return kAudioSessionQueue;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
25
sdk/objc/helpers/RTCUIApplicationStatusObserver.h
Normal file
25
sdk/objc/helpers/RTCUIApplicationStatusObserver.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#if defined(WEBRTC_IOS)
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_EXTENSION_UNAVAILABLE_IOS("Application status not available in app extensions.")
|
||||
@interface RTCUIApplicationStatusObserver : NSObject
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
+ (void)prepareForUse;
|
||||
|
||||
- (BOOL)isApplicationActive;
|
||||
|
||||
@end
|
||||
|
||||
#endif // WEBRTC_IOS
|
||||
114
sdk/objc/helpers/RTCUIApplicationStatusObserver.m
Normal file
114
sdk/objc/helpers/RTCUIApplicationStatusObserver.m
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "RTCUIApplicationStatusObserver.h"
|
||||
|
||||
#if defined(WEBRTC_IOS)
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
@interface RTCUIApplicationStatusObserver ()
|
||||
|
||||
@property(nonatomic, assign) BOOL initialized;
|
||||
@property(nonatomic, assign) UIApplicationState state;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RTCUIApplicationStatusObserver {
|
||||
BOOL _initialized;
|
||||
dispatch_block_t _initializeBlock;
|
||||
dispatch_semaphore_t _waitForInitializeSemaphore;
|
||||
UIApplicationState _state;
|
||||
|
||||
id<NSObject> _activeObserver;
|
||||
id<NSObject> _backgroundObserver;
|
||||
}
|
||||
|
||||
@synthesize initialized = _initialized;
|
||||
@synthesize state = _state;
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static id sharedInstance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
// Method to make sure observers are added and the initialization block is
|
||||
// scheduled to run on the main queue.
|
||||
+ (void)prepareForUse {
|
||||
__unused RTCUIApplicationStatusObserver *observer = [self sharedInstance];
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
if (self = [super init]) {
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
__weak RTCUIApplicationStatusObserver *weakSelf = self;
|
||||
_activeObserver = [center addObserverForName:UIApplicationDidBecomeActiveNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note) {
|
||||
weakSelf.state =
|
||||
[UIApplication sharedApplication].applicationState;
|
||||
}];
|
||||
|
||||
_backgroundObserver = [center addObserverForName:UIApplicationDidEnterBackgroundNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *note) {
|
||||
weakSelf.state =
|
||||
[UIApplication sharedApplication].applicationState;
|
||||
}];
|
||||
|
||||
_waitForInitializeSemaphore = dispatch_semaphore_create(1);
|
||||
_initialized = NO;
|
||||
_initializeBlock = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{
|
||||
weakSelf.state = [UIApplication sharedApplication].applicationState;
|
||||
weakSelf.initialized = YES;
|
||||
});
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), _initializeBlock);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center removeObserver:_activeObserver];
|
||||
[center removeObserver:_backgroundObserver];
|
||||
}
|
||||
|
||||
- (BOOL)isApplicationActive {
|
||||
// NOTE: The function `dispatch_block_wait` can only legally be called once.
|
||||
// Because of this, if several threads call the `isApplicationActive` method before
|
||||
// the `_initializeBlock` has been executed, instead of multiple threads calling
|
||||
// `dispatch_block_wait`, the other threads need to wait for the first waiting thread
|
||||
// instead.
|
||||
if (!_initialized) {
|
||||
dispatch_semaphore_wait(_waitForInitializeSemaphore, DISPATCH_TIME_FOREVER);
|
||||
if (!_initialized) {
|
||||
long ret = dispatch_block_wait(_initializeBlock,
|
||||
dispatch_time(DISPATCH_TIME_NOW, 10.0 * NSEC_PER_SEC));
|
||||
RTC_DCHECK_EQ(ret, 0);
|
||||
}
|
||||
dispatch_semaphore_signal(_waitForInitializeSemaphore);
|
||||
}
|
||||
return _state == UIApplicationStateActive;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // WEBRTC_IOS
|
||||
81
sdk/objc/helpers/UIDevice+RTCDevice.h
Normal file
81
sdk/objc/helpers/UIDevice+RTCDevice.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, RTCDeviceType) {
|
||||
RTCDeviceTypeUnknown,
|
||||
RTCDeviceTypeIPhone1G,
|
||||
RTCDeviceTypeIPhone3G,
|
||||
RTCDeviceTypeIPhone3GS,
|
||||
RTCDeviceTypeIPhone4,
|
||||
RTCDeviceTypeIPhone4Verizon,
|
||||
RTCDeviceTypeIPhone4S,
|
||||
RTCDeviceTypeIPhone5GSM,
|
||||
RTCDeviceTypeIPhone5GSM_CDMA,
|
||||
RTCDeviceTypeIPhone5CGSM,
|
||||
RTCDeviceTypeIPhone5CGSM_CDMA,
|
||||
RTCDeviceTypeIPhone5SGSM,
|
||||
RTCDeviceTypeIPhone5SGSM_CDMA,
|
||||
RTCDeviceTypeIPhone6Plus,
|
||||
RTCDeviceTypeIPhone6,
|
||||
RTCDeviceTypeIPhone6S,
|
||||
RTCDeviceTypeIPhone6SPlus,
|
||||
RTCDeviceTypeIPhone7,
|
||||
RTCDeviceTypeIPhone7Plus,
|
||||
RTCDeviceTypeIPhoneSE,
|
||||
RTCDeviceTypeIPhone8,
|
||||
RTCDeviceTypeIPhone8Plus,
|
||||
RTCDeviceTypeIPhoneX,
|
||||
RTCDeviceTypeIPodTouch1G,
|
||||
RTCDeviceTypeIPodTouch2G,
|
||||
RTCDeviceTypeIPodTouch3G,
|
||||
RTCDeviceTypeIPodTouch4G,
|
||||
RTCDeviceTypeIPodTouch5G,
|
||||
RTCDeviceTypeIPodTouch6G,
|
||||
RTCDeviceTypeIPad,
|
||||
RTCDeviceTypeIPad2Wifi,
|
||||
RTCDeviceTypeIPad2GSM,
|
||||
RTCDeviceTypeIPad2CDMA,
|
||||
RTCDeviceTypeIPad2Wifi2,
|
||||
RTCDeviceTypeIPadMiniWifi,
|
||||
RTCDeviceTypeIPadMiniGSM,
|
||||
RTCDeviceTypeIPadMiniGSM_CDMA,
|
||||
RTCDeviceTypeIPad3Wifi,
|
||||
RTCDeviceTypeIPad3GSM_CDMA,
|
||||
RTCDeviceTypeIPad3GSM,
|
||||
RTCDeviceTypeIPad4Wifi,
|
||||
RTCDeviceTypeIPad4GSM,
|
||||
RTCDeviceTypeIPad4GSM_CDMA,
|
||||
RTCDeviceTypeIPad5,
|
||||
RTCDeviceTypeIPad6,
|
||||
RTCDeviceTypeIPadAirWifi,
|
||||
RTCDeviceTypeIPadAirCellular,
|
||||
RTCDeviceTypeIPadAirWifiCellular,
|
||||
RTCDeviceTypeIPadAir2,
|
||||
RTCDeviceTypeIPadMini2GWifi,
|
||||
RTCDeviceTypeIPadMini2GCellular,
|
||||
RTCDeviceTypeIPadMini2GWifiCellular,
|
||||
RTCDeviceTypeIPadMini3,
|
||||
RTCDeviceTypeIPadMini4,
|
||||
RTCDeviceTypeIPadPro9Inch,
|
||||
RTCDeviceTypeIPadPro12Inch,
|
||||
RTCDeviceTypeIPadPro12Inch2,
|
||||
RTCDeviceTypeIPadPro10Inch,
|
||||
RTCDeviceTypeSimulatori386,
|
||||
RTCDeviceTypeSimulatorx86_64,
|
||||
};
|
||||
|
||||
@interface UIDevice (RTCDevice)
|
||||
|
||||
+ (RTCDeviceType)deviceType;
|
||||
+ (BOOL)isIOS11OrLater;
|
||||
|
||||
@end
|
||||
120
sdk/objc/helpers/UIDevice+RTCDevice.mm
Normal file
120
sdk/objc/helpers/UIDevice+RTCDevice.mm
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#import "UIDevice+RTCDevice.h"
|
||||
|
||||
#import <sys/utsname.h>
|
||||
#include <memory>
|
||||
|
||||
@implementation UIDevice (RTCDevice)
|
||||
|
||||
+ (RTCDeviceType)deviceType {
|
||||
NSDictionary *machineNameToType = @{
|
||||
@"iPhone1,1": @(RTCDeviceTypeIPhone1G),
|
||||
@"iPhone1,2": @(RTCDeviceTypeIPhone3G),
|
||||
@"iPhone2,1": @(RTCDeviceTypeIPhone3GS),
|
||||
@"iPhone3,1": @(RTCDeviceTypeIPhone4),
|
||||
@"iPhone3,2": @(RTCDeviceTypeIPhone4),
|
||||
@"iPhone3,3": @(RTCDeviceTypeIPhone4Verizon),
|
||||
@"iPhone4,1": @(RTCDeviceTypeIPhone4S),
|
||||
@"iPhone5,1": @(RTCDeviceTypeIPhone5GSM),
|
||||
@"iPhone5,2": @(RTCDeviceTypeIPhone5GSM_CDMA),
|
||||
@"iPhone5,3": @(RTCDeviceTypeIPhone5CGSM),
|
||||
@"iPhone5,4": @(RTCDeviceTypeIPhone5CGSM_CDMA),
|
||||
@"iPhone6,1": @(RTCDeviceTypeIPhone5SGSM),
|
||||
@"iPhone6,2": @(RTCDeviceTypeIPhone5SGSM_CDMA),
|
||||
@"iPhone7,1": @(RTCDeviceTypeIPhone6Plus),
|
||||
@"iPhone7,2": @(RTCDeviceTypeIPhone6),
|
||||
@"iPhone8,1": @(RTCDeviceTypeIPhone6S),
|
||||
@"iPhone8,2": @(RTCDeviceTypeIPhone6SPlus),
|
||||
@"iPhone8,4": @(RTCDeviceTypeIPhoneSE),
|
||||
@"iPhone9,1": @(RTCDeviceTypeIPhone7),
|
||||
@"iPhone9,2": @(RTCDeviceTypeIPhone7Plus),
|
||||
@"iPhone9,3": @(RTCDeviceTypeIPhone7),
|
||||
@"iPhone9,4": @(RTCDeviceTypeIPhone7Plus),
|
||||
@"iPhone10,1": @(RTCDeviceTypeIPhone8),
|
||||
@"iPhone10,2": @(RTCDeviceTypeIPhone8Plus),
|
||||
@"iPhone10,3": @(RTCDeviceTypeIPhoneX),
|
||||
@"iPhone10,4": @(RTCDeviceTypeIPhone8),
|
||||
@"iPhone10,5": @(RTCDeviceTypeIPhone8Plus),
|
||||
@"iPhone10,6": @(RTCDeviceTypeIPhoneX),
|
||||
@"iPod1,1": @(RTCDeviceTypeIPodTouch1G),
|
||||
@"iPod2,1": @(RTCDeviceTypeIPodTouch2G),
|
||||
@"iPod3,1": @(RTCDeviceTypeIPodTouch3G),
|
||||
@"iPod4,1": @(RTCDeviceTypeIPodTouch4G),
|
||||
@"iPod5,1": @(RTCDeviceTypeIPodTouch5G),
|
||||
@"iPod7,1": @(RTCDeviceTypeIPodTouch6G),
|
||||
@"iPad1,1": @(RTCDeviceTypeIPad),
|
||||
@"iPad2,1": @(RTCDeviceTypeIPad2Wifi),
|
||||
@"iPad2,2": @(RTCDeviceTypeIPad2GSM),
|
||||
@"iPad2,3": @(RTCDeviceTypeIPad2CDMA),
|
||||
@"iPad2,4": @(RTCDeviceTypeIPad2Wifi2),
|
||||
@"iPad2,5": @(RTCDeviceTypeIPadMiniWifi),
|
||||
@"iPad2,6": @(RTCDeviceTypeIPadMiniGSM),
|
||||
@"iPad2,7": @(RTCDeviceTypeIPadMiniGSM_CDMA),
|
||||
@"iPad3,1": @(RTCDeviceTypeIPad3Wifi),
|
||||
@"iPad3,2": @(RTCDeviceTypeIPad3GSM_CDMA),
|
||||
@"iPad3,3": @(RTCDeviceTypeIPad3GSM),
|
||||
@"iPad3,4": @(RTCDeviceTypeIPad4Wifi),
|
||||
@"iPad3,5": @(RTCDeviceTypeIPad4GSM),
|
||||
@"iPad3,6": @(RTCDeviceTypeIPad4GSM_CDMA),
|
||||
@"iPad4,1": @(RTCDeviceTypeIPadAirWifi),
|
||||
@"iPad4,2": @(RTCDeviceTypeIPadAirCellular),
|
||||
@"iPad4,3": @(RTCDeviceTypeIPadAirWifiCellular),
|
||||
@"iPad4,4": @(RTCDeviceTypeIPadMini2GWifi),
|
||||
@"iPad4,5": @(RTCDeviceTypeIPadMini2GCellular),
|
||||
@"iPad4,6": @(RTCDeviceTypeIPadMini2GWifiCellular),
|
||||
@"iPad4,7": @(RTCDeviceTypeIPadMini3),
|
||||
@"iPad4,8": @(RTCDeviceTypeIPadMini3),
|
||||
@"iPad4,9": @(RTCDeviceTypeIPadMini3),
|
||||
@"iPad5,1": @(RTCDeviceTypeIPadMini4),
|
||||
@"iPad5,2": @(RTCDeviceTypeIPadMini4),
|
||||
@"iPad5,3": @(RTCDeviceTypeIPadAir2),
|
||||
@"iPad5,4": @(RTCDeviceTypeIPadAir2),
|
||||
@"iPad6,3": @(RTCDeviceTypeIPadPro9Inch),
|
||||
@"iPad6,4": @(RTCDeviceTypeIPadPro9Inch),
|
||||
@"iPad6,7": @(RTCDeviceTypeIPadPro12Inch),
|
||||
@"iPad6,8": @(RTCDeviceTypeIPadPro12Inch),
|
||||
@"iPad6,11": @(RTCDeviceTypeIPad5),
|
||||
@"iPad6,12": @(RTCDeviceTypeIPad5),
|
||||
@"iPad7,1": @(RTCDeviceTypeIPadPro12Inch2),
|
||||
@"iPad7,2": @(RTCDeviceTypeIPadPro12Inch2),
|
||||
@"iPad7,3": @(RTCDeviceTypeIPadPro10Inch),
|
||||
@"iPad7,4": @(RTCDeviceTypeIPadPro10Inch),
|
||||
@"iPad7,5": @(RTCDeviceTypeIPad6),
|
||||
@"iPad7,6": @(RTCDeviceTypeIPad6),
|
||||
@"i386": @(RTCDeviceTypeSimulatori386),
|
||||
@"x86_64": @(RTCDeviceTypeSimulatorx86_64),
|
||||
};
|
||||
|
||||
RTCDeviceType deviceType = RTCDeviceTypeUnknown;
|
||||
NSNumber *typeNumber = machineNameToType[[self machineName]];
|
||||
if (typeNumber) {
|
||||
deviceType = static_cast<RTCDeviceType>(typeNumber.integerValue);
|
||||
}
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
+ (NSString *)machineName {
|
||||
struct utsname systemInfo;
|
||||
uname(&systemInfo);
|
||||
return [[NSString alloc] initWithCString:systemInfo.machine
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
+ (double)currentDeviceSystemVersion {
|
||||
return [self currentDevice].systemVersion.doubleValue;
|
||||
}
|
||||
|
||||
+ (BOOL)isIOS11OrLater {
|
||||
return [self currentDeviceSystemVersion] >= 11.0;
|
||||
}
|
||||
|
||||
@end
|
||||
13
sdk/objc/helpers/noop.mm
Normal file
13
sdk/objc/helpers/noop.mm
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// This file is only needed to make ninja happy on some platforms.
|
||||
// On some platforms it is not possible to link an rtc_static_library
|
||||
// without any source file listed in the GN target.
|
||||
116
sdk/objc/helpers/scoped_cftyperef.h
Normal file
116
sdk/objc/helpers/scoped_cftyperef.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SDK_OBJC_HELPERS_SCOPED_CFTYPEREF_H_
|
||||
#define SDK_OBJC_HELPERS_SCOPED_CFTYPEREF_H_
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
namespace rtc {
|
||||
|
||||
// RETAIN: ScopedTypeRef should retain the object when it takes
|
||||
// ownership.
|
||||
// ASSUME: Assume the object already has already been retained.
|
||||
// ScopedTypeRef takes over ownership.
|
||||
enum class RetainPolicy { RETAIN, ASSUME };
|
||||
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
struct CFTypeRefTraits {
|
||||
static T InvalidValue() { return nullptr; }
|
||||
static void Release(T ref) { CFRelease(ref); }
|
||||
static T Retain(T ref) {
|
||||
CFRetain(ref);
|
||||
return ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Traits>
|
||||
class ScopedTypeRef {
|
||||
public:
|
||||
ScopedTypeRef() : ptr_(Traits::InvalidValue()) {}
|
||||
explicit ScopedTypeRef(T ptr) : ptr_(ptr) {}
|
||||
ScopedTypeRef(T ptr, RetainPolicy policy) : ScopedTypeRef(ptr) {
|
||||
if (ptr_ && policy == RetainPolicy::RETAIN)
|
||||
Traits::Retain(ptr_);
|
||||
}
|
||||
|
||||
ScopedTypeRef(const ScopedTypeRef<T, Traits>& rhs) : ptr_(rhs.ptr_) {
|
||||
if (ptr_)
|
||||
ptr_ = Traits::Retain(ptr_);
|
||||
}
|
||||
|
||||
~ScopedTypeRef() {
|
||||
if (ptr_) {
|
||||
Traits::Release(ptr_);
|
||||
}
|
||||
}
|
||||
|
||||
T get() const { return ptr_; }
|
||||
T operator->() const { return ptr_; }
|
||||
explicit operator bool() const { return ptr_; }
|
||||
|
||||
bool operator!() const { return !ptr_; }
|
||||
|
||||
ScopedTypeRef& operator=(const T& rhs) {
|
||||
if (ptr_)
|
||||
Traits::Release(ptr_);
|
||||
ptr_ = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ScopedTypeRef& operator=(const ScopedTypeRef<T, Traits>& rhs) {
|
||||
reset(rhs.get(), RetainPolicy::RETAIN);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// This is intended to take ownership of objects that are
|
||||
// created by pass-by-pointer initializers.
|
||||
T* InitializeInto() {
|
||||
RTC_DCHECK(!ptr_);
|
||||
return &ptr_;
|
||||
}
|
||||
|
||||
void reset(T ptr, RetainPolicy policy = RetainPolicy::ASSUME) {
|
||||
if (ptr && policy == RetainPolicy::RETAIN)
|
||||
Traits::Retain(ptr);
|
||||
if (ptr_)
|
||||
Traits::Release(ptr_);
|
||||
ptr_ = ptr;
|
||||
}
|
||||
|
||||
T release() {
|
||||
T temp = ptr_;
|
||||
ptr_ = Traits::InvalidValue();
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
T ptr_;
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
using ScopedCFTypeRef =
|
||||
internal::ScopedTypeRef<T, internal::CFTypeRefTraits<T>>;
|
||||
|
||||
template <typename T>
|
||||
static ScopedCFTypeRef<T> AdoptCF(T cftype) {
|
||||
return ScopedCFTypeRef<T>(cftype, RetainPolicy::RETAIN);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static ScopedCFTypeRef<T> ScopedCF(T cftype) {
|
||||
return ScopedCFTypeRef<T>(cftype);
|
||||
}
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // SDK_OBJC_HELPERS_SCOPED_CFTYPEREF_H_
|
||||
Reference in New Issue
Block a user