Replace direct pointers and references to QuicAlarms with a QuicAlarmProxy

This will be used in the multiplexer code, where there is no QuicAlarm corresponding to any individual alarm.

PiperOrigin-RevId: 689906296
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index 843ef84..c2f8412 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -211,12 +211,12 @@
       processing_ack_frame_(false),
       supports_release_time_(false),
       release_time_into_future_(QuicTime::Delta::Zero()),
-      blackhole_detector_(this, &alarms_.network_blackhole_detector_alarm()),
+      blackhole_detector_(this, alarms_.network_blackhole_detector_alarm()),
       idle_network_detector_(this, clock_->ApproximateNow(),
-                             &alarms_.idle_network_detector_alarm()),
+                             alarms_.idle_network_detector_alarm()),
       path_validator_(alarm_factory_, &arena_, this, random_generator_, clock_,
                       &context_),
-      ping_manager_(perspective, this, &alarms_.ping_alarm()),
+      ping_manager_(perspective, this, alarms_.ping_alarm()),
       multi_port_probing_interval_(kDefaultMultiPortProbingInterval),
       connection_id_generator_(generator),
       received_client_addresses_cache_(kMaxReceivedClientAddressSize) {
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index cbb587e..f21bc78 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -2157,40 +2157,43 @@
 
   void GenerateNewOutgoingFlowLabel();
 
-  QuicAlarm& ack_alarm() { return alarms_.ack_alarm(); }
-  const QuicAlarm& ack_alarm() const { return alarms_.ack_alarm(); }
-  QuicAlarm& retransmission_alarm() { return alarms_.retransmission_alarm(); }
-  const QuicAlarm& retransmission_alarm() const {
+  QuicAlarmProxy ack_alarm() { return alarms_.ack_alarm(); }
+  QuicAlarmProxy retransmission_alarm() {
     return alarms_.retransmission_alarm();
   }
-  QuicAlarm& send_alarm() { return alarms_.send_alarm(); }
-  const QuicAlarm& send_alarm() const { return alarms_.send_alarm(); }
-  QuicAlarm& mtu_discovery_alarm() { return alarms_.mtu_discovery_alarm(); }
-  const QuicAlarm& mtu_discovery_alarm() const {
-    return alarms_.mtu_discovery_alarm();
-  }
-  QuicAlarm& process_undecryptable_packets_alarm() {
+  QuicAlarmProxy send_alarm() { return alarms_.send_alarm(); }
+  QuicAlarmProxy mtu_discovery_alarm() { return alarms_.mtu_discovery_alarm(); }
+  QuicAlarmProxy process_undecryptable_packets_alarm() {
     return alarms_.process_undecryptable_packets_alarm();
   }
-  const QuicAlarm& process_undecryptable_packets_alarm() const {
-    return alarms_.process_undecryptable_packets_alarm();
-  }
-  QuicAlarm& discard_previous_one_rtt_keys_alarm() {
+  QuicAlarmProxy discard_previous_one_rtt_keys_alarm() {
     return alarms_.discard_previous_one_rtt_keys_alarm();
   }
-  const QuicAlarm& discard_previous_one_rtt_keys_alarm() const {
-    return alarms_.discard_previous_one_rtt_keys_alarm();
-  }
-  QuicAlarm& discard_zero_rtt_decryption_keys_alarm() {
+  QuicAlarmProxy discard_zero_rtt_decryption_keys_alarm() {
     return alarms_.discard_zero_rtt_decryption_keys_alarm();
   }
-  const QuicAlarm& discard_zero_rtt_decryption_keys_alarm() const {
-    return alarms_.discard_zero_rtt_decryption_keys_alarm();
-  }
-  QuicAlarm& multi_port_probing_alarm() {
+  QuicAlarmProxy multi_port_probing_alarm() {
     return alarms_.multi_port_probing_alarm();
   }
-  const QuicAlarm& multi_port_probing_alarm() const {
+
+  QuicConstAlarmProxy ack_alarm() const { return alarms_.ack_alarm(); }
+  QuicConstAlarmProxy retransmission_alarm() const {
+    return alarms_.retransmission_alarm();
+  }
+  QuicConstAlarmProxy send_alarm() const { return alarms_.send_alarm(); }
+  QuicConstAlarmProxy mtu_discovery_alarm() const {
+    return alarms_.mtu_discovery_alarm();
+  }
+  QuicConstAlarmProxy process_undecryptable_packets_alarm() const {
+    return alarms_.process_undecryptable_packets_alarm();
+  }
+  QuicConstAlarmProxy discard_previous_one_rtt_keys_alarm() const {
+    return alarms_.discard_previous_one_rtt_keys_alarm();
+  }
+  QuicConstAlarmProxy discard_zero_rtt_decryption_keys_alarm() const {
+    return alarms_.discard_zero_rtt_decryption_keys_alarm();
+  }
+  QuicConstAlarmProxy multi_port_probing_alarm() const {
     return alarms_.multi_port_probing_alarm();
   }
 
diff --git a/quiche/quic/core/quic_connection_alarms.h b/quiche/quic/core/quic_connection_alarms.h
index b265fa1..4a40ccf 100644
--- a/quiche/quic/core/quic_connection_alarms.h
+++ b/quiche/quic/core/quic_connection_alarms.h
@@ -5,11 +5,13 @@
 #ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_ALARMS_H_
 #define QUICHE_QUIC_CORE_QUIC_CONNECTION_ALARMS_H_
 
+#include "absl/base/nullability.h"
 #include "quiche/quic/core/quic_alarm.h"
 #include "quiche/quic/core/quic_alarm_factory.h"
 #include "quiche/quic/core/quic_arena_scoped_ptr.h"
 #include "quiche/quic/core/quic_connection_context.h"
 #include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_time.h"
 #include "quiche/common/platform/api/quiche_export.h"
 
 namespace quic {
@@ -33,59 +35,117 @@
   virtual QuicConnectionContext* context() = 0;
 };
 
+namespace test {
+class QuicConnectionAlarmsPeer;
+}
+
 class QUICHE_EXPORT QuicConnectionAlarms {
  public:
+  // Provides a QuicAlarm-like interface to an alarm contained within
+  // QuicConnectionAlarms.
+  class AlarmProxy {
+   public:
+    explicit AlarmProxy(absl::Nonnull<QuicAlarm*> alarm) : alarm_(alarm) {}
+
+    bool IsSet() const { return alarm_->IsSet(); }
+    QuicTime deadline() const { return alarm_->deadline(); }
+    bool IsPermanentlyCancelled() const {
+      return alarm_->IsPermanentlyCancelled();
+    }
+
+    void Set(QuicTime new_deadline) { alarm_->Set(new_deadline); }
+    void Update(QuicTime new_deadline, QuicTime::Delta granularity) {
+      alarm_->Update(new_deadline, granularity);
+    }
+    void Cancel() { alarm_->Cancel(); }
+    void PermanentCancel() { alarm_->PermanentCancel(); }
+
+   private:
+    friend class ::quic::test::QuicConnectionAlarmsPeer;
+
+    absl::Nonnull<QuicAlarm*> alarm_;
+  };
+  class ConstAlarmProxy {
+   public:
+    explicit ConstAlarmProxy(const QuicAlarm* alarm) : alarm_(alarm) {}
+
+    bool IsSet() const { return alarm_->IsSet(); }
+    QuicTime deadline() const { return alarm_->deadline(); }
+    bool IsPermanentlyCancelled() const {
+      return alarm_->IsPermanentlyCancelled();
+    }
+
+   private:
+    friend class ::quic::test::QuicConnectionAlarmsPeer;
+
+    const QuicAlarm* alarm_;
+  };
+
   QuicConnectionAlarms(QuicConnectionAlarmsDelegate* delegate,
                        QuicAlarmFactory& alarm_factory,
                        QuicConnectionArena& arena);
 
-  QuicAlarm& ack_alarm() { return *ack_alarm_; }
-  QuicAlarm& retransmission_alarm() { return *retransmission_alarm_; }
-  QuicAlarm& send_alarm() { return *send_alarm_; }
-  QuicAlarm& mtu_discovery_alarm() { return *mtu_discovery_alarm_; }
-  QuicAlarm& process_undecryptable_packets_alarm() {
-    return *process_undecryptable_packets_alarm_;
+  AlarmProxy ack_alarm() { return AlarmProxy(ack_alarm_.get()); }
+  AlarmProxy retransmission_alarm() {
+    return AlarmProxy(retransmission_alarm_.get());
   }
-  QuicAlarm& discard_previous_one_rtt_keys_alarm() {
-    return *discard_previous_one_rtt_keys_alarm_;
+  AlarmProxy send_alarm() { return AlarmProxy(send_alarm_.get()); }
+  AlarmProxy mtu_discovery_alarm() {
+    return AlarmProxy(mtu_discovery_alarm_.get());
   }
-  QuicAlarm& discard_zero_rtt_decryption_keys_alarm() {
-    return *discard_zero_rtt_decryption_keys_alarm_;
+  AlarmProxy process_undecryptable_packets_alarm() {
+    return AlarmProxy(process_undecryptable_packets_alarm_.get());
   }
-  QuicAlarm& multi_port_probing_alarm() { return *multi_port_probing_alarm_; }
-  QuicAlarm& idle_network_detector_alarm() {
-    return *idle_network_detector_alarm_;
+  AlarmProxy discard_previous_one_rtt_keys_alarm() {
+    return AlarmProxy(discard_previous_one_rtt_keys_alarm_.get());
   }
-  QuicAlarm& network_blackhole_detector_alarm() {
-    return *network_blackhole_detector_alarm_;
+  AlarmProxy discard_zero_rtt_decryption_keys_alarm() {
+    return AlarmProxy(discard_zero_rtt_decryption_keys_alarm_.get());
   }
-  QuicAlarm& ping_alarm() { return *ping_alarm_; }
+  AlarmProxy multi_port_probing_alarm() {
+    return AlarmProxy(multi_port_probing_alarm_.get());
+  }
+  AlarmProxy idle_network_detector_alarm() {
+    return AlarmProxy(idle_network_detector_alarm_.get());
+  }
+  AlarmProxy network_blackhole_detector_alarm() {
+    return AlarmProxy(network_blackhole_detector_alarm_.get());
+  }
+  AlarmProxy ping_alarm() { return AlarmProxy(ping_alarm_.get()); }
 
-  const QuicAlarm& ack_alarm() const { return *ack_alarm_; }
-  const QuicAlarm& retransmission_alarm() const {
-    return *retransmission_alarm_;
+  ConstAlarmProxy ack_alarm() const {
+    return ConstAlarmProxy(ack_alarm_.get());
   }
-  const QuicAlarm& send_alarm() const { return *send_alarm_; }
-  const QuicAlarm& mtu_discovery_alarm() const { return *mtu_discovery_alarm_; }
-  const QuicAlarm& process_undecryptable_packets_alarm() const {
-    return *process_undecryptable_packets_alarm_;
+  ConstAlarmProxy retransmission_alarm() const {
+    return ConstAlarmProxy(retransmission_alarm_.get());
   }
-  const QuicAlarm& discard_previous_one_rtt_keys_alarm() const {
-    return *discard_previous_one_rtt_keys_alarm_;
+  ConstAlarmProxy send_alarm() const {
+    return ConstAlarmProxy(send_alarm_.get());
   }
-  const QuicAlarm& discard_zero_rtt_decryption_keys_alarm() const {
-    return *discard_zero_rtt_decryption_keys_alarm_;
+  ConstAlarmProxy mtu_discovery_alarm() const {
+    return ConstAlarmProxy(mtu_discovery_alarm_.get());
   }
-  const QuicAlarm& multi_port_probing_alarm() const {
-    return *multi_port_probing_alarm_;
+  ConstAlarmProxy process_undecryptable_packets_alarm() const {
+    return ConstAlarmProxy(process_undecryptable_packets_alarm_.get());
   }
-  const QuicAlarm& idle_network_detector_alarm() const {
-    return *idle_network_detector_alarm_;
+  ConstAlarmProxy discard_previous_one_rtt_keys_alarm() const {
+    return ConstAlarmProxy(discard_previous_one_rtt_keys_alarm_.get());
   }
-  const QuicAlarm& network_blackhole_detector_alarm() const {
-    return *network_blackhole_detector_alarm_;
+  ConstAlarmProxy discard_zero_rtt_decryption_keys_alarm() const {
+    return ConstAlarmProxy(discard_zero_rtt_decryption_keys_alarm_.get());
   }
-  const QuicAlarm& ping_alarm() const { return *ping_alarm_; }
+  ConstAlarmProxy multi_port_probing_alarm() const {
+    return ConstAlarmProxy(multi_port_probing_alarm_.get());
+  }
+  ConstAlarmProxy idle_network_detector_alarm() const {
+    return ConstAlarmProxy(idle_network_detector_alarm_.get());
+  }
+  ConstAlarmProxy network_blackhole_detector_alarm() const {
+    return ConstAlarmProxy(network_blackhole_detector_alarm_.get());
+  }
+  ConstAlarmProxy ping_alarm() const {
+    return ConstAlarmProxy(ping_alarm_.get());
+  }
 
  private:
   // An alarm that fires when an ACK should be sent to the peer.
@@ -117,6 +177,9 @@
   QuicArenaScopedPtr<QuicAlarm> ping_alarm_;
 };
 
+using QuicAlarmProxy = QuicConnectionAlarms::AlarmProxy;
+using QuicConstAlarmProxy = QuicConnectionAlarms::ConstAlarmProxy;
+
 }  // namespace quic
 
 #endif  // QUICHE_QUIC_CORE_QUIC_CONNECTION_ALARMS_H_
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index ae219f3..9d5a937 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -427,54 +427,49 @@
         .WillRepeatedly(Return(QuicBandwidth::Infinite()));
   }
 
-  TestAlarmFactory::TestAlarm* GetAckAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetAckAlarm(this));
+  QuicTestAlarmProxy GetAckAlarm() {
+    return QuicTestAlarmProxy(QuicConnectionPeer::GetAckAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetPingAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetPingAlarm(this));
+  QuicTestAlarmProxy GetPingAlarm() {
+    return QuicTestAlarmProxy(QuicConnectionPeer::GetPingAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetRetransmissionAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetRetransmissionAlarm(this));
+  QuicTestAlarmProxy GetRetransmissionAlarm() {
+    return QuicTestAlarmProxy(QuicConnectionPeer::GetRetransmissionAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetSendAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetSendAlarm(this));
+  QuicTestAlarmProxy GetSendAlarm() {
+    return QuicTestAlarmProxy(QuicConnectionPeer::GetSendAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetTimeoutAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetIdleNetworkDetectorAlarm(this));
+  QuicTestAlarmProxy GetTimeoutAlarm() {
+    return QuicTestAlarmProxy(
+        QuicConnectionPeer::GetIdleNetworkDetectorAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetMtuDiscoveryAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
+  QuicTestAlarmProxy GetMtuDiscoveryAlarm() {
+    return QuicTestAlarmProxy(QuicConnectionPeer::GetMtuDiscoveryAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetProcessUndecryptablePacketsAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(this));
+  QuicTestAlarmProxy GetProcessUndecryptablePacketsAlarm() {
+    return QuicTestAlarmProxy(
+        QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetDiscardPreviousOneRttKeysAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(this));
+  QuicTestAlarmProxy GetDiscardPreviousOneRttKeysAlarm() {
+    return QuicTestAlarmProxy(
+        QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetDiscardZeroRttDecryptionKeysAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(this));
+  QuicTestAlarmProxy GetDiscardZeroRttDecryptionKeysAlarm() {
+    return QuicTestAlarmProxy(
+        QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetBlackholeDetectorAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetBlackholeDetectorAlarm(this));
+  QuicTestAlarmProxy GetBlackholeDetectorAlarm() {
+    return QuicTestAlarmProxy(
+        QuicConnectionPeer::GetBlackholeDetectorAlarm(this));
   }
 
   TestAlarmFactory::TestAlarm* GetRetirePeerIssuedConnectionIdAlarm() {
@@ -487,9 +482,9 @@
         QuicConnectionPeer::GetRetireSelfIssuedConnectionIdAlarm(this));
   }
 
-  TestAlarmFactory::TestAlarm* GetMultiPortProbingAlarm() {
-    return reinterpret_cast<TestAlarmFactory::TestAlarm*>(
-        &QuicConnectionPeer::GetMultiPortProbingAlarm(this));
+  QuicTestAlarmProxy GetMultiPortProbingAlarm() {
+    return QuicTestAlarmProxy(
+        QuicConnectionPeer::GetMultiPortProbingAlarm(this));
   }
 
   void PathDegradingTimeout() {
@@ -11581,8 +11576,7 @@
   ;
   ProcessAckPacket(1, &frame);
   EXPECT_TRUE(connection_.BlackholeDetectionInProgress());
-  QuicAlarm* retransmission_alarm = connection_.GetRetransmissionAlarm();
-  EXPECT_TRUE(retransmission_alarm->IsSet());
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 
   // ACK packet 1 - 5 and 7.
   QuicAckFrame frame2 =
diff --git a/quiche/quic/core/quic_idle_network_detector.cc b/quiche/quic/core/quic_idle_network_detector.cc
index 211b2e1..1d5db46 100644
--- a/quiche/quic/core/quic_idle_network_detector.cc
+++ b/quiche/quic/core/quic_idle_network_detector.cc
@@ -19,14 +19,15 @@
 }  // namespace
 
 QuicIdleNetworkDetector::QuicIdleNetworkDetector(Delegate* delegate,
-                                                 QuicTime now, QuicAlarm* alarm)
+                                                 QuicTime now,
+                                                 QuicAlarmProxy alarm)
     : delegate_(delegate),
       start_time_(now),
       handshake_timeout_(QuicTime::Delta::Infinite()),
       time_of_last_received_packet_(now),
       time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
       idle_network_timeout_(QuicTime::Delta::Infinite()),
-      alarm_(*alarm) {}
+      alarm_(alarm) {}
 
 void QuicIdleNetworkDetector::OnAlarm() {
   if (handshake_timeout_.IsInfinite()) {
diff --git a/quiche/quic/core/quic_idle_network_detector.h b/quiche/quic/core/quic_idle_network_detector.h
index 5661e37..d6ea7a5 100644
--- a/quiche/quic/core/quic_idle_network_detector.h
+++ b/quiche/quic/core/quic_idle_network_detector.h
@@ -7,6 +7,7 @@
 
 #include "quiche/quic/core/quic_alarm.h"
 #include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_connection_alarms.h"
 #include "quiche/quic/core/quic_one_block_arena.h"
 #include "quiche/quic/core/quic_time.h"
 #include "quiche/quic/platform/api/quic_export.h"
@@ -36,7 +37,8 @@
     virtual void OnIdleNetworkDetected() = 0;
   };
 
-  QuicIdleNetworkDetector(Delegate* delegate, QuicTime now, QuicAlarm* alarm);
+  QuicIdleNetworkDetector(Delegate* delegate, QuicTime now,
+                          QuicAlarmProxy alarm);
 
   void OnAlarm();
 
@@ -104,7 +106,7 @@
   // Idle network timeout. Infinite means no idle network timeout.
   QuicTime::Delta idle_network_timeout_;
 
-  QuicAlarm& alarm_;
+  QuicAlarmProxy alarm_;
 
   bool shorter_idle_timeout_on_sent_packet_ = false;
 
diff --git a/quiche/quic/core/quic_idle_network_detector_test.cc b/quiche/quic/core/quic_idle_network_detector_test.cc
index d34d8cb..458bc27 100644
--- a/quiche/quic/core/quic_idle_network_detector_test.cc
+++ b/quiche/quic/core/quic_idle_network_detector_test.cc
@@ -11,6 +11,7 @@
 #include "quiche/quic/platform/api/quic_flags.h"
 #include "quiche/quic/platform/api/quic_test.h"
 #include "quiche/quic/test_tools/mock_quic_connection_alarms.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
 #include "quiche/quic/test_tools/quic_test_utils.h"
 
 namespace quic {
@@ -18,7 +19,7 @@
 
 class QuicIdleNetworkDetectorTestPeer {
  public:
-  static QuicAlarm& GetAlarm(QuicIdleNetworkDetector* detector) {
+  static QuicAlarmProxy GetAlarm(QuicIdleNetworkDetector* detector) {
     return detector->alarm_;
   }
 };
@@ -36,10 +37,9 @@
   QuicIdleNetworkDetectorTest()
       : alarms_(&connection_alarms_delegate_, alarm_factory_, arena_),
         detector_(&delegate_, clock_.Now() + QuicTimeDelta::FromSeconds(1),
-                  &alarms_.idle_network_detector_alarm()) {
+                  alarms_.idle_network_detector_alarm()),
+        alarm_(alarms_.idle_network_detector_alarm()) {
     clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
-    alarm_ = static_cast<MockAlarmFactory::TestAlarm*>(
-        &alarms_.idle_network_detector_alarm());
     ON_CALL(connection_alarms_delegate_, OnIdleDetectorAlarm())
         .WillByDefault([&] { detector_.OnAlarm(); });
   }
@@ -52,7 +52,7 @@
   QuicConnectionAlarms alarms_;
   MockClock clock_;
   QuicIdleNetworkDetector detector_;
-  MockAlarmFactory::TestAlarm* alarm_;
+  QuicTestAlarmProxy alarm_;
 };
 
 TEST_F(QuicIdleNetworkDetectorTest,
diff --git a/quiche/quic/core/quic_network_blackhole_detector.cc b/quiche/quic/core/quic_network_blackhole_detector.cc
index 99e71fa..99cdd04 100644
--- a/quiche/quic/core/quic_network_blackhole_detector.cc
+++ b/quiche/quic/core/quic_network_blackhole_detector.cc
@@ -6,13 +6,14 @@
 
 #include <algorithm>
 
+#include "quiche/quic/core/quic_connection_alarms.h"
 #include "quiche/quic/core/quic_constants.h"
 
 namespace quic {
 
 QuicNetworkBlackholeDetector::QuicNetworkBlackholeDetector(Delegate* delegate,
-                                                           QuicAlarm* alarm)
-    : delegate_(delegate), alarm_(*alarm) {}
+                                                           QuicAlarmProxy alarm)
+    : delegate_(delegate), alarm_(alarm) {}
 
 void QuicNetworkBlackholeDetector::OnAlarm() {
   QuicTime next_deadline = GetEarliestDeadline();
@@ -91,7 +92,7 @@
                    path_mtu_reduction_deadline_});
 }
 
-void QuicNetworkBlackholeDetector::UpdateAlarm() const {
+void QuicNetworkBlackholeDetector::UpdateAlarm() {
   // If called after OnBlackholeDetected(), the alarm may have been permanently
   // cancelled and is not safe to be armed again.
   if (alarm_.IsPermanentlyCancelled()) {
diff --git a/quiche/quic/core/quic_network_blackhole_detector.h b/quiche/quic/core/quic_network_blackhole_detector.h
index e160a62..97b7f23 100644
--- a/quiche/quic/core/quic_network_blackhole_detector.h
+++ b/quiche/quic/core/quic_network_blackhole_detector.h
@@ -5,9 +5,7 @@
 #ifndef QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
 #define QUICHE_QUIC_CORE_QUIC_NETWORK_BLACKHOLE_DETECTOR_H_
 
-#include "quiche/quic/core/quic_alarm.h"
-#include "quiche/quic/core/quic_alarm_factory.h"
-#include "quiche/quic/core/quic_one_block_arena.h"
+#include "quiche/quic/core/quic_connection_alarms.h"
 #include "quiche/quic/core/quic_time.h"
 #include "quiche/quic/platform/api/quic_export.h"
 #include "quiche/quic/platform/api/quic_flags.h"
@@ -40,7 +38,7 @@
     virtual void OnPathMtuReductionDetected() = 0;
   };
 
-  QuicNetworkBlackholeDetector(Delegate* delegate, QuicAlarm* alarm);
+  QuicNetworkBlackholeDetector(Delegate* delegate, QuicAlarmProxy alarm);
 
   // Called to stop all detections. If |permanent|, the alarm will be cancelled
   // permanently and future calls to RestartDetection will be no-op.
@@ -67,7 +65,7 @@
   QuicTime GetLastDeadline() const;
 
   // Update alarm to the next deadline.
-  void UpdateAlarm() const;
+  void UpdateAlarm();
 
   Delegate* delegate_;  // Not owned.
 
@@ -81,7 +79,7 @@
   // path mtu reduction detection is in progress.
   QuicTime path_mtu_reduction_deadline_ = QuicTime::Zero();
 
-  QuicAlarm& alarm_;
+  QuicAlarmProxy alarm_;
 };
 
 }  // namespace quic
diff --git a/quiche/quic/core/quic_network_blackhole_detector_test.cc b/quiche/quic/core/quic_network_blackhole_detector_test.cc
index cad8534..7849ff2 100644
--- a/quiche/quic/core/quic_network_blackhole_detector_test.cc
+++ b/quiche/quic/core/quic_network_blackhole_detector_test.cc
@@ -8,6 +8,7 @@
 #include "quiche/quic/core/quic_one_block_arena.h"
 #include "quiche/quic/platform/api/quic_test.h"
 #include "quiche/quic/test_tools/mock_quic_connection_alarms.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
 #include "quiche/quic/test_tools/quic_test_utils.h"
 
 namespace quic {
@@ -15,8 +16,8 @@
 
 class QuicNetworkBlackholeDetectorPeer {
  public:
-  static QuicAlarm* GetAlarm(QuicNetworkBlackholeDetector* detector) {
-    return &detector->alarm_;
+  static QuicAlarmProxy GetAlarm(QuicNetworkBlackholeDetector* detector) {
+    return detector->alarm_;
   }
 };
 
@@ -36,9 +37,8 @@
  public:
   QuicNetworkBlackholeDetectorTest()
       : alarms_(&connection_alarms_delegate_, alarm_factory_, arena_),
-        detector_(&delegate_, &alarms_.network_blackhole_detector_alarm()),
-        alarm_(static_cast<MockAlarmFactory::TestAlarm*>(
-            QuicNetworkBlackholeDetectorPeer::GetAlarm(&detector_))),
+        detector_(&delegate_, alarms_.network_blackhole_detector_alarm()),
+        alarm_(QuicNetworkBlackholeDetectorPeer::GetAlarm(&detector_)),
         path_degrading_delay_(
             QuicTime::Delta::FromSeconds(kPathDegradingDelayInSeconds)),
         path_mtu_reduction_delay_(
@@ -65,7 +65,7 @@
 
   QuicNetworkBlackholeDetector detector_;
 
-  MockAlarmFactory::TestAlarm* alarm_;
+  QuicTestAlarmProxy alarm_;
   MockClock clock_;
   const QuicTime::Delta path_degrading_delay_;
   const QuicTime::Delta path_mtu_reduction_delay_;
diff --git a/quiche/quic/core/quic_ping_manager.cc b/quiche/quic/core/quic_ping_manager.cc
index e0c7e20..533dd10 100644
--- a/quiche/quic/core/quic_ping_manager.cc
+++ b/quiche/quic/core/quic_ping_manager.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "quiche/quic/core/quic_connection_alarms.h"
 #include "quiche/quic/platform/api/quic_flags.h"
 
 namespace quic {
@@ -20,8 +21,8 @@
 }  // namespace
 
 QuicPingManager::QuicPingManager(Perspective perspective, Delegate* delegate,
-                                 QuicAlarm* alarm)
-    : perspective_(perspective), delegate_(delegate), alarm_(*alarm) {}
+                                 QuicAlarmProxy alarm)
+    : perspective_(perspective), delegate_(delegate), alarm_(alarm) {}
 
 void QuicPingManager::SetAlarm(QuicTime now, bool should_keep_alive,
                                bool has_in_flight_packets) {
diff --git a/quiche/quic/core/quic_ping_manager.h b/quiche/quic/core/quic_ping_manager.h
index a62f827..3250416 100644
--- a/quiche/quic/core/quic_ping_manager.h
+++ b/quiche/quic/core/quic_ping_manager.h
@@ -7,6 +7,7 @@
 
 #include "quiche/quic/core/quic_alarm.h"
 #include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_connection_alarms.h"
 #include "quiche/quic/core/quic_constants.h"
 #include "quiche/quic/core/quic_one_block_arena.h"
 #include "quiche/quic/core/quic_time.h"
@@ -38,7 +39,7 @@
   };
 
   QuicPingManager(Perspective perspective, Delegate* delegate,
-                  QuicAlarm* alarm);
+                  QuicAlarmProxy alarm);
 
   // Called to set |alarm_|.
   void SetAlarm(QuicTime now, bool should_keep_alive,
@@ -99,7 +100,7 @@
 
   QuicTime keep_alive_deadline_ = QuicTime::Zero();
 
-  QuicAlarm& alarm_;
+  QuicAlarmProxy alarm_;
 };
 
 }  // namespace quic
diff --git a/quiche/quic/core/quic_ping_manager_test.cc b/quiche/quic/core/quic_ping_manager_test.cc
index fa65054..4b82224 100644
--- a/quiche/quic/core/quic_ping_manager_test.cc
+++ b/quiche/quic/core/quic_ping_manager_test.cc
@@ -8,6 +8,7 @@
 #include "quiche/quic/core/quic_one_block_arena.h"
 #include "quiche/quic/platform/api/quic_test.h"
 #include "quiche/quic/test_tools/mock_quic_connection_alarms.h"
+#include "quiche/quic/test_tools/quic_connection_peer.h"
 #include "quiche/quic/test_tools/quic_test_utils.h"
 
 namespace quic {
@@ -15,8 +16,8 @@
 
 class QuicPingManagerPeer {
  public:
-  static QuicAlarm* GetAlarm(QuicPingManager* manager) {
-    return &manager->alarm_;
+  static QuicAlarmProxy GetAlarm(QuicPingManager* manager) {
+    return manager->alarm_;
   }
 
   static void SetPerspective(QuicPingManager* manager,
@@ -40,9 +41,8 @@
  public:
   QuicPingManagerTest()
       : alarms_(&connection_alarms_delegate_, alarm_factory_, arena_),
-        manager_(Perspective::IS_CLIENT, &delegate_, &alarms_.ping_alarm()),
-        alarm_(static_cast<MockAlarmFactory::TestAlarm*>(
-            QuicPingManagerPeer::GetAlarm(&manager_))) {
+        manager_(Perspective::IS_CLIENT, &delegate_, alarms_.ping_alarm()),
+        alarm_(QuicPingManagerPeer::GetAlarm(&manager_)) {
     clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
     ON_CALL(connection_alarms_delegate_, OnPingAlarm()).WillByDefault([&] {
       manager_.OnAlarm();
@@ -57,7 +57,7 @@
   MockAlarmFactory alarm_factory_;
   QuicConnectionAlarms alarms_;
   QuicPingManager manager_;
-  MockAlarmFactory::TestAlarm* alarm_;
+  QuicTestAlarmProxy alarm_;
 };
 
 TEST_F(QuicPingManagerTest, KeepAliveTimeout) {
diff --git a/quiche/quic/test_tools/quic_connection_peer.cc b/quiche/quic/test_tools/quic_connection_peer.cc
index 6a47bfa..8b728ef 100644
--- a/quiche/quic/test_tools/quic_connection_peer.cc
+++ b/quiche/quic/test_tools/quic_connection_peer.cc
@@ -7,8 +7,10 @@
 #include <memory>
 #include <string>
 
+
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/congestion_control/send_algorithm_interface.h"
+#include "quiche/quic/core/quic_connection_alarms.h"
 #include "quiche/quic/core/quic_packet_writer.h"
 #include "quiche/quic/core/quic_received_packet_manager.h"
 #include "quiche/quic/platform/api/quic_flags.h"
@@ -16,11 +18,18 @@
 #include "quiche/quic/test_tools/quic_connection_id_manager_peer.h"
 #include "quiche/quic/test_tools/quic_framer_peer.h"
 #include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "quiche/quic/test_tools/quic_test_utils.h"
 
 namespace quic {
 namespace test {
 
 // static
+void QuicConnectionAlarmsPeer::Fire(QuicAlarmProxy alarm) {
+  auto* real_alarm = static_cast<TestAlarmFactory::TestAlarm*>(alarm.alarm_);
+  real_alarm->Fire();
+}
+
+// static
 void QuicConnectionPeer::SetSendAlgorithm(
     QuicConnection* connection, SendAlgorithmInterface* send_algorithm) {
   GetSentPacketManager(connection)->SetSendAlgorithm(send_algorithm);
@@ -120,46 +129,46 @@
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetAckAlarm(QuicConnection* connection) {
+QuicAlarmProxy QuicConnectionPeer::GetAckAlarm(QuicConnection* connection) {
   return connection->alarms_.ack_alarm();
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetPingAlarm(QuicConnection* connection) {
+QuicAlarmProxy QuicConnectionPeer::GetPingAlarm(QuicConnection* connection) {
   return connection->alarms_.ping_alarm();
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetRetransmissionAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetRetransmissionAlarm(
     QuicConnection* connection) {
   return connection->alarms_.retransmission_alarm();
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetSendAlarm(QuicConnection* connection) {
+QuicAlarmProxy QuicConnectionPeer::GetSendAlarm(QuicConnection* connection) {
   return connection->alarms_.send_alarm();
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetMtuDiscoveryAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetMtuDiscoveryAlarm(
     QuicConnection* connection) {
   return connection->alarms_.mtu_discovery_alarm();
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetProcessUndecryptablePacketsAlarm(
     QuicConnection* connection) {
   return connection->alarms_.process_undecryptable_packets_alarm();
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetDiscardPreviousOneRttKeysAlarm(
     QuicConnection* connection) {
   return connection->alarms_.discard_previous_one_rtt_keys_alarm();
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetDiscardZeroRttDecryptionKeysAlarm(
     QuicConnection* connection) {
   return connection->alarms_.discard_zero_rtt_decryption_keys_alarm();
 }
@@ -324,7 +333,7 @@
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetBlackholeDetectorAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetBlackholeDetectorAlarm(
     QuicConnection* connection) {
   return connection->alarms_.network_blackhole_detector_alarm();
 }
@@ -354,7 +363,7 @@
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetIdleNetworkDetectorAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetIdleNetworkDetectorAlarm(
     QuicConnection* connection) {
   return connection->alarms_.idle_network_detector_alarm();
 }
@@ -366,7 +375,7 @@
 }
 
 // static
-QuicAlarm& QuicConnectionPeer::GetMultiPortProbingAlarm(
+QuicAlarmProxy QuicConnectionPeer::GetMultiPortProbingAlarm(
     QuicConnection* connection) {
   return connection->alarms_.multi_port_probing_alarm();
 }
diff --git a/quiche/quic/test_tools/quic_connection_peer.h b/quiche/quic/test_tools/quic_connection_peer.h
index 2eff481..50babe7 100644
--- a/quiche/quic/test_tools/quic_connection_peer.h
+++ b/quiche/quic/test_tools/quic_connection_peer.h
@@ -9,6 +9,7 @@
 
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_alarms.h"
 #include "quiche/quic/core/quic_connection_id.h"
 #include "quiche/quic/core/quic_connection_stats.h"
 #include "quiche/quic/core/quic_packets.h"
@@ -31,6 +32,21 @@
 
 namespace test {
 
+class QuicConnectionAlarmsPeer {
+ public:
+  static void Fire(QuicAlarmProxy alarm);
+};
+
+class QuicTestAlarmProxy : public QuicAlarmProxy {
+ public:
+  explicit QuicTestAlarmProxy(QuicAlarmProxy proxy) : QuicAlarmProxy(proxy) {}
+
+  void Fire() { QuicConnectionAlarmsPeer::Fire(*this); }
+
+  // TODO: b/375591469 - fix all references to this method, and remove it.
+  QuicTestAlarmProxy* operator->() { return this; }
+};
+
 // Peer to make public a number of otherwise private QuicConnection methods.
 class QuicConnectionPeer {
  public:
@@ -78,16 +94,16 @@
 
   static QuicFramer* GetFramer(QuicConnection* connection);
 
-  static QuicAlarm& GetAckAlarm(QuicConnection* connection);
-  static QuicAlarm& GetPingAlarm(QuicConnection* connection);
-  static QuicAlarm& GetRetransmissionAlarm(QuicConnection* connection);
-  static QuicAlarm& GetSendAlarm(QuicConnection* connection);
-  static QuicAlarm& GetMtuDiscoveryAlarm(QuicConnection* connection);
-  static QuicAlarm& GetProcessUndecryptablePacketsAlarm(
+  static QuicAlarmProxy GetAckAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetPingAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetRetransmissionAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetSendAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetMtuDiscoveryAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetProcessUndecryptablePacketsAlarm(
       QuicConnection* connection);
-  static QuicAlarm& GetDiscardPreviousOneRttKeysAlarm(
+  static QuicAlarmProxy GetDiscardPreviousOneRttKeysAlarm(
       QuicConnection* connection);
-  static QuicAlarm& GetDiscardZeroRttDecryptionKeysAlarm(
+  static QuicAlarmProxy GetDiscardZeroRttDecryptionKeysAlarm(
       QuicConnection* connection);
   static QuicAlarm* GetRetirePeerIssuedConnectionIdAlarm(
       QuicConnection* connection);
@@ -136,7 +152,7 @@
   static QuicNetworkBlackholeDetector& GetBlackholeDetector(
       QuicConnection* connection);
 
-  static QuicAlarm& GetBlackholeDetectorAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetBlackholeDetectorAlarm(QuicConnection* connection);
 
   static QuicTime GetPathDegradingDeadline(QuicConnection* connection);
 
@@ -145,7 +161,7 @@
   static QuicTime GetPathMtuReductionDetectionDeadline(
       QuicConnection* connection);
 
-  static QuicAlarm& GetIdleNetworkDetectorAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetIdleNetworkDetectorAlarm(QuicConnection* connection);
 
   static QuicTime GetIdleNetworkDeadline(QuicConnection* connection);
 
@@ -220,7 +236,7 @@
 
   static void FlushCoalescedPacket(QuicConnection* connection);
 
-  static QuicAlarm& GetMultiPortProbingAlarm(QuicConnection* connection);
+  static QuicAlarmProxy GetMultiPortProbingAlarm(QuicConnection* connection);
 
   static void SetInProbeTimeOut(QuicConnection* connection, bool value);
 
diff --git a/quiche/quic/test_tools/quic_test_utils.h b/quiche/quic/test_tools/quic_test_utils.h
index 3f675f0..7842c5a 100644
--- a/quiche/quic/test_tools/quic_test_utils.h
+++ b/quiche/quic/test_tools/quic_test_utils.h
@@ -568,15 +568,7 @@
 
 class TestAlarmFactory : public QuicAlarmFactory {
  public:
-  class TestAlarm : public QuicAlarm {
-   public:
-    explicit TestAlarm(QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
-        : QuicAlarm(std::move(delegate)) {}
-
-    void SetImpl() override {}
-    void CancelImpl() override {}
-    using QuicAlarm::Fire;
-  };
+  using TestAlarm = MockAlarmFactory::TestAlarm;
 
   TestAlarmFactory() {}
   TestAlarmFactory(const TestAlarmFactory&) = delete;