WebRTC: Update RTCPeerConnection.add/removeTrack() and add test
authoradam.bergkvist@ericsson.com <adam.bergkvist@ericsson.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jan 2016 20:20:13 +0000 (20:20 +0000)
committeradam.bergkvist@ericsson.com <adam.bergkvist@ericsson.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Jan 2016 20:20:13 +0000 (20:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153010

Reviewed by Eric Carlson.

Source/WebCore:

RTCPeerConnection.add/removeTrack() are not fully spec compliant yet, since that would
require support for RTCRtpTransceiver which is a new work-in-progress feature. Use
Vector, instead of map, for senders and receivers since nothing is removed from these
sets anymore.

Test: fast/mediastream/RTCPeerConnection-add-removeTrack.html

* Modules/mediastream/RTCPeerConnection.cpp:
(WebCore::RTCPeerConnection::addTrack):
(WebCore::RTCPeerConnection::removeTrack):
(WebCore::RTCPeerConnection::queuedCreateOffer): Deleted.
* Modules/mediastream/RTCPeerConnection.h:
* Modules/mediastream/RTCRtpSender.cpp:
(WebCore::RTCRtpSender::RTCRtpSender):
* Modules/mediastream/RTCRtpSender.h:
(WebCore::RTCRtpSender::create):
(WebCore::RTCRtpSender::mediaStreamIds):

LayoutTests:

Add test for RTCPeerConnection.add/removeTrack() (currently not covered by other tests).
This test also covers some of the functionality of RTCRtpSender.

* fast/mediastream/RTCPeerConnection-add-removeTrack-expected.txt: Added.
* fast/mediastream/RTCPeerConnection-add-removeTrack.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194918 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/mediastream/RTCPeerConnection-add-removeTrack-expected.txt [new file with mode: 0644]
LayoutTests/fast/mediastream/RTCPeerConnection-add-removeTrack.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp
Source/WebCore/Modules/mediastream/RTCPeerConnection.h
Source/WebCore/Modules/mediastream/RTCRtpSender.cpp
Source/WebCore/Modules/mediastream/RTCRtpSender.h

index 8079d1ded02e44fafab99b7197ed98be799c02a1..7881a87dcd02f303eea917d5a847231c186a855f 100644 (file)
@@ -1,3 +1,16 @@
+2016-01-12  Adam Bergkvist  <adam.bergkvist@ericsson.com>
+
+        WebRTC: Update RTCPeerConnection.add/removeTrack() and add test
+        https://bugs.webkit.org/show_bug.cgi?id=153010
+
+        Reviewed by Eric Carlson.
+
+        Add test for RTCPeerConnection.add/removeTrack() (currently not covered by other tests).
+        This test also covers some of the functionality of RTCRtpSender.
+
+        * fast/mediastream/RTCPeerConnection-add-removeTrack-expected.txt: Added.
+        * fast/mediastream/RTCPeerConnection-add-removeTrack.html: Added.
+
 2016-01-12  Jiewen Tan  <jiewen_tan@apple.com>
 
         Null dereference loading Blink layout test editing/selection/selectstart-event-crash.html
 2016-01-12  Jiewen Tan  <jiewen_tan@apple.com>
 
         Null dereference loading Blink layout test editing/selection/selectstart-event-crash.html
diff --git a/LayoutTests/fast/mediastream/RTCPeerConnection-add-removeTrack-expected.txt b/LayoutTests/fast/mediastream/RTCPeerConnection-add-removeTrack-expected.txt
new file mode 100644 (file)
index 0000000..fa33959
--- /dev/null
@@ -0,0 +1,27 @@
+Test basic behavior of RTCPeerConnection.add/removeTrack()
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS pc.getSenders().length is 0
+PASS sender = pc.addTrack(track, stream) did not throw exception.
+PASS sender is an instance of RTCRtpSender
+PASS sender.track is track
+PASS pc.getSenders().length is 1
+PASS pc.getSenders()[0] is sender
+Try to add same track again
+PASS sender = pc.addTrack(track, stream) threw exception Error: InvalidModificationError: DOM Exception 13.
+PASS sender2 = pc.addTrack(track2, stream, stream2) did not throw exception.
+PASS pc.getSenders().length is 2
+PASS pc.getSenders()[0] is sender
+PASS pc.getSenders()[1] is sender2
+PASS pc.removeTrack(sender) did not throw exception.
+Sender is still in getSenders() list
+PASS pc.getSenders().length is 2
+PASS senderFromPc2 = pc2.addTrack(track, stream) did not throw exception.
+removeTrack() with 'foreign' sender must be ignored (not throw)
+PASS pc.removeTrack(senderFromPc2) did not throw exception.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/mediastream/RTCPeerConnection-add-removeTrack.html b/LayoutTests/fast/mediastream/RTCPeerConnection-add-removeTrack.html
new file mode 100644 (file)
index 0000000..d1ed5a3
--- /dev/null
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+    <head>
+        <script src="../../resources/js-test-pre.js"></script>
+    </head>
+    <body>
+        <script>
+            var stream;
+            var stream2;
+            var track;
+            var track2;
+            var sender;
+            var sender2;
+            var senderFromPc2
+
+            description("Test basic behavior of RTCPeerConnection.add/removeTrack()");
+
+            if (window.testRunner)
+                testRunner.setUserMediaPermission(true);
+            else {
+                debug("This test can not be run without the testRunner");
+                finishJSTest();
+            }
+
+            var pc = new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
+            var pc2 = new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
+
+            navigator.mediaDevices.getUserMedia({ "video": true })
+            .then(function (s) {
+                stream = s;
+                track = stream.getTracks()[0];
+
+                shouldBe("pc.getSenders().length", "0");
+
+                shouldNotThrow("sender = pc.addTrack(track, stream)");
+                shouldBeType("sender", "RTCRtpSender");
+                shouldBe("sender.track", "track");
+                shouldBe("pc.getSenders().length", "1");
+                shouldBe("pc.getSenders()[0]", "sender");
+
+                debug("Try to add same track again");
+                shouldThrow("sender = pc.addTrack(track, stream)");
+
+                track2 = track.clone();
+                stream2 = stream.clone();
+
+                shouldNotThrow("sender2 = pc.addTrack(track2, stream, stream2)");
+                shouldBe("pc.getSenders().length", "2");
+
+                // Order in list returned by getSenders() is unspecified.
+                if (pc.getSenders()[0] == sender) {
+                    shouldBe("pc.getSenders()[0]", "sender");
+                    shouldBe("pc.getSenders()[1]", "sender2");
+                } else {
+                    shouldBe("pc.getSenders()[0]", "sender2");
+                    shouldBe("pc.getSenders()[1]", "sender1");
+                }
+
+                shouldNotThrow("pc.removeTrack(sender)");
+                debug("Sender is still in getSenders() list")
+                shouldBe("pc.getSenders().length", "2");
+
+                shouldNotThrow("senderFromPc2 = pc2.addTrack(track, stream)");
+                debug("removeTrack() with 'foreign' sender must be ignored (not throw)");
+                shouldNotThrow("pc.removeTrack(senderFromPc2)");
+
+                finishJSTest();
+            })
+            .catch(function (error) {
+                testFailed("Error caught in promise chain: " + error);
+                finishJSTest();
+            });
+
+            window.jsTestIsAsync = true;
+            window.successfullyParsed = true;
+
+        </script>
+        <script src="../../resources/js-test-post.js"></script>
+    </body>
+</html>
index 01c7a57ea5e308e2834ee75b3284259d660c85ef..da9b9ef91d960431c16ecdc11eac0bba80cfa121 100644 (file)
@@ -1,3 +1,28 @@
+2016-01-12  Adam Bergkvist  <adam.bergkvist@ericsson.com>
+
+        WebRTC: Update RTCPeerConnection.add/removeTrack() and add test
+        https://bugs.webkit.org/show_bug.cgi?id=153010
+
+        Reviewed by Eric Carlson.
+
+        RTCPeerConnection.add/removeTrack() are not fully spec compliant yet, since that would
+        require support for RTCRtpTransceiver which is a new work-in-progress feature. Use
+        Vector, instead of map, for senders and receivers since nothing is removed from these
+        sets anymore.
+
+        Test: fast/mediastream/RTCPeerConnection-add-removeTrack.html
+
+        * Modules/mediastream/RTCPeerConnection.cpp:
+        (WebCore::RTCPeerConnection::addTrack):
+        (WebCore::RTCPeerConnection::removeTrack):
+        (WebCore::RTCPeerConnection::queuedCreateOffer): Deleted.
+        * Modules/mediastream/RTCPeerConnection.h:
+        * Modules/mediastream/RTCRtpSender.cpp:
+        (WebCore::RTCRtpSender::RTCRtpSender):
+        * Modules/mediastream/RTCRtpSender.h:
+        (WebCore::RTCRtpSender::create):
+        (WebCore::RTCRtpSender::mediaStreamIds):
+
 2016-01-12  Brady Eidson  <beidson@apple.com>
 
         Modern IDB: Check in empty SQLite backing store implementation.
 2016-01-12  Brady Eidson  <beidson@apple.com>
 
         Modern IDB: Check in empty SQLite backing store implementation.
index 2122aaa340176e3922baccfc3416c8e7ff62514f..1dd65b2fbfd521a78adfc7117e00831b4ce4fbbd 100644 (file)
@@ -49,8 +49,6 @@
 #include "RTCIceCandidate.h"
 #include "RTCIceCandidateEvent.h"
 #include "RTCOfferAnswerOptions.h"
 #include "RTCIceCandidate.h"
 #include "RTCIceCandidateEvent.h"
 #include "RTCOfferAnswerOptions.h"
-#include "RTCRtpReceiver.h"
-#include "RTCRtpSender.h"
 #include "RTCSessionDescription.h"
 #include "RTCTrackEvent.h"
 #include <wtf/MainThread.h>
 #include "RTCSessionDescription.h"
 #include "RTCTrackEvent.h"
 #include <wtf/MainThread.h>
@@ -104,24 +102,6 @@ RTCPeerConnection::~RTCPeerConnection()
     stop();
 }
 
     stop();
 }
 
-Vector<RefPtr<RTCRtpSender>> RTCPeerConnection::getSenders() const
-{
-    Vector<RefPtr<RTCRtpSender>> senders;
-    senders.reserveCapacity(m_senderSet.size());
-    copyValuesToVector(m_senderSet, senders);
-
-    return senders;
-}
-
-Vector<RefPtr<RTCRtpReceiver>> RTCPeerConnection::getReceivers() const
-{
-    Vector<RefPtr<RTCRtpReceiver>> receivers;
-    receivers.reserveCapacity(m_receiverSet.size());
-    copyValuesToVector(m_receiverSet, receivers);
-
-    return receivers;
-}
-
 RefPtr<RTCRtpSender> RTCPeerConnection::addTrack(RefPtr<MediaStreamTrack>&& track, Vector<MediaStream*> streams, ExceptionCode& ec)
 {
     if (!track) {
 RefPtr<RTCRtpSender> RTCPeerConnection::addTrack(RefPtr<MediaStreamTrack>&& track, Vector<MediaStream*> streams, ExceptionCode& ec)
 {
     if (!track) {
@@ -140,15 +120,20 @@ RefPtr<RTCRtpSender> RTCPeerConnection::addTrack(RefPtr<MediaStreamTrack>&& trac
         return nullptr;
     }
 
         return nullptr;
     }
 
-    if (m_senderSet.contains(track->id())) {
-        // FIXME: Spec says InvalidParameter
-        ec = INVALID_MODIFICATION_ERR;
-        return nullptr;
+    for (auto& sender : m_senderSet) {
+        if (sender->track()->id() == track->id()) {
+            // FIXME: Spec says InvalidParameter
+            ec = INVALID_MODIFICATION_ERR;
+            return nullptr;
+        }
     }
 
     }
 
-    const String& trackId = track->id();
-    RefPtr<RTCRtpSender> sender = RTCRtpSender::create(WTFMove(track), streams[0]->id());
-    m_senderSet.add(trackId, sender);
+    Vector<String> mediaStreamIds;
+    for (auto stream : streams)
+        mediaStreamIds.append(stream->id());
+
+    RefPtr<RTCRtpSender> sender = RTCRtpSender::create(WTFMove(track), WTFMove(mediaStreamIds));
+    m_senderSet.append(sender);
 
     m_backend->markAsNeedingNegotiation();
 
 
     m_backend->markAsNeedingNegotiation();
 
@@ -167,7 +152,7 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec)
         return;
     }
 
         return;
     }
 
-    if (!m_senderSet.remove(sender->track()->id()))
+    if (!m_senderSet.contains(sender))
         return;
 
     m_backend->markAsNeedingNegotiation();
         return;
 
     m_backend->markAsNeedingNegotiation();
index a4f9025eaec6ba7909a3aa21529b93b6e1f2b4f6..9f9e875890908b7ac1359a7adac72afba07c36b2 100644 (file)
@@ -41,6 +41,8 @@
 // FIXME: Workaround for bindings bug http://webkit.org/b/150121
 #include "JSMediaStream.h"
 #include "PeerConnectionBackend.h"
 // FIXME: Workaround for bindings bug http://webkit.org/b/150121
 #include "JSMediaStream.h"
 #include "PeerConnectionBackend.h"
+#include "RTCRtpReceiver.h"
+#include "RTCRtpSender.h"
 #include "ScriptWrappable.h"
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
 #include "ScriptWrappable.h"
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
@@ -54,8 +56,6 @@ class RTCConfiguration;
 class RTCDataChannel;
 class RTCIceCandidate;
 class RTCPeerConnectionErrorCallback;
 class RTCDataChannel;
 class RTCIceCandidate;
 class RTCPeerConnectionErrorCallback;
-class RTCRtpReceiver;
-class RTCRtpSender;
 class RTCSessionDescription;
 class RTCStatsCallback;
 
 class RTCSessionDescription;
 class RTCStatsCallback;
 
@@ -64,8 +64,8 @@ public:
     static RefPtr<RTCPeerConnection> create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, ExceptionCode&);
     ~RTCPeerConnection();
 
     static RefPtr<RTCPeerConnection> create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, ExceptionCode&);
     ~RTCPeerConnection();
 
-    Vector<RefPtr<RTCRtpSender>> getSenders() const override;
-    Vector<RefPtr<RTCRtpReceiver>> getReceivers() const;
+    Vector<RefPtr<RTCRtpSender>> getSenders() const override { return m_senderSet; }
+    Vector<RefPtr<RTCRtpReceiver>> getReceivers() const { return m_receiverSet; }
 
     RefPtr<RTCRtpSender> addTrack(RefPtr<MediaStreamTrack>&&, Vector<MediaStream*>, ExceptionCode&);
     void removeTrack(RTCRtpSender*, ExceptionCode&);
 
     RefPtr<RTCRtpSender> addTrack(RefPtr<MediaStreamTrack>&&, Vector<MediaStream*>, ExceptionCode&);
     void removeTrack(RTCRtpSender*, ExceptionCode&);
@@ -135,8 +135,8 @@ private:
     PeerConnectionStates::IceGatheringState m_iceGatheringState;
     PeerConnectionStates::IceConnectionState m_iceConnectionState;
 
     PeerConnectionStates::IceGatheringState m_iceGatheringState;
     PeerConnectionStates::IceConnectionState m_iceConnectionState;
 
-    HashMap<String, RefPtr<RTCRtpSender>> m_senderSet;
-    HashMap<String, RefPtr<RTCRtpReceiver>> m_receiverSet;
+    Vector<RefPtr<RTCRtpSender>> m_senderSet;
+    Vector<RefPtr<RTCRtpReceiver>> m_receiverSet;
 
     Vector<RefPtr<RTCDataChannel>> m_dataChannels;
 
 
     Vector<RefPtr<RTCDataChannel>> m_dataChannels;
 
index e007dbe571c7affc2cb07e9c55f05bbe60f670a7..66d3740620a0e9d5c63786e3bc795afc1f3ed869 100644 (file)
@@ -35,9 +35,9 @@
 
 namespace WebCore {
 
 
 namespace WebCore {
 
-RTCRtpSender::RTCRtpSender(RefPtr<MediaStreamTrack>&& track, const String& mediaStreamId)
+RTCRtpSender::RTCRtpSender(RefPtr<MediaStreamTrack>&& track, Vector<String>&& mediaStreamIds)
     : RTCRtpSenderReceiverBase(WTFMove(track))
     : RTCRtpSenderReceiverBase(WTFMove(track))
-    , m_mediaStreamId(mediaStreamId)
+    , m_mediaStreamIds(WTFMove(mediaStreamIds))
 {
 }
 
 {
 }
 
index f44973904fbf8f4c0ceae7f65c817c6856d8905d..257d3263a8b2237c11533c879e575b46fc854817 100644 (file)
@@ -40,17 +40,17 @@ namespace WebCore {
 
 class RTCRtpSender : public RTCRtpSenderReceiverBase {
 public:
 
 class RTCRtpSender : public RTCRtpSenderReceiverBase {
 public:
-    static Ref<RTCRtpSender> create(RefPtr<MediaStreamTrack>&& track, const String& mediaStreamId)
+    static Ref<RTCRtpSender> create(RefPtr<MediaStreamTrack>&& track, Vector<String>&& mediaStreamIds)
     {
     {
-        return adoptRef(*new RTCRtpSender(WTFMove(track), mediaStreamId));
+        return adoptRef(*new RTCRtpSender(WTFMove(track), WTFMove(mediaStreamIds)));
     }
 
     }
 
-    const String& mediaStreamId() const { return m_mediaStreamId; }
+    const Vector<String>& mediaStreamIds() const { return m_mediaStreamIds; }
 
 private:
 
 private:
-    RTCRtpSender(RefPtr<MediaStreamTrack>&&, const String& mediaStreamId);
+    RTCRtpSender(RefPtr<MediaStreamTrack>&&, Vector<String>&& mediaStreamIds);
 
 
-    String m_mediaStreamId;
+    Vector<String> m_mediaStreamIds;
 };
 
 } // namespace WebCore
 };
 
 } // namespace WebCore