Abstract away the interface of QuicTransport into WebTransportStream and WebTransportSession.

PiperOrigin-RevId: 361909959
Change-Id: I2b3307e6662c4b048224b09a9cb0ec6de1fb039b
diff --git a/quic/core/web_transport_interface.h b/quic/core/web_transport_interface.h
new file mode 100644
index 0000000..a458e65
--- /dev/null
+++ b/quic/core/web_transport_interface.h
@@ -0,0 +1,107 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This header contains interfaces that abstract away different backing
+// protocols for WebTransport.
+
+#ifndef QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+#define QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
+
+#include <cstddef>
+
+#include "absl/base/attributes.h"
+#include "absl/strings/string_view.h"
+#include "quic/core/quic_datagram_queue.h"
+#include "quic/core/quic_types.h"
+#include "quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Visitor that gets notified about events related to a WebTransport stream.
+class QUIC_EXPORT_PRIVATE WebTransportStreamVisitor {
+ public:
+  virtual ~WebTransportStreamVisitor() {}
+
+  // Called whenever the stream has readable data available.
+  virtual void OnCanRead() = 0;
+  // Called when all the data on the stream has been consumed and a FIN has been
+  // received.
+  virtual void OnFinRead() = 0;
+  // Called whenever the stream is not write-blocked and can accept new data.
+  virtual void OnCanWrite() = 0;
+};
+
+// A stream (either bidirectional or unidirectional) that is contained within a
+// WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportStream {
+ public:
+  virtual ~WebTransportStream() {}
+
+  // Reads at most |buffer_size| bytes into |buffer| and returns the number of
+  // bytes actually read.
+  virtual size_t Read(char* buffer, size_t buffer_size) = 0;
+  // Reads all available data and appends it to the end of |output|.
+  virtual size_t Read(std::string* output) = 0;
+  // Writes |data| into the stream.  Returns true on success.
+  virtual ABSL_MUST_USE_RESULT bool Write(absl::string_view data) = 0;
+  // Sends the FIN on the stream.  Returns true on success.
+  virtual ABSL_MUST_USE_RESULT bool SendFin() = 0;
+
+  // Indicates whether it is possible to write into stream right now.
+  virtual bool CanWrite() const = 0;
+  // Indicates the number of bytes that can be read from the stream.
+  virtual size_t ReadableBytes() const = 0;
+};
+
+// Visitor that gets notified about events related to a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportVisitor {
+ public:
+  virtual ~WebTransportVisitor() {}
+
+  // Notifies the visitor when the session is ready to exchange application
+  // data.
+  virtual void OnSessionReady() = 0;
+
+  // Notifies the visitor when a new stream has been received.  The stream in
+  // question can be retrieved using AcceptIncomingBidirectionalStream() or
+  // AcceptIncomingUnidirectionalStream().
+  virtual void OnIncomingBidirectionalStreamAvailable() = 0;
+  virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
+
+  // Notifies the visitor when a new datagram has been received.
+  virtual void OnDatagramReceived(absl::string_view datagram) = 0;
+
+  // Notifies the visitor that a new outgoing stream can now be created.
+  virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
+  virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
+};
+
+// An abstract interface for a WebTransport session.
+class QUIC_EXPORT_PRIVATE WebTransportSession {
+ public:
+  virtual ~WebTransportSession() {}
+
+  // Return the earliest incoming stream that has been received by the session
+  // but has not been accepted.  Returns nullptr if there are no incoming
+  // streams.
+  virtual WebTransportStream* AcceptIncomingBidirectionalStream() = 0;
+  virtual WebTransportStream* AcceptIncomingUnidirectionalStream() = 0;
+
+  // Returns true if flow control allows opening a new stream.
+  virtual bool CanOpenNextOutgoingBidirectionalStream() = 0;
+  virtual bool CanOpenNextOutgoingUnidirectionalStream() = 0;
+  // Opens a new WebTransport stream, or returns nullptr if that is not possible
+  // due to flow control.
+  virtual WebTransportStream* OpenOutgoingBidirectionalStream() = 0;
+  virtual WebTransportStream* OpenOutgoingUnidirectionalStream() = 0;
+
+  virtual MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) = 0;
+  // Sets the largest duration that a datagram can spend in the queue before
+  // being silently dropped.
+  virtual void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_WEB_TRANSPORT_INTERFACE_H_
diff --git a/quic/quic_transport/quic_transport_client_session.cc b/quic/quic_transport/quic_transport_client_session.cc
index 7b81f51..6838c4c 100644
--- a/quic/quic_transport/quic_transport_client_session.cc
+++ b/quic/quic_transport/quic_transport_client_session.cc
@@ -34,7 +34,7 @@
     const GURL& url,
     QuicCryptoClientConfig* crypto_config,
     url::Origin origin,
-    ClientVisitor* visitor,
+    WebTransportVisitor* visitor,
     std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer)
     : QuicSession(connection,
                   owner,
diff --git a/quic/quic_transport/quic_transport_client_session.h b/quic/quic_transport/quic_transport_client_session.h
index 686e5b3..6406bd5 100644
--- a/quic/quic_transport/quic_transport_client_session.h
+++ b/quic/quic_transport/quic_transport_client_session.h
@@ -21,6 +21,7 @@
 #include "quic/core/quic_session.h"
 #include "quic/core/quic_stream.h"
 #include "quic/core/quic_versions.h"
+#include "quic/core/web_transport_interface.h"
 #include "quic/platform/api/quic_bug_tracker.h"
 #include "quic/platform/api/quic_containers.h"
 #include "quic/quic_transport/quic_transport_protocol.h"
@@ -32,31 +33,10 @@
 // A client session for the QuicTransport protocol.
 class QUIC_EXPORT_PRIVATE QuicTransportClientSession
     : public QuicSession,
+      public WebTransportSession,
       public QuicTransportSessionInterface,
       public QuicCryptoClientStream::ProofHandler {
  public:
-  class QUIC_EXPORT_PRIVATE ClientVisitor {
-   public:
-    virtual ~ClientVisitor() {}
-
-    // Notifies the visitor when the client indication has been sent and the
-    // connection is ready to exchange application data.
-    virtual void OnSessionReady() = 0;
-
-    // Notifies the visitor when a new stream has been received.  The stream in
-    // question can be retrieved using AcceptIncomingBidirectionalStream() or
-    // AcceptIncomingUnidirectionalStream().
-    virtual void OnIncomingBidirectionalStreamAvailable() = 0;
-    virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
-
-    // Notifies the visitor when a new datagram has been received.
-    virtual void OnDatagramReceived(absl::string_view datagram) = 0;
-
-    // Notifies the visitor that a new outgoing stream can now be created.
-    virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
-    virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
-  };
-
   QuicTransportClientSession(
       QuicConnection* connection,
       Visitor* owner,
@@ -65,7 +45,7 @@
       const GURL& url,
       QuicCryptoClientConfig* crypto_config,
       url::Origin origin,
-      ClientVisitor* visitor,
+      WebTransportVisitor* visitor,
       std::unique_ptr<QuicDatagramQueue::Observer> datagram_observer);
 
   std::vector<std::string> GetAlpnsToOffer() const override {
@@ -106,14 +86,26 @@
   // Return the earliest incoming stream that has been received by the session
   // but has not been accepted.  Returns nullptr if there are no incoming
   // streams.
-  QuicTransportStream* AcceptIncomingBidirectionalStream();
-  QuicTransportStream* AcceptIncomingUnidirectionalStream();
+  QuicTransportStream* AcceptIncomingBidirectionalStream() override;
+  QuicTransportStream* AcceptIncomingUnidirectionalStream() override;
 
-  using QuicSession::CanOpenNextOutgoingBidirectionalStream;
-  using QuicSession::CanOpenNextOutgoingUnidirectionalStream;
-  QuicTransportStream* OpenOutgoingBidirectionalStream();
-  QuicTransportStream* OpenOutgoingUnidirectionalStream();
+  bool CanOpenNextOutgoingBidirectionalStream() override {
+    return QuicSession::CanOpenNextOutgoingBidirectionalStream();
+  }
+  bool CanOpenNextOutgoingUnidirectionalStream() override {
+    return QuicSession::CanOpenNextOutgoingUnidirectionalStream();
+  }
+  QuicTransportStream* OpenOutgoingBidirectionalStream() override;
+  QuicTransportStream* OpenOutgoingUnidirectionalStream() override;
 
+  MessageStatus SendOrQueueDatagram(QuicMemSlice datagram) override {
+    return datagram_queue()->SendOrQueueDatagram(std::move(datagram));
+  }
+  void SetDatagramMaxTimeInQueue(QuicTime::Delta max_time_in_queue) override {
+    datagram_queue()->SetMaxTimeInQueue(max_time_in_queue);
+  }
+
+  // For unit tests.
   using QuicSession::datagram_queue;
 
   // QuicCryptoClientStream::ProofHandler implementation.
@@ -147,7 +139,7 @@
   std::unique_ptr<QuicCryptoClientStream> crypto_stream_;
   GURL url_;
   url::Origin origin_;
-  ClientVisitor* visitor_;  // not owned
+  WebTransportVisitor* visitor_;  // not owned
   bool client_indication_sent_ = false;
   bool alpn_received_ = false;
   bool ready_ = false;
diff --git a/quic/quic_transport/quic_transport_integration_test.cc b/quic/quic_transport/quic_transport_integration_test.cc
index 1b42020..4e237c7 100644
--- a/quic/quic_transport/quic_transport_integration_test.cc
+++ b/quic/quic_transport/quic_transport_integration_test.cc
@@ -349,8 +349,7 @@
   WireUpEndpoints();
   RunHandshake();
 
-  client_->session()->datagram_queue()->SendOrQueueDatagram(
-      MemSliceFromString("test"));
+  client_->session()->SendOrQueueDatagram(MemSliceFromString("test"));
 
   bool datagram_received = false;
   EXPECT_CALL(*client_->visitor(), OnDatagramReceived(Eq("test")))
@@ -368,11 +367,10 @@
   RunHandshake();
 
   // Set the datagrams to effectively never expire.
-  client_->session()->datagram_queue()->SetMaxTimeInQueue(10000 * kRtt);
+  client_->session()->SetDatagramMaxTimeInQueue(10000 * kRtt);
   for (int i = 0; i < 1000; i++) {
-    client_->session()->datagram_queue()->SendOrQueueDatagram(
-        MemSliceFromString(std::string(
-            client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
+    client_->session()->SendOrQueueDatagram(MemSliceFromString(std::string(
+        client_->session()->GetGuaranteedLargestMessagePayload(), 'a')));
   }
 
   size_t received = 0;
diff --git a/quic/quic_transport/quic_transport_stream.h b/quic/quic_transport/quic_transport_stream.h
index 70f947c..776b07f 100644
--- a/quic/quic_transport/quic_transport_stream.h
+++ b/quic/quic_transport/quic_transport_stream.h
@@ -13,6 +13,7 @@
 #include "quic/core/quic_session.h"
 #include "quic/core/quic_stream.h"
 #include "quic/core/quic_types.h"
+#include "quic/core/web_transport_interface.h"
 #include "quic/quic_transport/quic_transport_session_interface.h"
 
 namespace quic {
@@ -20,41 +21,34 @@
 // QuicTransportStream is an extension of QuicStream that provides I/O interface
 // that is safe to use in the QuicTransport context.  The interface ensures no
 // application data is processed before the client indication is processed.
-class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream {
+class QUIC_EXPORT_PRIVATE QuicTransportStream : public QuicStream,
+                                                public WebTransportStream {
  public:
-  class QUIC_EXPORT_PRIVATE Visitor {
-   public:
-    virtual ~Visitor() {}
-    virtual void OnCanRead() = 0;
-    virtual void OnFinRead() = 0;
-    virtual void OnCanWrite() = 0;
-  };
-
   QuicTransportStream(QuicStreamId id,
                       QuicSession* session,
                       QuicTransportSessionInterface* session_interface);
 
   // Reads at most |buffer_size| bytes into |buffer| and returns the number of
   // bytes actually read.
-  size_t Read(char* buffer, size_t buffer_size);
+  size_t Read(char* buffer, size_t buffer_size) override;
   // Reads all available data and appends it to the end of |output|.
-  size_t Read(std::string* output);
+  size_t Read(std::string* output) override;
   // Writes |data| into the stream.  Returns true on success.
-  ABSL_MUST_USE_RESULT bool Write(absl::string_view data);
+  ABSL_MUST_USE_RESULT bool Write(absl::string_view data) override;
   // Sends the FIN on the stream.  Returns true on success.
-  ABSL_MUST_USE_RESULT bool SendFin();
+  ABSL_MUST_USE_RESULT bool SendFin() override;
 
   // Indicates whether it is possible to write into stream right now.
-  bool CanWrite() const;
+  bool CanWrite() const override;
   // Indicates the number of bytes that can be read from the stream.
-  size_t ReadableBytes() const;
+  size_t ReadableBytes() const override;
 
   // QuicSession method implementations.
   void OnDataAvailable() override;
   void OnCanWriteNewData() override;
 
-  Visitor* visitor() { return visitor_.get(); }
-  void set_visitor(std::unique_ptr<Visitor> visitor) {
+  WebTransportStreamVisitor* visitor() { return visitor_.get(); }
+  void set_visitor(std::unique_ptr<WebTransportStreamVisitor> visitor) {
     visitor_ = std::move(visitor);
   }
 
@@ -66,7 +60,7 @@
   void MaybeNotifyFinRead();
 
   QuicTransportSessionInterface* session_interface_;
-  std::unique_ptr<Visitor> visitor_ = nullptr;
+  std::unique_ptr<WebTransportStreamVisitor> visitor_ = nullptr;
   bool fin_read_notified_ = false;
 };
 
diff --git a/quic/test_tools/quic_transport_test_tools.h b/quic/test_tools/quic_transport_test_tools.h
index e0fcebc..0a3b52d 100644
--- a/quic/test_tools/quic_transport_test_tools.h
+++ b/quic/test_tools/quic_transport_test_tools.h
@@ -5,14 +5,14 @@
 #ifndef QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
 #define QUICHE_QUIC_TEST_TOOLS_QUIC_TRANSPORT_TEST_TOOLS_H_
 
+#include "quic/core/web_transport_interface.h"
 #include "quic/platform/api/quic_test.h"
-#include "quic/quic_transport/quic_transport_client_session.h"
 #include "quic/quic_transport/quic_transport_server_session.h"
 
 namespace quic {
 namespace test {
 
-class MockClientVisitor : public QuicTransportClientSession::ClientVisitor {
+class MockClientVisitor : public WebTransportVisitor {
  public:
   MOCK_METHOD(void, OnSessionReady, (), (override));
   MOCK_METHOD(void, OnIncomingBidirectionalStreamAvailable, (), (override));
@@ -28,7 +28,7 @@
   MOCK_METHOD(bool, ProcessPath, (const GURL&), (override));
 };
 
-class MockStreamVisitor : public QuicTransportStream::Visitor {
+class MockStreamVisitor : public WebTransportStreamVisitor {
  public:
   MOCK_METHOD(void, OnCanRead, (), (override));
   MOCK_METHOD(void, OnFinRead, (), (override));
diff --git a/quic/tools/quic_transport_simple_server_session.cc b/quic/tools/quic_transport_simple_server_session.cc
index ad93115..9acf502 100644
--- a/quic/tools/quic_transport_simple_server_session.cc
+++ b/quic/tools/quic_transport_simple_server_session.cc
@@ -21,7 +21,7 @@
 namespace {
 
 // Discards any incoming data.
-class DiscardVisitor : public QuicTransportStream::Visitor {
+class DiscardVisitor : public WebTransportStreamVisitor {
  public:
   DiscardVisitor(QuicTransportStream* stream) : stream_(stream) {}
 
@@ -40,7 +40,7 @@
 };
 
 // Echoes any incoming data back on the same stream.
-class BidirectionalEchoVisitor : public QuicTransportStream::Visitor {
+class BidirectionalEchoVisitor : public WebTransportStreamVisitor {
  public:
   BidirectionalEchoVisitor(QuicTransportStream* stream) : stream_(stream) {}
 
@@ -71,7 +71,7 @@
 };
 
 // Buffers all of the data and calls EchoStreamBack() on the parent session.
-class UnidirectionalEchoReadVisitor : public QuicTransportStream::Visitor {
+class UnidirectionalEchoReadVisitor : public WebTransportStreamVisitor {
  public:
   UnidirectionalEchoReadVisitor(QuicTransportSimpleServerSession* session,
                                 QuicTransportStream* stream)
@@ -97,7 +97,7 @@
 };
 
 // Sends supplied data.
-class UnidirectionalEchoWriteVisitor : public QuicTransportStream::Visitor {
+class UnidirectionalEchoWriteVisitor : public WebTransportStreamVisitor {
  public:
   UnidirectionalEchoWriteVisitor(QuicTransportStream* stream,
                                  const std::string& data)