Add callback-based interface to IceTransportInternal GatheringState

This allows both the signal and the callback to be used.

Bug: webrtc:11943
Change-Id: I89460126d415520295c7e7d4ee440156a6e9e5ab
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/329140
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41282}
diff --git a/p2p/base/fake_ice_transport.h b/p2p/base/fake_ice_transport.h
index ae7bf89..6172ebb 100644
--- a/p2p/base/fake_ice_transport.h
+++ b/p2p/base/fake_ice_transport.h
@@ -124,7 +124,7 @@
     RTC_DCHECK_RUN_ON(network_thread_);
     if (gathering_state_ != kIceGatheringComplete) {
       gathering_state_ = kIceGatheringComplete;
-      SignalGatheringState(this);
+      SendGatheringStateEvent();
     }
   }
 
@@ -232,7 +232,7 @@
     RTC_DCHECK_RUN_ON(network_thread_);
     if (gathering_state_ == kIceGatheringNew) {
       gathering_state_ = kIceGatheringGathering;
-      SignalGatheringState(this);
+      SendGatheringStateEvent();
     }
   }
 
diff --git a/p2p/base/ice_transport_internal.cc b/p2p/base/ice_transport_internal.cc
index fab6f20..0dc7e50 100644
--- a/p2p/base/ice_transport_internal.cc
+++ b/p2p/base/ice_transport_internal.cc
@@ -123,7 +123,13 @@
   return stun_keepalive_interval.value_or(STUN_KEEPALIVE_INTERVAL);
 }
 
-IceTransportInternal::IceTransportInternal() = default;
+IceTransportInternal::IceTransportInternal() {
+  // Set up detector for use of SignalGatheringState rather than
+  // SetGatheringStateCallback, and behave accordingly
+  // TODO(bugs.webrtc.org/11943): remove when Signal removed
+  SignalGatheringState.connect(
+      this, &IceTransportInternal::SignalGatheringStateFired);
+}
 
 IceTransportInternal::~IceTransportInternal() = default;
 
diff --git a/p2p/base/ice_transport_internal.h b/p2p/base/ice_transport_internal.h
index 358e102..38b6bfe 100644
--- a/p2p/base/ice_transport_internal.h
+++ b/p2p/base/ice_transport_internal.h
@@ -304,7 +304,13 @@
     return absl::nullopt;
   }
 
+  // Signal Exposed for backwards compatibility.
   sigslot::signal1<IceTransportInternal*> SignalGatheringState;
+  void SetGatheringStateCallback(
+      absl::AnyInvocable<void(IceTransportInternal*)> callback) {
+    RTC_DCHECK(!gathering_state_callback_);
+    gathering_state_callback_ = std::move(callback);
+  }
 
   // Handles sending and receiving of candidates.
   sigslot::signal2<IceTransportInternal*, const Candidate&>
@@ -378,6 +384,8 @@
   }
 
  protected:
+  void SendGatheringStateEvent() { SignalGatheringState(this); }
+
   webrtc::CallbackList<IceTransportInternal*,
                        const StunDictionaryView&,
                        rtc::ArrayView<uint16_t>>
@@ -385,6 +393,8 @@
   webrtc::CallbackList<IceTransportInternal*, const StunDictionaryWriter&>
       dictionary_writer_synced_callback_list_;
 
+  absl::AnyInvocable<void(IceTransportInternal*)> gathering_state_callback_;
+
   absl::AnyInvocable<void(IceTransportInternal*, const IceCandidateErrorEvent&)>
       candidate_error_callback_;
 
@@ -393,6 +403,14 @@
 
   absl::AnyInvocable<void(const cricket::CandidatePairChangeEvent&)>
       candidate_pair_change_callback_;
+
+ private:
+  // TODO(bugs.webrtc.org/11943): remove when removing Signal
+  void SignalGatheringStateFired(IceTransportInternal* transport) {
+    if (gathering_state_callback_) {
+      gathering_state_callback_(transport);
+    }
+  }
 };
 
 }  // namespace cricket
diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index 166dbe8..c41e460 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -884,7 +884,7 @@
                             ice_parameters_.ufrag, ice_parameters_.pwd)) {
     if (gathering_state_ != kIceGatheringGathering) {
       gathering_state_ = kIceGatheringGathering;
-      SignalGatheringState(this);
+      SendGatheringStateEvent();
     }
 
     if (!allocator_sessions_.empty()) {
@@ -1014,7 +1014,7 @@
   gathering_state_ = kIceGatheringComplete;
   RTC_LOG(LS_INFO) << "P2PTransportChannel: " << transport_name()
                    << ", component " << component() << " gathering complete";
-  SignalGatheringState(this);
+  SendGatheringStateEvent();
 }
 
 // Handle stun packets
diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc
index fc88d61..de30465 100644
--- a/pc/jsep_transport_controller.cc
+++ b/pc/jsep_transport_controller.cc
@@ -433,8 +433,11 @@
       this, &JsepTransportController::OnTransportWritableState_n);
   dtls->SignalReceivingState.connect(
       this, &JsepTransportController::OnTransportReceivingState_n);
-  dtls->ice_transport()->SignalGatheringState.connect(
-      this, &JsepTransportController::OnTransportGatheringState_n);
+  dtls->ice_transport()->SetGatheringStateCallback(
+      [this](cricket::IceTransportInternal* transport) {
+        RTC_DCHECK_RUN_ON(network_thread_);
+        OnTransportGatheringState_n(transport);
+      });
   dtls->ice_transport()->SignalCandidateGathered.connect(
       this, &JsepTransportController::OnTransportCandidateGathered_n);
   dtls->ice_transport()->SetCandidateErrorCallback(