blob: a4d21eb0793bb1cf75f3627d5d0c536b75362fff [file] [log] [blame]
Qingsi Wang1b368942018-06-13 13:54:08 -07001/*
2 * Copyright 2018 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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "p2p/base/regathering_controller.h"
Qingsi Wang1b368942018-06-13 13:54:08 -070012
13namespace webrtc {
14
15using Config = BasicRegatheringController::Config;
16
Danil Chapovalov00c71832018-06-15 15:58:38 +020017Config::Config(const absl::optional<rtc::IntervalRange>&
Qingsi Wang1b368942018-06-13 13:54:08 -070018 regather_on_all_networks_interval_range,
19 int regather_on_failed_networks_interval)
20 : regather_on_all_networks_interval_range(
21 regather_on_all_networks_interval_range),
22 regather_on_failed_networks_interval(
23 regather_on_failed_networks_interval) {}
24
25Config::Config(const Config& other) = default;
26
27Config::~Config() = default;
28Config& Config::operator=(const Config& other) = default;
29
30BasicRegatheringController::BasicRegatheringController(
31 const Config& config,
32 cricket::IceTransportInternal* ice_transport,
33 rtc::Thread* thread)
34 : config_(config),
35 ice_transport_(ice_transport),
36 thread_(thread),
37 rand_(rtc::SystemTimeNanos()) {
38 RTC_DCHECK(ice_transport_);
39 RTC_DCHECK(thread_);
Alex Loiko9289eda2018-11-23 16:18:59 +000040 ice_transport_->SignalStateChanged.connect(
Qingsi Wang1b368942018-06-13 13:54:08 -070041 this, &BasicRegatheringController::OnIceTransportStateChanged);
42 ice_transport->SignalWritableState.connect(
43 this, &BasicRegatheringController::OnIceTransportWritableState);
44 ice_transport->SignalReceivingState.connect(
45 this, &BasicRegatheringController::OnIceTransportReceivingState);
46 ice_transport->SignalNetworkRouteChanged.connect(
47 this, &BasicRegatheringController::OnIceTransportNetworkRouteChanged);
48}
49
50BasicRegatheringController::~BasicRegatheringController() = default;
51
52void BasicRegatheringController::Start() {
53 ScheduleRecurringRegatheringOnFailedNetworks();
54 if (config_.regather_on_all_networks_interval_range) {
55 ScheduleRecurringRegatheringOnAllNetworks();
56 }
57}
58
59void BasicRegatheringController::SetConfig(const Config& config) {
60 bool need_cancel_on_all_networks =
61 has_recurring_schedule_on_all_networks_ &&
62 (config_.regather_on_all_networks_interval_range !=
63 config.regather_on_all_networks_interval_range);
64 bool need_reschedule_on_all_networks =
65 config.regather_on_all_networks_interval_range &&
66 (config_.regather_on_all_networks_interval_range !=
67 config.regather_on_all_networks_interval_range);
68 bool need_cancel_and_reschedule_on_failed_networks =
69 has_recurring_schedule_on_failed_networks_ &&
70 (config_.regather_on_failed_networks_interval !=
71 config.regather_on_failed_networks_interval);
72 config_ = config;
73 if (need_cancel_on_all_networks) {
74 CancelScheduledRecurringRegatheringOnAllNetworks();
75 }
76 if (need_reschedule_on_all_networks) {
77 ScheduleRecurringRegatheringOnAllNetworks();
78 }
79 if (need_cancel_and_reschedule_on_failed_networks) {
80 CancelScheduledRecurringRegatheringOnFailedNetworks();
81 ScheduleRecurringRegatheringOnFailedNetworks();
82 }
83}
84
85void BasicRegatheringController::ScheduleRecurringRegatheringOnAllNetworks() {
86 RTC_DCHECK(config_.regather_on_all_networks_interval_range &&
87 config_.regather_on_all_networks_interval_range.value().min() >=
88 0);
89 int delay_ms = SampleRegatherAllNetworksInterval(
90 config_.regather_on_all_networks_interval_range.value());
91 CancelScheduledRecurringRegatheringOnAllNetworks();
92 has_recurring_schedule_on_all_networks_ = true;
93 invoker_for_all_networks_.AsyncInvokeDelayed<void>(
94 RTC_FROM_HERE, thread(),
95 rtc::Bind(
96 &BasicRegatheringController::RegatherOnAllNetworksIfDoneGathering,
97 this, true),
98 delay_ms);
99}
100
101void BasicRegatheringController::RegatherOnAllNetworksIfDoneGathering(
102 bool repeated) {
103 // Only regather when the current session is in the CLEARED state (i.e., not
104 // running or stopped). It is only possible to enter this state when we gather
105 // continually, so there is an implicit check on continual gathering here.
106 if (allocator_session_ && allocator_session_->IsCleared()) {
107 allocator_session_->RegatherOnAllNetworks();
108 }
109 if (repeated) {
110 ScheduleRecurringRegatheringOnAllNetworks();
111 }
112}
113
114void BasicRegatheringController::
115 ScheduleRecurringRegatheringOnFailedNetworks() {
116 RTC_DCHECK(config_.regather_on_failed_networks_interval >= 0);
117 CancelScheduledRecurringRegatheringOnFailedNetworks();
118 has_recurring_schedule_on_failed_networks_ = true;
119 invoker_for_failed_networks_.AsyncInvokeDelayed<void>(
120 RTC_FROM_HERE, thread(),
121 rtc::Bind(
122 &BasicRegatheringController::RegatherOnFailedNetworksIfDoneGathering,
123 this, true),
124 config_.regather_on_failed_networks_interval);
125}
126
127void BasicRegatheringController::RegatherOnFailedNetworksIfDoneGathering(
128 bool repeated) {
129 // Only regather when the current session is in the CLEARED state (i.e., not
130 // running or stopped). It is only possible to enter this state when we gather
131 // continually, so there is an implicit check on continual gathering here.
132 if (allocator_session_ && allocator_session_->IsCleared()) {
133 allocator_session_->RegatherOnFailedNetworks();
134 }
135 if (repeated) {
136 ScheduleRecurringRegatheringOnFailedNetworks();
137 }
138}
139
140void BasicRegatheringController::
141 CancelScheduledRecurringRegatheringOnAllNetworks() {
142 invoker_for_all_networks_.Clear();
143 has_recurring_schedule_on_all_networks_ = false;
144}
145
146void BasicRegatheringController::
147 CancelScheduledRecurringRegatheringOnFailedNetworks() {
148 invoker_for_failed_networks_.Clear();
149 has_recurring_schedule_on_failed_networks_ = false;
150}
151
152int BasicRegatheringController::SampleRegatherAllNetworksInterval(
153 const rtc::IntervalRange& range) {
154 return rand_.Rand(range.min(), range.max());
155}
156
157} // namespace webrtc