Add datagram_transport and congestion_control interface

This change introduces experimental datagram_transport interface and congestion_control interfaces. The goal is to integrate support for datagram transport in DTLS transport and set it up in a similar way we currently setup media_transport. Datagram transport will be injected in peer connection factory the same way media_transport is injected (we might even keep using the same factory which creates both media and datagram transports for now until we decided what to do next).

Bug: webrtc:9719
Change-Id: I80e70ce8d3827664ac5f5f7e55b706fe2dd2fbef
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/136782
Commit-Queue: Anton Sukhanov <sukhanov@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Bjorn Mellem <mellem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27943}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 2512bd4..b9c3229 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -86,6 +86,7 @@
     "bitrate_constraints.h",
     "candidate.cc",
     "candidate.h",
+    "congestion_control_interface.h",
     "crypto/crypto_options.cc",
     "crypto/crypto_options.h",
     "crypto/frame_decryptor_interface.h",
@@ -93,6 +94,7 @@
     "crypto_params.h",
     "data_channel_interface.cc",
     "data_channel_interface.h",
+    "datagram_transport_interface.h",
     "dtls_transport_interface.cc",
     "dtls_transport_interface.h",
     "dtmf_sender_interface.h",
diff --git a/api/congestion_control_interface.h b/api/congestion_control_interface.h
new file mode 100644
index 0000000..2e822db
--- /dev/null
+++ b/api/congestion_control_interface.h
@@ -0,0 +1,67 @@
+/* Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This is EXPERIMENTAL interface for media and datagram transports.
+
+#ifndef API_CONGESTION_CONTROL_INTERFACE_H_
+#define API_CONGESTION_CONTROL_INTERFACE_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "api/media_transport_interface.h"
+#include "api/units/data_rate.h"
+
+namespace webrtc {
+
+// Defines congestion control feedback interface for media and datagram
+// transports.
+class CongestionControlInterface {
+ public:
+  virtual ~CongestionControlInterface() = default;
+
+  // Updates allocation limits.
+  virtual void SetAllocatedBitrateLimits(
+      const MediaTransportAllocatedBitrateLimits& limits) = 0;
+
+  // Sets starting rate.
+  virtual void SetTargetBitrateLimits(
+      const MediaTransportTargetRateConstraints& target_rate_constraints) = 0;
+
+  // Intended for receive side. AddRttObserver registers an observer to be
+  // called for each RTT measurement, typically once per ACK. Before media
+  // transport is destructed the observer must be unregistered.
+  //
+  // TODO(sukhanov): Looks like AddRttObserver and RemoveRttObserver were
+  // never implemented for media transport, so keeping noop implementation.
+  virtual void AddRttObserver(MediaTransportRttObserver* observer) {}
+  virtual void RemoveRttObserver(MediaTransportRttObserver* observer) {}
+
+  // Adds a target bitrate observer. Before media transport is destructed
+  // the observer must be unregistered (by calling
+  // RemoveTargetTransferRateObserver).
+  // A newly registered observer will be called back with the latest recorded
+  // target rate, if available.
+  virtual void AddTargetTransferRateObserver(
+      TargetTransferRateObserver* observer) = 0;
+
+  // Removes an existing |observer| from observers. If observer was never
+  // registered, an error is logged and method does nothing.
+  virtual void RemoveTargetTransferRateObserver(
+      TargetTransferRateObserver* observer) = 0;
+
+  // Returns the last known target transfer rate as reported to the above
+  // observers.
+  virtual absl::optional<TargetTransferRate> GetLatestTargetTransferRate() = 0;
+};
+
+}  // namespace webrtc
+
+#endif  // API_CONGESTION_CONTROL_INTERFACE_H_
diff --git a/api/datagram_transport_interface.h b/api/datagram_transport_interface.h
new file mode 100644
index 0000000..d64c0f3
--- /dev/null
+++ b/api/datagram_transport_interface.h
@@ -0,0 +1,100 @@
+/* Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This is EXPERIMENTAL interface for media and datagram transports.
+
+#ifndef API_DATAGRAM_TRANSPORT_INTERFACE_H_
+#define API_DATAGRAM_TRANSPORT_INTERFACE_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "api/array_view.h"
+#include "api/congestion_control_interface.h"
+#include "api/media_transport_interface.h"
+#include "api/rtc_error.h"
+#include "api/units/data_rate.h"
+
+namespace rtc {
+class PacketTransportInternal;
+}  // namespace rtc
+
+namespace webrtc {
+
+typedef int64_t DatagramId;
+
+// All sink methods are called on network thread.
+class DatagramSinkInterface {
+ public:
+  virtual ~DatagramSinkInterface() {}
+
+  // Called when new packet is received.
+  virtual void OnDatagramReceived(rtc::ArrayView<const uint8_t> data) = 0;
+
+  // Called when datagram is actually sent (datragram can be delayed due
+  // to congestion control or fusing). |datagram_id| is same as passed in
+  // QuicTransportInterface::SendDatagram.
+  virtual void OnDatagramSent(DatagramId datagram_id) = 0;
+};
+
+// Datagram transport allows to send and receive unreliable packets (datagrams)
+// and receive feedback from congestion control (via
+// CongestionControlInterface). The idea is to send RTP packets as datagrams and
+// have underlying implementation of datagram transport to use QUIC datagram
+// protocol.
+class DatagramTransportInterface {
+ public:
+  virtual ~DatagramTransportInterface() = default;
+
+  // Connect the datagram transport to the ICE transport.
+  // The implementation must be able to ignore incoming packets that don't
+  // belong to it.
+  virtual void Connect(rtc::PacketTransportInternal* packet_transport) = 0;
+
+  // Returns congestion control feedback interface or nullptr if datagram
+  // transport does not implement congestion control.
+  //
+  // Note that right now datagram transport is used without congestion control,
+  // but we plan to use it in the future.
+  virtual CongestionControlInterface* congestion_control() = 0;
+
+  // Sets a state observer callback. Before datagram transport is destroyed, the
+  // callback must be unregistered by setting it to nullptr.
+  // A newly registered callback will be called with the current state.
+  // Datagram transport does not invoke this callback concurrently.
+  virtual void SetTransportStateCallback(
+      MediaTransportStateCallback* callback) = 0;
+
+  // Start asynchronous send of datagram. The status returned by this method
+  // only pertains to the synchronous operations (e.g. serialization /
+  // packetization), not to the asynchronous operation.
+  //
+  // Datagrams larger than GetLargestDatagramSize() will fail and return error.
+  //
+  // Datagrams are sent in FIFO order.
+  virtual RTCError SendDatagram(rtc::ArrayView<const uint8_t> data,
+                                DatagramId datagram_id) = 0;
+
+  // Returns maximum size of datagram message, does not change.
+  // TODO(sukhanov): Because value may be undefined before connection setup
+  // is complete, consider returning error when called before connection is
+  // established. Currently returns hardcoded const, because integration
+  // prototype may call before connection is established.
+  virtual size_t GetLargestDatagramSize() const = 0;
+
+  // Sets packet sink. Sink must be unset by calling
+  // SetDataTransportSink(nullptr) before the data transport is destroyed or
+  // before new sink is set.
+  virtual void SetDatagramSink(DatagramSinkInterface* sink) = 0;
+};
+
+}  // namespace webrtc
+
+#endif  // API_DATAGRAM_TRANSPORT_INTERFACE_H_