Split `QuicConnectionTracer` into two interfaces:
- A `QuicPlatformConnectionContext` interface that get notified when a `QuicConnection` becomes active or inactive.
- A new smaller `QuicConnectionTracer` that only contains PrintXXX methods.

This allows subclasses of `QuicPlatformConnectionContext` to save/restore contexts unrelated to tracing, e.g. census information.

PiperOrigin-RevId: 641299648
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index 91bc01d..a879b6c 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -1292,6 +1292,11 @@
   QuicConnectionContext* context() override { return &context_; }
   const QuicConnectionContext* context() const { return &context_; }
 
+  void set_context_listener(
+      std::unique_ptr<QuicConnectionContextListener> listener) {
+    context_.listener.swap(listener);
+  }
+
   void set_tracer(std::unique_ptr<QuicConnectionTracer> tracer) {
     context_.tracer.swap(tracer);
   }
diff --git a/quiche/quic/core/quic_connection_context.cc b/quiche/quic/core/quic_connection_context.cc
index a2b797d..d1feda5 100644
--- a/quiche/quic/core/quic_connection_context.cc
+++ b/quiche/quic/core/quic_connection_context.cc
@@ -20,15 +20,15 @@
     QuicConnectionContext* new_context)
     : old_context_(QuicConnectionContext::Current()) {
   current_context = new_context;
-  if (new_context && new_context->tracer) {
-    new_context->tracer->Activate();
+  if (new_context && new_context->listener) {
+    new_context->listener->Activate();
   }
 }
 
 QuicConnectionContextSwitcher::~QuicConnectionContextSwitcher() {
   QuicConnectionContext* current = QuicConnectionContext::Current();
-  if (current && current->tracer) {
-    current->tracer->Deactivate();
+  if (current && current->listener) {
+    current->listener->Deactivate();
   }
   current_context = old_context_;
 }
diff --git a/quiche/quic/core/quic_connection_context.h b/quiche/quic/core/quic_connection_context.h
index 222910e..37f99d4 100644
--- a/quiche/quic/core/quic_connection_context.h
+++ b/quiche/quic/core/quic_connection_context.h
@@ -5,6 +5,8 @@
 #ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
 #define QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
 
+#include <memory>
+
 #include "absl/strings/str_format.h"
 #include "absl/strings/string_view.h"
 #include "quiche/quic/platform/api/quic_export.h"
@@ -33,23 +35,6 @@
     std::string s = absl::StrFormat(format, args...);
     PrintString(s);
   }
-
- private:
-  friend class QuicConnectionContextSwitcher;
-
-  // Called by QuicConnectionContextSwitcher, when |this| becomes the current
-  // thread's QUIC connection tracer.
-  //
-  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
-  // constructor/destructor, they always come in pairs.
-  virtual void Activate() {}
-
-  // Called by QuicConnectionContextSwitcher, when |this| stops from being the
-  // current thread's QUIC connection tracer.
-  //
-  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
-  // constructor/destructor, they always come in pairs.
-  virtual void Deactivate() {}
 };
 
 // QuicBugListener is a helper class for implementing QUIC_BUG. The QUIC_BUG
@@ -61,6 +46,32 @@
                          absl::string_view bug_message) = 0;
 };
 
+// QuicConnectionContextListener provides the interfaces that are called when
+// a QuicConnection becomes active or inactive. If there are platform-specific
+// preparation or cleanup work needed for the members of QuicConnectionContext
+// to function, those work can be done in the implementation of this interface.
+class QUICHE_EXPORT QuicConnectionContextListener {
+ public:
+  virtual ~QuicConnectionContextListener() = default;
+
+ private:
+  friend class QuicConnectionContextSwitcher;
+
+  // Called by QuicConnectionContextSwitcher when a QUIC connection becomes
+  // active in the current thread.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Activate() = 0;
+
+  // Called by QuicConnectionContextSwitcher when a QUIC connection becomes
+  // inactive in the current thread.
+  //
+  // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
+  // constructor/destructor, they always come in pairs.
+  virtual void Deactivate() = 0;
+};
+
 // QuicConnectionContext is a per-QuicConnection context that includes
 // facilities useable by any part of a QuicConnection. A QuicConnectionContext
 // is owned by a QuicConnection.
@@ -76,6 +87,7 @@
   // function is not called from a 'top-level' QuicConnection function.
   static QuicConnectionContext* Current();
 
+  std::unique_ptr<QuicConnectionContextListener> listener;
   std::unique_ptr<QuicConnectionTracer> tracer;
   std::unique_ptr<QuicBugListener> bug_listener;
 };