Make PeerConnectionTest.doTest wait for ice candidates
This change the PeerConnectionTest.doTest wait for at least one ice candidate and also make sure the list of candidates in gotIceCandidates is synchronized.

BUG=webrtc:5010

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

Cr-Commit-Position: refs/heads/master@{#9997}
diff --git a/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java b/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
index 870b2e5..7affbd9 100644
--- a/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
+++ b/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
@@ -38,6 +38,7 @@
 import java.util.Arrays;
 import java.util.IdentityHashMap;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeSet;
 import java.util.concurrent.CountDownLatch;
@@ -72,7 +73,7 @@
         new LinkedList<String>();
     private LinkedList<String> expectedRemoveStreamLabels =
         new LinkedList<String>();
-    public LinkedList<IceCandidate> gotIceCandidates =
+    private final LinkedList<IceCandidate> gotIceCandidates =
         new LinkedList<IceCandidate>();
     private Map<MediaStream, WeakReference<VideoRenderer>> renderers =
         new IdentityHashMap<MediaStream, WeakReference<VideoRenderer>>();
@@ -109,7 +110,10 @@
       // We don't assert expectedIceCandidates >= 0 because it's hard to know
       // how many to expect, in general.  We only use expectIceCandidates to
       // assert a minimal count.
-      gotIceCandidates.add(candidate);
+      synchronized (gotIceCandidates) {
+        gotIceCandidates.add(candidate);
+        gotIceCandidates.notifyAll();
+      }
     }
 
     private synchronized void setSize(int width, int height) {
@@ -376,6 +380,17 @@
                            (new Throwable()).getStackTrace()[1]);
       }
     }
+
+    // This methods return a list of all currently gathered ice candidates or waits until
+    // 1 candidate have been gathered.
+    public List<IceCandidate> getAtLeastOneIceCandidate() throws InterruptedException {
+      synchronized (gotIceCandidates) {
+        while (gotIceCandidates.isEmpty()) {
+          gotIceCandidates.wait();
+        }
+        return new LinkedList<IceCandidate>(gotIceCandidates);
+      }
+    }
   }
 
   private static class SdpObserverLatch implements SdpObserver {
@@ -634,14 +649,17 @@
     answeringExpectations.expectDataChannel("offeringDC");
     answeringExpectations.expectStateChange(DataChannel.State.OPEN);
 
-    for (IceCandidate candidate : offeringExpectations.gotIceCandidates) {
+    // Wait for at least one ice candidate from the offering PC and forward them to the answering
+    // PC.
+    for (IceCandidate candidate : offeringExpectations.getAtLeastOneIceCandidate()) {
       answeringPC.addIceCandidate(candidate);
     }
-    offeringExpectations.gotIceCandidates.clear();
-    for (IceCandidate candidate : answeringExpectations.gotIceCandidates) {
+
+    // Wait for at least one ice candidate from the answering PC and forward them to the offering
+    // PC.
+    for (IceCandidate candidate : answeringExpectations.getAtLeastOneIceCandidate()) {
       offeringPC.addIceCandidate(candidate);
     }
-    answeringExpectations.gotIceCandidates.clear();
 
     offeringExpectations.waitForAllExpectationsToBeSatisfied();
     answeringExpectations.waitForAllExpectationsToBeSatisfied();