Remove Java PC support.
This cl removes none Android Java support.

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

Cr-Commit-Position: refs/heads/master@{#11522}
diff --git a/talk/app/webrtc/java/README b/talk/app/webrtc/java/README
index 454046c..f367556 100644
--- a/talk/app/webrtc/java/README
+++ b/talk/app/webrtc/java/README
@@ -2,22 +2,9 @@
 well as the JNI glue C++ code that lets the Java implementation reuse the C++
 implementation of the same API.
 
-To build the Java API and related tests, build with 
-OS=linux or OS=android and include
-build_with_libjingle=1 build_with_chromium=0
-in $GYP_DEFINES.
+To build the Java API and related tests, build with OS=android in $GYP_DEFINES.
 
 To use the Java API, start by looking at the public interface of
 org.webrtc.PeerConnection{,Factory} and the org.webrtc.PeerConnectionTest.
 
 To understand the implementation of the API, see the native code in jni/.
-
-An example command-line to build & run the unittest:
-cd path/to/trunk
-GYP_DEFINES="build_with_libjingle=1 build_with_chromium=0 java_home=path/to/JDK" gclient runhooks && \
-    ninja -C out/Debug libjingle_peerconnection_java_unittest && \
-    ./out/Debug/libjingle_peerconnection_java_unittest
-(where path/to/JDK should contain include/jni.h)
-
-During development it can be helpful to run the JVM with the -Xcheck:jni flag.
-
diff --git a/talk/app/webrtc/java/jni/classreferenceholder.cc b/talk/app/webrtc/java/jni/classreferenceholder.cc
index a7d36c2..0d52bc5 100644
--- a/talk/app/webrtc/java/jni/classreferenceholder.cc
+++ b/talk/app/webrtc/java/jni/classreferenceholder.cc
@@ -62,28 +62,21 @@
 }
 
 ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
+  LoadClass(jni, "android/graphics/SurfaceTexture");
   LoadClass(jni, "java/nio/ByteBuffer");
   LoadClass(jni, "java/util/ArrayList");
   LoadClass(jni, "org/webrtc/AudioTrack");
+  LoadClass(jni, "org/webrtc/CameraEnumerator");
+  LoadClass(jni, "org/webrtc/Camera2Enumerator");
+  LoadClass(jni, "org/webrtc/CameraEnumerationAndroid");
   LoadClass(jni, "org/webrtc/DataChannel");
   LoadClass(jni, "org/webrtc/DataChannel$Buffer");
   LoadClass(jni, "org/webrtc/DataChannel$Init");
   LoadClass(jni, "org/webrtc/DataChannel$State");
-  LoadClass(jni, "org/webrtc/IceCandidate");
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
-  LoadClass(jni, "android/graphics/SurfaceTexture");
-  LoadClass(jni, "org/webrtc/CameraEnumerator");
-  LoadClass(jni, "org/webrtc/Camera2Enumerator");
-  LoadClass(jni, "org/webrtc/CameraEnumerationAndroid");
-  LoadClass(jni, "org/webrtc/VideoCapturerAndroid");
-  LoadClass(jni, "org/webrtc/VideoCapturerAndroid$NativeObserver");
   LoadClass(jni, "org/webrtc/EglBase");
   LoadClass(jni, "org/webrtc/EglBase$Context");
   LoadClass(jni, "org/webrtc/EglBase14$Context");
-  LoadClass(jni, "org/webrtc/NetworkMonitor");
-  LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$ConnectionType");
-  LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$IPAddress");
-  LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$NetworkInformation");
+  LoadClass(jni, "org/webrtc/IceCandidate");
   LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder");
   LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder$OutputBufferInfo");
   LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder$VideoCodecType");
@@ -91,11 +84,13 @@
   LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedTextureBuffer");
   LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedOutputBuffer");
   LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$VideoCodecType");
-  LoadClass(jni, "org/webrtc/SurfaceTextureHelper");
-#endif
   LoadClass(jni, "org/webrtc/MediaSource$State");
   LoadClass(jni, "org/webrtc/MediaStream");
   LoadClass(jni, "org/webrtc/MediaStreamTrack$State");
+  LoadClass(jni, "org/webrtc/NetworkMonitor");
+  LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$ConnectionType");
+  LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$IPAddress");
+  LoadClass(jni, "org/webrtc/NetworkMonitorAutoDetect$NetworkInformation");
   LoadClass(jni, "org/webrtc/PeerConnectionFactory");
   LoadClass(jni, "org/webrtc/PeerConnection$BundlePolicy");
   LoadClass(jni, "org/webrtc/PeerConnection$ContinualGatheringPolicy");
@@ -112,8 +107,10 @@
   LoadClass(jni, "org/webrtc/SessionDescription$Type");
   LoadClass(jni, "org/webrtc/StatsReport");
   LoadClass(jni, "org/webrtc/StatsReport$Value");
+  LoadClass(jni, "org/webrtc/SurfaceTextureHelper");
+  LoadClass(jni, "org/webrtc/VideoCapturerAndroid");
+  LoadClass(jni, "org/webrtc/VideoCapturerAndroid$NativeObserver");
   LoadClass(jni, "org/webrtc/VideoRenderer$I420Frame");
-  LoadClass(jni, "org/webrtc/VideoCapturer");
   LoadClass(jni, "org/webrtc/VideoTrack");
 }
 
diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc
index 3237cd3..bbbd77f 100644
--- a/talk/app/webrtc/java/jni/peerconnection_jni.cc
+++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc
@@ -59,7 +59,12 @@
 #include <limits>
 #include <utility>
 
+#include "talk/app/webrtc/androidvideocapturer.h"
 #include "talk/app/webrtc/dtlsidentitystore.h"
+#include "talk/app/webrtc/java/jni/androidmediadecoder_jni.h"
+#include "talk/app/webrtc/java/jni/androidmediaencoder_jni.h"
+#include "talk/app/webrtc/java/jni/androidvideocapturer_jni.h"
+#include "talk/app/webrtc/java/jni/androidnetworkmonitor_jni.h"
 #include "talk/app/webrtc/java/jni/classreferenceholder.h"
 #include "talk/app/webrtc/java/jni/jni_helpers.h"
 #include "talk/app/webrtc/java/jni/native_handle_impl.h"
@@ -83,20 +88,10 @@
 #include "webrtc/media/webrtc/webrtcvideodecoderfactory.h"
 #include "webrtc/media/webrtc/webrtcvideoencoderfactory.h"
 #include "webrtc/system_wrappers/include/field_trial_default.h"
+#include "webrtc/system_wrappers/include/logcat_trace_context.h"
 #include "webrtc/system_wrappers/include/trace.h"
 #include "webrtc/voice_engine/include/voe_base.h"
 
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
-#include "talk/app/webrtc/androidvideocapturer.h"
-#include "talk/app/webrtc/java/jni/androidmediadecoder_jni.h"
-#include "talk/app/webrtc/java/jni/androidmediaencoder_jni.h"
-#include "talk/app/webrtc/java/jni/androidnetworkmonitor_jni.h"
-#include "talk/app/webrtc/java/jni/androidvideocapturer_jni.h"
-#include "webrtc/modules/video_render/video_render_internal.h"
-#include "webrtc/system_wrappers/include/logcat_trace_context.h"
-using webrtc::LogcatTraceContext;
-#endif
-
 using cricket::WebRtcVideoDecoderFactory;
 using cricket::WebRtcVideoEncoderFactory;
 using rtc::Bind;
@@ -112,6 +107,7 @@
 using webrtc::DataChannelInterface;
 using webrtc::DataChannelObserver;
 using webrtc::IceCandidateInterface;
+using webrtc::LogcatTraceContext;
 using webrtc::MediaConstraintsInterface;
 using webrtc::MediaSourceInterface;
 using webrtc::MediaStreamInterface;
@@ -137,11 +133,9 @@
 // Field trials initialization string
 static char *field_trials_init_string = NULL;
 
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
 // Set in PeerConnectionFactory_initializeAndroidGlobals().
 static bool factory_static_initialized = false;
 static bool video_hw_acceleration_enabled = true;
-#endif
 
 // Return the (singleton) Java Enum object corresponding to |index|;
 // |state_class_fragment| is something like "MediaSource$State".
@@ -889,18 +883,14 @@
   std::string path = JavaToStdString(jni, j_path);
   if (nativeLevels != webrtc::kTraceNone) {
     webrtc::Trace::set_level_filter(nativeLevels);
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
     if (path != "logcat:") {
-#endif
       RTC_CHECK_EQ(0, webrtc::Trace::SetTraceFile(path.c_str(), false))
           << "SetTraceFile failed";
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
     } else {
       // Intentionally leak this to avoid needing to reason about its lifecycle.
       // It keeps no state and functions only as a dispatch point.
       static LogcatTraceContext* g_trace_callback = new LogcatTraceContext();
     }
-#endif
   }
   if (nativeSeverity >= rtc::LS_SENSITIVE && nativeSeverity <= rtc::LS_ERROR) {
     rtc::LogMessage::LogToDebug(
@@ -940,10 +930,6 @@
   delete reinterpret_cast<cricket::VideoCapturer*>(j_p);
 }
 
-JOW(void, VideoRenderer_freeGuiVideoRenderer)(JNIEnv*, jclass, jlong j_p) {
-  delete reinterpret_cast<VideoRendererWrapper*>(j_p);
-}
-
 JOW(void, VideoRenderer_freeWrappedVideoRenderer)(JNIEnv*, jclass, jlong j_p) {
   delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p);
 }
@@ -995,7 +981,6 @@
   return (jlong)new PCOJava(jni, j_observer);
 }
 
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
 JOW(jboolean, PeerConnectionFactory_initializeAndroidGlobals)(
     JNIEnv* jni, jclass, jobject context,
     jboolean initialize_audio, jboolean initialize_video,
@@ -1005,7 +990,6 @@
   AndroidNetworkMonitor::SetAndroidContext(jni, context);
   if (!factory_static_initialized) {
     if (initialize_video) {
-      failure |= webrtc::SetRenderAndroidVM(GetJVM());
       failure |= AndroidVideoCapturerJni::SetAndroidObjects(jni, context);
     }
     if (initialize_audio)
@@ -1014,7 +998,6 @@
   }
   return !failure;
 }
-#endif  // defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
 
 JOW(void, PeerConnectionFactory_initializeFieldTrials)(
     JNIEnv* jni, jclass, jstring j_trials_init_string) {
@@ -1185,7 +1168,7 @@
   if (has_options) {
     options = ParseOptionsFromJava(jni, joptions);
   }
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
+
   if (video_hw_acceleration_enabled) {
     encoder_factory = new MediaCodecVideoEncoderFactory();
     decoder_factory = new MediaCodecVideoDecoderFactory();
@@ -1196,7 +1179,7 @@
     network_monitor_factory = new AndroidNetworkMonitorFactory();
     rtc::NetworkMonitorFactory::SetFactory(network_monitor_factory);
   }
-#endif
+
   rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
       webrtc::CreatePeerConnectionFactory(worker_thread,
                                           signaling_thread,
@@ -1299,42 +1282,30 @@
 JOW(jboolean, PeerConnectionFactory_nativeStartAecDump)(
     JNIEnv* jni, jclass, jlong native_factory, jint file,
     jint filesize_limit_bytes) {
-#if defined(ANDROID)
   rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
       factoryFromJava(native_factory));
   return factory->StartAecDump(file, filesize_limit_bytes);
-#else
-  return false;
-#endif
 }
 
 JOW(void, PeerConnectionFactory_nativeStopAecDump)(
     JNIEnv* jni, jclass, jlong native_factory) {
-#if defined(ANDROID)
   rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
       factoryFromJava(native_factory));
   factory->StopAecDump();
-#endif
 }
 
 JOW(jboolean, PeerConnectionFactory_nativeStartRtcEventLog)(
     JNIEnv* jni, jclass, jlong native_factory, jint file) {
-#if defined(ANDROID)
   rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
       factoryFromJava(native_factory));
   return factory->StartRtcEventLog(file);
-#else
-  return false;
-#endif
 }
 
 JOW(void, PeerConnectionFactory_nativeStopRtcEventLog)(
     JNIEnv* jni, jclass, jlong native_factory) {
-#if defined(ANDROID)
   rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
       factoryFromJava(native_factory));
   factory->StopRtcEventLog();
-#endif
 }
 
 JOW(void, PeerConnectionFactory_nativeSetOptions)(
@@ -1359,7 +1330,6 @@
 JOW(void, PeerConnectionFactory_nativeSetVideoHwAccelerationOptions)(
     JNIEnv* jni, jclass, jlong native_factory, jobject local_egl_context,
     jobject remote_egl_context) {
-#if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD)
   OwnedFactoryAndThreads* owned_factory =
       reinterpret_cast<OwnedFactoryAndThreads*>(native_factory);
 
@@ -1383,7 +1353,6 @@
     LOG(LS_INFO) << "Set EGL context for HW decoding.";
     decoder_factory->SetEGLContext(jni, remote_egl_context);
   }
-#endif
 }
 
 static PeerConnectionInterface::IceTransportsType
@@ -1893,75 +1862,6 @@
   return JavaEnumFromIndex(jni, "MediaSource$State", p->state());
 }
 
-JOW(jobject, VideoCapturer_nativeCreateVideoCapturer)(
-    JNIEnv* jni, jclass, jstring j_device_name) {
-// Since we can't create platform specific java implementations in Java, we
-// defer the creation to C land.
-#if defined(ANDROID)
-  // TODO(nisse): This case is intended to be deleted.
-  jclass j_video_capturer_class(
-      FindClass(jni, "org/webrtc/VideoCapturerAndroid"));
-  const int camera_id = jni->CallStaticIntMethod(
-      j_video_capturer_class,
-      GetStaticMethodID(jni, j_video_capturer_class, "lookupDeviceName",
-                        "(Ljava/lang/String;)I"),
-      j_device_name);
-  CHECK_EXCEPTION(jni) << "error during VideoCapturerAndroid.lookupDeviceName";
-  if (camera_id == -1)
-    return nullptr;
-  jobject j_video_capturer = jni->NewObject(
-      j_video_capturer_class,
-      GetMethodID(jni, j_video_capturer_class, "<init>", "(I)V"), camera_id);
-  CHECK_EXCEPTION(jni) << "error during creation of VideoCapturerAndroid";
-  jfieldID helper_fid = GetFieldID(jni, j_video_capturer_class, "surfaceHelper",
-                                   "Lorg/webrtc/SurfaceTextureHelper;");
-
-  rtc::scoped_refptr<webrtc::AndroidVideoCapturerDelegate> delegate =
-      new rtc::RefCountedObject<AndroidVideoCapturerJni>(
-          jni, j_video_capturer,
-          GetObjectField(jni, j_video_capturer, helper_fid));
-  rtc::scoped_ptr<cricket::VideoCapturer> capturer(
-      new webrtc::AndroidVideoCapturer(delegate));
-
-#else
-  std::string device_name = JavaToStdString(jni, j_device_name);
-  scoped_ptr<cricket::DeviceManagerInterface> device_manager(
-      cricket::DeviceManagerFactory::Create());
-  RTC_CHECK(device_manager->Init()) << "DeviceManager::Init() failed";
-  cricket::Device device;
-  if (!device_manager->GetVideoCaptureDevice(device_name, &device)) {
-    LOG(LS_ERROR) << "GetVideoCaptureDevice failed for " << device_name;
-    return 0;
-  }
-  scoped_ptr<cricket::VideoCapturer> capturer(
-      device_manager->CreateVideoCapturer(device));
-
-  jclass j_video_capturer_class(
-      FindClass(jni, "org/webrtc/VideoCapturer"));
-  const jmethodID j_videocapturer_ctor(GetMethodID(
-      jni, j_video_capturer_class, "<init>", "()V"));
-  jobject j_video_capturer =
-      jni->NewObject(j_video_capturer_class,
-                     j_videocapturer_ctor);
-  CHECK_EXCEPTION(jni) << "error during creation of VideoCapturer";
-
-#endif
-  const jmethodID j_videocapturer_set_native_capturer(GetMethodID(
-      jni, j_video_capturer_class, "setNativeCapturer", "(J)V"));
-  jni->CallVoidMethod(j_video_capturer,
-                      j_videocapturer_set_native_capturer,
-                      jlongFromPointer(capturer.release()));
-  CHECK_EXCEPTION(jni) << "error during setNativeCapturer";
-  return j_video_capturer;
-}
-
-JOW(jlong, VideoRenderer_nativeCreateGuiVideoRenderer)(
-    JNIEnv* jni, jclass, int x, int y) {
-  scoped_ptr<VideoRendererWrapper> renderer(VideoRendererWrapper::Create(
-      cricket::VideoRendererFactory::CreateGuiVideoRenderer(x, y)));
-  return (jlong)renderer.release();
-}
-
 JOW(jlong, VideoRenderer_nativeWrapVideoRenderer)(
     JNIEnv* jni, jclass, jobject j_callbacks) {
   scoped_ptr<JavaVideoRendererWrapper> renderer(
diff --git a/talk/app/webrtc/java/src/org/webrtc/VideoCapturer.java b/talk/app/webrtc/java/src/org/webrtc/VideoCapturer.java
index 158cc34..ad41053 100644
--- a/talk/app/webrtc/java/src/org/webrtc/VideoCapturer.java
+++ b/talk/app/webrtc/java/src/org/webrtc/VideoCapturer.java
@@ -28,19 +28,13 @@
 package org.webrtc;
 
 /** Java version of cricket::VideoCapturer. */
+// TODO(perkj): Merge VideoCapturer and VideoCapturerAndroid.
 public class VideoCapturer {
   private long nativeVideoCapturer;
 
   protected VideoCapturer() {
   }
 
-  public static VideoCapturer create(String deviceName) {
-    Object capturer = nativeCreateVideoCapturer(deviceName);
-    if (capturer != null)
-      return (VideoCapturer) (capturer);
-    return null;
-  }
-
   // Sets |nativeCapturer| to be owned by VideoCapturer.
   protected void setNativeCapturer(long nativeCapturer) {
     this.nativeVideoCapturer = nativeCapturer;
@@ -64,7 +58,5 @@
     }
   }
 
-  private static native Object nativeCreateVideoCapturer(String deviceName);
-
   private static native void free(long nativeVideoCapturer);
 }
diff --git a/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java b/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java
index 2e307fc..c14802e 100644
--- a/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java
+++ b/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java
@@ -144,27 +144,14 @@
      }
    }
 
-  // |this| either wraps a native (GUI) renderer or a client-supplied Callbacks
-  // (Java) implementation; this is indicated by |isWrappedVideoRenderer|.
   long nativeVideoRenderer;
-  private final boolean isWrappedVideoRenderer;
-
-  public static VideoRenderer createGui(int x, int y) {
-    long nativeVideoRenderer = nativeCreateGuiVideoRenderer(x, y);
-    if (nativeVideoRenderer == 0) {
-      return null;
-    }
-    return new VideoRenderer(nativeVideoRenderer);
-  }
 
   public VideoRenderer(Callbacks callbacks) {
     nativeVideoRenderer = nativeWrapVideoRenderer(callbacks);
-    isWrappedVideoRenderer = true;
   }
 
   private VideoRenderer(long nativeVideoRenderer) {
     this.nativeVideoRenderer = nativeVideoRenderer;
-    isWrappedVideoRenderer = false;
   }
 
   public void dispose() {
@@ -172,19 +159,12 @@
       // Already disposed.
       return;
     }
-    if (!isWrappedVideoRenderer) {
-      freeGuiVideoRenderer(nativeVideoRenderer);
-    } else {
-      freeWrappedVideoRenderer(nativeVideoRenderer);
-    }
+
+    freeWrappedVideoRenderer(nativeVideoRenderer);
     nativeVideoRenderer = 0;
   }
 
-  private static native long nativeCreateGuiVideoRenderer(int x, int y);
   private static native long nativeWrapVideoRenderer(Callbacks callbacks);
-
-  private static native void freeGuiVideoRenderer(long nativeVideoRenderer);
   private static native void freeWrappedVideoRenderer(long nativeVideoRenderer);
-
   private static native void releaseNativeFrame(long nativeFramePointer);
 }
diff --git a/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java b/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
deleted file mode 100644
index 50f4d73..0000000
--- a/talk/app/webrtc/java/testcommon/src/org/webrtc/PeerConnectionTest.java
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
- * libjingle
- * Copyright 2013 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.webrtc;
-
-import org.webrtc.PeerConnection.IceConnectionState;
-import org.webrtc.PeerConnection.IceGatheringState;
-import org.webrtc.PeerConnection.SignalingState;
-
-import java.io.File;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-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;
-import java.util.concurrent.TimeUnit;
-
-import static junit.framework.Assert.*;
-
-/** End-to-end tests for PeerConnection.java. */
-public class PeerConnectionTest {
-  // Set to true to render video.
-  private static final boolean RENDER_TO_GUI = false;
-  private static final int TIMEOUT_SECONDS = 20;
-  private TreeSet<String> threadsBeforeTest = null;
-
-  private static class ObserverExpectations implements PeerConnection.Observer,
-                                                       VideoRenderer.Callbacks,
-                                                       DataChannel.Observer,
-                                                       StatsObserver {
-    private final String name;
-    private int expectedIceCandidates = 0;
-    private int expectedErrors = 0;
-    private int expectedRenegotiations = 0;
-    private int previouslySeenWidth = 0;
-    private int previouslySeenHeight = 0;
-    private int expectedFramesDelivered = 0;
-    private LinkedList<SignalingState> expectedSignalingChanges =
-        new LinkedList<SignalingState>();
-    private LinkedList<IceConnectionState> expectedIceConnectionChanges =
-        new LinkedList<IceConnectionState>();
-    private LinkedList<IceGatheringState> expectedIceGatheringChanges =
-        new LinkedList<IceGatheringState>();
-    private LinkedList<String> expectedAddStreamLabels =
-        new LinkedList<String>();
-    private LinkedList<String> expectedRemoveStreamLabels =
-        new LinkedList<String>();
-    private final LinkedList<IceCandidate> gotIceCandidates =
-        new LinkedList<IceCandidate>();
-    private Map<MediaStream, WeakReference<VideoRenderer>> renderers =
-        new IdentityHashMap<MediaStream, WeakReference<VideoRenderer>>();
-    private DataChannel dataChannel;
-    private LinkedList<DataChannel.Buffer> expectedBuffers =
-        new LinkedList<DataChannel.Buffer>();
-    private LinkedList<DataChannel.State> expectedStateChanges =
-        new LinkedList<DataChannel.State>();
-    private LinkedList<String> expectedRemoteDataChannelLabels =
-        new LinkedList<String>();
-    private int expectedStatsCallbacks = 0;
-    private LinkedList<StatsReport[]> gotStatsReports =
-        new LinkedList<StatsReport[]>();
-
-    public ObserverExpectations(String name) {
-      this.name = name;
-    }
-
-    public synchronized void setDataChannel(DataChannel dataChannel) {
-      assertNull(this.dataChannel);
-      this.dataChannel = dataChannel;
-      this.dataChannel.registerObserver(this);
-      assertNotNull(this.dataChannel);
-    }
-
-    public synchronized void expectIceCandidates(int count) {
-      expectedIceCandidates += count;
-    }
-
-    @Override
-    public synchronized void onIceCandidate(IceCandidate candidate) {
-      --expectedIceCandidates;
-
-      // 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.
-      synchronized (gotIceCandidates) {
-        gotIceCandidates.add(candidate);
-        gotIceCandidates.notifyAll();
-      }
-    }
-
-    private synchronized void setSize(int width, int height) {
-      assertFalse(RENDER_TO_GUI);
-      // Because different camera devices (fake & physical) produce different
-      // resolutions, we only sanity-check the set sizes,
-      assertTrue(width > 0);
-      assertTrue(height > 0);
-      if (previouslySeenWidth > 0) {
-        assertEquals(previouslySeenWidth, width);
-        assertEquals(previouslySeenHeight, height);
-      } else {
-        previouslySeenWidth = width;
-        previouslySeenHeight = height;
-      }
-    }
-
-    public synchronized void expectFramesDelivered(int count) {
-      assertFalse(RENDER_TO_GUI);
-      expectedFramesDelivered += count;
-    }
-
-    @Override
-    public synchronized void renderFrame(VideoRenderer.I420Frame frame) {
-      setSize(frame.rotatedWidth(), frame.rotatedHeight());
-      --expectedFramesDelivered;
-      VideoRenderer.renderFrameDone(frame);
-    }
-
-    public synchronized void expectSignalingChange(SignalingState newState) {
-      expectedSignalingChanges.add(newState);
-    }
-
-    @Override
-    public synchronized void onSignalingChange(SignalingState newState) {
-      assertEquals(expectedSignalingChanges.removeFirst(), newState);
-    }
-
-    public synchronized void expectIceConnectionChange(
-        IceConnectionState newState) {
-      expectedIceConnectionChanges.add(newState);
-    }
-
-    @Override
-    public synchronized void onIceConnectionChange(
-        IceConnectionState newState) {
-      // TODO(bemasc): remove once delivery of ICECompleted is reliable
-      // (https://code.google.com/p/webrtc/issues/detail?id=3021).
-      if (newState.equals(IceConnectionState.COMPLETED)) {
-        return;
-      }
-
-      if (expectedIceConnectionChanges.isEmpty()) {
-        System.out.println(name + "Got an unexpected ice connection change " + newState);
-        return;
-      }
-
-      assertEquals(expectedIceConnectionChanges.removeFirst(), newState);
-    }
-
-    @Override
-    public synchronized void onIceConnectionReceivingChange(boolean receiving) {
-      System.out.println(name + "Got an ice connection receiving change " + receiving);
-    }
-
-    public synchronized void expectIceGatheringChange(
-        IceGatheringState newState) {
-      expectedIceGatheringChanges.add(newState);
-    }
-
-    @Override
-    public synchronized void onIceGatheringChange(IceGatheringState newState) {
-      // It's fine to get a variable number of GATHERING messages before
-      // COMPLETE fires (depending on how long the test runs) so we don't assert
-      // any particular count.
-      if (newState == IceGatheringState.GATHERING) {
-        return;
-      }
-      assertEquals(expectedIceGatheringChanges.removeFirst(), newState);
-    }
-
-    public synchronized void expectAddStream(String label) {
-      expectedAddStreamLabels.add(label);
-    }
-
-    @Override
-    public synchronized void onAddStream(MediaStream stream) {
-      assertEquals(expectedAddStreamLabels.removeFirst(), stream.label());
-      assertEquals(1, stream.videoTracks.size());
-      assertEquals(1, stream.audioTracks.size());
-      assertTrue(stream.videoTracks.get(0).id().endsWith("VideoTrack"));
-      assertTrue(stream.audioTracks.get(0).id().endsWith("AudioTrack"));
-      assertEquals("video", stream.videoTracks.get(0).kind());
-      assertEquals("audio", stream.audioTracks.get(0).kind());
-      VideoRenderer renderer = createVideoRenderer(this);
-      stream.videoTracks.get(0).addRenderer(renderer);
-      assertNull(renderers.put(
-          stream, new WeakReference<VideoRenderer>(renderer)));
-    }
-
-    public synchronized void expectRemoveStream(String label) {
-      expectedRemoveStreamLabels.add(label);
-    }
-
-    @Override
-    public synchronized void onRemoveStream(MediaStream stream) {
-      assertEquals(expectedRemoveStreamLabels.removeFirst(), stream.label());
-      WeakReference<VideoRenderer> renderer = renderers.remove(stream);
-      assertNotNull(renderer);
-      assertNotNull(renderer.get());
-      assertEquals(1, stream.videoTracks.size());
-      stream.videoTracks.get(0).removeRenderer(renderer.get());
-    }
-
-    public synchronized void expectDataChannel(String label) {
-      expectedRemoteDataChannelLabels.add(label);
-    }
-
-    @Override
-    public synchronized void onDataChannel(DataChannel remoteDataChannel) {
-      assertEquals(expectedRemoteDataChannelLabels.removeFirst(),
-                   remoteDataChannel.label());
-      setDataChannel(remoteDataChannel);
-      assertEquals(DataChannel.State.CONNECTING, dataChannel.state());
-    }
-
-    public synchronized void expectRenegotiationNeeded() {
-      ++expectedRenegotiations;
-    }
-
-    @Override
-    public synchronized void onRenegotiationNeeded() {
-      assertTrue(--expectedRenegotiations >= 0);
-    }
-
-    public synchronized void expectMessage(ByteBuffer expectedBuffer,
-                                           boolean expectedBinary) {
-      expectedBuffers.add(
-          new DataChannel.Buffer(expectedBuffer, expectedBinary));
-    }
-
-    @Override
-    public synchronized void onMessage(DataChannel.Buffer buffer) {
-      DataChannel.Buffer expected = expectedBuffers.removeFirst();
-      assertEquals(expected.binary, buffer.binary);
-      assertTrue(expected.data.equals(buffer.data));
-    }
-
-    @Override
-    public synchronized void onBufferedAmountChange(long previousAmount) {
-      assertFalse(previousAmount == dataChannel.bufferedAmount());
-    }
-
-    @Override
-    public synchronized void onStateChange() {
-      assertEquals(expectedStateChanges.removeFirst(), dataChannel.state());
-    }
-
-    public synchronized void expectStateChange(DataChannel.State state) {
-      expectedStateChanges.add(state);
-    }
-
-    @Override
-    public synchronized void onComplete(StatsReport[] reports) {
-      if (--expectedStatsCallbacks < 0) {
-        throw new RuntimeException("Unexpected stats report: " + reports);
-      }
-      gotStatsReports.add(reports);
-    }
-
-    public synchronized void expectStatsCallback() {
-      ++expectedStatsCallbacks;
-    }
-
-    public synchronized LinkedList<StatsReport[]> takeStatsReports() {
-      LinkedList<StatsReport[]> got = gotStatsReports;
-      gotStatsReports = new LinkedList<StatsReport[]>();
-      return got;
-    }
-
-    // Return a set of expectations that haven't been satisfied yet, possibly
-    // empty if no such expectations exist.
-    public synchronized TreeSet<String> unsatisfiedExpectations() {
-      TreeSet<String> stillWaitingForExpectations = new TreeSet<String>();
-      if (expectedIceCandidates > 0) {  // See comment in onIceCandidate.
-        stillWaitingForExpectations.add("expectedIceCandidates");
-      }
-      if (expectedErrors != 0) {
-        stillWaitingForExpectations.add("expectedErrors: " + expectedErrors);
-      }
-      if (expectedSignalingChanges.size() != 0) {
-        stillWaitingForExpectations.add(
-            "expectedSignalingChanges: " + expectedSignalingChanges.size());
-      }
-      if (expectedIceConnectionChanges.size() != 0) {
-        stillWaitingForExpectations.add("expectedIceConnectionChanges: " +
-                                        expectedIceConnectionChanges.size());
-      }
-      if (expectedIceGatheringChanges.size() != 0) {
-        stillWaitingForExpectations.add("expectedIceGatheringChanges: " +
-                                        expectedIceGatheringChanges.size());
-      }
-      if (expectedAddStreamLabels.size() != 0) {
-        stillWaitingForExpectations.add(
-            "expectedAddStreamLabels: " + expectedAddStreamLabels.size());
-      }
-      if (expectedRemoveStreamLabels.size() != 0) {
-        stillWaitingForExpectations.add(
-            "expectedRemoveStreamLabels: " + expectedRemoveStreamLabels.size());
-      }
-      if (expectedFramesDelivered > 0) {
-        stillWaitingForExpectations.add(
-            "expectedFramesDelivered: " + expectedFramesDelivered);
-      }
-      if (!expectedBuffers.isEmpty()) {
-        stillWaitingForExpectations.add(
-            "expectedBuffers: " + expectedBuffers.size());
-      }
-      if (!expectedStateChanges.isEmpty()) {
-        stillWaitingForExpectations.add(
-            "expectedStateChanges: " + expectedStateChanges.size());
-      }
-      if (!expectedRemoteDataChannelLabels.isEmpty()) {
-        stillWaitingForExpectations.add("expectedRemoteDataChannelLabels: " +
-                                        expectedRemoteDataChannelLabels.size());
-      }
-      if (expectedStatsCallbacks != 0) {
-        stillWaitingForExpectations.add(
-            "expectedStatsCallbacks: " + expectedStatsCallbacks);
-      }
-      return stillWaitingForExpectations;
-    }
-
-    public boolean waitForAllExpectationsToBeSatisfied(int timeoutSeconds) {
-      // TODO(fischman): problems with this approach:
-      // - come up with something better than a poll loop
-      // - avoid serializing expectations explicitly; the test is not as robust
-      //   as it could be because it must place expectations between wait
-      //   statements very precisely (e.g. frame must not arrive before its
-      //   expectation, and expectation must not be registered so early as to
-      //   stall a wait).  Use callbacks to fire off dependent steps instead of
-      //   explicitly waiting, so there can be just a single wait at the end of
-      //   the test.
-      long endTime = System.currentTimeMillis() + 1000 * timeoutSeconds;
-      TreeSet<String> prev = null;
-      TreeSet<String> stillWaitingForExpectations = unsatisfiedExpectations();
-      while (!stillWaitingForExpectations.isEmpty()) {
-        if (!stillWaitingForExpectations.equals(prev)) {
-          System.out.println(
-              name + " still waiting at\n    " +
-              (new Throwable()).getStackTrace()[1] +
-              "\n    for: " +
-              Arrays.toString(stillWaitingForExpectations.toArray()));
-        }
-        if (endTime < System.currentTimeMillis()) {
-          System.out.println(name + " timed out waiting for: "
-              + Arrays.toString(stillWaitingForExpectations.toArray()));
-          return false;
-        }
-        try {
-          Thread.sleep(10);
-        } catch (InterruptedException e) {
-          throw new RuntimeException(e);
-        }
-        prev = stillWaitingForExpectations;
-        stillWaitingForExpectations = unsatisfiedExpectations();
-      }
-      if (prev == null) {
-        System.out.println(name + " didn't need to wait at\n    " +
-                           (new Throwable()).getStackTrace()[1]);
-      }
-      return true;
-    }
-
-    // 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 {
-    private boolean success = false;
-    private SessionDescription sdp = null;
-    private String error = null;
-    private CountDownLatch latch = new CountDownLatch(1);
-
-    public SdpObserverLatch() {}
-
-    @Override
-    public void onCreateSuccess(SessionDescription sdp) {
-      this.sdp = sdp;
-      onSetSuccess();
-    }
-
-    @Override
-    public void onSetSuccess() {
-      success = true;
-      latch.countDown();
-    }
-
-    @Override
-    public void onCreateFailure(String error) {
-      onSetFailure(error);
-    }
-
-    @Override
-    public void onSetFailure(String error) {
-      this.error = error;
-      latch.countDown();
-    }
-
-    public boolean await() {
-      try {
-        assertTrue(latch.await(1000, TimeUnit.MILLISECONDS));
-        return getSuccess();
-      } catch (Exception e) {
-        throw new RuntimeException(e);
-      }
-    }
-
-    public boolean getSuccess() {
-      return success;
-    }
-
-    public SessionDescription getSdp() {
-      return sdp;
-    }
-
-    public String getError() {
-      return error;
-    }
-  }
-
-  static int videoWindowsMapped = -1;
-
-  private static VideoRenderer createVideoRenderer(
-      VideoRenderer.Callbacks videoCallbacks) {
-    if (!RENDER_TO_GUI) {
-      return new VideoRenderer(videoCallbacks);
-    }
-    ++videoWindowsMapped;
-    assertTrue(videoWindowsMapped < 4);
-    int x = videoWindowsMapped % 2 != 0 ? 700 : 0;
-    int y = videoWindowsMapped >= 2 ? 0 : 500;
-    return VideoRenderer.createGui(x, y);
-  }
-
-  // Return a weak reference to test that ownership is correctly held by
-  // PeerConnection, not by test code.
-  private static WeakReference<MediaStream> addTracksToPC(
-      PeerConnectionFactory factory, PeerConnection pc,
-      VideoSource videoSource,
-      String streamLabel, String videoTrackId, String audioTrackId,
-      VideoRenderer.Callbacks videoCallbacks) {
-    MediaStream lMS = factory.createLocalMediaStream(streamLabel);
-    VideoTrack videoTrack =
-        factory.createVideoTrack(videoTrackId, videoSource);
-    assertNotNull(videoTrack);
-    VideoRenderer videoRenderer = createVideoRenderer(videoCallbacks);
-    assertNotNull(videoRenderer);
-    videoTrack.addRenderer(videoRenderer);
-    lMS.addTrack(videoTrack);
-    // Just for fun, let's remove and re-add the track.
-    lMS.removeTrack(videoTrack);
-    lMS.addTrack(videoTrack);
-    lMS.addTrack(factory.createAudioTrack(
-        audioTrackId, factory.createAudioSource(new MediaConstraints())));
-    pc.addStream(lMS);
-    return new WeakReference<MediaStream>(lMS);
-  }
-
-  // Used for making sure thread handles are not leaked.
-  // Call initializeThreadCheck before a test and finalizeThreadCheck after
-  // a test.
-  void initializeThreadCheck() {
-    System.gc();  // Encourage any GC-related threads to start up.
-    threadsBeforeTest = allThreads();
-  }
-
-  void finalizeThreadCheck() throws Exception {
-    // TreeSet<String> threadsAfterTest = allThreads();
-
-    // TODO(tommi): Figure out a more reliable way to do this test.  As is
-    // we're seeing three possible 'normal' situations:
-    // 1.  before and after sets are equal.
-    // 2.  before contains 3 threads that do not exist in after.
-    // 3.  after contains 3 threads that do not exist in before.
-    //
-    // Maybe it would be better to do the thread enumeration from C++ and get
-    // the thread names as well, in order to determine what these 3 threads are.
-
-    // assertEquals(threadsBeforeTest, threadsAfterTest);
-    // Thread.sleep(100);
-  }
-
-  void doTest() throws Exception {
-    // Allow loopback interfaces too since our Android devices often don't
-    // have those.
-    PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
-    options.networkIgnoreMask = 0;
-    PeerConnectionFactory factory = new PeerConnectionFactory(options);
-    // Uncomment to get ALL WebRTC tracing and SENSITIVE libjingle logging.
-    // NOTE: this _must_ happen while |factory| is alive!
-    // Logging.enableTracing(
-    //     "/tmp/PeerConnectionTest-log.txt",
-    //     EnumSet.of(Logging.TraceLevel.TRACE_ALL),
-    //     Logging.Severity.LS_SENSITIVE);
-
-    MediaConstraints pcConstraints = new MediaConstraints();
-    pcConstraints.mandatory.add(
-        new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
-
-    LinkedList<PeerConnection.IceServer> iceServers =
-        new LinkedList<PeerConnection.IceServer>();
-    iceServers.add(new PeerConnection.IceServer(
-        "stun:stun.l.google.com:19302"));
-    iceServers.add(new PeerConnection.IceServer(
-        "turn:fake.example.com", "fakeUsername", "fakePassword"));
-    ObserverExpectations offeringExpectations =
-        new ObserverExpectations("PCTest:offerer");
-    PeerConnection offeringPC = factory.createPeerConnection(
-        iceServers, pcConstraints, offeringExpectations);
-    assertNotNull(offeringPC);
-
-    ObserverExpectations answeringExpectations =
-        new ObserverExpectations("PCTest:answerer");
-    PeerConnection answeringPC = factory.createPeerConnection(
-        iceServers, pcConstraints, answeringExpectations);
-    assertNotNull(answeringPC);
-
-    // We want to use the same camera for offerer & answerer, so create it here
-    // instead of in addTracksToPC.
-    VideoSource videoSource = factory.createVideoSource(
-        VideoCapturer.create(""), new MediaConstraints());
-
-    offeringExpectations.expectRenegotiationNeeded();
-    WeakReference<MediaStream> oLMS = addTracksToPC(
-        factory, offeringPC, videoSource, "offeredMediaStream",
-        "offeredVideoTrack", "offeredAudioTrack", offeringExpectations);
-
-    offeringExpectations.expectRenegotiationNeeded();
-    DataChannel offeringDC = offeringPC.createDataChannel(
-        "offeringDC", new DataChannel.Init());
-    assertEquals("offeringDC", offeringDC.label());
-
-    offeringExpectations.setDataChannel(offeringDC);
-    SdpObserverLatch sdpLatch = new SdpObserverLatch();
-    offeringPC.createOffer(sdpLatch, new MediaConstraints());
-    assertTrue(sdpLatch.await());
-    SessionDescription offerSdp = sdpLatch.getSdp();
-    assertEquals(offerSdp.type, SessionDescription.Type.OFFER);
-    assertFalse(offerSdp.description.isEmpty());
-
-    sdpLatch = new SdpObserverLatch();
-    answeringExpectations.expectSignalingChange(
-        SignalingState.HAVE_REMOTE_OFFER);
-    answeringExpectations.expectAddStream("offeredMediaStream");
-    // SCTP DataChannels are announced via OPEN messages over the established
-    // connection (not via SDP), so answeringExpectations can only register
-    // expecting the channel during ICE, below.
-    answeringPC.setRemoteDescription(sdpLatch, offerSdp);
-    assertEquals(
-        PeerConnection.SignalingState.STABLE, offeringPC.signalingState());
-    assertTrue(sdpLatch.await());
-    assertNull(sdpLatch.getSdp());
-
-    answeringExpectations.expectRenegotiationNeeded();
-    WeakReference<MediaStream> aLMS = addTracksToPC(
-        factory, answeringPC, videoSource, "answeredMediaStream",
-        "answeredVideoTrack", "answeredAudioTrack", answeringExpectations);
-
-    sdpLatch = new SdpObserverLatch();
-    answeringPC.createAnswer(sdpLatch, new MediaConstraints());
-    assertTrue(sdpLatch.await());
-    SessionDescription answerSdp = sdpLatch.getSdp();
-    assertEquals(answerSdp.type, SessionDescription.Type.ANSWER);
-    assertFalse(answerSdp.description.isEmpty());
-
-    offeringExpectations.expectIceCandidates(2);
-    answeringExpectations.expectIceCandidates(2);
-
-    offeringExpectations.expectIceGatheringChange(IceGatheringState.COMPLETE);
-    answeringExpectations.expectIceGatheringChange(IceGatheringState.COMPLETE);
-
-    sdpLatch = new SdpObserverLatch();
-    answeringExpectations.expectSignalingChange(SignalingState.STABLE);
-    answeringPC.setLocalDescription(sdpLatch, answerSdp);
-    assertTrue(sdpLatch.await());
-    assertNull(sdpLatch.getSdp());
-
-    sdpLatch = new SdpObserverLatch();
-    offeringExpectations.expectSignalingChange(SignalingState.HAVE_LOCAL_OFFER);
-    offeringPC.setLocalDescription(sdpLatch, offerSdp);
-    assertTrue(sdpLatch.await());
-    assertNull(sdpLatch.getSdp());
-    sdpLatch = new SdpObserverLatch();
-    offeringExpectations.expectSignalingChange(SignalingState.STABLE);
-    offeringExpectations.expectAddStream("answeredMediaStream");
-
-    offeringExpectations.expectIceConnectionChange(
-        IceConnectionState.CHECKING);
-    offeringExpectations.expectIceConnectionChange(
-        IceConnectionState.CONNECTED);
-    // TODO(bemasc): uncomment once delivery of ICECompleted is reliable
-    // (https://code.google.com/p/webrtc/issues/detail?id=3021).
-    //
-    // offeringExpectations.expectIceConnectionChange(
-    //     IceConnectionState.COMPLETED);
-    answeringExpectations.expectIceConnectionChange(
-        IceConnectionState.CHECKING);
-    answeringExpectations.expectIceConnectionChange(
-        IceConnectionState.CONNECTED);
-
-    offeringPC.setRemoteDescription(sdpLatch, answerSdp);
-    assertTrue(sdpLatch.await());
-    assertNull(sdpLatch.getSdp());
-
-    assertEquals(offeringPC.getLocalDescription().type, offerSdp.type);
-    assertEquals(offeringPC.getRemoteDescription().type, answerSdp.type);
-    assertEquals(answeringPC.getLocalDescription().type, answerSdp.type);
-    assertEquals(answeringPC.getRemoteDescription().type, offerSdp.type);
-
-    assertEquals(offeringPC.getSenders().size(), 2);
-    assertEquals(offeringPC.getReceivers().size(), 2);
-    assertEquals(answeringPC.getSenders().size(), 2);
-    assertEquals(answeringPC.getReceivers().size(), 2);
-
-    if (!RENDER_TO_GUI) {
-      // Wait for at least some frames to be delivered at each end (number
-      // chosen arbitrarily).
-      offeringExpectations.expectFramesDelivered(10);
-      answeringExpectations.expectFramesDelivered(10);
-    }
-
-    offeringExpectations.expectStateChange(DataChannel.State.OPEN);
-    // See commentary about SCTP DataChannels above for why this is here.
-    answeringExpectations.expectDataChannel("offeringDC");
-    answeringExpectations.expectStateChange(DataChannel.State.OPEN);
-
-    // 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);
-    }
-
-    // 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);
-    }
-
-    assertTrue(offeringExpectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
-    assertTrue(answeringExpectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
-
-    assertEquals(
-        PeerConnection.SignalingState.STABLE, offeringPC.signalingState());
-    assertEquals(
-        PeerConnection.SignalingState.STABLE, answeringPC.signalingState());
-
-    // Test send & receive UTF-8 text.
-    answeringExpectations.expectMessage(
-        ByteBuffer.wrap("hello!".getBytes(Charset.forName("UTF-8"))), false);
-    DataChannel.Buffer buffer = new DataChannel.Buffer(
-        ByteBuffer.wrap("hello!".getBytes(Charset.forName("UTF-8"))), false);
-    assertTrue(offeringExpectations.dataChannel.send(buffer));
-    assertTrue(answeringExpectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
-
-    // Construct this binary message two different ways to ensure no
-    // shortcuts are taken.
-    ByteBuffer expectedBinaryMessage = ByteBuffer.allocateDirect(5);
-    for (byte i = 1; i < 6; ++i) {
-      expectedBinaryMessage.put(i);
-    }
-    expectedBinaryMessage.flip();
-    offeringExpectations.expectMessage(expectedBinaryMessage, true);
-    assertTrue(answeringExpectations.dataChannel.send(
-        new DataChannel.Buffer(
-            ByteBuffer.wrap(new byte[] { 1, 2, 3, 4, 5 }), true)));
-    assertTrue(offeringExpectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
-
-    offeringExpectations.expectStateChange(DataChannel.State.CLOSING);
-    answeringExpectations.expectStateChange(DataChannel.State.CLOSING);
-    offeringExpectations.expectStateChange(DataChannel.State.CLOSED);
-    answeringExpectations.expectStateChange(DataChannel.State.CLOSED);
-    answeringExpectations.dataChannel.close();
-    offeringExpectations.dataChannel.close();
-
-    if (RENDER_TO_GUI) {
-      try {
-        Thread.sleep(3000);
-      } catch (Throwable t) {
-        throw new RuntimeException(t);
-      }
-    }
-
-    // TODO(fischman) MOAR test ideas:
-    // - Test that PC.removeStream() works; requires a second
-    //   createOffer/createAnswer dance.
-    // - audit each place that uses |constraints| for specifying non-trivial
-    //   constraints (and ensure they're honored).
-    // - test error cases
-    // - ensure reasonable coverage of _jni.cc is achieved.  Coverage is
-    //   extra-important because of all the free-text (class/method names, etc)
-    //   in JNI-style programming; make sure no typos!
-    // - Test that shutdown mid-interaction is crash-free.
-
-    // Free the Java-land objects, collect them, and sleep a bit to make sure we
-    // don't get late-arrival crashes after the Java-land objects have been
-    // freed.
-    shutdownPC(offeringPC, offeringExpectations);
-    offeringPC = null;
-    shutdownPC(answeringPC, answeringExpectations);
-    answeringPC = null;
-    videoSource.dispose();
-    factory.dispose();
-    System.gc();
-  }
-
-  private static void shutdownPC(
-      PeerConnection pc, ObserverExpectations expectations) {
-    expectations.dataChannel.unregisterObserver();
-    expectations.dataChannel.dispose();
-    expectations.expectStatsCallback();
-    assertTrue(pc.getStats(expectations, null));
-    assertTrue(expectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
-    expectations.expectIceConnectionChange(IceConnectionState.CLOSED);
-    expectations.expectSignalingChange(SignalingState.CLOSED);
-    pc.close();
-    assertTrue(expectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
-    expectations.expectStatsCallback();
-    assertTrue(pc.getStats(expectations, null));
-    assertTrue(expectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
-
-    System.out.println("FYI stats: ");
-    int reportIndex = -1;
-    for (StatsReport[] reports : expectations.takeStatsReports()) {
-      System.out.println(" Report #" + (++reportIndex));
-      for (int i = 0; i < reports.length; ++i) {
-        System.out.println("  " + reports[i].toString());
-      }
-    }
-    assertEquals(1, reportIndex);
-    System.out.println("End stats.");
-
-    pc.dispose();
-  }
-
-  // Returns a set of thread IDs belonging to this process, as Strings.
-  private static TreeSet<String> allThreads() {
-    TreeSet<String> threads = new TreeSet<String>();
-    // This pokes at /proc instead of using the Java APIs because we're also
-    // looking for libjingle/webrtc native threads, most of which won't have
-    // attached to the JVM.
-    for (String threadId : (new File("/proc/self/task")).list()) {
-      threads.add(threadId);
-    }
-    return threads;
-  }
-}