| Index: webrtc/api/androidtests/src/org/webrtc/PeerConnectionTest.java
|
| diff --git a/webrtc/api/androidtests/src/org/webrtc/PeerConnectionTest.java b/webrtc/api/androidtests/src/org/webrtc/PeerConnectionTest.java
|
| deleted file mode 100644
|
| index a4cb3093bc082562d25b46d0bea9b06d0c4f1506..0000000000000000000000000000000000000000
|
| --- a/webrtc/api/androidtests/src/org/webrtc/PeerConnectionTest.java
|
| +++ /dev/null
|
| @@ -1,1025 +0,0 @@
|
| -/*
|
| - * Copyright 2013 The WebRTC project authors. All Rights Reserved.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license
|
| - * that can be found in the LICENSE file in the root of the source
|
| - * tree. An additional intellectual property rights grant can be found
|
| - * in the file PATENTS. All contributing project authors may
|
| - * be found in the AUTHORS file in the root of the source tree.
|
| - */
|
| -
|
| -package org.webrtc;
|
| -
|
| -import org.webrtc.Metrics.HistogramInfo;
|
| -import org.webrtc.PeerConnection.IceConnectionState;
|
| -import org.webrtc.PeerConnection.IceGatheringState;
|
| -import org.webrtc.PeerConnection.SignalingState;
|
| -
|
| -import android.test.ActivityTestCase;
|
| -import android.test.suitebuilder.annotation.MediumTest;
|
| -
|
| -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.HashSet;
|
| -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;
|
| -
|
| -/** End-to-end tests for PeerConnection.java. */
|
| -public class PeerConnectionTest extends ActivityTestCase {
|
| - private static final int TIMEOUT_SECONDS = 20;
|
| - private TreeSet<String> threadsBeforeTest = null;
|
| -
|
| - @Override
|
| - protected void setUp() {
|
| - assertTrue(PeerConnectionFactory.initializeAndroidGlobals(
|
| - getInstrumentation().getContext(), true, true, true));
|
| - }
|
| -
|
| - 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 expectedWidth = 0;
|
| - private int expectedHeight = 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[]>();
|
| - private final HashSet<MediaStream> gotRemoteStreams = new HashSet<MediaStream>();
|
| -
|
| - 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();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onIceCandidatesRemoved(IceCandidate[] candidates) {}
|
| -
|
| - public synchronized void setExpectedResolution(int width, int height) {
|
| - expectedWidth = width;
|
| - expectedHeight = height;
|
| - }
|
| -
|
| - public synchronized void expectFramesDelivered(int count) {
|
| - expectedFramesDelivered += count;
|
| - }
|
| -
|
| - @Override
|
| - public synchronized void renderFrame(VideoRenderer.I420Frame frame) {
|
| - assertTrue(expectedWidth > 0);
|
| - assertTrue(expectedHeight > 0);
|
| - assertEquals(expectedWidth, frame.rotatedWidth());
|
| - assertEquals(expectedHeight, 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)));
|
| - gotRemoteStreams.add(stream);
|
| - }
|
| -
|
| - 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());
|
| - gotRemoteStreams.remove(stream);
|
| - }
|
| -
|
| - 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);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Sets the expected resolution for an ObserverExpectations once a frame
|
| - // has been captured.
|
| - private static class ExpectedResolutionSetter implements VideoRenderer.Callbacks {
|
| - private ObserverExpectations observer;
|
| -
|
| - public ExpectedResolutionSetter(ObserverExpectations observer) {
|
| - this.observer = observer;
|
| - }
|
| -
|
| - @Override
|
| - public synchronized void renderFrame(VideoRenderer.I420Frame frame) {
|
| - // Because different camera devices (fake & physical) produce different
|
| - // resolutions, we only sanity-check the set sizes,
|
| - assertTrue(frame.rotatedWidth() > 0);
|
| - assertTrue(frame.rotatedHeight() > 0);
|
| - observer.setExpectedResolution(frame.rotatedWidth(), frame.rotatedHeight());
|
| - }
|
| - }
|
| -
|
| - 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) {
|
| - return new VideoRenderer(videoCallbacks);
|
| - }
|
| -
|
| - // 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);
|
| - }
|
| -
|
| - // 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.
|
| -
|
| - @MediumTest
|
| - public void testCompleteSession() throws Exception {
|
| - Metrics.enable();
|
| - // 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.
|
| - final CameraEnumerator enumerator = new Camera1Enumerator(false /* captureToTexture */);
|
| - final VideoCapturer videoCapturer =
|
| - enumerator.createCapturer(enumerator.getDeviceNames()[0], null);
|
| - final VideoSource videoSource = factory.createVideoSource(videoCapturer);
|
| - videoCapturer.startCapture(640, 480, 30);
|
| -
|
| - offeringExpectations.expectRenegotiationNeeded();
|
| - WeakReference<MediaStream> oLMS =
|
| - addTracksToPC(factory, offeringPC, videoSource, "offeredMediaStream", "offeredVideoTrack",
|
| - "offeredAudioTrack", new ExpectedResolutionSetter(answeringExpectations));
|
| -
|
| - 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",
|
| - new ExpectedResolutionSetter(offeringExpectations));
|
| -
|
| - 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);
|
| -
|
| - // 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());
|
| -
|
| - // Set a bitrate limit for the outgoing video stream for the offerer.
|
| - RtpSender videoSender = null;
|
| - for (RtpSender sender : offeringPC.getSenders()) {
|
| - if (sender.track().kind().equals("video")) {
|
| - videoSender = sender;
|
| - }
|
| - }
|
| - assertNotNull(videoSender);
|
| - RtpParameters rtpParameters = videoSender.getParameters();
|
| - assertNotNull(rtpParameters);
|
| - assertEquals(1, rtpParameters.encodings.size());
|
| - assertNull(rtpParameters.encodings.get(0).maxBitrateBps);
|
| -
|
| - rtpParameters.encodings.get(0).maxBitrateBps = 300000;
|
| - assertTrue(videoSender.setParameters(rtpParameters));
|
| -
|
| - // Verify that we can read back the updated value.
|
| - rtpParameters = videoSender.getParameters();
|
| - assertEquals(300000, (int) rtpParameters.encodings.get(0).maxBitrateBps);
|
| -
|
| - // 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();
|
| -
|
| - // Free the Java-land objects and collect them.
|
| - shutdownPC(offeringPC, offeringExpectations);
|
| - offeringPC = null;
|
| - shutdownPC(answeringPC, answeringExpectations);
|
| - answeringPC = null;
|
| - getMetrics();
|
| - videoCapturer.stopCapture();
|
| - videoCapturer.dispose();
|
| - videoSource.dispose();
|
| - factory.dispose();
|
| - System.gc();
|
| - }
|
| -
|
| - @MediumTest
|
| - public void testTrackRemoval() 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);
|
| -
|
| - 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"));
|
| -
|
| - 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.
|
| - final CameraEnumerator enumerator = new Camera1Enumerator(false /* captureToTexture */);
|
| - final VideoCapturer videoCapturer =
|
| - enumerator.createCapturer(enumerator.getDeviceNames()[0], null);
|
| - final VideoSource videoSource = factory.createVideoSource(videoCapturer);
|
| - videoCapturer.startCapture(640, 480, 30);
|
| -
|
| - // Add offerer media stream.
|
| - offeringExpectations.expectRenegotiationNeeded();
|
| - WeakReference<MediaStream> oLMS =
|
| - addTracksToPC(factory, offeringPC, videoSource, "offeredMediaStream", "offeredVideoTrack",
|
| - "offeredAudioTrack", new ExpectedResolutionSetter(answeringExpectations));
|
| -
|
| - // Create offer.
|
| - 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());
|
| -
|
| - // Set local description for offerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - offeringExpectations.expectSignalingChange(SignalingState.HAVE_LOCAL_OFFER);
|
| - offeringExpectations.expectIceCandidates(2);
|
| - offeringExpectations.expectIceGatheringChange(IceGatheringState.COMPLETE);
|
| - offeringPC.setLocalDescription(sdpLatch, offerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Set remote description for answerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringExpectations.expectSignalingChange(SignalingState.HAVE_REMOTE_OFFER);
|
| - answeringExpectations.expectAddStream("offeredMediaStream");
|
| - answeringPC.setRemoteDescription(sdpLatch, offerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Add answerer media stream.
|
| - answeringExpectations.expectRenegotiationNeeded();
|
| - WeakReference<MediaStream> aLMS = addTracksToPC(factory, answeringPC, videoSource,
|
| - "answeredMediaStream", "answeredVideoTrack", "answeredAudioTrack",
|
| - new ExpectedResolutionSetter(offeringExpectations));
|
| -
|
| - // Create answer.
|
| - 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());
|
| -
|
| - // Set local description for answerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringExpectations.expectSignalingChange(SignalingState.STABLE);
|
| - answeringExpectations.expectIceCandidates(2);
|
| - answeringExpectations.expectIceGatheringChange(IceGatheringState.COMPLETE);
|
| - answeringPC.setLocalDescription(sdpLatch, answerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Set remote description for offerer.
|
| - 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());
|
| -
|
| - // 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);
|
| - }
|
| -
|
| - // Wait for one frame of the correct size to be delivered.
|
| - // Otherwise we could get a dummy black frame of unexpcted size when the
|
| - // video track is removed.
|
| - offeringExpectations.expectFramesDelivered(1);
|
| - answeringExpectations.expectFramesDelivered(1);
|
| -
|
| - assertTrue(offeringExpectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
|
| - assertTrue(answeringExpectations.waitForAllExpectationsToBeSatisfied(TIMEOUT_SECONDS));
|
| -
|
| - assertEquals(PeerConnection.SignalingState.STABLE, offeringPC.signalingState());
|
| - assertEquals(PeerConnection.SignalingState.STABLE, answeringPC.signalingState());
|
| -
|
| - // Now do another negotiation, removing the video track from one peer.
|
| - // This previously caused a crash on pc.dispose().
|
| - // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5128
|
| - VideoTrack offererVideoTrack = oLMS.get().videoTracks.get(0);
|
| - // Note that when we call removeTrack, we regain responsibility for
|
| - // disposing of the track.
|
| - oLMS.get().removeTrack(offererVideoTrack);
|
| -
|
| - // Create offer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - offeringPC.createOffer(sdpLatch, new MediaConstraints());
|
| - assertTrue(sdpLatch.await());
|
| - offerSdp = sdpLatch.getSdp();
|
| - assertEquals(offerSdp.type, SessionDescription.Type.OFFER);
|
| - assertFalse(offerSdp.description.isEmpty());
|
| -
|
| - // Set local description for offerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - offeringExpectations.expectSignalingChange(SignalingState.HAVE_LOCAL_OFFER);
|
| - offeringPC.setLocalDescription(sdpLatch, offerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Set remote description for answerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringExpectations.expectSignalingChange(SignalingState.HAVE_REMOTE_OFFER);
|
| - answeringPC.setRemoteDescription(sdpLatch, offerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Create answer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringPC.createAnswer(sdpLatch, new MediaConstraints());
|
| - assertTrue(sdpLatch.await());
|
| - answerSdp = sdpLatch.getSdp();
|
| - assertEquals(answerSdp.type, SessionDescription.Type.ANSWER);
|
| - assertFalse(answerSdp.description.isEmpty());
|
| -
|
| - // Set local description for answerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringExpectations.expectSignalingChange(SignalingState.STABLE);
|
| - answeringPC.setLocalDescription(sdpLatch, answerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Set remote description for offerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - offeringExpectations.expectSignalingChange(SignalingState.STABLE);
|
| - offeringPC.setRemoteDescription(sdpLatch, answerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Make sure the track was really removed.
|
| - // TODO(deadbeef): Currently the expectation is that the video track's
|
| - // state will be set to "ended". However, in the future, it's likely that
|
| - // the video track will be completely removed from the remote stream
|
| - // (as it is on the C++ level).
|
| - MediaStream aRMS = answeringExpectations.gotRemoteStreams.iterator().next();
|
| - assertEquals(aRMS.videoTracks.get(0).state(), MediaStreamTrack.State.ENDED);
|
| -
|
| - // Finally, remove the audio track as well, which should completely remove
|
| - // the remote stream. This used to trigger an assert.
|
| - // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5128
|
| - AudioTrack offererAudioTrack = oLMS.get().audioTracks.get(0);
|
| - oLMS.get().removeTrack(offererAudioTrack);
|
| -
|
| - // Create offer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - offeringPC.createOffer(sdpLatch, new MediaConstraints());
|
| - assertTrue(sdpLatch.await());
|
| - offerSdp = sdpLatch.getSdp();
|
| - assertEquals(offerSdp.type, SessionDescription.Type.OFFER);
|
| - assertFalse(offerSdp.description.isEmpty());
|
| -
|
| - // Set local description for offerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - offeringExpectations.expectSignalingChange(SignalingState.HAVE_LOCAL_OFFER);
|
| - offeringPC.setLocalDescription(sdpLatch, offerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Set remote description for answerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringExpectations.expectSignalingChange(SignalingState.HAVE_REMOTE_OFFER);
|
| - answeringExpectations.expectRemoveStream("offeredMediaStream");
|
| - answeringPC.setRemoteDescription(sdpLatch, offerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Create answer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringPC.createAnswer(sdpLatch, new MediaConstraints());
|
| - assertTrue(sdpLatch.await());
|
| - answerSdp = sdpLatch.getSdp();
|
| - assertEquals(answerSdp.type, SessionDescription.Type.ANSWER);
|
| - assertFalse(answerSdp.description.isEmpty());
|
| -
|
| - // Set local description for answerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - answeringExpectations.expectSignalingChange(SignalingState.STABLE);
|
| - answeringPC.setLocalDescription(sdpLatch, answerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Set remote description for offerer.
|
| - sdpLatch = new SdpObserverLatch();
|
| - offeringExpectations.expectSignalingChange(SignalingState.STABLE);
|
| - offeringPC.setRemoteDescription(sdpLatch, answerSdp);
|
| - assertTrue(sdpLatch.await());
|
| - assertNull(sdpLatch.getSdp());
|
| -
|
| - // Make sure the stream was really removed.
|
| - assertTrue(answeringExpectations.gotRemoteStreams.isEmpty());
|
| -
|
| - // Free the Java-land objects and collect them.
|
| - shutdownPC(offeringPC, offeringExpectations);
|
| - offeringPC = null;
|
| - shutdownPC(answeringPC, answeringExpectations);
|
| - answeringPC = null;
|
| - offererVideoTrack.dispose();
|
| - offererAudioTrack.dispose();
|
| - videoCapturer.stopCapture();
|
| - videoCapturer.dispose();
|
| - videoSource.dispose();
|
| - factory.dispose();
|
| - System.gc();
|
| - }
|
| -
|
| - private static void getMetrics() {
|
| - Metrics metrics = Metrics.getAndReset();
|
| - assertTrue(metrics.map.size() > 0);
|
| - // Test for example that the lifetime of a Call is recorded.
|
| - String name = "WebRTC.Call.LifetimeInSeconds";
|
| - assertTrue(metrics.map.containsKey(name));
|
| - HistogramInfo info = metrics.map.get(name);
|
| - assertTrue(info.samples.size() > 0);
|
| - }
|
| -
|
| - private static void shutdownPC(PeerConnection pc, ObserverExpectations expectations) {
|
| - if (expectations.dataChannel != null) {
|
| - 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;
|
| - }
|
| -}
|
|
|