1 /*
2  *  Copyright 2017 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 #include "call/call_factory.h"
12 
13 #include <stdio.h>
14 
15 #include <memory>
16 #include <string>
17 
18 #include "absl/types/optional.h"
19 #include "api/test/simulated_network.h"
20 #include "call/call.h"
21 #include "call/degraded_call.h"
22 #include "rtc_base/checks.h"
23 #include "system_wrappers/include/field_trial.h"
24 
25 namespace webrtc {
26 namespace {
ParseConfigParam(std::string exp_name,int * field)27 bool ParseConfigParam(std::string exp_name, int* field) {
28   std::string group = field_trial::FindFullName(exp_name);
29   if (group.empty())
30     return false;
31 
32   return (sscanf(group.c_str(), "%d", field) == 1);
33 }
34 
ParseDegradationConfig(bool send)35 absl::optional<webrtc::BuiltInNetworkBehaviorConfig> ParseDegradationConfig(
36     bool send) {
37   std::string exp_prefix = "WebRTCFakeNetwork";
38   if (send) {
39     exp_prefix += "Send";
40   } else {
41     exp_prefix += "Receive";
42   }
43 
44   webrtc::BuiltInNetworkBehaviorConfig config;
45   bool configured = false;
46   configured |=
47       ParseConfigParam(exp_prefix + "DelayMs", &config.queue_delay_ms);
48   configured |= ParseConfigParam(exp_prefix + "DelayStdDevMs",
49                                  &config.delay_standard_deviation_ms);
50   int queue_length = 0;
51   if (ParseConfigParam(exp_prefix + "QueueLength", &queue_length)) {
52     RTC_CHECK_GE(queue_length, 0);
53     config.queue_length_packets = queue_length;
54     configured = true;
55   }
56   configured |=
57       ParseConfigParam(exp_prefix + "CapacityKbps", &config.link_capacity_kbps);
58   configured |=
59       ParseConfigParam(exp_prefix + "LossPercent", &config.loss_percent);
60   int allow_reordering = 0;
61   if (ParseConfigParam(exp_prefix + "AllowReordering", &allow_reordering)) {
62     config.allow_reordering = true;
63     configured = true;
64   }
65   configured |= ParseConfigParam(exp_prefix + "AvgBurstLossLength",
66                                  &config.avg_burst_loss_length);
67   return configured
68              ? absl::optional<webrtc::BuiltInNetworkBehaviorConfig>(config)
69              : absl::nullopt;
70 }
71 }  // namespace
72 
CallFactory()73 CallFactory::CallFactory() {
74   call_thread_.Detach();
75 }
76 
CreateCall(const Call::Config & config)77 Call* CallFactory::CreateCall(const Call::Config& config) {
78   RTC_DCHECK_RUN_ON(&call_thread_);
79   absl::optional<webrtc::BuiltInNetworkBehaviorConfig> send_degradation_config =
80       ParseDegradationConfig(true);
81   absl::optional<webrtc::BuiltInNetworkBehaviorConfig>
82       receive_degradation_config = ParseDegradationConfig(false);
83 
84   if (send_degradation_config || receive_degradation_config) {
85     return new DegradedCall(std::unique_ptr<Call>(Call::Create(config)),
86                             send_degradation_config, receive_degradation_config,
87                             config.task_queue_factory);
88   }
89 
90   if (!module_thread_) {
91     module_thread_ = SharedModuleThread::Create(
92         ProcessThread::Create("SharedModThread"), [this]() {
93           RTC_DCHECK_RUN_ON(&call_thread_);
94           module_thread_ = nullptr;
95         });
96   }
97 
98   return Call::Create(config, module_thread_);
99 }
100 
CreateCallFactory()101 std::unique_ptr<CallFactoryInterface> CreateCallFactory() {
102   return std::unique_ptr<CallFactoryInterface>(new CallFactory());
103 }
104 
105 }  // namespace webrtc
106