1/*
2 *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#import "RTCPeerConnection+Private.h"
12
13#import "RTCLegacyStatsReport+Private.h"
14#import "RTCMediaStreamTrack+Private.h"
15#import "RTCRtpReceiver+Private.h"
16#import "RTCRtpSender+Private.h"
17#import "RTCStatisticsReport+Private.h"
18#import "helpers/NSString+StdString.h"
19
20#include "rtc_base/checks.h"
21
22namespace webrtc {
23
24class StatsCollectorCallbackAdapter : public RTCStatsCollectorCallback {
25 public:
26  StatsCollectorCallbackAdapter(RTCStatisticsCompletionHandler completion_handler)
27      : completion_handler_(completion_handler) {}
28
29  void OnStatsDelivered(const rtc::scoped_refptr<const RTCStatsReport> &report) override {
30    RTC_DCHECK(completion_handler_);
31    RTC_OBJC_TYPE(RTCStatisticsReport) *statisticsReport =
32        [[RTC_OBJC_TYPE(RTCStatisticsReport) alloc] initWithReport:*report];
33    completion_handler_(statisticsReport);
34    completion_handler_ = nil;
35  }
36
37 private:
38  RTCStatisticsCompletionHandler completion_handler_;
39};
40
41class StatsObserverAdapter : public StatsObserver {
42 public:
43  StatsObserverAdapter(
44      void (^completionHandler)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats)) {
45    completion_handler_ = completionHandler;
46  }
47
48  ~StatsObserverAdapter() override { completion_handler_ = nil; }
49
50  void OnComplete(const StatsReports& reports) override {
51    RTC_DCHECK(completion_handler_);
52    NSMutableArray *stats = [NSMutableArray arrayWithCapacity:reports.size()];
53    for (const auto* report : reports) {
54      RTC_OBJC_TYPE(RTCLegacyStatsReport) *statsReport =
55          [[RTC_OBJC_TYPE(RTCLegacyStatsReport) alloc] initWithNativeReport:*report];
56      [stats addObject:statsReport];
57    }
58    completion_handler_(stats);
59    completion_handler_ = nil;
60  }
61
62 private:
63  void (^completion_handler_)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats);
64};
65}  // namespace webrtc
66
67@implementation RTC_OBJC_TYPE (RTCPeerConnection)
68(Stats)
69
70    - (void)statisticsForSender : (RTC_OBJC_TYPE(RTCRtpSender) *)sender completionHandler
71    : (RTCStatisticsCompletionHandler)completionHandler {
72  rtc::scoped_refptr<webrtc::StatsCollectorCallbackAdapter> collector(
73      new rtc::RefCountedObject<webrtc::StatsCollectorCallbackAdapter>(completionHandler));
74  self.nativePeerConnection->GetStats(sender.nativeRtpSender, collector);
75}
76
77- (void)statisticsForReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver
78            completionHandler:(RTCStatisticsCompletionHandler)completionHandler {
79  rtc::scoped_refptr<webrtc::StatsCollectorCallbackAdapter> collector(
80      new rtc::RefCountedObject<webrtc::StatsCollectorCallbackAdapter>(completionHandler));
81  self.nativePeerConnection->GetStats(receiver.nativeRtpReceiver, collector);
82}
83
84- (void)statisticsWithCompletionHandler:(RTCStatisticsCompletionHandler)completionHandler {
85  rtc::scoped_refptr<webrtc::StatsCollectorCallbackAdapter> collector(
86      new rtc::RefCountedObject<webrtc::StatsCollectorCallbackAdapter>(completionHandler));
87  self.nativePeerConnection->GetStats(collector);
88}
89
90- (void)statsForTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)mediaStreamTrack
91     statsOutputLevel:(RTCStatsOutputLevel)statsOutputLevel
92    completionHandler:
93        (void (^)(NSArray<RTC_OBJC_TYPE(RTCLegacyStatsReport) *> *stats))completionHandler {
94  rtc::scoped_refptr<webrtc::StatsObserverAdapter> observer(
95      new rtc::RefCountedObject<webrtc::StatsObserverAdapter>
96          (completionHandler));
97  webrtc::PeerConnectionInterface::StatsOutputLevel nativeOutputLevel =
98      [[self class] nativeStatsOutputLevelForLevel:statsOutputLevel];
99  self.nativePeerConnection->GetStats(
100      observer, mediaStreamTrack.nativeTrack, nativeOutputLevel);
101}
102
103@end
104