blob: 5bc3c094cbeedd77556c8ff0d438cf7d57955428 [file] [log] [blame]
Artem Titove5cc85b2019-03-28 12:11:09 +01001/*
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
Artem Titov386802e2019-07-05 10:48:17 +020011#include "test/network/emulated_network_manager.h"
Artem Titove5cc85b2019-03-28 12:11:09 +010012
13#include <memory>
14#include <utility>
15
16#include "absl/memory/memory.h"
Niels Möller5e7a3ae2021-09-09 15:54:42 +020017#include "p2p/base/basic_packet_socket_factory.h"
Sebastian Jansson2a92d2b2020-01-13 16:49:32 +010018#include "test/network/fake_network_socket_server.h"
Artem Titove5cc85b2019-03-28 12:11:09 +010019
20namespace webrtc {
21namespace test {
22
23EmulatedNetworkManager::EmulatedNetworkManager(
Sebastian Janssonfc8279d2020-01-16 11:45:59 +010024 TimeController* time_controller,
Artem Titov806299e2019-04-12 12:17:19 +020025 TaskQueueForTest* task_queue,
Artem Titovbdecb3c2019-03-29 15:20:23 +010026 EndpointsContainer* endpoints_container)
Artem Titov806299e2019-04-12 12:17:19 +020027 : task_queue_(task_queue),
28 endpoints_container_(endpoints_container),
Artem Titove5cc85b2019-03-28 12:11:09 +010029 sent_first_update_(false),
Niels Möller5e7a3ae2021-09-09 15:54:42 +020030 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}
Artem Titove5cc85b2019-03-28 12:11:09 +010040
Sebastian Janssoncec24332019-12-04 14:26:50 +010041void EmulatedNetworkManager::EnableEndpoint(EmulatedEndpointImpl* endpoint) {
Artem Titovbdecb3c2019-03-29 15:20:23 +010042 RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
Artem Titove5cc85b2019-03-28 12:11:09 +010043 << "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
Henrik Boström2deee4b2022-01-20 11:58:05 +010044 network_thread_->PostTask([this, endpoint]() {
Artem Titove5cc85b2019-03-28 12:11:09 +010045 endpoint->Enable();
46 UpdateNetworksOnce();
47 });
48}
49
Sebastian Janssoncec24332019-12-04 14:26:50 +010050void EmulatedNetworkManager::DisableEndpoint(EmulatedEndpointImpl* endpoint) {
Artem Titovbdecb3c2019-03-29 15:20:23 +010051 RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
Artem Titove5cc85b2019-03-28 12:11:09 +010052 << "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
Henrik Boström2deee4b2022-01-20 11:58:05 +010053 network_thread_->PostTask([this, endpoint]() {
Artem Titove5cc85b2019-03-28 12:11:09 +010054 endpoint->Disable();
55 UpdateNetworksOnce();
56 });
57}
58
59// Network manager interface. All these methods are supposed to be called from
60// the same thread.
61void EmulatedNetworkManager::StartUpdating() {
Sebastian Jansson2a92d2b2020-01-13 16:49:32 +010062 RTC_DCHECK_RUN_ON(network_thread_.get());
Artem Titove5cc85b2019-03-28 12:11:09 +010063
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_)
Henrik Boström2deee4b2022-01-20 11:58:05 +010069 network_thread_->PostTask([this]() { MaybeSignalNetworksChanged(); });
Artem Titove5cc85b2019-03-28 12:11:09 +010070 } else {
Henrik Boström2deee4b2022-01-20 11:58:05 +010071 network_thread_->PostTask([this]() { UpdateNetworksOnce(); });
Artem Titove5cc85b2019-03-28 12:11:09 +010072 }
73 ++start_count_;
74}
75
76void EmulatedNetworkManager::StopUpdating() {
Sebastian Jansson2a92d2b2020-01-13 16:49:32 +010077 RTC_DCHECK_RUN_ON(network_thread_.get());
Artem Titove5cc85b2019-03-28 12:11:09 +010078 if (!start_count_)
79 return;
80
81 --start_count_;
82 if (!start_count_) {
83 sent_first_update_ = false;
84 }
85}
86
Artem Titov806299e2019-04-12 12:17:19 +020087void EmulatedNetworkManager::GetStats(
Artem Titov3e0b65d2020-07-23 02:19:02 +020088 std::function<void(std::unique_ptr<EmulatedNetworkStats>)> stats_callback)
89 const {
Artem Titov806299e2019-04-12 12:17:19 +020090 task_queue_->PostTask([stats_callback, this]() {
91 stats_callback(endpoints_container_->GetStats());
92 });
93}
94
Artem Titove5cc85b2019-03-28 12:11:09 +010095void EmulatedNetworkManager::UpdateNetworksOnce() {
Sebastian Jansson2a92d2b2020-01-13 16:49:32 +010096 RTC_DCHECK_RUN_ON(network_thread_.get());
Artem Titove5cc85b2019-03-28 12:11:09 +010097
Niels Möllerd959f3a2022-04-19 11:29:19 +020098 std::vector<std::unique_ptr<rtc::Network>> networks;
Artem Titove5cc85b2019-03-28 12:11:09 +010099 for (std::unique_ptr<rtc::Network>& net :
Artem Titovbdecb3c2019-03-29 15:20:23 +0100100 endpoints_container_->GetEnabledNetworks()) {
Artem Titove5cc85b2019-03-28 12:11:09 +0100101 net->set_default_local_address_provider(this);
Niels Möllerd959f3a2022-04-19 11:29:19 +0200102 networks.push_back(std::move(net));
Artem Titove5cc85b2019-03-28 12:11:09 +0100103 }
104
105 bool changed;
Niels Möllerd959f3a2022-04-19 11:29:19 +0200106 MergeNetworkList(std::move(networks), &changed);
Artem Titove5cc85b2019-03-28 12:11:09 +0100107 if (changed || !sent_first_update_) {
108 MaybeSignalNetworksChanged();
109 sent_first_update_ = true;
110 }
111}
112
113void EmulatedNetworkManager::MaybeSignalNetworksChanged() {
Sebastian Jansson2a92d2b2020-01-13 16:49:32 +0100114 RTC_DCHECK_RUN_ON(network_thread_.get());
Artem Titove5cc85b2019-03-28 12:11:09 +0100115 // If manager is stopped we don't need to signal anything.
116 if (start_count_ == 0) {
117 return;
118 }
119 SignalNetworksChanged();
120}
121
122} // namespace test
123} // namespace webrtc