Add QuicStreamsBlockedFrame and QuicMaxStreamsFrame classes

There are two main parts to this work
1) connecting up the new frames, replacing the old ones, to move data around the
   system. This also entails a lot of editorial changes (just changing names, comments,
   and so on, without notable logic chanages -- eg, "OnMaxStreamIdFrame" becomes
   "OnMaxStreamsFrame".

2) the second, and more complex, task is revising the stream id manager to work entirely
   with stream counts rather than stream-ids. For example, the logic to check whether a
   new stream can be created checks if the current-stream-count is less than the limit
   or not, rather than if the next stream id to hand out is above the limit or not.
   For all intents and purposes, this completely rewrote the stream ID manager.

   Another big change resulting from keeping track solely of stream counts is that the
   stream ID manager doesn't care whether it is doing unidirectional or bidirectional
   streams, nor does it care whether stream ids are client- or server- initiated.

gfe-relnote: N/A, all changes are for V99/IETF QUIC code only.

LOG_STORAGE_INCREASE(GB/week): 0
TMPLOG_STORAGE_INCREASE(GB): 0

This change neither adds nor deletes data stored. It adds two new codepoints to the QUIC FrameType enum.  These new enums reflect two new frames defined in IETF QUIC, which replace two now-deprecated frames (and their associated type codepoints). This is a name change/type codepoint extension; data is neither added nor deleted.

PiperOrigin-RevId: 244661277
Change-Id: I07cdb79db6bd15e1d5ece97b3aa2d67e94ccf00b
diff --git a/quic/core/quic_stream_id_manager_test.cc b/quic/core/quic_stream_id_manager_test.cc
index 3d0c06c..47b97cc 100644
--- a/quic/core/quic_stream_id_manager_test.cc
+++ b/quic/core/quic_stream_id_manager_test.cc
@@ -118,10 +118,10 @@
     connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
     session_ = QuicMakeUnique<TestQuicSession>(connection_);
     stream_id_manager_ =
-        GetParam() ? QuicSessionPeer::v99_bidirectional_stream_id_manager(
-                         session_.get())
-                   : QuicSessionPeer::v99_unidirectional_stream_id_manager(
-                         session_.get());
+        IsBidi() ? QuicSessionPeer::v99_bidirectional_stream_id_manager(
+                       session_.get())
+                 : QuicSessionPeer::v99_unidirectional_stream_id_manager(
+                       session_.get());
   }
 
   QuicTransportVersion transport_version() const {
@@ -154,6 +154,27 @@
            kV99StreamIdIncrement * n;
   }
 
+  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
+                               Perspective perspective) {
+    // Calculate and build up stream ID rather than use
+    // GetFirst... because the tests that rely on this method
+    // needs to do the stream count where #1 is 0/1/2/3, and not
+    // take into account that stream 0 is special.
+    QuicStreamId id =
+        ((stream_count - 1) * QuicUtils::StreamIdDelta(QUIC_VERSION_99));
+    if (IsUnidi()) {
+      id |= 0x2;
+    }
+    if (perspective == Perspective::IS_SERVER) {
+      id |= 0x1;
+    }
+    return id;
+  }
+
+  // GetParam returns true if the test is for bidirectional streams
+  bool IsUnidi() { return GetParam() ? false : true; }
+  bool IsBidi() { return GetParam(); }
+
   MockQuicConnectionHelper helper_;
   MockAlarmFactory alarm_factory_;
   StrictMock<MockQuicConnection>* connection_;
@@ -178,128 +199,146 @@
 TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerClientInitialization) {
   // These fields are inited via the QuicSession constructor to default
   // values defined as a constant.
+  // If bidi, Crypto stream default created  at start up, it is one
+  // more stream to account for since initialization is "number of
+  // request/responses" & crypto is added in to that, not streams.
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection + (GetParam() ? 1 : 0),
+            stream_id_manager_->outgoing_max_streams());
+  // Test is predicated on having 1 static stream going if bidi, 0 if not...)
+  EXPECT_EQ((GetParam() ? 1u : 0),
+            stream_id_manager_->outgoing_static_stream_count());
+
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->max_allowed_incoming_streams());
+            stream_id_manager_->incoming_actual_max_streams());
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->max_allowed_outgoing_streams());
+            stream_id_manager_->incoming_advertised_max_streams());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+            stream_id_manager_->incoming_initial_max_open_streams());
 
   // The window for advertising updates to the MAX STREAM ID is half the number
   // of streams allowed.
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection / kMaxStreamIdWindowDivisor,
-            stream_id_manager_->max_stream_id_window());
-
-  // This test runs as a client, so it initiates (that is to say, outgoing)
-  // even-numbered stream IDs. Also, our implementation starts allocating
-  // stream IDs at 0 (for clients) 1 (for servers) -- before taking statically
-  // allocated streams into account. The -1 in the calculation is
-  // because the value being tested is the maximum allowed stream ID, not the
-  // first unallowed stream id.
-  const QuicStreamId kExpectedMaxOutgoingStreamId =
-      (GetParam() ? session_->next_outgoing_bidirectional_stream_id()
-                  : session_->next_outgoing_unidirectional_stream_id()) +
-      ((kDefaultMaxStreamsPerConnection - 1) * kV99StreamIdIncrement);
-  EXPECT_EQ(kExpectedMaxOutgoingStreamId,
-            stream_id_manager_->max_allowed_outgoing_stream_id());
-
-  // Same for IDs of incoming streams...
-  const QuicStreamId kExpectedMaxIncomingStreamId =
-      stream_id_manager_->first_incoming_dynamic_stream_id() +
-      (kDefaultMaxStreamsPerConnection - 1) * kV99StreamIdIncrement;
-  EXPECT_EQ(kExpectedMaxIncomingStreamId,
-            stream_id_manager_->actual_max_allowed_incoming_stream_id());
-  EXPECT_EQ(kExpectedMaxIncomingStreamId,
-            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
-}
-
-// This test checks that the initialization for the maximum allowed outgoing
-// stream id is correct.
-TEST_P(QuicStreamIdManagerTestClient, CheckMaxAllowedOutgoing) {
-  const size_t kNumOutgoingStreams = 124;
-  stream_id_manager_->SetMaxOpenOutgoingStreams(kNumOutgoingStreams);
-  EXPECT_EQ(kNumOutgoingStreams,
-            stream_id_manager_->max_allowed_outgoing_streams());
-
-  // Check that the maximum available stream is properly set.
-  size_t expected_max_outgoing_id =
-      (GetParam() ? session_->next_outgoing_bidirectional_stream_id()
-                  : session_->next_outgoing_unidirectional_stream_id()) +
-      ((kNumOutgoingStreams - 1) * kV99StreamIdIncrement);
-  EXPECT_EQ(expected_max_outgoing_id,
-            stream_id_manager_->max_allowed_outgoing_stream_id());
-}
-
-// This test checks that the initialization for the maximum allowed incoming
-// stream id is correct.
-TEST_P(QuicStreamIdManagerTestClient, CheckMaxAllowedIncoming) {
-  const size_t kStreamCount = 245;
-  stream_id_manager_->SetMaxOpenIncomingStreams(kStreamCount);
-  EXPECT_EQ(kStreamCount, stream_id_manager_->max_allowed_incoming_streams());
-  // Check that the window is 1/2 (integer math) of the stream count.
-  EXPECT_EQ(kStreamCount / 2, stream_id_manager_->max_stream_id_window());
-
-  // Actual- and advertised- maxima start out equal.
-  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
-            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
-
-  // Check that the maximum stream ID is properly calculated.
-  EXPECT_EQ(stream_id_manager_->first_incoming_dynamic_stream_id() +
-                ((kStreamCount - 1) * kV99StreamIdIncrement),
-            stream_id_manager_->actual_max_allowed_incoming_stream_id());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection / kMaxStreamsWindowDivisor,
+            stream_id_manager_->max_streams_window());
 }
 
 // This test checks that the stream advertisement window is set to 1
 // if the number of stream ids is 1. This is a special case in the code.
-TEST_P(QuicStreamIdManagerTestClient, CheckMaxStreamIdWindow1) {
+TEST_P(QuicStreamIdManagerTestClient, CheckMaxStreamsWindow1) {
   stream_id_manager_->SetMaxOpenIncomingStreams(1);
-  EXPECT_EQ(1u, stream_id_manager_->max_allowed_incoming_streams());
+  EXPECT_EQ(1u, stream_id_manager_->incoming_initial_max_open_streams());
+  EXPECT_EQ(1u, stream_id_manager_->incoming_actual_max_streams());
   // If streamid_count/2==0 (integer math) force it to 1.
-  EXPECT_EQ(1u, stream_id_manager_->max_stream_id_window());
+  EXPECT_EQ(1u, stream_id_manager_->max_streams_window());
 }
 
-// Check the case of the stream ID in a STREAM_ID_BLOCKED frame is less than the
-// stream ID most recently advertised in a MAX_STREAM_ID frame. This should
-// cause a MAX_STREAM_ID frame with the most recently advertised stream id to be
-// sent.
-TEST_P(QuicStreamIdManagerTestClient, ProcessStreamIdBlockedOk) {
+// Test that stream counts that would exceed the implementation maximum are
+// safely handled.
+// First, check that setting up to and including the implementation maximum
+// is OK.
+TEST_P(QuicStreamIdManagerTestClient, CheckMaxStreamsBadValuesToMaxOkOutgoing) {
+  QuicStreamCount implementation_max =
+      QuicUtils::GetMaxStreamCount(!GetParam(), /* GetParam==true for bidi */
+                                   Perspective::IS_CLIENT);
+  stream_id_manager_->AdjustMaxOpenOutgoingStreams(implementation_max - 1u);
+  // If bidi, Crypto stream default created  at start up, it is one
+  // more stream to account for since initialization is "number of
+  // request/responses" & crypto is added in to that, not streams.
+  EXPECT_EQ(implementation_max - 1u + (GetParam() ? 1 : 0),
+            stream_id_manager_->outgoing_max_streams());
+
+  stream_id_manager_->AdjustMaxOpenOutgoingStreams(implementation_max);
+  EXPECT_EQ(implementation_max, stream_id_manager_->outgoing_max_streams());
+}
+
+// Now check that setting to a value larger than the maximum fails.
+TEST_P(QuicStreamIdManagerTestClient,
+       CheckMaxStreamsBadValuesOverMaxFailsOutgoing) {
+  QuicStreamCount implementation_max =
+      QuicUtils::GetMaxStreamCount(!GetParam(), /* GetParam==true for bidi */
+                                   Perspective::IS_CLIENT);
+  // Ensure that the limit is less than the implementation maximum.
+  EXPECT_LT(stream_id_manager_->outgoing_max_streams(), implementation_max);
+
+  // Try to go over.
+  stream_id_manager_->AdjustMaxOpenOutgoingStreams(implementation_max + 1);
+  // Should be pegged at the max.
+  EXPECT_EQ(implementation_max, stream_id_manager_->outgoing_max_streams());
+}
+
+// Now do the same for the incoming streams
+TEST_P(QuicStreamIdManagerTestClient, CheckMaxStreamsBadValuesIncoming) {
+  QuicStreamCount implementation_max =
+      QuicUtils::GetMaxStreamCount(!GetParam(), /* GetParam==true for bidi */
+                                   Perspective::IS_CLIENT);
+  stream_id_manager_->SetMaxOpenIncomingStreams(implementation_max - 1u);
+  EXPECT_EQ(implementation_max - 1u,
+            stream_id_manager_->incoming_initial_max_open_streams());
+  EXPECT_EQ(implementation_max - 1u,
+            stream_id_manager_->incoming_actual_max_streams());
+  EXPECT_EQ((implementation_max - 1u) / 2,
+            stream_id_manager_->max_streams_window());
+
+  stream_id_manager_->SetMaxOpenIncomingStreams(implementation_max);
+  EXPECT_EQ(implementation_max,
+            stream_id_manager_->incoming_initial_max_open_streams());
+  EXPECT_EQ(implementation_max,
+            stream_id_manager_->incoming_actual_max_streams());
+  EXPECT_EQ(implementation_max / 2, stream_id_manager_->max_streams_window());
+
+  // Reset to 1 so that we can detect the change.
+  stream_id_manager_->SetMaxOpenIncomingStreams(1u);
+  EXPECT_EQ(1u, stream_id_manager_->incoming_initial_max_open_streams());
+  EXPECT_EQ(1u, stream_id_manager_->incoming_actual_max_streams());
+  EXPECT_EQ(1u, stream_id_manager_->max_streams_window());
+  // Now try to exceed the max, without wrapping.
+  stream_id_manager_->SetMaxOpenIncomingStreams(implementation_max + 1);
+  EXPECT_EQ(implementation_max,
+            stream_id_manager_->incoming_initial_max_open_streams());
+  EXPECT_EQ(implementation_max,
+            stream_id_manager_->incoming_actual_max_streams());
+  EXPECT_EQ(implementation_max / 2, stream_id_manager_->max_streams_window());
+}
+
+// Check the case of the stream count in a STREAMS_BLOCKED frame is less than
+// the count most recently advertised in a MAX_STREAMS frame. This should cause
+// a MAX_STREAMS frame with the most recently advertised count to be sent.
+TEST_P(QuicStreamIdManagerTestClient, ProcessStreamsBlockedOk) {
   EXPECT_CALL(*connection_, SendControlFrame(_))
       .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
-  QuicStreamId stream_id =
-      stream_id_manager_->advertised_max_allowed_incoming_stream_id() -
-      kV99StreamIdIncrement;
-  QuicStreamIdBlockedFrame frame(0, stream_id);
-  session_->OnStreamIdBlockedFrame(frame);
+  QuicStreamCount stream_count =
+      stream_id_manager_->incoming_initial_max_open_streams() - 1;
+  QuicStreamsBlockedFrame frame(0, stream_count, /*unidirectional=*/false);
+  session_->OnStreamsBlockedFrame(frame);
 
-  // We should see a MAX_STREAM_ID frame.
-  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);
+  // We should see a MAX_STREAMS frame.
+  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
 
   // and it should advertise the current max-allowed value.
-  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
-            session_->save_frame().max_stream_id_frame.max_stream_id);
+  EXPECT_EQ(stream_id_manager_->incoming_initial_max_open_streams(),
+            session_->save_frame().max_streams_frame.stream_count);
 }
 
-// Check the case of the stream ID in a STREAM_ID_BLOCKED frame is equal to
-// stream ID most recently advertised in a MAX_STREAM_ID frame. No
-// MAX_STREAM_ID should be generated.
-TEST_P(QuicStreamIdManagerTestClient, ProcessStreamIdBlockedNoOp) {
+// Check the case of the stream count in a STREAMS_BLOCKED frame is equal to the
+// count most recently advertised in a MAX_STREAMS frame. No MAX_STREAMS
+// should be generated.
+TEST_P(QuicStreamIdManagerTestClient, ProcessStreamsBlockedNoOp) {
   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  QuicStreamId stream_id =
-      stream_id_manager_->advertised_max_allowed_incoming_stream_id();
-  QuicStreamIdBlockedFrame frame(0, stream_id);
-  session_->OnStreamIdBlockedFrame(frame);
+  QuicStreamCount stream_count =
+      stream_id_manager_->incoming_initial_max_open_streams();
+  QuicStreamsBlockedFrame frame(0, stream_count, /*unidirectional=*/false);
+  session_->OnStreamsBlockedFrame(frame);
 }
 
-// Check the case of the stream ID in a STREAM_ID_BLOCKED frame is greater than
-// the stream ID most recently advertised in a MAX_STREAM_ID frame. Expect a
+// Check the case of the stream count in a STREAMS_BLOCKED frame is greater than
+// the count most recently advertised in a MAX_STREAMS frame. Expect a
 // connection close with an error.
-TEST_P(QuicStreamIdManagerTestClient, ProcessStreamIdBlockedTooBig) {
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
+TEST_P(QuicStreamIdManagerTestClient, ProcessStreamsBlockedTooBig) {
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAMS_BLOCKED_ERROR, _, _));
   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  QuicStreamId stream_id =
-      stream_id_manager_->advertised_max_allowed_incoming_stream_id() +
-      kV99StreamIdIncrement;
-  QuicStreamIdBlockedFrame frame(0, stream_id);
-  session_->OnStreamIdBlockedFrame(frame);
+  QuicStreamCount stream_count =
+      stream_id_manager_->incoming_initial_max_open_streams() + 1;
+  QuicStreamsBlockedFrame frame(0, stream_count, /*unidirectional=*/false);
+  session_->OnStreamsBlockedFrame(frame);
 }
 
 // Same basic tests as above, but calls
@@ -310,8 +349,8 @@
 // First test make sure that streams with ids below the limit are accepted.
 TEST_P(QuicStreamIdManagerTestClient, IsIncomingStreamIdValidBelowLimit) {
   QuicStreamId stream_id =
-      stream_id_manager_->actual_max_allowed_incoming_stream_id() -
-      kV99StreamIdIncrement;
+      StreamCountToId(stream_id_manager_->incoming_actual_max_streams() - 1,
+                      Perspective::IS_CLIENT);
   EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
   EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
 }
@@ -319,227 +358,219 @@
 // Accept a stream with an ID that equals the limit.
 TEST_P(QuicStreamIdManagerTestClient, IsIncomingStreamIdValidAtLimit) {
   QuicStreamId stream_id =
-      stream_id_manager_->actual_max_allowed_incoming_stream_id();
+      StreamCountToId(stream_id_manager_->incoming_actual_max_streams(),
+                      Perspective::IS_CLIENT);
   EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
   EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
 }
 
 // Close the connection if the id exceeds the limit.
 TEST_P(QuicStreamIdManagerTestClient, IsIncomingStreamIdInValidAboveLimit) {
-  QuicStreamId stream_id =
-      stream_id_manager_->actual_max_allowed_incoming_stream_id() +
-      kV99StreamIdIncrement;
+  QuicStreamId stream_id = StreamCountToId(
+      stream_id_manager_->incoming_actual_max_streams() + 1,
+      Perspective::IS_SERVER);  // This node is a client, incoming
+                                // stream ids must be server-originated.
   std::string error_details =
-      GetParam() ? "Stream id 401 above 397" : "Stream id 403 above 399";
+      GetParam() ? "Stream id 401 would exceed stream count limit 100"
+                 : "Stream id 403 would exceed stream count limit 100";
   EXPECT_CALL(*connection_,
               CloseConnection(QUIC_INVALID_STREAM_ID, error_details, _));
   EXPECT_FALSE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
 }
 
-// Test that a client will reject a MAX_STREAM_ID that specifies a
-// server-initiated stream ID.
-TEST_P(QuicStreamIdManagerTestClient, RejectServerMaxStreamId) {
-  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();
-
-  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
-  // current MAX.
-  id += (kV99StreamIdIncrement * 2);
-
-  // Make it an odd (server-initiated) ID.
-  id |= 0x1;
-  EXPECT_FALSE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));
-
-  // Make the frame and process it; should result in the connection being
-  // closed.
-  QuicMaxStreamIdFrame frame(0, id);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAM_ID_ERROR, _, _));
-  session_->OnMaxStreamIdFrame(frame);
-}
-
-// Test that a client will reject a STREAM_ID_BLOCKED that specifies a
-// client-initiated stream ID. STREAM_ID_BLOCKED from a server should specify an
-// odd (server-initiated_ ID). Generate one with an odd ID and check that the
-// connection is closed.
-TEST_P(QuicStreamIdManagerTestClient, RejectServerStreamIdBlocked) {
-  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();
-
-  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
-  // current MAX.
-  id += (kV99StreamIdIncrement * 2);
-  // Make sure it's odd, like a client-initiated ID.
-  id &= ~0x01;
-  EXPECT_TRUE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));
-
-  // Generate and process the frame; connection should be closed.
-  QuicStreamIdBlockedFrame frame(0, id);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
-  session_->OnStreamIdBlockedFrame(frame);
-}
-
-// Test functionality for reception of a MAX STREAM ID frame. This code is
+// Test functionality for reception of a MAX_STREAMS frame. This code is
 // client/server-agnostic.
-TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerClientOnMaxStreamIdFrame) {
-  // Get the current maximum allowed outgoing stream ID.
-  QuicStreamId initial_stream_id =
-      stream_id_manager_->max_allowed_outgoing_stream_id();
-  QuicMaxStreamIdFrame frame;
+TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerClientOnMaxStreamsFrame) {
+  // Get the current maximum allowed outgoing stream count.
+  QuicStreamCount initial_stream_count =
+      // need to know the number of request/response streams.
+      // This is the total number of outgoing streams (which includes both
+      // req/resp and statics) minus just the statics...
+      stream_id_manager_->outgoing_max_streams() -
+      stream_id_manager_->outgoing_static_stream_count();
 
-  // If the stream ID in the frame is < the current maximum then
-  // the frame should be ignored.
-  frame.max_stream_id = initial_stream_id - kV99StreamIdIncrement;
-  EXPECT_TRUE(stream_id_manager_->OnMaxStreamIdFrame(frame));
-  EXPECT_EQ(initial_stream_id,
-            stream_id_manager_->max_allowed_outgoing_stream_id());
+  QuicMaxStreamsFrame frame;
 
-  // A stream ID greater than the current limit should increase the limit.
-  frame.max_stream_id = initial_stream_id + kV99StreamIdIncrement;
-  EXPECT_TRUE(stream_id_manager_->OnMaxStreamIdFrame(frame));
-  EXPECT_EQ(initial_stream_id + kV99StreamIdIncrement,
-            stream_id_manager_->max_allowed_outgoing_stream_id());
+  // Even though the stream count in the frame is < the initial maximum,
+  // it is should be ignored since the initial max was set via
+  // the constructor (an educated guess) and the MAX STREAMS frame
+  // is authoritative.
+  frame.stream_count = initial_stream_count - 1;
+
+  frame.unidirectional = IsUnidi();
+  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  EXPECT_EQ(initial_stream_count - 1,
+            stream_id_manager_->outgoing_max_streams());
+
+  QuicStreamCount save_outgoing_max_streams =
+      stream_id_manager_->outgoing_max_streams();
+  // Now that there has been one MAX STREAMS frame, we should not
+  // accept a MAX_STREAMS that reduces the limit...
+  frame.stream_count = initial_stream_count - 2;
+  frame.unidirectional = IsUnidi();
+  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  // should not change from previous setting.
+  EXPECT_EQ(save_outgoing_max_streams,
+            stream_id_manager_->outgoing_max_streams());
+
+  // A stream count greater than the current limit should increase the limit.
+  frame.stream_count = initial_stream_count + 1;
+  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+
+  EXPECT_EQ(initial_stream_count + 1,
+            stream_id_manager_->outgoing_max_streams());
 }
 
-// Test functionality for reception of a STREAM ID BLOCKED frame.
+// Test functionality for reception of a STREAMS_BLOCKED frame.
 // This code is client/server-agnostic.
-TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerOnStreamIdBlockedFrame) {
-  // Get the current maximum allowed incoming stream ID.
-  QuicStreamId advertised_stream_id =
-      stream_id_manager_->advertised_max_allowed_incoming_stream_id();
-  QuicStreamIdBlockedFrame frame;
+TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerOnStreamsBlockedFrame) {
+  // Get the current maximum allowed incoming stream count.
+  QuicStreamCount advertised_stream_count =
+      stream_id_manager_->incoming_advertised_max_streams();
+  QuicStreamsBlockedFrame frame;
 
-  // If the peer is saying it's blocked on the stream ID that
+  frame.unidirectional = IsUnidi();
+
+  // If the peer is saying it's blocked on the stream count that
   // we've advertised, it's a noop since the peer has the correct information.
-  frame.stream_id = advertised_stream_id;
-  EXPECT_TRUE(stream_id_manager_->OnStreamIdBlockedFrame(frame));
+  frame.stream_count = advertised_stream_count;
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  EXPECT_TRUE(stream_id_manager_->OnStreamsBlockedFrame(frame));
 
-  // If the peer is saying it's blocked on a stream ID that is larger
+  // If the peer is saying it's blocked on a stream count that is larger
   // than what we've advertised, the connection should get closed.
-  frame.stream_id = advertised_stream_id + kV99StreamIdIncrement;
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
-  EXPECT_FALSE(stream_id_manager_->OnStreamIdBlockedFrame(frame));
+  frame.stream_count = advertised_stream_count + 1;
+  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAMS_BLOCKED_ERROR, _, _));
+  EXPECT_FALSE(stream_id_manager_->OnStreamsBlockedFrame(frame));
 
-  // If the peer is saying it's blocked on a stream ID that is less than
-  // what we've advertised, we send a MAX STREAM ID frame and update
+  // If the peer is saying it's blocked on a count that is less than
+  // our actual count, we send a MAX_STREAMS frame and update
   // the advertised value.
   // First, need to bump up the actual max so there is room for the MAX
-  // STREAM_ID frame to send a larger ID.
-  QuicStreamId actual_stream_id =
-      stream_id_manager_->actual_max_allowed_incoming_stream_id();
-  stream_id_manager_->OnStreamClosed(
-      stream_id_manager_->first_incoming_dynamic_stream_id());
-  EXPECT_EQ(actual_stream_id + kV99StreamIdIncrement,
-            stream_id_manager_->actual_max_allowed_incoming_stream_id());
-  EXPECT_GT(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
-            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
+  // STREAMS frame to send a larger ID.
+  QuicStreamCount actual_stream_count =
+      stream_id_manager_->incoming_actual_max_streams();
 
-  // Now simulate receiving a STTREAM_ID_BLOCKED frame...
-  // Changing the actual maximum, above, forces a MAX STREAM ID frame to be
-  // sent, so the logic for that (SendMaxStreamIdFrame(), etc) is tested.
-  frame.stream_id = advertised_stream_id;
+  // Closing a stream will result in the ability to initiate one more
+  // stream
+  stream_id_manager_->OnStreamClosed(
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(stream_id_manager_));
+  EXPECT_EQ(actual_stream_count + 1,
+            stream_id_manager_->incoming_actual_max_streams());
+  EXPECT_EQ(stream_id_manager_->incoming_actual_max_streams(),
+            stream_id_manager_->incoming_advertised_max_streams() + 1);
+
+  // Now simulate receiving a STREAMS_BLOCKED frame...
+  // Changing the actual maximum, above, forces a MAX_STREAMS frame to be
+  // sent, so the logic for that (SendMaxStreamsFrame(), etc) is tested.
+
+  // The STREAMS_BLOCKED frame contains the previous advertised count,
+  // not the one that the peer would have received as a result of the
+  // MAX_STREAMS sent earler.
+  frame.stream_count = advertised_stream_count;
+
   EXPECT_CALL(*connection_, SendControlFrame(_))
       .Times(1)
       .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
-  EXPECT_TRUE(stream_id_manager_->OnStreamIdBlockedFrame(frame));
-  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
-            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
-  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);
-  EXPECT_EQ(stream_id_manager_->advertised_max_allowed_incoming_stream_id(),
-            session_->save_frame().max_stream_id_frame.max_stream_id);
 
-  // Ensure a client initiated stream ID is rejected.
-  frame.stream_id = GetParam() ? GetNthClientInitiatedBidirectionalId(1)
-                               : GetNthClientInitiatedUnidirectionalId(1);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
-  EXPECT_FALSE(stream_id_manager_->OnStreamIdBlockedFrame(frame));
+  EXPECT_TRUE(stream_id_manager_->OnStreamsBlockedFrame(frame));
+  // Check that the saved frame is correct.
+  EXPECT_EQ(stream_id_manager_->incoming_actual_max_streams(),
+            stream_id_manager_->incoming_advertised_max_streams());
+  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
+  EXPECT_EQ(stream_id_manager_->incoming_advertised_max_streams(),
+            session_->save_frame().max_streams_frame.stream_count);
+  // Make sure that this is the only MAX_STREAMS
+  EXPECT_EQ(1u, GetControlFrameId(session_->save_frame()));
 }
 
 // Test GetNextOutgoingStream. This is client/server agnostic.
-TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerGetNextOutgoingFrame) {
+TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerGetNextOutgoingStream) {
   // Number of streams we can open and the first one we should get when
   // opening...
   int number_of_streams = kDefaultMaxStreamsPerConnection;
   QuicStreamId stream_id =
-      GetParam() ? session_->next_outgoing_bidirectional_stream_id()
-                 : session_->next_outgoing_unidirectional_stream_id();
+      IsUnidi() ? session_->next_outgoing_unidirectional_stream_id()
+                : session_->next_outgoing_bidirectional_stream_id();
 
+  // If bidi, Crypto stream default created  at start up, it is one
+  // more stream to account for since initialization is "number of
+  // request/responses" & crypto is added in to that, not streams.
+  EXPECT_EQ(number_of_streams + (IsBidi() ? 1 : 0),
+            stream_id_manager_->outgoing_max_streams());
   while (number_of_streams) {
     EXPECT_TRUE(stream_id_manager_->CanOpenNextOutgoingStream());
     EXPECT_EQ(stream_id, stream_id_manager_->GetNextOutgoingStreamId());
     stream_id += kV99StreamIdIncrement;
     number_of_streams--;
   }
-  EXPECT_EQ(stream_id - kV99StreamIdIncrement,
-            stream_id_manager_->max_allowed_outgoing_stream_id());
 
   // If we try to check that the next outgoing stream id is available it should
-  // A) fail and B) generate a STREAM_ID_BLOCKED frame.
+  // A) fail and B) generate a STREAMS_BLOCKED frame.
   EXPECT_CALL(*connection_, SendControlFrame(_))
       .Times(1)
       .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
   EXPECT_FALSE(stream_id_manager_->CanOpenNextOutgoingStream());
-  EXPECT_EQ(STREAM_ID_BLOCKED_FRAME, session_->save_frame().type);
-  EXPECT_EQ(stream_id_manager_->max_allowed_outgoing_stream_id(),
-            session_->save_frame().max_stream_id_frame.max_stream_id);
+  EXPECT_EQ(STREAMS_BLOCKED_FRAME, session_->save_frame().type);
+  // If bidi, Crypto stream default created  at start up, it is one
+  // more stream to account for since initialization is "number of
+  // request/responses" & crypto is added in to that, not streams.
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection + (IsBidi() ? 1 : 0),
+            session_->save_frame().max_streams_frame.stream_count);
   // If we try to get the next id (above the limit), it should cause a quic-bug.
   EXPECT_QUIC_BUG(
       stream_id_manager_->GetNextOutgoingStreamId(),
-      "Attempt allocate a new outgoing stream ID would exceed the limit");
+      "Attempt to allocate a new outgoing stream that would exceed the limit");
 }
 
 // Ensure that MaybeIncreaseLargestPeerStreamId works properly. This is
 // server/client agnostic.
 TEST_P(QuicStreamIdManagerTestClient,
        StreamIdManagerServerMaybeIncreaseLargestPeerStreamId) {
-  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
-      stream_id_manager_->actual_max_allowed_incoming_stream_id()));
+  QuicStreamId max_stream_id =
+      StreamCountToId(stream_id_manager_->incoming_actual_max_streams(),
+                      Perspective::IS_SERVER);
+  EXPECT_TRUE(
+      stream_id_manager_->MaybeIncreaseLargestPeerStreamId(max_stream_id));
+
   QuicStreamId server_initiated_stream_id =
-      GetParam() ? GetNthServerInitiatedBidirectionalId(0)
-                 : GetNthServerInitiatedUnidirectionalId(0);
+      StreamCountToId(1u,  // get 1st id
+                      Perspective::IS_SERVER);
   EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
       server_initiated_stream_id));
   // A bad stream ID results in a closed connection.
   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
   EXPECT_FALSE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
-      stream_id_manager_->actual_max_allowed_incoming_stream_id() +
-      kV99StreamIdIncrement));
+      max_stream_id + kV99StreamIdIncrement));
 }
 
-// Test the MAX STREAM ID Window functionality.
-// Free up Stream ID space. Do not expect to see a MAX_STREAM_ID
-// until |window| stream ids are available.
-TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerServerMaxStreamId) {
-  // Test that a MAX_STREAM_ID frame is generated when the peer has less than
-  // |max_stream_id_window_| streams left that it can initiate.
+// Test the MAX STREAMS Window functionality.
+TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerServerMaxStreams) {
+  // Test that a MAX_STREAMS frame is generated when the peer has less than
+  // |max_streams_window_| streams left that it can initiate.
 
-  // First, open, and then close, max_stream_id_window_ streams.  This will
-  // max_stream_id_window_ streams available for the peer -- no MAX_STREAM_ID
+  // First, open, and then close, max_streams_window_ streams.  This will
+  // max_streams_window_ streams available for the peer -- no MAX_STREAMS
   // should be sent. The -1 is because the check in
-  // QuicStreamIdManager::MaybeSendMaxStreamIdFrame sends a MAX_STREAM_ID if the
-  // number of available streams at the peer is <= |max_stream_id_window_|
-  int stream_count = stream_id_manager_->max_stream_id_window() - 1;
-
-  QuicStreamId advertised_max =
-      stream_id_manager_->advertised_max_allowed_incoming_stream_id();
-  QuicStreamId expected_actual_max_id =
-      stream_id_manager_->actual_max_allowed_incoming_stream_id();
+  // QuicStreamIdManager::MaybeSendMaxStreamsFrame sends a MAX_STREAMS if the
+  // number of available streams at the peer is <= |max_streams_window_|
+  int stream_count = stream_id_manager_->max_streams_window() - 1;
 
   // Should not get a control-frame transmission since the peer should have
   // "plenty" of stream IDs to use.
   EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  // This test runs as a client, so the first stream to release is 2, a
-  // server-initiated stream.
-  QuicStreamId stream_id = GetParam()
-                               ? GetNthServerInitiatedBidirectionalId(0)
-                               : GetNthServerInitiatedUnidirectionalId(0);
+
+  // Get the first incoming stream ID to try and allocate.
+  QuicStreamId stream_id = IsBidi() ? GetNthServerInitiatedBidirectionalId(0)
+                                    : GetNthServerInitiatedUnidirectionalId(0);
   size_t old_available_incoming_streams =
       stream_id_manager_->available_incoming_streams();
-
   while (stream_count) {
     EXPECT_TRUE(
         stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
 
+    // This node should think that the peer believes it has one fewer
+    // stream it can create.
     old_available_incoming_streams--;
     EXPECT_EQ(old_available_incoming_streams,
               stream_id_manager_->available_incoming_streams());
@@ -548,27 +579,31 @@
     stream_id += kV99StreamIdIncrement;
   }
 
-  // Now close them, still should get no MAX_STREAM_ID
-  stream_count = stream_id_manager_->max_stream_id_window();
-  stream_id = GetParam() ? GetNthServerInitiatedBidirectionalId(0)
-                         : GetNthServerInitiatedUnidirectionalId(0);
+  // Now close them, still should get no MAX_STREAMS
+  stream_count = stream_id_manager_->max_streams_window();
+  stream_id = IsBidi() ? GetNthServerInitiatedBidirectionalId(0)
+                       : GetNthServerInitiatedUnidirectionalId(0);
+  QuicStreamCount expected_actual_max =
+      stream_id_manager_->incoming_actual_max_streams();
+  QuicStreamCount expected_advertised_max_streams =
+      stream_id_manager_->incoming_advertised_max_streams();
   while (stream_count) {
     stream_id_manager_->OnStreamClosed(stream_id);
     stream_count--;
     stream_id += kV99StreamIdIncrement;
-    expected_actual_max_id += kV99StreamIdIncrement;
-    EXPECT_EQ(expected_actual_max_id,
-              stream_id_manager_->actual_max_allowed_incoming_stream_id());
+    expected_actual_max++;
+    EXPECT_EQ(expected_actual_max,
+              stream_id_manager_->incoming_actual_max_streams());
     // Advertised maximum should remain the same.
-    EXPECT_EQ(advertised_max,
-              stream_id_manager_->advertised_max_allowed_incoming_stream_id());
+    EXPECT_EQ(expected_advertised_max_streams,
+              stream_id_manager_->incoming_advertised_max_streams());
   }
 
   // This should not change.
   EXPECT_EQ(old_available_incoming_streams,
             stream_id_manager_->available_incoming_streams());
 
-  // Now whenever we close a stream we should get a MAX_STREAM_ID frame.
+  // Now whenever we close a stream we should get a MAX_STREAMS frame.
   // Above code closed all the open streams, so we have to open/close
   EXPECT_CALL(*connection_, SendControlFrame(_))
       .Times(1)
@@ -577,37 +612,74 @@
   stream_id_manager_->OnStreamClosed(stream_id);
   stream_id += kV99StreamIdIncrement;
 
-  // Check that the MAX STREAM ID was sent and has the correct values.
-  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);
-  EXPECT_EQ(stream_id_manager_->advertised_max_allowed_incoming_stream_id(),
-            session_->save_frame().max_stream_id_frame.max_stream_id);
+  // Check that the MAX STREAMS was sent and has the correct values.
+  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
+  EXPECT_EQ(stream_id_manager_->incoming_advertised_max_streams(),
+            session_->save_frame().max_streams_frame.stream_count);
 }
 
-// Test that registering static stream IDs causes the stream ID limit to rise
+// Test that registering static stream IDs causes the stream limit to rise
 // accordingly. This is server/client agnostic.
 TEST_P(QuicStreamIdManagerTestClient, TestStaticStreamAdjustment) {
   QuicStreamId first_dynamic =
-      stream_id_manager_->first_incoming_dynamic_stream_id();
-  QuicStreamId expected_max_incoming =
-      stream_id_manager_->actual_max_allowed_incoming_stream_id();
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(stream_id_manager_);
+  QuicStreamCount actual_max =
+      stream_id_manager_->incoming_actual_max_streams();
 
   // First test will register the first dynamic stream id as being for a static
-  // stream.  This takes one stream ID out of the low-end of the dynamic range
-  // so therefore the high end should go up by 1 ID.
-  expected_max_incoming += kV99StreamIdIncrement;
+  // stream.
   stream_id_manager_->RegisterStaticStream(first_dynamic);
-  EXPECT_EQ(expected_max_incoming,
-            stream_id_manager_->actual_max_allowed_incoming_stream_id());
+  // Should go up by 1 stream/stream id.
+  EXPECT_EQ(actual_max + 1, stream_id_manager_->incoming_actual_max_streams());
+}
 
-  // Now be extreme, increase static by 100 stream ids.  A discontinuous
-  // jump is not allowed; make sure.
-  first_dynamic += kV99StreamIdIncrement * 100;
-  expected_max_incoming += kV99StreamIdIncrement * 100;
-  std::string bug_detail =
-      GetParam() ? "allocate 5 got 401" : "allocate 7 got 403";
-  EXPECT_QUIC_BUG(
-      stream_id_manager_->RegisterStaticStream(first_dynamic),
-      "Error in incoming static stream allocation, expected to " + bug_detail);
+// Check that the OnMaxStreamFrame logic properly handles all the
+// cases of offered max streams and outgoing_static_stream_count_,
+// checking for the wrap conditions. Tests in client perspective, necessary
+// because internally, some calculations depend on the client/server
+// perspective.
+TEST_P(QuicStreamIdManagerTestClient, TestMaxStreamsWrapChecks) {
+  QuicStreamCount max_stream_count =
+      QuicUtils::GetMaxStreamCount(IsUnidi(), Perspective::IS_CLIENT);
+  QuicMaxStreamsFrame frame;
+  frame.unidirectional = IsUnidi();
+
+  // Check the case where the offered stream count is less than the
+  // maximum
+  frame.stream_count = max_stream_count - 10;
+  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  EXPECT_EQ(max_stream_count - 10, stream_id_manager_->outgoing_max_streams());
+
+  // Now check if the offered count is larger than the max.
+  // The count should be pegged at the max.
+  frame.stream_count = max_stream_count + 10;
+  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  EXPECT_EQ(max_stream_count, stream_id_manager_->outgoing_max_streams());
+}
+
+// Check that edge conditions of the stream count in a STREAMS_BLOCKED frame
+// are. properly handled.
+TEST_P(QuicStreamIdManagerTestClient, StreamsBlockedEdgeConditions) {
+  QuicStreamsBlockedFrame frame;
+  frame.unidirectional = IsUnidi();
+
+  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 does nothing
+  // when max_allowed_incoming_streams is 0.
+  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  stream_id_manager_->SetMaxOpenIncomingStreams(0);
+  frame.stream_count = 0;
+  stream_id_manager_->OnStreamsBlockedFrame(frame);
+
+  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 invokes a
+  // MAX STREAMS, count = 123, when the MaxOpen... is set to 123.
+  EXPECT_CALL(*connection_, SendControlFrame(_))
+      .Times(1)
+      .WillOnce(Invoke(session_.get(), &TestQuicSession::SaveFrame));
+  stream_id_manager_->SetMaxOpenIncomingStreams(123);
+  frame.stream_count = 0;
+  stream_id_manager_->OnStreamsBlockedFrame(frame);
+  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
+  EXPECT_EQ(123u, session_->save_frame().max_streams_frame.stream_count);
 }
 
 // Following tests all are server-specific. They depend, in some way, on
@@ -626,42 +698,13 @@
 TEST_P(QuicStreamIdManagerTestServer, CheckMaxAllowedOutgoing) {
   const size_t kIncomingStreamCount = 123;
   stream_id_manager_->SetMaxOpenOutgoingStreams(kIncomingStreamCount);
-  EXPECT_EQ(kIncomingStreamCount,
-            stream_id_manager_->max_allowed_outgoing_streams());
-
-  // Check that the max outgoing stream id is properly calculated
-  EXPECT_EQ(stream_id_manager_->GetNextOutgoingStreamId() +
-                ((kIncomingStreamCount - 1) * kV99StreamIdIncrement),
-            stream_id_manager_->max_allowed_outgoing_stream_id());
+  EXPECT_EQ(kIncomingStreamCount, stream_id_manager_->outgoing_max_streams());
 }
 
-// This test checks that the initialization for the maximum allowed incoming
-// stream id is correct.
-TEST_P(QuicStreamIdManagerTestServer, CheckMaxAllowedIncoming) {
-  const size_t kIncomingStreamCount = 245;
-  stream_id_manager_->SetMaxOpenIncomingStreams(kIncomingStreamCount);
-  EXPECT_EQ(kIncomingStreamCount,
-            stream_id_manager_->max_allowed_incoming_streams());
-
-  // Check that the window is 1/2 (integer math) of the stream count.
-  EXPECT_EQ((kIncomingStreamCount / 2),
-            stream_id_manager_->max_stream_id_window());
-
-  // Actual- and advertised- maxima start out equal.
-  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
-            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
-
-  // First stream ID the client should use should be 3, this means that the max
-  // stream id is 491 -- ((number of stream ids-1) * 2) + first available id.
-  EXPECT_EQ(stream_id_manager_->first_incoming_dynamic_stream_id() +
-                ((kIncomingStreamCount - 1) * kV99StreamIdIncrement),
-            stream_id_manager_->actual_max_allowed_incoming_stream_id());
-}
-
-// Test that a MAX_STREAM_ID frame is generated when half the stream ids become
+// Test that a MAX_STREAMS frame is generated when half the stream ids become
 // available. This has a useful side effect of testing that when streams are
 // closed, the number of available stream ids increases.
-TEST_P(QuicStreamIdManagerTestServer, MaxStreamIdSlidingWindow) {
+TEST_P(QuicStreamIdManagerTestServer, MaxStreamsSlidingWindow) {
   // Ignore OnStreamReset calls.
   EXPECT_CALL(*connection_, OnStreamReset(_, _)).WillRepeatedly(Return());
   // Capture control frames for analysis.
@@ -669,16 +712,17 @@
       .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
   // Simulate config being negotiated, causing the limits all to be initialized.
   session_->OnConfigNegotiated();
-  QuicStreamId first_advert =
-      stream_id_manager_->advertised_max_allowed_incoming_stream_id();
+  QuicStreamCount first_advert =
+      stream_id_manager_->incoming_advertised_max_streams();
 
-  // Open/close enough streams to shrink the window without causing a MAX STREAM
-  // ID to be generated. The window will open (and a MAX STREAM ID generated)
-  // when max_stream_id_window() stream IDs have been made available. The loop
+  // Open/close enough streams to shrink the window without causing a MAX
+  // STREAMS to be generated. The window will open (and a MAX STREAMS generated)
+  // when max_streams_window() stream IDs have been made available. The loop
   // will make that many stream IDs available, so the last CloseStream should
-  // cause a MAX STREAM ID frame to be generated.
-  int i = static_cast<int>(stream_id_manager_->max_stream_id_window());
-  QuicStreamId id = stream_id_manager_->first_incoming_dynamic_stream_id();
+  // cause a MAX STREAMS frame to be generated.
+  int i = static_cast<int>(stream_id_manager_->max_streams_window());
+  QuicStreamId id =
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(stream_id_manager_);
   while (i) {
     QuicStream* stream = session_->GetOrCreateStream(id);
     EXPECT_NE(nullptr, stream);
@@ -687,10 +731,10 @@
     // to the stream being added to the locally_closed_streams_highest_offset_
     // map, and therefore not counting as truly being closed. The test requires
     // that the stream truly close, so that new streams become available,
-    // causing the MAX_STREAM_ID to be sent.
+    // causing the MAX_STREAMS to be sent.
     stream->set_fin_received(true);
     EXPECT_EQ(id, stream->id());
-    if (GetParam()) {
+    if (IsBidi()) {
       // Only send reset for incoming bidirectional streams.
       EXPECT_CALL(*session_, SendRstStream(_, _, _));
     }
@@ -698,147 +742,111 @@
     i--;
     id += kV99StreamIdIncrement;
   }
-  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);
-  QuicStreamId second_advert =
-      session_->save_frame().max_stream_id_frame.max_stream_id;
-  EXPECT_EQ(first_advert + (stream_id_manager_->max_stream_id_window() *
-                            kV99StreamIdIncrement),
+  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
+  QuicStreamCount second_advert =
+      session_->save_frame().max_streams_frame.stream_count;
+  EXPECT_EQ(first_advert + stream_id_manager_->max_streams_window(),
             second_advert);
 }
 
 // Tast that an attempt to create an outgoing stream does not exceed the limit
-// and that it generates an appropriate STREAM_ID_BLOCKED frame.
+// and that it generates an appropriate STREAMS_BLOCKED frame.
 TEST_P(QuicStreamIdManagerTestServer, NewStreamDoesNotExceedLimit) {
-  size_t stream_count = stream_id_manager_->max_allowed_outgoing_streams();
+  size_t stream_count = stream_id_manager_->outgoing_max_streams();
   EXPECT_NE(0u, stream_count);
   TestQuicStream* stream;
   while (stream_count) {
-    stream = GetParam() ? session_->CreateOutgoingBidirectionalStream()
-                        : session_->CreateOutgoingUnidirectionalStream();
+    stream = IsBidi() ? session_->CreateOutgoingBidirectionalStream()
+                      : session_->CreateOutgoingUnidirectionalStream();
     EXPECT_NE(stream, nullptr);
     stream_count--;
   }
-  // Quis Custodiet Ipsos Custodes.
-  EXPECT_EQ(stream->id(), stream_id_manager_->max_allowed_outgoing_stream_id());
-  // Create another, it should fail. Should also send a STREAM_ID_BLOCKED
+
+  EXPECT_EQ(stream_id_manager_->outgoing_stream_count(),
+            stream_id_manager_->outgoing_max_streams());
+  // Create another, it should fail. Should also send a STREAMS_BLOCKED
   // control frame.
   EXPECT_CALL(*connection_, SendControlFrame(_));
-  stream = GetParam() ? session_->CreateOutgoingBidirectionalStream()
-                      : session_->CreateOutgoingUnidirectionalStream();
+  stream = IsBidi() ? session_->CreateOutgoingBidirectionalStream()
+                    : session_->CreateOutgoingUnidirectionalStream();
   EXPECT_EQ(nullptr, stream);
 }
 
-// Test that a server will reject a MAX_STREAM_ID that specifies a
-// client-initiated stream ID.
-TEST_P(QuicStreamIdManagerTestServer, RejectClientMaxStreamId) {
-  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();
-
-  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
-  // current MAX.
-  id += (kV99StreamIdIncrement * 2);
-
-  // Turn it into a client-initiated ID (even).
-  id &= ~0x1;
-  EXPECT_TRUE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));
-
-  // Generate a MAX_STREAM_ID frame and process it; the connection should close.
-  QuicMaxStreamIdFrame frame(0, id);
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAM_ID_ERROR, _, _));
-  session_->OnMaxStreamIdFrame(frame);
-}
-
-// Test that a server will reject a STREAM_ID_BLOCKED that specifies a
-// server-initiated stream ID. STREAM_ID_BLOCKED from a client should specify an
-// even (client-initiated_ ID) generate one with an odd ID and check that the
-// connection is closed.
-TEST_P(QuicStreamIdManagerTestServer, RejectClientStreamIdBlocked) {
-  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();
-
-  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
-  // current MAX.
-  id += (kV99StreamIdIncrement * 2);
-
-  // Make the ID odd, so it looks like the client is trying to specify a
-  // server-initiated ID.
-  id |= 0x1;
-  EXPECT_FALSE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));
-
-  // Generate a STREAM_ID_BLOCKED frame and process it; the connection should
-  // close.
-  QuicStreamIdBlockedFrame frame(0, id);
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
-  session_->OnStreamIdBlockedFrame(frame);
-}
-
 // Check that the parameters used by the stream ID manager are properly
 // initialized
 TEST_P(QuicStreamIdManagerTestServer, StreamIdManagerServerInitialization) {
   // These fields are inited via the QuicSession constructor to default
   // values defined as a constant.
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->max_allowed_incoming_streams());
+            stream_id_manager_->incoming_initial_max_open_streams());
+  // If bidi, Crypto stream default created  at start up, it is one
+  // more stream to account for since initialization is "number of
+  // request/responses" & crypto is added in to that, not streams.
+  // Since this is the server, the stream is incoming.
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection + (IsBidi() ? 1 : 0),
+            stream_id_manager_->incoming_actual_max_streams());
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->max_allowed_outgoing_streams());
+            stream_id_manager_->outgoing_max_streams());
 
   // The window for advertising updates to the MAX STREAM ID is half the number
   // of stream allowed.
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection / kMaxStreamIdWindowDivisor,
-            stream_id_manager_->max_stream_id_window());
-
-  // This test runs as a server, so it initiates (that is to say, outgoing)
-  // even-numbered stream IDs. The -1 in the calculation is because the value
-  // being tested is the maximum allowed stream ID, not the first unallowed
-  // stream id.
-  const QuicStreamId kExpectedMaxOutgoingStreamId =
-      (GetParam() ? session_->next_outgoing_bidirectional_stream_id()
-                  : session_->next_outgoing_unidirectional_stream_id()) +
-      ((kDefaultMaxStreamsPerConnection - 1) * kV99StreamIdIncrement);
-  EXPECT_EQ(kExpectedMaxOutgoingStreamId,
-            stream_id_manager_->max_allowed_outgoing_stream_id());
-
-  // Same for IDs of incoming streams... But they are client initiated, so are
-  // even.
-  const QuicStreamId kExpectedMaxIncomingStreamId =
-      GetParam() ? GetNthClientInitiatedBidirectionalId(
-                       kDefaultMaxStreamsPerConnection - 1)
-                 : GetNthClientInitiatedUnidirectionalId(
-                       kDefaultMaxStreamsPerConnection - 1);
-  EXPECT_EQ(kExpectedMaxIncomingStreamId,
-            stream_id_manager_->actual_max_allowed_incoming_stream_id());
-  EXPECT_EQ(kExpectedMaxIncomingStreamId,
-            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
+  EXPECT_EQ(kDefaultMaxStreamsPerConnection / kMaxStreamsWindowDivisor,
+            stream_id_manager_->max_streams_window());
 }
 
 TEST_P(QuicStreamIdManagerTestServer, AvailableStreams) {
   stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
-      GetParam() ? GetNthClientInitiatedBidirectionalId(3)
-                 : GetNthClientInitiatedUnidirectionalId(3));
+      IsBidi() ? GetNthClientInitiatedBidirectionalId(3)
+               : GetNthClientInitiatedUnidirectionalId(3));
   EXPECT_TRUE(stream_id_manager_->IsAvailableStream(
-      GetParam() ? GetNthClientInitiatedBidirectionalId(1)
-                 : GetNthClientInitiatedUnidirectionalId(1)));
+      IsBidi() ? GetNthClientInitiatedBidirectionalId(1)
+               : GetNthClientInitiatedUnidirectionalId(1)));
   EXPECT_TRUE(stream_id_manager_->IsAvailableStream(
-      GetParam() ? GetNthClientInitiatedBidirectionalId(2)
-                 : GetNthClientInitiatedUnidirectionalId(2)));
+      IsBidi() ? GetNthClientInitiatedBidirectionalId(2)
+               : GetNthClientInitiatedUnidirectionalId(2)));
 }
 
 // Tests that if MaybeIncreaseLargestPeerStreamId is given an extremely
 // large stream ID (larger than the limit) it is rejected.
 // This is a regression for Chromium bugs 909987 and 910040
 TEST_P(QuicStreamIdManagerTestServer, ExtremeMaybeIncreaseLargestPeerStreamId) {
-  QuicStreamId too_big_stream_id =
-      stream_id_manager_->actual_max_allowed_incoming_stream_id() +
-      kV99StreamIdIncrement * 20;
-
+  QuicStreamId too_big_stream_id = StreamCountToId(
+      stream_id_manager_->incoming_actual_max_streams() + 20,
+      Perspective::IS_CLIENT);  // This node is a server, incoming stream
+                                // ids must be client-originated.
   std::string error_details =
-      GetParam() ? "Stream id 480 above 400" : "Stream id 478 above 398";
+      IsBidi() ? "Stream id 480 would exceed stream count limit 101"
+               : "Stream id 478 would exceed stream count limit 100";
   EXPECT_CALL(*connection_,
               CloseConnection(QUIC_INVALID_STREAM_ID, error_details, _));
-
   EXPECT_FALSE(
       stream_id_manager_->MaybeIncreaseLargestPeerStreamId(too_big_stream_id));
 }
 
+// Check that the OnMaxStreamFrame logic properly handles all the
+// cases of offered max streams and outgoing_static_stream_count_,
+// checking for the wrap conditions. Tests in server perspective, necessary
+// because internally, some calculations depend on the client/server
+// perspective.
+TEST_P(QuicStreamIdManagerTestServer, TestMaxStreamsWrapChecks) {
+  QuicStreamCount max_stream_count =
+      QuicUtils::GetMaxStreamCount(IsUnidi(), Perspective::IS_SERVER);
+  QuicMaxStreamsFrame frame;
+  frame.unidirectional = IsUnidi();
+
+  // Check the case where the offered stream count is less than the
+  // implementation maximum,
+  frame.stream_count = max_stream_count - 10;
+  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  EXPECT_EQ(max_stream_count - 10, stream_id_manager_->outgoing_max_streams());
+
+  // Check the case where the offered stream count is greater than the
+  // implementation maximum. The count should peg at the maximum.
+  frame.stream_count = max_stream_count + 10;
+  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  EXPECT_EQ(max_stream_count, stream_id_manager_->outgoing_max_streams());
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic