Fixing the behavior of the candidate filter with pooled candidates.

According to JSEP, the candidate filter does not affect pooled
candidates because they can be filtered once they're ready to be
surfaced to the application.

So, pooled port allocator sessions will use a filter of CF_ALL, with a
new filter applied when the session is taken by a P2PTransportChannel.

When the filter is applied:
* Some candidates may no longer be returned by ReadyCandidates()
* Some candidates may no longer have a "related address" (for privacy)
* Some ports may no longer be returned by ReadyPorts()

To simplify this, the candidate filtering logic is now moved up from
the Ports to the BasicPortAllocator, with some helper methods to perform
the filtering and stripping out of data.

R=honghaiz@webrtc.org, pthatcher@webrtc.org

Review URL: https://codereview.webrtc.org/1998813002 .

Cr-Commit-Position: refs/heads/master@{#12856}
diff --git a/webrtc/p2p/base/portallocator_unittest.cc b/webrtc/p2p/base/portallocator_unittest.cc
index 2e16725..dd84523 100644
--- a/webrtc/p2p/base/portallocator_unittest.cc
+++ b/webrtc/p2p/base/portallocator_unittest.cc
@@ -15,6 +15,7 @@
 #include "webrtc/p2p/base/fakeportallocator.h"
 #include "webrtc/p2p/base/portallocator.h"
 
+static const char kSessionId[] = "session id";
 static const char kContentName[] = "test content";
 // Based on ICE_UFRAG_LENGTH
 static const char kIceUfrag[] = "TESTICEUFRAG0000";
@@ -37,6 +38,20 @@
                                  candidate_pool_size);
   }
 
+  std::unique_ptr<cricket::FakePortAllocatorSession> CreateSession(
+      const std::string& sid,
+      const std::string& content_name,
+      int component,
+      const std::string& ice_ufrag,
+      const std::string& ice_pwd) {
+    return std::unique_ptr<cricket::FakePortAllocatorSession>(
+        static_cast<cricket::FakePortAllocatorSession*>(
+            allocator_
+                ->CreateSession(sid, content_name, component, ice_ufrag,
+                                ice_pwd)
+                .release()));
+  }
+
   const cricket::FakePortAllocatorSession* GetPooledSession() const {
     return static_cast<const cricket::FakePortAllocatorSession*>(
         allocator_->GetPooledSession());
@@ -76,6 +91,19 @@
   EXPECT_EQ(0, GetAllPooledSessionsReturnCount());
 }
 
+// Call CreateSession and verify that the parameters passed in and the
+// candidate filter are applied as expected.
+TEST_F(PortAllocatorTest, CreateSession) {
+  allocator_->set_candidate_filter(cricket::CF_RELAY);
+  auto session = CreateSession(kSessionId, kContentName, 1, kIceUfrag, kIcePwd);
+  ASSERT_NE(nullptr, session);
+  EXPECT_EQ(cricket::CF_RELAY, session->candidate_filter());
+  EXPECT_EQ(kContentName, session->content_name());
+  EXPECT_EQ(1, session->component());
+  EXPECT_EQ(kIceUfrag, session->ice_ufrag());
+  EXPECT_EQ(kIcePwd, session->ice_pwd());
+}
+
 TEST_F(PortAllocatorTest, SetConfigurationUpdatesIceServers) {
   cricket::ServerAddresses stun_servers_1 = {stun_server_1};
   std::vector<cricket::RelayServerConfig> turn_servers_1 = {turn_server_1};
@@ -203,3 +231,17 @@
   EXPECT_EQ(kIceUfrag, session->ice_ufrag());
   EXPECT_EQ(kIcePwd, session->ice_pwd());
 }
+
+// According to JSEP, candidate filtering should be done when the pooled
+// candidates are surfaced to the application. This means when a pooled
+// session is taken. So a pooled session should gather candidates
+// unfiltered until it's returned by TakePooledSession.
+TEST_F(PortAllocatorTest, TakePooledSessionUpdatesCandidateFilter) {
+  allocator_->set_candidate_filter(cricket::CF_RELAY);
+  SetConfigurationWithPoolSize(1);
+  auto peeked_session = GetPooledSession();
+  ASSERT_NE(nullptr, peeked_session);
+  EXPECT_EQ(cricket::CF_ALL, peeked_session->candidate_filter());
+  auto session = TakePooledSession();
+  EXPECT_EQ(cricket::CF_RELAY, session->candidate_filter());
+}