Add a usage pattern bit for host-host connections.

Bug: None
Change-Id: I66dee594295212fcc40a7706f688c9ab15967775
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/149341
Commit-Queue: Qingsi Wang <qingsi@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29172}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 0b943b51..e2e6bd5 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -4316,6 +4316,13 @@
     return;
   }
 
+  if (event.selected_candidate_pair.local_candidate().type() ==
+          LOCAL_PORT_TYPE &&
+      event.selected_candidate_pair.remote_candidate().type() ==
+          LOCAL_PORT_TYPE) {
+    NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
+  }
+
   Observer()->OnIceSelectedCandidatePairChanged(event);
 }
 
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index 550a9ee..b6da82a 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -103,7 +103,13 @@
     // successfully added, either via AddIceCandidate or from the remote
     // description.
     REMOTE_CANDIDATE_ADDED = 0x20000,
-    MAX_VALUE = 0x40000,
+    // An explicit host-host candidate pair is selected, i.e. both the local and
+    // the remote candidates have the host type. This does not include candidate
+    // pairs formed with equivalent prflx remote candidates, e.g. a host-prflx
+    // pair where the prflx candidate has the same base as a host candidate of
+    // the remote peer.
+    DIRECT_CONNECTION_SELECTED = 0x40000,
+    MAX_VALUE = 0x80000,
   };
 
   explicit PeerConnection(PeerConnectionFactory* factory,
diff --git a/pc/peer_connection_histogram_unittest.cc b/pc/peer_connection_histogram_unittest.cc
index bdf6994..2894c48 100644
--- a/pc/peer_connection_histogram_unittest.cc
+++ b/pc/peer_connection_histogram_unittest.cc
@@ -416,6 +416,7 @@
        PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
   // In this case, we may or may not have PRIVATE_CANDIDATE_COLLECTED,
   // depending on the machine configuration.
@@ -456,8 +457,12 @@
        PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
 
+  // Without a resolver, the callee cannot resolve the received mDNS candidate
+  // but can still connect with the caller via a prflx candidate. As a result,
+  // the bit for the direct connection should not be logged.
   int expected_fingerprint_callee = MakeUsageFingerprint(
       {PeerConnection::UsageEvent::AUDIO_ADDED,
        PeerConnection::UsageEvent::VIDEO_ADDED,
@@ -492,6 +497,8 @@
   caller->pc()->Close();
   callee->pc()->Close();
 
+  // Similar to the test above, the caller connects with the callee via a prflx
+  // candidate.
   int expected_fingerprint_caller = MakeUsageFingerprint(
       {PeerConnection::UsageEvent::AUDIO_ADDED,
        PeerConnection::UsageEvent::VIDEO_ADDED,
@@ -514,6 +521,7 @@
        PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
 
   EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
@@ -540,6 +548,7 @@
        PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
   EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
   EXPECT_TRUE(
@@ -615,6 +624,7 @@
        PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
 
   int expected_fingerprint_callee = MakeUsageFingerprint(
@@ -626,6 +636,7 @@
        PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
 
   EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
@@ -653,6 +664,7 @@
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
        PeerConnection::UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
 
   int expected_fingerprint_callee = MakeUsageFingerprint(
@@ -665,6 +677,7 @@
        PeerConnection::UsageEvent::ADD_ICE_CANDIDATE_SUCCEEDED,
        PeerConnection::UsageEvent::REMOTE_CANDIDATE_ADDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
 
   EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));
@@ -724,7 +737,9 @@
   callee->pc()->Close();
 
   // The caller should not have added any remote candidate either via
-  // AddIceCandidate or from the remote description.
+  // AddIceCandidate or from the remote description. Also, the caller connects
+  // with the callee via a prflx candidate and hence no direct connection bit
+  // should be set.
   int expected_fingerprint_caller = MakeUsageFingerprint(
       {PeerConnection::UsageEvent::DATA_ADDED,
        PeerConnection::UsageEvent::SET_LOCAL_DESCRIPTION_SUCCEEDED,
@@ -745,6 +760,7 @@
        PeerConnection::UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED,
        PeerConnection::UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED,
        PeerConnection::UsageEvent::ICE_STATE_CONNECTED,
+       PeerConnection::UsageEvent::DIRECT_CONNECTION_SELECTED,
        PeerConnection::UsageEvent::CLOSE_CALLED});
 
   EXPECT_EQ(2, webrtc::metrics::NumSamples(kUsagePatternMetric));