summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/sdk/objc/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/sdk/objc/helpers')
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.h23
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.mm51
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.h34
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.mm45
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.h30
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.m123
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher+Private.h18
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.h46
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.m65
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.h17
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.mm25
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/noop.mm13
-rw-r--r--third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h116
13 files changed, 606 insertions, 0 deletions
diff --git a/third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.h b/third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.h
new file mode 100644
index 0000000000..32ab6877f0
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.h
@@ -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
diff --git a/third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.mm b/third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.mm
new file mode 100644
index 0000000000..0814ecc6c5
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/AVCaptureSession+DevicePosition.mm
@@ -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
diff --git a/third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.h b/third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.h
new file mode 100644
index 0000000000..b0324e8a19
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.h
@@ -0,0 +1,34 @@
+/*
+ * 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>
+
+#include "absl/strings/string_view.h"
+
+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
+
+@interface NSString (AbslStringView)
+
++ (NSString *)stringForAbslStringView:(const absl::string_view)abslStringView;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.mm b/third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.mm
new file mode 100644
index 0000000000..c98432c445
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/NSString+StdString.mm
@@ -0,0 +1,45 @@
+/*
+ * 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"
+
+#include "absl/strings/string_view.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
+
+@implementation NSString (AbslStringView)
+
++ (NSString *)stringForAbslStringView:(const absl::string_view)abslStringView {
+ return [[NSString alloc] initWithBytes:abslStringView.data()
+ length:abslStringView.length()
+ encoding:NSUTF8StringEncoding];
+}
+
+@end
diff --git a/third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.h b/third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.h
new file mode 100644
index 0000000000..db9b15a45c
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.h
@@ -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_OBJC_EXPORT
+@interface RTC_OBJC_TYPE (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
diff --git a/third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.m b/third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.m
new file mode 100644
index 0000000000..12e87d8d64
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/RTCCameraPreviewView.m
@@ -0,0 +1,123 @@
+/*
+ * 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 RTC_OBJC_TYPE (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;
+ }
+ _captureSession = captureSession;
+ [RTC_OBJC_TYPE(RTCDispatcher)
+ dispatchAsyncOnType:RTCDispatcherTypeMain
+ block:^{
+ AVCaptureVideoPreviewLayer *previewLayer = [self previewLayer];
+ [RTC_OBJC_TYPE(RTCDispatcher)
+ dispatchAsyncOnType:RTCDispatcherTypeCaptureSession
+ block:^{
+ previewLayer.session = captureSession;
+ [RTC_OBJC_TYPE(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
diff --git a/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher+Private.h b/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher+Private.h
new file mode 100644
index 0000000000..195c651790
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher+Private.h
@@ -0,0 +1,18 @@
+/*
+ * 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 RTC_OBJC_TYPE (RTCDispatcher)
+()
+
+ + (dispatch_queue_t)dispatchQueueForType : (RTCDispatcherQueueType)dispatchType;
+
+@end
diff --git a/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.h b/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.h
new file mode 100644
index 0000000000..e148af6dea
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.h
@@ -0,0 +1,46 @@
+/*
+ * 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,
+ // Used for operations on NWPathMonitor.
+ RTCDispatcherTypeNetworkMonitor,
+};
+
+/** Dispatcher that asynchronously dispatches blocks to a specific
+ * shared dispatch queue.
+ */
+RTC_OBJC_EXPORT
+@interface RTC_OBJC_TYPE (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
diff --git a/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.m b/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.m
new file mode 100644
index 0000000000..4df19bc297
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/RTCDispatcher.m
@@ -0,0 +1,65 @@
+/*
+ * 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;
+static dispatch_queue_t kNetworkMonitorQueue = nil;
+
+@implementation RTC_OBJC_TYPE (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);
+ kNetworkMonitorQueue =
+ dispatch_queue_create("org.webrtc.RTCDispatcherNetworkMonitor", 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;
+ case RTCDispatcherTypeNetworkMonitor:
+ return kNetworkMonitorQueue;
+ }
+}
+
+@end
diff --git a/third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.h b/third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.h
new file mode 100644
index 0000000000..4d04f38f8c
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.h
@@ -0,0 +1,17 @@
+/*
+ * 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>
+
+@interface UIDevice (RTCDevice)
+
++ (NSString *)machineName;
+
+@end
diff --git a/third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.mm b/third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.mm
new file mode 100644
index 0000000000..f3c21991b8
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/UIDevice+RTCDevice.mm
@@ -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.
+ */
+
+#import "UIDevice+RTCDevice.h"
+
+#import <sys/utsname.h>
+#include <memory>
+
+@implementation UIDevice (RTCDevice)
+
++ (NSString *)machineName {
+ struct utsname systemInfo;
+ uname(&systemInfo);
+ return [[NSString alloc] initWithCString:systemInfo.machine
+ encoding:NSUTF8StringEncoding];
+}
+
+@end
diff --git a/third_party/libwebrtc/sdk/objc/helpers/noop.mm b/third_party/libwebrtc/sdk/objc/helpers/noop.mm
new file mode 100644
index 0000000000..16a8e6d5c1
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/noop.mm
@@ -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.
diff --git a/third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h b/third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h
new file mode 100644
index 0000000000..092f02b3af
--- /dev/null
+++ b/third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h
@@ -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_