Minor changes to make WebTransport over HTTP/3 integration work.

* QuicSpdyClientSession/Stream are now exported into Chrome proper.
* QuicSpdySession sets up a datagram queue observer
* QuicSpdySession provides a virtual method for overriding quic_h3_datagram feature flag.

PiperOrigin-RevId: 367333659
Change-Id: I9c7918c0e6e08c7864179cc36517eabbc5157b13
diff --git a/quic/core/http/quic_spdy_client_session.h b/quic/core/http/quic_spdy_client_session.h
index 345c014..88df049 100644
--- a/quic/core/http/quic_spdy_client_session.h
+++ b/quic/core/http/quic_spdy_client_session.h
@@ -20,7 +20,8 @@
 class QuicConnection;
 class QuicServerId;
 
-class QUIC_NO_EXPORT QuicSpdyClientSession : public QuicSpdyClientSessionBase {
+class QUIC_EXPORT_PRIVATE QuicSpdyClientSession
+    : public QuicSpdyClientSessionBase {
  public:
   // Takes ownership of |connection|. Caller retains ownership of
   // |promised_by_url|.
diff --git a/quic/core/http/quic_spdy_client_stream.h b/quic/core/http/quic_spdy_client_stream.h
index b62f496..2318465 100644
--- a/quic/core/http/quic_spdy_client_stream.h
+++ b/quic/core/http/quic_spdy_client_stream.h
@@ -19,7 +19,7 @@
 
 // All this does right now is send an SPDY request, and aggregate the
 // SPDY response.
-class QUIC_NO_EXPORT QuicSpdyClientStream : public QuicSpdyStream {
+class QUIC_EXPORT_PRIVATE QuicSpdyClientStream : public QuicSpdyStream {
  public:
   QuicSpdyClientStream(QuicStreamId id,
                        QuicSpdyClientSession* session,
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc
index 37db9ac..1694810 100644
--- a/quic/core/http/quic_spdy_session.cc
+++ b/quic/core/http/quic_spdy_session.cc
@@ -474,7 +474,8 @@
                   VersionUsesHttp3(connection->transport_version())
                       ? static_cast<QuicStreamCount>(
                             kHttp3StaticUnidirectionalStreamCount)
-                      : 0u),
+                      : 0u,
+                  std::make_unique<DatagramObserver>(this)),
       send_control_stream_(nullptr),
       receive_control_stream_(nullptr),
       qpack_encoder_receive_stream_(nullptr),
@@ -553,7 +554,7 @@
       qpack_maximum_blocked_streams_;
   settings_.values[SETTINGS_MAX_FIELD_SECTION_SIZE] =
       max_inbound_header_list_size_;
-  if (GetQuicReloadableFlag(quic_h3_datagram) && version().UsesHttp3()) {
+  if (ShouldNegotiateHttp3Datagram() && version().UsesHttp3()) {
     QUIC_RELOADABLE_FLAG_COUNT(quic_h3_datagram);
     settings_.values[SETTINGS_H3_DATAGRAM] = 1;
   }
@@ -923,7 +924,7 @@
 }
 
 bool QuicSpdySession::WillNegotiateWebTransport() {
-  return GetQuicReloadableFlag(quic_h3_datagram) && version().UsesHttp3() &&
+  return ShouldNegotiateHttp3Datagram() && version().UsesHttp3() &&
          ShouldNegotiateWebTransport();
 }
 
@@ -1168,7 +1169,7 @@
                          id));
         return false;
       case SETTINGS_H3_DATAGRAM: {
-        if (!GetQuicReloadableFlag(quic_h3_datagram)) {
+        if (!ShouldNegotiateHttp3Datagram()) {
           break;
         }
         QUIC_DVLOG(1) << ENDPOINT << "SETTINGS_H3_DATAGRAM received with value "
@@ -1855,6 +1856,20 @@
   return stream;
 }
 
+void QuicSpdySession::OnDatagramProcessed(
+    absl::optional<MessageStatus> /*status*/) {
+  // TODO(b/184598230): make this work with multiple datagram flows.
+}
+
+void QuicSpdySession::DatagramObserver::OnDatagramProcessed(
+    absl::optional<MessageStatus> status) {
+  session_->OnDatagramProcessed(status);
+}
+
+bool QuicSpdySession::ShouldNegotiateHttp3Datagram() {
+  return GetQuicReloadableFlag(quic_h3_datagram);
+}
+
 #undef ENDPOINT  // undef for jumbo builds
 
 }  // namespace quic
diff --git a/quic/core/http/quic_spdy_session.h b/quic/core/http/quic_spdy_session.h
index e0bf096..b200484 100644
--- a/quic/core/http/quic_spdy_session.h
+++ b/quic/core/http/quic_spdy_session.h
@@ -553,11 +553,28 @@
   // QuicConnectionVisitorInterface method.
   void BeforeConnectionCloseSent() override;
 
+  // Called whenever a datagram is dequeued or dropped from datagram_queue().
+  virtual void OnDatagramProcessed(absl::optional<MessageStatus> status);
+
+  // Returns true if HTTP/3 datagram extension should be supported.
+  virtual bool ShouldNegotiateHttp3Datagram();
+
  private:
   friend class test::QuicSpdySessionPeer;
 
   class SpdyFramerVisitor;
 
+  // Proxies OnDatagramProcessed() calls to the session.
+  class QUIC_EXPORT_PRIVATE DatagramObserver
+      : public QuicDatagramQueue::Observer {
+   public:
+    explicit DatagramObserver(QuicSpdySession* session) : session_(session) {}
+    void OnDatagramProcessed(absl::optional<MessageStatus> status) override;
+
+   private:
+    QuicSpdySession* session_;  // not owned
+  };
+
   struct QUIC_EXPORT_PRIVATE BufferedWebTransportStream {
     WebTransportSessionId session_id;
     QuicStreamId stream_id;