Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2013 Google Inc. | 3 * Copyright 2013 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 import org.webrtc.PeerConnection.SignalingState; | 32 import org.webrtc.PeerConnection.SignalingState; |
| 33 | 33 |
| 34 import java.io.File; | 34 import java.io.File; |
| 35 import java.lang.ref.WeakReference; | 35 import java.lang.ref.WeakReference; |
| 36 import java.nio.ByteBuffer; | 36 import java.nio.ByteBuffer; |
| 37 import java.nio.charset.Charset; | 37 import java.nio.charset.Charset; |
| 38 import java.util.Arrays; | 38 import java.util.Arrays; |
| 39 import java.util.IdentityHashMap; | 39 import java.util.IdentityHashMap; |
| 40 import java.util.LinkedList; | 40 import java.util.LinkedList; |
| 41 import java.util.List; | 41 import java.util.List; |
| 42 import java.util.HashSet; | |
| 42 import java.util.Map; | 43 import java.util.Map; |
| 43 import java.util.TreeSet; | 44 import java.util.TreeSet; |
| 44 import java.util.concurrent.CountDownLatch; | 45 import java.util.concurrent.CountDownLatch; |
| 45 import java.util.concurrent.TimeUnit; | 46 import java.util.concurrent.TimeUnit; |
| 46 | 47 |
| 47 import static junit.framework.Assert.*; | 48 import static junit.framework.Assert.*; |
| 48 | 49 |
| 49 /** End-to-end tests for PeerConnection.java. */ | 50 /** End-to-end tests for PeerConnection.java. */ |
| 50 public class PeerConnectionTest { | 51 public class PeerConnectionTest { |
| 51 // Set to true to render video. | 52 // Set to true to render video. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 81 private DataChannel dataChannel; | 82 private DataChannel dataChannel; |
| 82 private LinkedList<DataChannel.Buffer> expectedBuffers = | 83 private LinkedList<DataChannel.Buffer> expectedBuffers = |
| 83 new LinkedList<DataChannel.Buffer>(); | 84 new LinkedList<DataChannel.Buffer>(); |
| 84 private LinkedList<DataChannel.State> expectedStateChanges = | 85 private LinkedList<DataChannel.State> expectedStateChanges = |
| 85 new LinkedList<DataChannel.State>(); | 86 new LinkedList<DataChannel.State>(); |
| 86 private LinkedList<String> expectedRemoteDataChannelLabels = | 87 private LinkedList<String> expectedRemoteDataChannelLabels = |
| 87 new LinkedList<String>(); | 88 new LinkedList<String>(); |
| 88 private int expectedStatsCallbacks = 0; | 89 private int expectedStatsCallbacks = 0; |
| 89 private LinkedList<StatsReport[]> gotStatsReports = | 90 private LinkedList<StatsReport[]> gotStatsReports = |
| 90 new LinkedList<StatsReport[]>(); | 91 new LinkedList<StatsReport[]>(); |
| 92 private final HashSet<MediaStream> gotRemoteStreams = | |
| 93 new HashSet<MediaStream>(); | |
| 91 | 94 |
| 92 public ObserverExpectations(String name) { | 95 public ObserverExpectations(String name) { |
| 93 this.name = name; | 96 this.name = name; |
| 94 } | 97 } |
| 95 | 98 |
| 96 public synchronized void setDataChannel(DataChannel dataChannel) { | 99 public synchronized void setDataChannel(DataChannel dataChannel) { |
| 97 assertNull(this.dataChannel); | 100 assertNull(this.dataChannel); |
| 98 this.dataChannel = dataChannel; | 101 this.dataChannel = dataChannel; |
| 99 this.dataChannel.registerObserver(this); | 102 this.dataChannel.registerObserver(this); |
| 100 assertNotNull(this.dataChannel); | 103 assertNotNull(this.dataChannel); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 assertEquals(1, stream.videoTracks.size()); | 209 assertEquals(1, stream.videoTracks.size()); |
| 207 assertEquals(1, stream.audioTracks.size()); | 210 assertEquals(1, stream.audioTracks.size()); |
| 208 assertTrue(stream.videoTracks.get(0).id().endsWith("VideoTrack")); | 211 assertTrue(stream.videoTracks.get(0).id().endsWith("VideoTrack")); |
| 209 assertTrue(stream.audioTracks.get(0).id().endsWith("AudioTrack")); | 212 assertTrue(stream.audioTracks.get(0).id().endsWith("AudioTrack")); |
| 210 assertEquals("video", stream.videoTracks.get(0).kind()); | 213 assertEquals("video", stream.videoTracks.get(0).kind()); |
| 211 assertEquals("audio", stream.audioTracks.get(0).kind()); | 214 assertEquals("audio", stream.audioTracks.get(0).kind()); |
| 212 VideoRenderer renderer = createVideoRenderer(this); | 215 VideoRenderer renderer = createVideoRenderer(this); |
| 213 stream.videoTracks.get(0).addRenderer(renderer); | 216 stream.videoTracks.get(0).addRenderer(renderer); |
| 214 assertNull(renderers.put( | 217 assertNull(renderers.put( |
| 215 stream, new WeakReference<VideoRenderer>(renderer))); | 218 stream, new WeakReference<VideoRenderer>(renderer))); |
| 219 gotRemoteStreams.add(stream); | |
| 216 } | 220 } |
| 217 | 221 |
| 218 public synchronized void expectRemoveStream(String label) { | 222 public synchronized void expectRemoveStream(String label) { |
| 219 expectedRemoveStreamLabels.add(label); | 223 expectedRemoveStreamLabels.add(label); |
| 220 } | 224 } |
| 221 | 225 |
| 222 @Override | 226 @Override |
| 223 public synchronized void onRemoveStream(MediaStream stream) { | 227 public synchronized void onRemoveStream(MediaStream stream) { |
| 224 assertEquals(expectedRemoveStreamLabels.removeFirst(), stream.label()); | 228 assertEquals(expectedRemoveStreamLabels.removeFirst(), stream.label()); |
| 225 WeakReference<VideoRenderer> renderer = renderers.remove(stream); | 229 WeakReference<VideoRenderer> renderer = renderers.remove(stream); |
| 226 assertNotNull(renderer); | 230 assertNotNull(renderer); |
| 227 assertNotNull(renderer.get()); | 231 assertNotNull(renderer.get()); |
| 228 assertEquals(1, stream.videoTracks.size()); | 232 assertEquals(1, stream.videoTracks.size()); |
| 229 stream.videoTracks.get(0).removeRenderer(renderer.get()); | 233 stream.videoTracks.get(0).removeRenderer(renderer.get()); |
| 234 gotRemoteStreams.remove(stream); | |
| 230 } | 235 } |
| 231 | 236 |
| 232 public synchronized void expectDataChannel(String label) { | 237 public synchronized void expectDataChannel(String label) { |
| 233 expectedRemoteDataChannelLabels.add(label); | 238 expectedRemoteDataChannelLabels.add(label); |
| 234 } | 239 } |
| 235 | 240 |
| 236 @Override | 241 @Override |
| 237 public synchronized void onDataChannel(DataChannel remoteDataChannel) { | 242 public synchronized void onDataChannel(DataChannel remoteDataChannel) { |
| 238 assertEquals(expectedRemoteDataChannelLabels.removeFirst(), | 243 assertEquals(expectedRemoteDataChannelLabels.removeFirst(), |
| 239 remoteDataChannel.label()); | 244 remoteDataChannel.label()); |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 offeringExpectations.dataChannel.close(); | 714 offeringExpectations.dataChannel.close(); |
| 710 | 715 |
| 711 if (RENDER_TO_GUI) { | 716 if (RENDER_TO_GUI) { |
| 712 try { | 717 try { |
| 713 Thread.sleep(3000); | 718 Thread.sleep(3000); |
| 714 } catch (Throwable t) { | 719 } catch (Throwable t) { |
| 715 throw new RuntimeException(t); | 720 throw new RuntimeException(t); |
| 716 } | 721 } |
| 717 } | 722 } |
| 718 | 723 |
| 724 // Do another negotiation, removing the video track from one peer. | |
|
AlexG
2016/01/26 22:03:36
I think it should be under the boolean flag in doT
Taylor Brandstetter
2016/01/26 22:43:10
I just went ahead and created a separate test meth
| |
| 725 // This previously caused a crash on pc.dispose(). | |
| 726 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=5128 | |
| 727 VideoTrack offererVideoTrack = oLMS.get().videoTracks.get(0); | |
| 728 // Note that when we call removeTrack, we regain responsibility for | |
| 729 // disposing of the track. | |
| 730 oLMS.get().removeTrack(offererVideoTrack); | |
| 731 sdpLatch = new SdpObserverLatch(); | |
| 732 offeringPC.createOffer(sdpLatch, new MediaConstraints()); | |
| 733 assertTrue(sdpLatch.await()); | |
| 734 offerSdp = sdpLatch.getSdp(); | |
| 735 assertEquals(offerSdp.type, SessionDescription.Type.OFFER); | |
| 736 assertFalse(offerSdp.description.isEmpty()); | |
| 737 | |
| 738 // Set remote offer. | |
| 739 sdpLatch = new SdpObserverLatch(); | |
| 740 answeringExpectations.expectSignalingChange( | |
| 741 SignalingState.HAVE_REMOTE_OFFER); | |
| 742 answeringPC.setRemoteDescription(sdpLatch, offerSdp); | |
| 743 assertEquals( | |
| 744 PeerConnection.SignalingState.STABLE, offeringPC.signalingState()); | |
| 745 assertTrue(sdpLatch.await()); | |
| 746 assertNull(sdpLatch.getSdp()); | |
| 747 | |
| 748 sdpLatch = new SdpObserverLatch(); | |
| 749 answeringPC.createAnswer(sdpLatch, new MediaConstraints()); | |
| 750 assertTrue(sdpLatch.await()); | |
| 751 answerSdp = sdpLatch.getSdp(); | |
| 752 assertEquals(answerSdp.type, SessionDescription.Type.ANSWER); | |
| 753 assertFalse(answerSdp.description.isEmpty()); | |
| 754 | |
| 755 // Set local answer. | |
| 756 sdpLatch = new SdpObserverLatch(); | |
| 757 answeringExpectations.expectSignalingChange(SignalingState.STABLE); | |
| 758 answeringPC.setLocalDescription(sdpLatch, answerSdp); | |
| 759 assertTrue(sdpLatch.await()); | |
| 760 assertNull(sdpLatch.getSdp()); | |
| 761 | |
| 762 // Set local offer. | |
| 763 sdpLatch = new SdpObserverLatch(); | |
| 764 offeringExpectations.expectSignalingChange(SignalingState.HAVE_LOCAL_OFFER); | |
| 765 offeringPC.setLocalDescription(sdpLatch, offerSdp); | |
| 766 assertTrue(sdpLatch.await()); | |
| 767 assertNull(sdpLatch.getSdp()); | |
| 768 | |
| 769 // Set remote answer. | |
| 770 sdpLatch = new SdpObserverLatch(); | |
| 771 offeringExpectations.expectSignalingChange(SignalingState.STABLE); | |
| 772 offeringPC.setRemoteDescription(sdpLatch, answerSdp); | |
| 773 assertTrue(sdpLatch.await()); | |
| 774 assertNull(sdpLatch.getSdp()); | |
| 775 | |
| 776 // Make sure the track was really removed. | |
| 777 // TODO(deadbeef): Currently the expectation is that the video track's | |
| 778 // state will be set to "ended". However, in the future, it's likely that | |
| 779 // the video track will be completely removed from the remote stream | |
| 780 // (as it is on the C++ level). | |
| 781 MediaStream aRMS = answeringExpectations.gotRemoteStreams.iterator().next(); | |
| 782 assertEquals(aRMS.videoTracks.get(0).state(), MediaStreamTrack.State.ENDED); | |
| 783 | |
| 719 // TODO(fischman) MOAR test ideas: | 784 // TODO(fischman) MOAR test ideas: |
| 720 // - Test that PC.removeStream() works; requires a second | 785 // - Test that PC.removeStream() works; requires a second |
| 721 // createOffer/createAnswer dance. | 786 // createOffer/createAnswer dance. |
| 722 // - audit each place that uses |constraints| for specifying non-trivial | 787 // - audit each place that uses |constraints| for specifying non-trivial |
| 723 // constraints (and ensure they're honored). | 788 // constraints (and ensure they're honored). |
| 724 // - test error cases | 789 // - test error cases |
| 725 // - ensure reasonable coverage of _jni.cc is achieved. Coverage is | 790 // - ensure reasonable coverage of _jni.cc is achieved. Coverage is |
| 726 // extra-important because of all the free-text (class/method names, etc) | 791 // extra-important because of all the free-text (class/method names, etc) |
| 727 // in JNI-style programming; make sure no typos! | 792 // in JNI-style programming; make sure no typos! |
| 728 // - Test that shutdown mid-interaction is crash-free. | 793 // - Test that shutdown mid-interaction is crash-free. |
| 729 | 794 |
| 730 // Free the Java-land objects, collect them, and sleep a bit to make sure we | 795 // Free the Java-land objects, collect them, and sleep a bit to make sure we |
| 731 // don't get late-arrival crashes after the Java-land objects have been | 796 // don't get late-arrival crashes after the Java-land objects have been |
| 732 // freed. | 797 // freed. |
| 733 shutdownPC(offeringPC, offeringExpectations); | 798 shutdownPC(offeringPC, offeringExpectations); |
| 734 offeringPC = null; | 799 offeringPC = null; |
| 735 shutdownPC(answeringPC, answeringExpectations); | 800 shutdownPC(answeringPC, answeringExpectations); |
| 736 answeringPC = null; | 801 answeringPC = null; |
| 802 offererVideoTrack.dispose(); | |
| 737 videoSource.dispose(); | 803 videoSource.dispose(); |
| 738 factory.dispose(); | 804 factory.dispose(); |
| 739 System.gc(); | 805 System.gc(); |
| 740 } | 806 } |
| 741 | 807 |
| 742 private static void shutdownPC( | 808 private static void shutdownPC( |
| 743 PeerConnection pc, ObserverExpectations expectations) { | 809 PeerConnection pc, ObserverExpectations expectations) { |
| 744 expectations.dataChannel.unregisterObserver(); | 810 expectations.dataChannel.unregisterObserver(); |
| 745 expectations.dataChannel.dispose(); | 811 expectations.dataChannel.dispose(); |
| 746 expectations.expectStatsCallback(); | 812 expectations.expectStatsCallback(); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 773 TreeSet<String> threads = new TreeSet<String>(); | 839 TreeSet<String> threads = new TreeSet<String>(); |
| 774 // This pokes at /proc instead of using the Java APIs because we're also | 840 // This pokes at /proc instead of using the Java APIs because we're also |
| 775 // looking for libjingle/webrtc native threads, most of which won't have | 841 // looking for libjingle/webrtc native threads, most of which won't have |
| 776 // attached to the JVM. | 842 // attached to the JVM. |
| 777 for (String threadId : (new File("/proc/self/task")).list()) { | 843 for (String threadId : (new File("/proc/self/task")).list()) { |
| 778 threads.add(threadId); | 844 threads.add(threadId); |
| 779 } | 845 } |
| 780 return threads; | 846 return threads; |
| 781 } | 847 } |
| 782 } | 848 } |
| OLD | NEW |