Replace `kAckDecimationDelay` by protocol flag `quic_ack_decimation_delay` so we can experiment with different values.

Similarly, replace `kDefaultDelayedAckTimeMs` by flag `quic_default_delayed_ack_time_ms`.

PiperOrigin-RevId: 628465118
diff --git a/quiche/common/quiche_protocol_flags_list.h b/quiche/common/quiche_protocol_flags_list.h
index 7477f87..bcdec6b 100644
--- a/quiche/common/quiche_protocol_flags_list.h
+++ b/quiche/common/quiche_protocol_flags_list.h
@@ -251,4 +251,16 @@
 QUICHE_PROTOCOL_FLAG(bool, quiche_oghttp2_debug_trace, false,
                      "If true, emits trace logs for HTTP/2 events.")
 
+QUICHE_PROTOCOL_FLAG(
+    float, quic_ack_decimation_delay, 0.25f,
+    "The fraction of a min_rtt when doing ack decimation, this fraction can be "
+    "overridden by connection option AKD3.")
+
+// Uses a 25ms delayed ack timer. Helps with better signaling
+// in low-bandwidth (< ~384 kbps), where an ack is sent per packet.
+// NOTE: If the flag value exceeds half of kMinRetransmissionTimeMs, it will be
+// clamped to that value.
+QUICHE_PROTOCOL_FLAG(int64_t, quic_default_delayed_ack_time_ms, 25,
+                     "Default maximum delayed ack time, in ms.")
+
 #endif
diff --git a/quiche/quic/core/frames/quic_ack_frequency_frame.h b/quiche/quic/core/frames/quic_ack_frequency_frame.h
index 03f8746..660b1a7 100644
--- a/quiche/quic/core/frames/quic_ack_frequency_frame.h
+++ b/quiche/quic/core/frames/quic_ack_frequency_frame.h
@@ -42,7 +42,7 @@
 
   // The maximum time that ack packets can be delayed.
   QuicTime::Delta max_ack_delay =
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(kDefaultPeerDelayedAckTimeMs);
 };
 
 }  // namespace quic
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index d60bede..710890b 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -1126,7 +1126,7 @@
 // and ensure it gets to the server.
 TEST_P(EndToEndTest, SimpleRequestResponseWithAckDelayChange) {
   // Force the ACK delay to be something other than the default.
-  constexpr uint32_t kClientMaxAckDelay = kDefaultDelayedAckTimeMs + 100u;
+  const uint32_t kClientMaxAckDelay = GetDefaultDelayedAckTimeMs() + 100u;
   client_config_.SetMaxAckDelayToSendMs(kClientMaxAckDelay);
   ASSERT_TRUE(Initialize());
 
diff --git a/quiche/quic/core/quic_config.cc b/quiche/quic/core/quic_config.cc
index 04235cf..1ccba2e 100644
--- a/quiche/quic/core/quic_config.cc
+++ b/quiche/quic/core/quic_config.cc
@@ -1010,7 +1010,7 @@
 
   SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
   SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
-  SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
+  SetMaxAckDelayToSendMs(GetDefaultDelayedAckTimeMs());
   SetAckDelayExponentToSend(kDefaultAckDelayExponent);
   SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
   SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
@@ -1042,7 +1042,7 @@
     max_unidirectional_streams_.ToHandshakeMessage(out);
     ack_delay_exponent_.ToHandshakeMessage(out);
   }
-  if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
+  if (max_ack_delay_ms_.GetSendValue() != GetDefaultDelayedAckTimeMs()) {
     // Only send max ack delay if it is using a non-default value, because
     // the default value is used by QuicSentPacketManager if it is not
     // sent during the handshake, and we want to save bytes.
diff --git a/quiche/quic/core/quic_config_test.cc b/quiche/quic/core/quic_config_test.cc
index 9351118..499c647 100644
--- a/quiche/quic/core/quic_config_test.cc
+++ b/quiche/quic/core/quic_config_test.cc
@@ -120,7 +120,7 @@
     return;
   }
   const uint32_t kTestMaxAckDelayMs =
-      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
+      static_cast<uint32_t>(GetDefaultDelayedAckTimeMs() + 1);
   QuicConfig client_config;
   QuicTagVector cgst;
   cgst.push_back(kQBIC);
@@ -187,7 +187,7 @@
       0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
       0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f};
   const uint32_t kTestMaxAckDelayMs =
-      static_cast<uint32_t>(kDefaultDelayedAckTimeMs + 1);
+      static_cast<uint32_t>(GetDefaultDelayedAckTimeMs() + 1);
   QuicConfig server_config;
   QuicTagVector cgst;
   cgst.push_back(kQBIC);
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 2f27ed8..b199c6d 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -1236,7 +1236,7 @@
   }
 
   QuicTime::Delta DefaultDelayedAckTime() {
-    return QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+    return QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   }
 
   const QuicStopWaitingFrame InitStopWaitingFrame(uint64_t least_unacked) {
@@ -12936,7 +12936,7 @@
 
   EXPECT_EQ(captured_frame.packet_tolerance, 10u);
   EXPECT_EQ(captured_frame.max_ack_delay,
-            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+            QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs()));
 
   // Sending packet 102 does not trigger sending another AckFrequencyFrame.
   SendStreamDataToPeer(/*id=*/1, "baz", /*offset=*/6, NO_FIN, nullptr);
@@ -12974,7 +12974,7 @@
 
   EXPECT_EQ(captured_frame.packet_tolerance, 2u);
   EXPECT_EQ(captured_frame.max_ack_delay,
-            QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+            QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs()));
 }
 
 TEST_P(QuicConnectionTest, FastRecoveryOfLostServerHello) {
@@ -15730,8 +15730,8 @@
   connection_.SendStreamDataWithString(0, std::string(10, 'a'), 0, FIN);
 
   // Receives 1-RTT ACK for 0-RTT packet after RTT + ack_delay.
-  clock_.AdvanceTime(
-      kTestRTT + QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs));
+  clock_.AdvanceTime(kTestRTT + QuicTime::Delta::FromMilliseconds(
+                                    GetDefaultDelayedAckTimeMs()));
   EXPECT_EQ(0u, QuicConnectionPeer::NumUndecryptablePackets(&connection_));
   peer_framer_.SetEncrypter(
       ENCRYPTION_FORWARD_SECURE,
@@ -15739,7 +15739,7 @@
   QuicAckFrame ack_frame = InitAckFrame(1);
   // Peer reported ACK delay.
   ack_frame.ack_delay_time =
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   QuicFrames frames;
   frames.push_back(QuicFrame(&ack_frame));
   QuicPacketHeader header =
diff --git a/quiche/quic/core/quic_constants.cc b/quiche/quic/core/quic_constants.cc
index b9594fa..e3cd3ea 100644
--- a/quiche/quic/core/quic_constants.cc
+++ b/quiche/quic/core/quic_constants.cc
@@ -4,6 +4,11 @@
 
 #include "quiche/quic/core/quic_constants.h"
 
+#include <algorithm>
+#include <cstdint>
+
+#include "quiche/quic/platform/api/quic_flags.h"
+
 namespace quic {
 
 const char* const kFinalOffsetHeaderKey = ":final-offset";
@@ -22,4 +27,10 @@
   return kFirstSendingPacketNumber;
 }
 
+int64_t GetDefaultDelayedAckTimeMs() {
+  // The delayed ack time must not be greater than half the min RTO.
+  return std::min<int64_t>(GetQuicFlag(quic_default_delayed_ack_time_ms),
+                           kMinRetransmissionTimeMs / 2);
+}
+
 }  // namespace quic
diff --git a/quiche/quic/core/quic_constants.h b/quiche/quic/core/quic_constants.h
index cb81cd4..b08fe33 100644
--- a/quiche/quic/core/quic_constants.h
+++ b/quiche/quic/core/quic_constants.h
@@ -137,10 +137,12 @@
 // trailing headers over QUIC.
 QUICHE_EXPORT extern const char* const kFinalOffsetHeaderKey;
 
-// Default maximum delayed ack time, in ms.
-// Uses a 25ms delayed ack timer. Helps with better signaling
-// in low-bandwidth (< ~384 kbps), where an ack is sent per packet.
-inline constexpr int64_t kDefaultDelayedAckTimeMs = 25;
+// Returns the local default delayed ack time, in ms.
+QUICHE_EXPORT int64_t GetDefaultDelayedAckTimeMs();
+
+// Delayed ack time that we assume the peer will use by default, in ms. This
+// should be equal to the default value of --quic_default_delayed_ack_time_ms.
+inline constexpr int64_t kDefaultPeerDelayedAckTimeMs = 25;
 
 // Default minimum delayed ack time, in ms (used only for sender control of ack
 // frequency).
@@ -200,9 +202,6 @@
 // define the minimum RTO to 200ms, we will use the same until we have data to
 // support a higher or lower value.
 inline constexpr const int64_t kMinRetransmissionTimeMs = 200;
-// The delayed ack time must not be greater than half the min RTO.
-static_assert(kDefaultDelayedAckTimeMs <= kMinRetransmissionTimeMs / 2,
-              "Delayed ack time must be less than or equal half the MinRTO");
 
 // We define an unsigned 16-bit floating point value, inspired by IEEE floats
 // (http://en.wikipedia.org/wiki/Half_precision_floating-point_format),
@@ -299,8 +298,8 @@
 // This intends to avoid the beginning of slow start, when CWNDs may be
 // rapidly increasing.
 inline constexpr QuicPacketCount kMinReceivedBeforeAckDecimation = 100;
-// One quarter RTT delay when doing ack decimation.
-inline constexpr float kAckDecimationDelay = 0.25;
+// Ask peer to use one quarter RTT delay when doing ack decimation.
+inline constexpr float kPeerAckDecimationDelay = 0.25;
 
 // The default alarm granularity assumed by QUIC code.
 inline constexpr QuicTime::Delta kAlarmGranularity =
diff --git a/quiche/quic/core/quic_received_packet_manager.cc b/quiche/quic/core/quic_received_packet_manager.cc
index 6cef3e4..8d56d51 100644
--- a/quiche/quic/core/quic_received_packet_manager.cc
+++ b/quiche/quic/core/quic_received_packet_manager.cc
@@ -46,12 +46,12 @@
       num_retransmittable_packets_received_since_last_ack_sent_(0),
       min_received_before_ack_decimation_(kMinReceivedBeforeAckDecimation),
       ack_frequency_(kDefaultRetransmittablePacketsBeforeAck),
-      ack_decimation_delay_(kAckDecimationDelay),
+      ack_decimation_delay_(GetQuicFlag(quic_ack_decimation_delay)),
       unlimited_ack_decimation_(false),
       one_immediate_ack_(false),
       ignore_order_(false),
       local_max_ack_delay_(
-          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
+          QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs())),
       ack_timeout_(QuicTime::Zero()),
       time_of_previous_received_packet_(QuicTime::Zero()),
       was_last_packet_missing_(false),
diff --git a/quiche/quic/core/quic_received_packet_manager_test.cc b/quiche/quic/core/quic_received_packet_manager_test.cc
index f79323a..ffc8862 100644
--- a/quiche/quic/core/quic_received_packet_manager_test.cc
+++ b/quiche/quic/core/quic_received_packet_manager_test.cc
@@ -40,7 +40,7 @@
 const bool kInstigateAck = true;
 const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
 const QuicTime::Delta kDelayedAckTime =
-    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+    QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
 
 class QuicReceivedPacketManagerTest : public QuicTest {
  protected:
diff --git a/quiche/quic/core/quic_sent_packet_manager.cc b/quiche/quic/core/quic_sent_packet_manager.cc
index 9dc1048..5b8e3fa 100644
--- a/quiche/quic/core/quic_sent_packet_manager.cc
+++ b/quiche/quic/core/quic_sent_packet_manager.cc
@@ -82,7 +82,7 @@
       largest_mtu_acked_(0),
       handshake_finished_(false),
       peer_max_ack_delay_(
-          QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
+          QuicTime::Delta::FromMilliseconds(kDefaultPeerDelayedAckTimeMs)),
       rtt_updated_(false),
       acked_packets_iter_(last_ack_frame_.packets.rbegin()),
       consecutive_pto_count_(0),
@@ -637,7 +637,7 @@
   frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck;
   auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt()
                                             : rtt_stats_.MinOrInitialRtt();
-  frame.max_ack_delay = rtt * kAckDecimationDelay;
+  frame.max_ack_delay = rtt * kPeerAckDecimationDelay;
   frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_);
   // TODO(haoyuewang) Remove this once kDefaultMinAckDelayTimeMs is updated to
   // 5 ms on the client side.
diff --git a/quiche/quic/core/quic_sent_packet_manager_test.cc b/quiche/quic/core/quic_sent_packet_manager_test.cc
index 5a0c4df..cec6902 100644
--- a/quiche/quic/core/quic_sent_packet_manager_test.cc
+++ b/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -1847,7 +1847,7 @@
   // Verify PTO is correctly set.
   QuicTime::Delta expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   QuicTime packet1_sent_time = clock_.Now();
   EXPECT_EQ(clock_.Now() + expected_pto_delay,
             manager_.GetRetransmissionTime());
@@ -1889,7 +1889,7 @@
       rtt_stats->SmoothedOrInitialRtt() +
       std::max(kPtoRttvarMultiplier * rtt_stats->mean_deviation(),
                QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
 
   // Verify PTO is correctly re-armed based on sent time of packet 4.
   EXPECT_EQ(sent_time + expected_pto_delay, manager_.GetRetransmissionTime());
@@ -1914,7 +1914,7 @@
   // Verify PTO period is correctly set.
   QuicTime::Delta expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   // Verify PTO is set based on left edge.
   QuicTime deadline = packet1_sent_time + expected_pto_delay;
   EXPECT_EQ(deadline, manager_.GetRetransmissionTime());
@@ -2001,7 +2001,7 @@
   // Verify PTO is correctly set based on 2 times rtt var.
   QuicTime::Delta expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   EXPECT_EQ(clock_.Now() + expected_pto_delay,
             manager_.GetRetransmissionTime());
 }
@@ -2109,7 +2109,7 @@
   // is armed by left edge.
   expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   EXPECT_EQ(packet4_sent_time + expected_pto_delay,
             manager_.GetRetransmissionTime());
 }
@@ -2166,7 +2166,7 @@
   manager_.SetHandshakeConfirmed();
   expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   // Verify PTO timeout is now based on packet 3 as handshake is
   // complete/confirmed.
   EXPECT_EQ(packet3_sent_time + expected_pto_delay,
@@ -2188,7 +2188,7 @@
   // Verify PTO is correctly set.
   QuicTime::Delta expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   const QuicTime packet1_sent_time = clock_.Now();
   EXPECT_EQ(packet1_sent_time + expected_pto_delay,
             manager_.GetRetransmissionTime());
@@ -2229,7 +2229,7 @@
       rtt_stats->SmoothedOrInitialRtt() +
       std::max(kPtoRttvarMultiplier * rtt_stats->mean_deviation(),
                QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
 
   // Verify PTO is correctly re-armed based on sent time of packet 4.
   EXPECT_EQ(packet3_sent_time + expected_pto_delay,
@@ -2251,7 +2251,7 @@
   // Verify PTO is correctly set.
   QuicTime::Delta expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   const QuicTime packet1_sent_time = clock_.Now();
   EXPECT_EQ(packet1_sent_time + expected_pto_delay,
             manager_.GetRetransmissionTime());
@@ -2281,7 +2281,7 @@
   // packet3 (right edge).
   expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   QuicTime packet3_sent_time = clock_.Now();
   EXPECT_EQ(packet3_sent_time + expected_pto_delay * 2,
             manager_.GetRetransmissionTime());
@@ -2299,7 +2299,7 @@
       rtt_stats->SmoothedOrInitialRtt() +
       std::max(kPtoRttvarMultiplier * rtt_stats->mean_deviation(),
                QuicTime::Delta::FromMilliseconds(1)) +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
 
   // Verify PTO is correctly re-armed based on sent time of packet 3 (left
   // edge).
@@ -2363,7 +2363,7 @@
   // complete/confirmed.
   expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   EXPECT_EQ(packet3_sent_time + expected_pto_delay,
             manager_.GetRetransmissionTime());
 
@@ -2430,7 +2430,7 @@
   // complete/confirmed.
   expected_pto_delay =
       srtt + kPtoRttvarMultiplier * rtt_stats->mean_deviation() +
-      QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
   EXPECT_EQ(packet3_sent_time + expected_pto_delay,
             manager_.GetRetransmissionTime());
 
diff --git a/quiche/quic/core/uber_received_packet_manager_test.cc b/quiche/quic/core/uber_received_packet_manager_test.cc
index 97b2a80..1a85e8c 100644
--- a/quiche/quic/core/uber_received_packet_manager_test.cc
+++ b/quiche/quic/core/uber_received_packet_manager_test.cc
@@ -31,7 +31,7 @@
 const bool kInstigateAck = true;
 const QuicTime::Delta kMinRttMs = QuicTime::Delta::FromMilliseconds(40);
 const QuicTime::Delta kDelayedAckTime =
-    QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+    QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
 
 EncryptionLevel GetEncryptionLevel(PacketNumberSpace packet_number_space) {
   switch (packet_number_space) {
diff --git a/quiche/quic/test_tools/quic_test_client.cc b/quiche/quic/test_tools/quic_test_client.cc
index edfa0a0..d0d0a2e 100644
--- a/quiche/quic/test_tools/quic_test_client.cc
+++ b/quiche/quic/test_tools/quic_test_client.cc
@@ -860,7 +860,7 @@
   // kWaitDuration is a period of time that is long enough for all delayed
   // acks to be sent and received on the other end.
   const QuicTime::Delta kWaitDuration =
-      4 * QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs);
+      4 * QuicTime::Delta::FromMilliseconds(GetDefaultDelayedAckTimeMs());
 
   const QuicClock* clock = client()->client_session()->connection()->clock();