Add origin trial ids to non-standard stats members.

Bug: chromium:943076
Change-Id: I2d8211d3acd844cf602ed1c7de08bb7441263950
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/128420
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27186}
diff --git a/api/stats/rtc_stats.h b/api/stats/rtc_stats.h
index 2407ce0..ff79336 100644
--- a/api/stats/rtc_stats.h
+++ b/api/stats/rtc_stats.h
@@ -319,8 +319,19 @@
   T value_;
 };
 
-// Same as above, but "is_standardized" returns false.
-//
+// Non-standard stats members can be exposed to the JavaScript API in Chrome
+// e.g. through origin trials. The group ID can be used by the blink layer to
+// determine if a stats member should be exposed or not. Multiple non-standard
+// stats members can share the same group ID so that they are exposed together.
+enum class NonStandardGroupId {
+  // I2E:
+  // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/hE2B1iItPDk
+  kRtcAudioJitterBufferMaxPackets,
+  // I2E:
+  // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/YbhMyqLXXXo
+  kRtcStatsRelativePacketArrivalDelay,
+};
+
 // Using inheritance just so that it's obvious from the member's declaration
 // whether it's standardized or not.
 template <typename T>
@@ -328,21 +339,30 @@
  public:
   explicit RTCNonStandardStatsMember(const char* name)
       : RTCStatsMember<T>(name) {}
+  RTCNonStandardStatsMember(const char* name,
+                            std::initializer_list<NonStandardGroupId> group_ids)
+      : RTCStatsMember<T>(name), group_ids_(group_ids) {}
   RTCNonStandardStatsMember(const char* name, const T& value)
       : RTCStatsMember<T>(name, value) {}
   RTCNonStandardStatsMember(const char* name, T&& value)
       : RTCStatsMember<T>(name, std::move(value)) {}
   explicit RTCNonStandardStatsMember(const RTCNonStandardStatsMember<T>& other)
-      : RTCStatsMember<T>(other) {}
+      : RTCStatsMember<T>(other), group_ids_(other.group_ids_) {}
   explicit RTCNonStandardStatsMember(RTCNonStandardStatsMember<T>&& other)
-      : RTCStatsMember<T>(std::move(other)) {}
+      : group_ids_(std::move(other.group_ids_)),
+        RTCStatsMember<T>(std::move(other)) {}
 
   bool is_standardized() const override { return false; }
 
+  std::vector<NonStandardGroupId> group_ids() const { return group_ids_; }
+
   T& operator=(const T& value) { return RTCStatsMember<T>::operator=(value); }
   T& operator=(const T&& value) {
     return RTCStatsMember<T>::operator=(std::move(value));
   }
+
+ private:
+  std::vector<NonStandardGroupId> group_ids_;
 };
 }  // namespace webrtc
 
diff --git a/stats/rtc_stats_unittest.cc b/stats/rtc_stats_unittest.cc
index 0755660..1a948ba 100644
--- a/stats/rtc_stats_unittest.cc
+++ b/stats/rtc_stats_unittest.cc
@@ -339,6 +339,16 @@
   EXPECT_FALSE(unstandardized.is_standardized());
 }
 
+TEST(RTCStatsTest, NonStandardGroupId) {
+  auto group_id = NonStandardGroupId::kRtcAudioJitterBufferMaxPackets;
+  RTCNonStandardStatsMember<int32_t> with_group_id("stat", {group_id});
+  std::vector<NonStandardGroupId> expected_ids({group_id});
+  EXPECT_EQ(expected_ids, with_group_id.group_ids());
+
+  RTCNonStandardStatsMember<int32_t> without_group_id("stat");
+  EXPECT_TRUE(without_group_id.group_ids().empty());
+}
+
 // Death tests.
 // Disabled on Android because death tests misbehave on Android, see
 // base/test/gtest_util.h.
diff --git a/stats/rtcstats_objects.cc b/stats/rtcstats_objects.cc
index ccf2574..69b5e0a 100644
--- a/stats/rtcstats_objects.cc
+++ b/stats/rtcstats_objects.cc
@@ -14,6 +14,8 @@
 
 #include "rtc_base/checks.h"
 
+#include "api/stats/rtc_stats.h"
+
 namespace webrtc {
 
 const char* const RTCDataChannelState::kConnecting = "connecting";
@@ -426,9 +428,16 @@
       total_samples_duration("totalSamplesDuration"),
       concealed_samples("concealedSamples"),
       concealment_events("concealmentEvents"),
-      jitter_buffer_flushes("jitterBufferFlushes"),
-      delayed_packet_outage_samples("delayedPacketOutageSamples"),
-      relative_packet_arrival_delay("relativePacketArrivalDelay"),
+      jitter_buffer_flushes(
+          "jitterBufferFlushes",
+          {NonStandardGroupId::kRtcAudioJitterBufferMaxPackets}),
+      delayed_packet_outage_samples(
+          "delayedPacketOutageSamples",
+          {NonStandardGroupId::kRtcAudioJitterBufferMaxPackets,
+           NonStandardGroupId::kRtcStatsRelativePacketArrivalDelay}),
+      relative_packet_arrival_delay(
+          "relativePacketArrivalDelay",
+          {NonStandardGroupId::kRtcStatsRelativePacketArrivalDelay}),
       freeze_count("freezeCount"),
       pause_count("pauseCount"),
       total_freezes_duration("totalFreezesDuration"),