PeerConnectionInterface::GetStats() with selector argument added.

This exposes the stats selection algorithm[1] on the PeerConnection.

Per-spec, there are four flavors of getStats():
1. RTCPeerConnection.getStats().
2. RTCPeerConnection.getStats(MediaStreamTrack selector).
3. RTCRtpSender.getStats().
4. RTCRtpReceiver.getStats().

1) is the parameterless getStats() which is already shipped.
2) is the same as 3) and 4) except the track is used to look up the
corresponding sender/receiver to use as the selector.
3) and 4) perform stats collection with a filter, which is implemented
in RTCStatsCollector.GetStatsReport(selector).

For technical reasons, it is easier to place GetStats() on the
PeerConnection where the RTCStatsCollector lives than to place it on the
sender/receiver. Passing the selector as an argument or as a "this"
makes little difference other than style. Wiring Chrome up such that the
JavaScript APIs is like the spec is trivial after GetStats() is added to
PeerConnectionInterface.

This CL also adds comments documenting our intent to deprecate and
remove the legacy GetStats() APIs some time in the future.

[1] https://w3c.github.io/webrtc-pc/#dfn-stats-selection-algorithm

Bug: chromium:680172
Change-Id: I09316ba6f20b25d4f9c11785d0a1a1262d6062a1
Reviewed-on: https://webrtc-review.googlesource.com/62900
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22602}
diff --git a/pc/rtcstats_integrationtest.cc b/pc/rtcstats_integrationtest.cc
index 40d07f7..cdc46d7 100644
--- a/pc/rtcstats_integrationtest.cc
+++ b/pc/rtcstats_integrationtest.cc
@@ -137,10 +137,26 @@
   rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCaller() {
     return GetStats(caller_->pc());
   }
+  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCaller(
+      rtc::scoped_refptr<RtpSenderInterface> selector) {
+    return GetStats(caller_->pc(), selector);
+  }
+  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCaller(
+      rtc::scoped_refptr<RtpReceiverInterface> selector) {
+    return GetStats(caller_->pc(), selector);
+  }
 
   rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCallee() {
     return GetStats(callee_->pc());
   }
+  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCallee(
+      rtc::scoped_refptr<RtpSenderInterface> selector) {
+    return GetStats(callee_->pc(), selector);
+  }
+  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCallee(
+      rtc::scoped_refptr<RtpReceiverInterface> selector) {
+    return GetStats(callee_->pc(), selector);
+  }
 
  protected:
   static rtc::scoped_refptr<const RTCStatsReport> GetStats(
@@ -152,6 +168,17 @@
     return stats_obtainer->report();
   }
 
+  template <typename T>
+  static rtc::scoped_refptr<const RTCStatsReport> GetStats(
+      PeerConnectionInterface* pc,
+      rtc::scoped_refptr<T> selector) {
+    rtc::scoped_refptr<RTCStatsObtainer> stats_obtainer =
+        RTCStatsObtainer::Create();
+    pc->GetStats(selector, stats_obtainer);
+    EXPECT_TRUE_WAIT(stats_obtainer->report(), kGetStatsTimeoutMs);
+    return stats_obtainer->report();
+  }
+
   // |network_thread_| uses |virtual_socket_server_| so they must be
   // constructed/destructed in the correct order.
   rtc::VirtualSocketServer virtual_socket_server_;
@@ -315,7 +342,7 @@
       : report_(report) {
   }
 
-  void VerifyReport() {
+  void VerifyReport(std::vector<const char*> allowed_missing_stats) {
     std::set<const char*> missing_stats = StatsTypes();
     bool verify_successful = true;
     std::vector<const RTCTransportStats*> transport_stats =
@@ -367,9 +394,10 @@
         verify_successful = false;
       }
     }
-    if (!missing_stats.empty()) {
-      verify_successful = false;
-      for (const char* missing : missing_stats) {
+    for (const char* missing : missing_stats) {
+      if (std::find(allowed_missing_stats.begin(), allowed_missing_stats.end(),
+                    missing) == allowed_missing_stats.end()) {
+        verify_successful = false;
         EXPECT_TRUE(false) << "Missing expected stats type: " << missing;
       }
     }
@@ -718,7 +746,7 @@
   StartCall();
 
   rtc::scoped_refptr<const RTCStatsReport> report = GetStatsFromCaller();
-  RTCStatsReportVerifier(report.get()).VerifyReport();
+  RTCStatsReportVerifier(report.get()).VerifyReport({});
   EXPECT_EQ(report->ToJson(), RTCStatsReportTraceListener::last_trace());
 }
 
@@ -726,10 +754,68 @@
   StartCall();
 
   rtc::scoped_refptr<const RTCStatsReport> report = GetStatsFromCallee();
-  RTCStatsReportVerifier(report.get()).VerifyReport();
+  RTCStatsReportVerifier(report.get()).VerifyReport({});
   EXPECT_EQ(report->ToJson(), RTCStatsReportTraceListener::last_trace());
 }
 
+// These tests exercise the integration of the stats selection algorithm inside
+// of PeerConnection. See rtcstatstraveral_unittest.cc for more detailed stats
+// traversal tests on particular stats graphs.
+TEST_F(RTCStatsIntegrationTest, GetStatsWithSenderSelector) {
+  StartCall();
+  ASSERT_FALSE(caller_->pc()->GetSenders().empty());
+  rtc::scoped_refptr<const RTCStatsReport> report =
+      GetStatsFromCaller(caller_->pc()->GetSenders()[0]);
+  std::vector<const char*> allowed_missing_stats = {
+      // TODO(hbos): Include RTC[Audio/Video]ReceiverStats when implemented.
+      // TODO(hbos): Include RTCRemoteOutboundRtpStreamStats when implemented.
+      // TODO(hbos): Include RTCRtpContributingSourceStats when implemented.
+      RTCInboundRTPStreamStats::kType, RTCPeerConnectionStats::kType,
+      RTCMediaStreamStats::kType, RTCDataChannelStats::kType,
+  };
+  RTCStatsReportVerifier(report.get()).VerifyReport(allowed_missing_stats);
+  EXPECT_TRUE(report->size());
+}
+
+TEST_F(RTCStatsIntegrationTest, GetStatsWithReceiverSelector) {
+  StartCall();
+
+  ASSERT_FALSE(caller_->pc()->GetReceivers().empty());
+  rtc::scoped_refptr<const RTCStatsReport> report =
+      GetStatsFromCaller(caller_->pc()->GetReceivers()[0]);
+  std::vector<const char*> allowed_missing_stats = {
+      // TODO(hbos): Include RTC[Audio/Video]SenderStats when implemented.
+      // TODO(hbos): Include RTCRemoteInboundRtpStreamStats when implemented.
+      // TODO(hbos): Include RTCRtpContributingSourceStats when implemented.
+      RTCOutboundRTPStreamStats::kType, RTCPeerConnectionStats::kType,
+      RTCMediaStreamStats::kType, RTCDataChannelStats::kType,
+  };
+  RTCStatsReportVerifier(report.get()).VerifyReport(allowed_missing_stats);
+  EXPECT_TRUE(report->size());
+}
+
+TEST_F(RTCStatsIntegrationTest, GetStatsWithInvalidSenderSelector) {
+  StartCall();
+
+  ASSERT_FALSE(callee_->pc()->GetSenders().empty());
+  // The selector is invalid for the caller because it belongs to the callee.
+  auto invalid_selector = callee_->pc()->GetSenders()[0];
+  rtc::scoped_refptr<const RTCStatsReport> report =
+      GetStatsFromCaller(invalid_selector);
+  EXPECT_FALSE(report->size());
+}
+
+TEST_F(RTCStatsIntegrationTest, GetStatsWithInvalidReceiverSelector) {
+  StartCall();
+
+  ASSERT_FALSE(callee_->pc()->GetReceivers().empty());
+  // The selector is invalid for the caller because it belongs to the callee.
+  auto invalid_selector = callee_->pc()->GetReceivers()[0];
+  rtc::scoped_refptr<const RTCStatsReport> report =
+      GetStatsFromCaller(invalid_selector);
+  EXPECT_FALSE(report->size());
+}
+
 TEST_F(RTCStatsIntegrationTest, GetsStatsWhileDestroyingPeerConnections) {
   StartCall();