Add field to NetworkParams for updating BBRv1's exit-startup-on-loss behavior

This CL adds the enable_bbr_exit_startup_on_loss field to quic::SendAlgorithmInterface::NetworkParams.

This new field has a similar effect as the B1AL connection option, but it can be applied to established connections via AdjustNetworkParameters().

Protected by Bool field that is guaranteed to be false: quic::SendAlgorithmInterface::NetworkParams::enable_bbr_exit_startup_on_loss.

PiperOrigin-RevId: 882112082
diff --git a/quiche/quic/core/congestion_control/bbr_sender.cc b/quiche/quic/core/congestion_control/bbr_sender.cc
index ba24e8c..d4a1e93 100644
--- a/quiche/quic/core/congestion_control/bbr_sender.cc
+++ b/quiche/quic/core/congestion_control/bbr_sender.cc
@@ -78,7 +78,9 @@
       recovery_state(sender.recovery_state_),
       recovery_window(sender.recovery_window_),
       last_sample_is_app_limited(sender.last_sample_is_app_limited_),
-      end_of_app_limited_phase(sender.sampler_.end_of_app_limited_phase()) {}
+      end_of_app_limited_phase(sender.sampler_.end_of_app_limited_phase()),
+      exit_startup_on_loss_even_if_app_limited(
+          sender.exit_startup_on_loss_even_if_app_limited_) {}
 
 BbrSender::DebugState::DebugState(const DebugState& state) = default;
 
@@ -298,6 +300,11 @@
   }
 
   if (mode_ == STARTUP) {
+    if (params.enable_bbr_exit_startup_on_loss) {
+      QUIC_CODE_COUNT(quic_bbr_exit_startup_on_loss_network_param_true);
+      exit_startup_on_loss_even_if_app_limited_ = true;
+    }
+
     if (bandwidth.IsZero()) {
       // Ignore bad bandwidth samples.
       return;
diff --git a/quiche/quic/core/congestion_control/bbr_sender.h b/quiche/quic/core/congestion_control/bbr_sender.h
index fccc145..e8b819b 100644
--- a/quiche/quic/core/congestion_control/bbr_sender.h
+++ b/quiche/quic/core/congestion_control/bbr_sender.h
@@ -89,6 +89,8 @@
 
     bool last_sample_is_app_limited;
     QuicPacketNumber end_of_app_limited_phase;
+
+    bool exit_startup_on_loss_even_if_app_limited;
   };
 
   BbrSender(QuicTime now, const RttStats* rtt_stats,
diff --git a/quiche/quic/core/congestion_control/bbr_sender_test.cc b/quiche/quic/core/congestion_control/bbr_sender_test.cc
index 9c85f9b..a419f9c 100644
--- a/quiche/quic/core/congestion_control/bbr_sender_test.cc
+++ b/quiche/quic/core/congestion_control/bbr_sender_test.cc
@@ -1294,6 +1294,29 @@
             sender_->ExportDebugState().congestion_window);
 }
 
+TEST_F(BbrSenderTest, ExitStartupOnLossAdjustedByNetworkParameter) {
+  SetQuicReloadableFlag(quic_bbr_always_exit_startup_on_loss, false);
+
+  sender_ = SetupBbrSender(&bbr_sender_);
+  CreateDefaultSetup();
+
+  EXPECT_FALSE(
+      sender_->ExportDebugState().exit_startup_on_loss_even_if_app_limited)
+      << "Precondition failed: exit-startup-on-loss behavior must be disabled "
+      << "before the test adjusts network parameters.";
+
+  SendAlgorithmInterface::NetworkParams network_params;
+
+  bbr_sender_.connection()->AdjustNetworkParameters(network_params);
+  EXPECT_FALSE(
+      sender_->ExportDebugState().exit_startup_on_loss_even_if_app_limited);
+
+  network_params.enable_bbr_exit_startup_on_loss = true;
+  bbr_sender_.connection()->AdjustNetworkParameters(network_params);
+  EXPECT_TRUE(
+      sender_->ExportDebugState().exit_startup_on_loss_even_if_app_limited);
+}
+
 // Ensures bandwidth estimate does not change after a loss only event.
 // Regression test for b/151239871.
 TEST_F(BbrSenderTest, LossOnlyCongestionEvent) {
diff --git a/quiche/quic/core/congestion_control/send_algorithm_interface.h b/quiche/quic/core/congestion_control/send_algorithm_interface.h
index 47bf5b4..41a4114 100644
--- a/quiche/quic/core/congestion_control/send_algorithm_interface.h
+++ b/quiche/quic/core/congestion_control/send_algorithm_interface.h
@@ -68,6 +68,10 @@
     // the bandwidth and rtt to large values before passing them to the send
     // algorithm.
     bool clamp_cwnd_and_rtt_before_send_algorithm = false;
+    // TODO: b/409269141 - Remove this field when deprecating the experiment.
+    // When true, `BbrSender` will enable the exit-startup-on-loss behavior
+    // without requiring the `kB1AL` connection option.
+    bool enable_bbr_exit_startup_on_loss = false;
   };
 
   static SendAlgorithmInterface* Create(