blob: 5367a803a0dbd79cad1f4997ab61aba36924032d [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"
17
18namespace webrtc {
19namespace test {
20
21EmulatedNetworkManager::EmulatedNetworkManager(
22 Clock* clock,
Artem Titov806299e2019-04-12 12:17:19 +020023 TaskQueueForTest* task_queue,
Artem Titovbdecb3c2019-03-29 15:20:23 +010024 EndpointsContainer* endpoints_container)
Artem Titov806299e2019-04-12 12:17:19 +020025 : task_queue_(task_queue),
26 endpoints_container_(endpoints_container),
Artem Titovbdecb3c2019-03-29 15:20:23 +010027 socket_server_(clock, endpoints_container),
Artem Titove5cc85b2019-03-28 12:11:09 +010028 network_thread_(&socket_server_),
29 sent_first_update_(false),
30 start_count_(0) {
31 network_thread_.SetName("net_thread", nullptr);
32 network_thread_.Start();
33}
34
35void EmulatedNetworkManager::EnableEndpoint(EmulatedEndpoint* endpoint) {
Artem Titovbdecb3c2019-03-29 15:20:23 +010036 RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
Artem Titove5cc85b2019-03-28 12:11:09 +010037 << "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
38 network_thread_.PostTask(RTC_FROM_HERE, [this, endpoint]() {
39 endpoint->Enable();
40 UpdateNetworksOnce();
41 });
42}
43
44void EmulatedNetworkManager::DisableEndpoint(EmulatedEndpoint* endpoint) {
Artem Titovbdecb3c2019-03-29 15:20:23 +010045 RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
Artem Titove5cc85b2019-03-28 12:11:09 +010046 << "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
47 network_thread_.PostTask(RTC_FROM_HERE, [this, endpoint]() {
48 endpoint->Disable();
49 UpdateNetworksOnce();
50 });
51}
52
53// Network manager interface. All these methods are supposed to be called from
54// the same thread.
55void EmulatedNetworkManager::StartUpdating() {
56 RTC_DCHECK_RUN_ON(&network_thread_);
57
58 if (start_count_) {
59 // If network interfaces are already discovered and signal is sent,
60 // we should trigger network signal immediately for the new clients
61 // to start allocating ports.
62 if (sent_first_update_)
63 network_thread_.PostTask(RTC_FROM_HERE,
64 [this]() { MaybeSignalNetworksChanged(); });
65 } else {
66 network_thread_.PostTask(RTC_FROM_HERE, [this]() { UpdateNetworksOnce(); });
67 }
68 ++start_count_;
69}
70
71void EmulatedNetworkManager::StopUpdating() {
72 RTC_DCHECK_RUN_ON(&network_thread_);
73 if (!start_count_)
74 return;
75
76 --start_count_;
77 if (!start_count_) {
78 sent_first_update_ = false;
79 }
80}
81
Artem Titov806299e2019-04-12 12:17:19 +020082void EmulatedNetworkManager::GetStats(
83 std::function<void(EmulatedNetworkStats)> stats_callback) const {
84 task_queue_->PostTask([stats_callback, this]() {
85 stats_callback(endpoints_container_->GetStats());
86 });
87}
88
Artem Titove5cc85b2019-03-28 12:11:09 +010089void EmulatedNetworkManager::UpdateNetworksOnce() {
90 RTC_DCHECK_RUN_ON(&network_thread_);
91
92 std::vector<rtc::Network*> networks;
93 for (std::unique_ptr<rtc::Network>& net :
Artem Titovbdecb3c2019-03-29 15:20:23 +010094 endpoints_container_->GetEnabledNetworks()) {
Artem Titove5cc85b2019-03-28 12:11:09 +010095 net->set_default_local_address_provider(this);
96 networks.push_back(net.release());
97 }
98
99 bool changed;
100 MergeNetworkList(networks, &changed);
101 if (changed || !sent_first_update_) {
102 MaybeSignalNetworksChanged();
103 sent_first_update_ = true;
104 }
105}
106
107void EmulatedNetworkManager::MaybeSignalNetworksChanged() {
108 RTC_DCHECK_RUN_ON(&network_thread_);
109 // If manager is stopped we don't need to signal anything.
110 if (start_count_ == 0) {
111 return;
112 }
113 SignalNetworksChanged();
114}
115
116} // namespace test
117} // namespace webrtc