Avoid invoking ExtensionVisitorInterface::OnSetting() for known SETTINGS parameters.

This CL changes Http2DecoderAdapter::OnSetting() to avoid calling
extension_->OnSetting() for known SETTINGS parameters (defined as
SpdyKnownSettingsId [1]). This change allows classes (e.g., OgHttp2Session) to
implement SpdyFramerVisitorInterface and ExtensionVisitorInterface without
having known SETTINGS parameters passed to them twice.

Archaeology shows prior state as:
  1. SpdyFramerVisitorInterface::OnSetting() only accepted known SETTINGS;
     ExtensionVisitorInterface::OnSetting() only accepted unknown SETTINGS.
  2. Both OnSetting()s accepted known and unknown SETTINGS as of cl/186393706.
  3. This CL causes ExtensionVisitorInterface::OnSetting() to only accept
     unknown SETTINGS; SpdyFramerVisitorInterface::OnSetting() still accepts
     known and unknown SETTINGS.

Note that Http2SettingsFields has a method IsSupportedParameter() [2], but that
would return false for certain SETTINGS parameters like
SETTINGS_ENABLE_CONNECT_PROTOCOL that we do not want to send to the
ExtensionVisitorInterface. Thus, this CL opts for ParseSettingsId() instead and
adds coverage to SpdyFramerTest.ReadKnownAndUnknownSettingsWithExtension.

This CL should be a functional no-op because production
ExtensionVisitorInterface::OnSetting() implementations currently check only for
the METADATA SETTINGS parameter, which would still be considered unknown.

[1] http://google3/third_party/spdy/core/spdy_protocol.h;l=139-162;rcl=387836338
[2] http://google3/third_party/http2/http2_structures.h;l=214;rcl=434624268

PiperOrigin-RevId: 435345949
diff --git a/http2/adapter/oghttp2_adapter_test.cc b/http2/adapter/oghttp2_adapter_test.cc
index 1925173..2aa0255 100644
--- a/http2/adapter/oghttp2_adapter_test.cc
+++ b/http2/adapter/oghttp2_adapter_test.cc
@@ -113,12 +113,10 @@
   EXPECT_CALL(server_visitor, OnFrameHeader(0, 12, SETTINGS, 0x0));
   EXPECT_CALL(server_visitor, OnSettingsStart());
   EXPECT_CALL(server_visitor,
-              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}))
-      .Times(2);
+              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}));
   EXPECT_CALL(
       server_visitor,
-      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}))
-      .Times(2);
+      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}));
   EXPECT_CALL(server_visitor, OnSettingsEnd());
   {
     const int64_t result = server_adapter->ProcessBytes(client_visitor.data());
@@ -167,8 +165,7 @@
   EXPECT_CALL(client_visitor, OnSettingsStart());
   EXPECT_CALL(client_visitor,
               OnSetting(Http2Setting{
-                  Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1u}))
-      .Times(2);
+                  Http2KnownSettingsId::ENABLE_CONNECT_PROTOCOL, 1u}));
   EXPECT_CALL(client_visitor, OnSettingsEnd());
   {
     const int64_t result = client_adapter->ProcessBytes(server_visitor.data());
@@ -179,12 +176,10 @@
   EXPECT_CALL(server_visitor, OnFrameHeader(0, 12, SETTINGS, 0x0));
   EXPECT_CALL(server_visitor, OnSettingsStart());
   EXPECT_CALL(server_visitor,
-              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}))
-      .Times(2);
+              OnSetting(Http2Setting{Http2KnownSettingsId::ENABLE_PUSH, 0u}));
   EXPECT_CALL(
       server_visitor,
-      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}))
-      .Times(2);
+      OnSetting(Http2Setting{Http2KnownSettingsId::MAX_HEADER_LIST_SIZE, 42u}));
   EXPECT_CALL(server_visitor, OnSettingsEnd());
   {
     const int64_t result = server_adapter->ProcessBytes(client_visitor.data());
@@ -1603,8 +1598,6 @@
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
   EXPECT_CALL(visitor, OnSettingsStart());
   EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 100u}));
-  // Duplicate setting callback due to the way extensions work.
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 100u}));
   EXPECT_CALL(visitor, OnSettingsEnd());
 
   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
@@ -1636,8 +1629,6 @@
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
   EXPECT_CALL(visitor, OnSettingsStart());
   EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 40960u}));
-  // Duplicate setting callback due to the way extensions work.
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{HEADER_TABLE_SIZE, 40960u}));
   EXPECT_CALL(visitor, OnSettingsEnd());
 
   const int64_t stream_result = adapter->ProcessBytes(stream_frames);
@@ -2077,9 +2068,6 @@
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
   EXPECT_CALL(visitor, OnSettingsStart());
   EXPECT_CALL(visitor, OnSetting);
-  // TODO(diannahu): Remove this duplicate call with a separate
-  // ExtensionVisitorInterface implementation.
-  EXPECT_CALL(visitor, OnSetting);
   EXPECT_CALL(visitor, OnSettingsEnd());
 
   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
@@ -2189,10 +2177,7 @@
   // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
   EXPECT_CALL(visitor, OnSettingsStart());
-  // TODO(diannahu): Remove the duplicate call with a separate
-  // ExtensionVisitorInterface implementation.
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}))
-      .Times(2);
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
   EXPECT_CALL(visitor, OnSettingsEnd());
   EXPECT_CALL(visitor, OnFrameHeader(0, 4, WINDOW_UPDATE, 0));
   EXPECT_CALL(visitor, OnWindowUpdate(0, 65536));
@@ -2310,10 +2295,7 @@
   // SETTINGS with INITIAL_STREAM_WINDOW
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
   EXPECT_CALL(visitor, OnSettingsStart());
-  // TODO(diannahu): Remove the duplicate call with a separate
-  // ExtensionVisitorInterface implementation.
-  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}))
-      .Times(2);
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, 80000u}));
   EXPECT_CALL(visitor, OnSettingsEnd());
 
   const int64_t settings_result = adapter->ProcessBytes(settings_frame);
@@ -2345,12 +2327,9 @@
   // Server preface (SETTINGS with INITIAL_STREAM_WINDOW)
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
   EXPECT_CALL(visitor, OnSettingsStart());
-  // TODO(diannahu): Remove the duplicate call with a separate
-  // ExtensionVisitorInterface implementation.
-  EXPECT_CALL(
-      visitor,
-      OnInvalidFrame(0, Http2VisitorInterface::InvalidFrameError::kFlowControl))
-      .Times(2);
+  EXPECT_CALL(visitor,
+              OnInvalidFrame(
+                  0, Http2VisitorInterface::InvalidFrameError::kFlowControl));
   EXPECT_CALL(visitor, OnConnectionError(ConnectionError::kFlowControlError));
 
   const int64_t initial_result = adapter->ProcessBytes(initial_frames);
@@ -2429,9 +2408,8 @@
 
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0));
   EXPECT_CALL(visitor, OnSettingsStart());
-  EXPECT_CALL(visitor,
-              OnSetting(Http2Setting{INITIAL_WINDOW_SIZE, kLargeInitialWindow}))
-      .Times(2);
+  EXPECT_CALL(visitor, OnSetting(Http2Setting{INITIAL_WINDOW_SIZE,
+                                              kLargeInitialWindow}));
   EXPECT_CALL(visitor, OnSettingsEnd());
 
   const int64_t read_result = adapter->ProcessBytes(frames);
@@ -3062,8 +3040,7 @@
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
   EXPECT_CALL(visitor, OnSettingsStart());
   EXPECT_CALL(visitor, OnSetting(Http2Setting{
-                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 2u}))
-      .Times(2);
+                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 2u}));
   EXPECT_CALL(visitor, OnSettingsEnd());
   EXPECT_CALL(visitor, OnFrameHeader(0, 0, SETTINGS, 0x1));
   EXPECT_CALL(visitor, OnSettingsAck());
@@ -3102,8 +3079,7 @@
   EXPECT_CALL(visitor, OnFrameHeader(0, 6, SETTINGS, 0x0));
   EXPECT_CALL(visitor, OnSettingsStart());
   EXPECT_CALL(visitor, OnSetting(Http2Setting{
-                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 5u}))
-      .Times(2);
+                           Http2KnownSettingsId::MAX_CONCURRENT_STREAMS, 5u}));
   EXPECT_CALL(visitor, OnSettingsEnd());
 
   adapter->ProcessBytes(update_streams);
@@ -5248,7 +5224,7 @@
   // Client preface (empty SETTINGS)
   EXPECT_CALL(server_visitor, OnFrameHeader(0, _, SETTINGS, 0));
   EXPECT_CALL(server_visitor, OnSettingsStart());
-  EXPECT_CALL(server_visitor, OnSetting(_)).Times(testing::AnyNumber());
+  EXPECT_CALL(server_visitor, OnSetting).Times(testing::AnyNumber());
   EXPECT_CALL(server_visitor, OnSettingsEnd());
   // Stream 1
   EXPECT_CALL(server_visitor, OnFrameHeader(1, _, HEADERS, 5));
diff --git a/spdy/core/http2_frame_decoder_adapter.cc b/spdy/core/http2_frame_decoder_adapter.cc
index f9e0f40..0f6da60 100644
--- a/spdy/core/http2_frame_decoder_adapter.cc
+++ b/spdy/core/http2_frame_decoder_adapter.cc
@@ -556,7 +556,8 @@
   QUICHE_DVLOG(1) << "OnSetting: " << setting_fields;
   const auto parameter = static_cast<SpdySettingsId>(setting_fields.parameter);
   visitor()->OnSetting(parameter, setting_fields.value);
-  if (extension_ != nullptr) {
+  SpdyKnownSettingsId known_id;
+  if (extension_ != nullptr && !spdy::ParseSettingsId(parameter, &known_id)) {
     extension_->OnSetting(parameter, setting_fields.value);
   }
 }
diff --git a/spdy/core/http2_frame_decoder_adapter.h b/spdy/core/http2_frame_decoder_adapter.h
index 0c21972..5664470 100644
--- a/spdy/core/http2_frame_decoder_adapter.h
+++ b/spdy/core/http2_frame_decoder_adapter.h
@@ -527,7 +527,7 @@
  public:
   virtual ~ExtensionVisitorInterface() {}
 
-  // Called when SETTINGS are received, including non-standard SETTINGS.
+  // Called when non-standard SETTINGS are received.
   virtual void OnSetting(SpdySettingsId id, uint32_t value) = 0;
 
   // Called when non-standard frames are received.
diff --git a/spdy/core/spdy_framer_test.cc b/spdy/core/spdy_framer_test.cc
index 80e6256..236a02f 100644
--- a/spdy/core/spdy_framer_test.cc
+++ b/spdy/core/spdy_framer_test.cc
@@ -3238,7 +3238,7 @@
 
 TEST_P(SpdyFramerTest, ReadKnownAndUnknownSettingsWithExtension) {
   const unsigned char kH2FrameData[] = {
-      0x00, 0x00, 0x12,        // Length: 18
+      0x00, 0x00, 0x18,        // Length: 24
       0x04,                    //   Type: SETTINGS
       0x00,                    //  Flags: none
       0x00, 0x00, 0x00, 0x00,  // Stream: 0
@@ -3248,6 +3248,8 @@
       0x00, 0x01, 0x00, 0x02,  //  Value: 65538
       0x00, 0x02,              //  Param: ENABLE_PUSH
       0x00, 0x00, 0x00, 0x01,  //  Value: 1
+      0x00, 0x08,              //  Param: ENABLE_CONNECT_PROTOCOL
+      0x00, 0x00, 0x00, 0x01,  //  Value: 1
   };
 
   TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
@@ -3257,14 +3259,13 @@
 
   // In HTTP/2, we ignore unknown settings because of extensions. However, we
   // pass the SETTINGS to the visitor, which can decide how to handle them.
-  EXPECT_EQ(3, visitor.setting_count_);
+  EXPECT_EQ(4, visitor.setting_count_);
   EXPECT_EQ(0, visitor.error_count_);
 
-  // The extension receives all SETTINGS, including the non-standard SETTINGS.
+  // The extension receives only the non-standard SETTINGS.
   EXPECT_THAT(
       extension.settings_received_,
-      testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538),
-                           testing::Pair(2, 1)));
+      testing::ElementsAre(testing::Pair(16, 2), testing::Pair(95, 65538)));
 }
 
 // Tests handling of SETTINGS frame with entries out of order.