Add IceControllerEvent::ICE_CONTROLLER_RECHECK

This patch adds a new enum value in IceControllerEvent::Type,
that allows an IceController to request a recheck without
any of the predefined event occuring.

This patch is a NOP for BasicIceController.

BUG=webrtc:10647

Change-Id: Idf1d0946480437109ff272946679fef559ca7beb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161047
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29976}
diff --git a/p2p/base/basic_ice_controller.cc b/p2p/base/basic_ice_controller.cc
index 9877388..09bc4f1 100644
--- a/p2p/base/basic_ice_controller.cc
+++ b/p2p/base/basic_ice_controller.cc
@@ -462,7 +462,9 @@
   }
 
   RTC_LOG(LS_INFO) << "delay initial selection up to " << min_delay << "ms";
-  return {absl::nullopt, min_delay};
+  reason.type = IceControllerEvent::ICE_CONTROLLER_RECHECK;
+  reason.recheck_delay_ms = min_delay;
+  return {absl::nullopt, reason};
 }
 
 IceControllerInterface::SwitchResult BasicIceController::ShouldSwitchConnection(
@@ -492,20 +494,22 @@
                                receiving_unchanged_threshold,
                                &missed_receiving_unchanged_threshold);
 
-  absl::optional<int> recheck_delay;
+  absl::optional<IceControllerEvent> recheck_event;
   if (missed_receiving_unchanged_threshold &&
       config_.receiving_switching_delay_or_default()) {
     // If we do not switch to the connection because it missed the receiving
     // threshold, the new connection is in a better receiving state than the
     // currently selected connection. So we need to re-check whether it needs
     // to be switched at a later time.
-    recheck_delay = config_.receiving_switching_delay_or_default();
+    recheck_event = reason;
+    recheck_event->recheck_delay_ms =
+        config_.receiving_switching_delay_or_default();
   }
 
   if (cmp < 0) {
     return {new_connection, absl::nullopt};
   } else if (cmp > 0) {
-    return {absl::nullopt, recheck_delay};
+    return {absl::nullopt, recheck_event};
   }
 
   // If everything else is the same, switch only if rtt has improved by
@@ -514,7 +518,7 @@
     return {new_connection, absl::nullopt};
   }
 
-  return {absl::nullopt, recheck_delay};
+  return {absl::nullopt, recheck_event};
 }
 
 IceControllerInterface::SwitchResult
diff --git a/p2p/base/ice_controller_interface.cc b/p2p/base/ice_controller_interface.cc
index 6c93012..6d9bb85 100644
--- a/p2p/base/ice_controller_interface.cc
+++ b/p2p/base/ice_controller_interface.cc
@@ -44,10 +44,12 @@
     case SELECTED_CONNECTION_DESTROYED:
       reason = "selected candidate pair destroyed";
       break;
+    case ICE_CONTROLLER_RECHECK:
+      reason = "ice-controller-request-recheck";
+      break;
   }
-  if (dampening_delay) {
-    reason += " (after switching dampening interval: " +
-              std::to_string(dampening_delay) + ")";
+  if (recheck_delay_ms) {
+    reason += " (after delay: " + std::to_string(recheck_delay_ms) + ")";
   }
   return reason;
 }
diff --git a/p2p/base/ice_controller_interface.h b/p2p/base/ice_controller_interface.h
index 4f8dc72..43bb884 100644
--- a/p2p/base/ice_controller_interface.h
+++ b/p2p/base/ice_controller_interface.h
@@ -32,7 +32,11 @@
     NOMINATION_ON_CONTROLLED_SIDE,
     DATA_RECEIVED,
     CONNECT_STATE_CHANGE,
-    SELECTED_CONNECTION_DESTROYED
+    SELECTED_CONNECTION_DESTROYED,
+    // The ICE_CONTROLLER_RECHECK enum value lets an IceController request
+    // P2PTransportChannel to recheck a switch periodically without an event
+    // taking place.
+    ICE_CONTROLLER_RECHECK,
   };
 
   IceControllerEvent(const Type& _type)  // NOLINT: runtime/explicit
@@ -40,7 +44,7 @@
   std::string ToString() const;
 
   Type type;
-  int dampening_delay = 0;
+  int recheck_delay_ms = 0;
 };
 
 // Defines the interface for a module that control
@@ -65,8 +69,8 @@
     // Connection that we should (optionally) switch to.
     absl::optional<const Connection*> connection;
 
-    // Delay in milliseconds when we should resort and try switching again.
-    absl::optional<int> recheck_delay_ms;
+    // An optional recheck event for when a Switch() should be attempted again.
+    absl::optional<IceControllerEvent> recheck_event;
   };
 
   virtual ~IceControllerInterface() = default;
diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index 8d67690..c11a6b4 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -234,17 +234,16 @@
                              reason);
   }
 
-  if (result.recheck_delay_ms.has_value()) {
+  if (result.recheck_event.has_value()) {
     // If we do not switch to the connection because it missed the receiving
     // threshold, the new connection is in a better receiving state than the
     // currently selected connection. So we need to re-check whether it needs
     // to be switched at a later time.
-    reason.dampening_delay = *result.recheck_delay_ms;
     invoker_.AsyncInvokeDelayed<void>(
         RTC_FROM_HERE, thread(),
         rtc::Bind(&P2PTransportChannel::SortConnectionsAndUpdateState, this,
-                  reason),
-        reason.dampening_delay);
+                  *result.recheck_event),
+        result.recheck_event->recheck_delay_ms);
   }
 
   return result.connection.has_value();