1 /*
2 * Copyright (c) 2019 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 #include "test/pc/e2e/test_peer.h"
11
12 #include <string>
13 #include <utility>
14
15 #include "absl/memory/memory.h"
16 #include "absl/strings/string_view.h"
17 #include "api/scoped_refptr.h"
18 #include "api/test/pclf/media_configuration.h"
19 #include "api/test/pclf/peer_configurer.h"
20 #include "modules/audio_processing/include/audio_processing.h"
21
22 namespace webrtc {
23 namespace webrtc_pc_e2e {
24 namespace {
25
26 class SetRemoteDescriptionCallback
27 : public webrtc::SetRemoteDescriptionObserverInterface {
28 public:
OnSetRemoteDescriptionComplete(webrtc::RTCError error)29 void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
30 is_called_ = true;
31 error_ = error;
32 }
33
is_called() const34 bool is_called() const { return is_called_; }
35
error() const36 webrtc::RTCError error() const { return error_; }
37
38 private:
39 bool is_called_ = false;
40 webrtc::RTCError error_;
41 };
42
43 } // namespace
44
configurable_params() const45 ConfigurableParams TestPeer::configurable_params() const {
46 MutexLock lock(&mutex_);
47 return configurable_params_;
48 }
49
AddVideoConfig(VideoConfig config)50 void TestPeer::AddVideoConfig(VideoConfig config) {
51 MutexLock lock(&mutex_);
52 configurable_params_.video_configs.push_back(std::move(config));
53 }
54
RemoveVideoConfig(absl::string_view stream_label)55 void TestPeer::RemoveVideoConfig(absl::string_view stream_label) {
56 MutexLock lock(&mutex_);
57 bool config_removed = false;
58 for (auto it = configurable_params_.video_configs.begin();
59 it != configurable_params_.video_configs.end(); ++it) {
60 if (*it->stream_label == stream_label) {
61 configurable_params_.video_configs.erase(it);
62 config_removed = true;
63 break;
64 }
65 }
66 RTC_CHECK(config_removed) << *params_.name << ": No video config with label ["
67 << stream_label << "] was found";
68 }
69
SetVideoSubscription(VideoSubscription subscription)70 void TestPeer::SetVideoSubscription(VideoSubscription subscription) {
71 MutexLock lock(&mutex_);
72 configurable_params_.video_subscription = std::move(subscription);
73 }
74
GetStats(RTCStatsCollectorCallback * callback)75 void TestPeer::GetStats(RTCStatsCollectorCallback* callback) {
76 pc()->signaling_thread()->PostTask(
77 SafeTask(signaling_thread_task_safety_,
78 [this, callback]() { pc()->GetStats(callback); }));
79 }
80
SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,std::string * error_out)81 bool TestPeer::SetRemoteDescription(
82 std::unique_ptr<SessionDescriptionInterface> desc,
83 std::string* error_out) {
84 RTC_CHECK(wrapper_) << "TestPeer is already closed";
85
86 auto observer = rtc::make_ref_counted<SetRemoteDescriptionCallback>();
87 // We're assuming (and asserting) that the PeerConnection implementation of
88 // SetRemoteDescription is synchronous when called on the signaling thread.
89 pc()->SetRemoteDescription(std::move(desc), observer);
90 RTC_CHECK(observer->is_called());
91 if (!observer->error().ok()) {
92 RTC_LOG(LS_ERROR) << *params_.name << ": Failed to set remote description: "
93 << observer->error().message();
94 if (error_out) {
95 *error_out = observer->error().message();
96 }
97 }
98 return observer->error().ok();
99 }
100
AddIceCandidates(std::vector<std::unique_ptr<IceCandidateInterface>> candidates)101 bool TestPeer::AddIceCandidates(
102 std::vector<std::unique_ptr<IceCandidateInterface>> candidates) {
103 RTC_CHECK(wrapper_) << "TestPeer is already closed";
104 bool success = true;
105 for (auto& candidate : candidates) {
106 if (!pc()->AddIceCandidate(candidate.get())) {
107 std::string candidate_str;
108 bool res = candidate->ToString(&candidate_str);
109 RTC_CHECK(res);
110 RTC_LOG(LS_ERROR) << "Failed to add ICE candidate, candidate_str="
111 << candidate_str;
112 success = false;
113 } else {
114 remote_ice_candidates_.push_back(std::move(candidate));
115 }
116 }
117 return success;
118 }
119
Close()120 void TestPeer::Close() {
121 signaling_thread_task_safety_->SetNotAlive();
122 wrapper_->pc()->Close();
123 remote_ice_candidates_.clear();
124 audio_processing_ = nullptr;
125 video_sources_.clear();
126 wrapper_ = nullptr;
127 worker_thread_ = nullptr;
128 }
129
TestPeer(rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,rtc::scoped_refptr<PeerConnectionInterface> pc,std::unique_ptr<MockPeerConnectionObserver> observer,Params params,ConfigurableParams configurable_params,std::vector<PeerConfigurer::VideoSource> video_sources,rtc::scoped_refptr<AudioProcessing> audio_processing,std::unique_ptr<rtc::Thread> worker_thread)130 TestPeer::TestPeer(
131 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
132 rtc::scoped_refptr<PeerConnectionInterface> pc,
133 std::unique_ptr<MockPeerConnectionObserver> observer,
134 Params params,
135 ConfigurableParams configurable_params,
136 std::vector<PeerConfigurer::VideoSource> video_sources,
137 rtc::scoped_refptr<AudioProcessing> audio_processing,
138 std::unique_ptr<rtc::Thread> worker_thread)
139 : params_(std::move(params)),
140 configurable_params_(std::move(configurable_params)),
141 worker_thread_(std::move(worker_thread)),
142 wrapper_(std::make_unique<PeerConnectionWrapper>(std::move(pc_factory),
143 std::move(pc),
144 std::move(observer))),
145 video_sources_(std::move(video_sources)),
146 audio_processing_(audio_processing) {
147 signaling_thread_task_safety_ = PendingTaskSafetyFlag::CreateDetached();
148 }
149
150 } // namespace webrtc_pc_e2e
151 } // namespace webrtc
152