xref: /aosp_15_r20/external/webrtc/test/network/emulated_network_manager.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 
11 #include "test/network/emulated_network_manager.h"
12 
13 #include <memory>
14 #include <utility>
15 
16 #include "absl/memory/memory.h"
17 #include "p2p/base/basic_packet_socket_factory.h"
18 #include "test/network/fake_network_socket_server.h"
19 
20 namespace webrtc {
21 namespace test {
22 
EmulatedNetworkManager(TimeController * time_controller,TaskQueueForTest * task_queue,EndpointsContainer * endpoints_container)23 EmulatedNetworkManager::EmulatedNetworkManager(
24     TimeController* time_controller,
25     TaskQueueForTest* task_queue,
26     EndpointsContainer* endpoints_container)
27     : task_queue_(task_queue),
28       endpoints_container_(endpoints_container),
29       sent_first_update_(false),
30       start_count_(0) {
31   auto socket_server =
32       std::make_unique<FakeNetworkSocketServer>(endpoints_container);
33   packet_socket_factory_ =
34       std::make_unique<rtc::BasicPacketSocketFactory>(socket_server.get());
35   // Since we pass ownership of the socket server to `network_thread_`, we must
36   // arrange that it outlives `packet_socket_factory_` which refers to it.
37   network_thread_ =
38       time_controller->CreateThread("net_thread", std::move(socket_server));
39 }
40 
EnableEndpoint(EmulatedEndpointImpl * endpoint)41 void EmulatedNetworkManager::EnableEndpoint(EmulatedEndpointImpl* endpoint) {
42   RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
43       << "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
44   network_thread_->PostTask([this, endpoint]() {
45     endpoint->Enable();
46     UpdateNetworksOnce();
47   });
48 }
49 
DisableEndpoint(EmulatedEndpointImpl * endpoint)50 void EmulatedNetworkManager::DisableEndpoint(EmulatedEndpointImpl* endpoint) {
51   RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
52       << "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
53   network_thread_->PostTask([this, endpoint]() {
54     endpoint->Disable();
55     UpdateNetworksOnce();
56   });
57 }
58 
59 // Network manager interface. All these methods are supposed to be called from
60 // the same thread.
StartUpdating()61 void EmulatedNetworkManager::StartUpdating() {
62   RTC_DCHECK_RUN_ON(network_thread_.get());
63 
64   if (start_count_) {
65     // If network interfaces are already discovered and signal is sent,
66     // we should trigger network signal immediately for the new clients
67     // to start allocating ports.
68     if (sent_first_update_)
69       network_thread_->PostTask([this]() { MaybeSignalNetworksChanged(); });
70   } else {
71     network_thread_->PostTask([this]() { UpdateNetworksOnce(); });
72   }
73   ++start_count_;
74 }
75 
StopUpdating()76 void EmulatedNetworkManager::StopUpdating() {
77   RTC_DCHECK_RUN_ON(network_thread_.get());
78   if (!start_count_)
79     return;
80 
81   --start_count_;
82   if (!start_count_) {
83     sent_first_update_ = false;
84   }
85 }
86 
GetStats(std::function<void (EmulatedNetworkStats)> stats_callback) const87 void EmulatedNetworkManager::GetStats(
88     std::function<void(EmulatedNetworkStats)> stats_callback) const {
89   task_queue_->PostTask([stats_callback, this]() {
90     stats_callback(endpoints_container_->GetStats());
91   });
92 }
93 
UpdateNetworksOnce()94 void EmulatedNetworkManager::UpdateNetworksOnce() {
95   RTC_DCHECK_RUN_ON(network_thread_.get());
96 
97   std::vector<std::unique_ptr<rtc::Network>> networks;
98   for (std::unique_ptr<rtc::Network>& net :
99        endpoints_container_->GetEnabledNetworks()) {
100     net->set_default_local_address_provider(this);
101     networks.push_back(std::move(net));
102   }
103 
104   bool changed;
105   MergeNetworkList(std::move(networks), &changed);
106   if (changed || !sent_first_update_) {
107     MaybeSignalNetworksChanged();
108     sent_first_update_ = true;
109   }
110 }
111 
MaybeSignalNetworksChanged()112 void EmulatedNetworkManager::MaybeSignalNetworksChanged() {
113   RTC_DCHECK_RUN_ON(network_thread_.get());
114   // If manager is stopped we don't need to signal anything.
115   if (start_count_ == 0) {
116     return;
117   }
118   SignalNetworksChanged();
119 }
120 
121 }  // namespace test
122 }  // namespace webrtc
123