Bug 1232082 - add pc.ontrack and RTCTrackEvent r=jesup,smaug

--HG--
extra : rebase_source : fea25f937aca628960e665d9655c60806dd7e7f5
This commit is contained in:
Jan-Ivar Bruaroey 2016-01-12 15:09:01 -05:00
parent cff09a85aa
commit b3526e95e1
10 changed files with 95 additions and 26 deletions

View File

@ -449,6 +449,9 @@ const kEventConstructors = {
return new RTCPeerConnectionIceEvent(aName, aProps);
},
},
RTCTrackEvent: {
// Difficult to test required arguments.
},
ScrollAreaEvent: { create: function (aName, aProps) {
var e = document.createEvent("scrollareaevent");
e.initScrollAreaEvent(aName, aProps.bubbles, aProps.cancelable,

View File

@ -405,8 +405,9 @@ RTCPeerConnection.prototype = {
"InvalidStateError");
}
this.makeGetterSetterEH("onaddstream");
this.makeGetterSetterEH("onaddtrack");
this.makeGetterSetterEH("ontrack");
this.makeLegacyGetterSetterEH("onaddstream", "Use peerConnection.ontrack instead.");
this.makeLegacyGetterSetterEH("onaddtrack", "Use peerConnection.ontrack instead.");
this.makeGetterSetterEH("onicecandidate");
this.makeGetterSetterEH("onnegotiationneeded");
this.makeGetterSetterEH("onsignalingstatechange");
@ -663,6 +664,18 @@ RTCPeerConnection.prototype = {
});
},
makeLegacyGetterSetterEH: function(name, msg) {
Object.defineProperty(this, name,
{
get:function() { return this.getEH(name); },
set:function(h) {
this.logWarning(name + " is deprecated! " + msg,
null, 0);
return this.setEH(name, h);
}
});
},
_addIdentityAssertion: function(sdpPromise, origin) {
if (!this._localIdp.enabled) {
return sdpPromise;
@ -1452,14 +1465,20 @@ PeerConnectionObserver.prototype = {
{ stream: stream }));
},
onAddTrack: function(track) {
onAddTrack: function(track, streams) {
let pc = this._dompc;
let receiver = pc._win.RTCRtpReceiver._create(pc._win,
new RTCRtpReceiver(this,
track));
pc._receivers.push(receiver);
let ev = new this._dompc._win.MediaStreamTrackEvent("addtrack",
{ track: track });
let ev = new this._dompc._win.RTCTrackEvent("track",
{ receiver: receiver,
track: track,
streams: streams });
this.dispatchEvent(ev);
// Fire legacy event as well for a little bit.
ev = new this._dompc._win.MediaStreamTrackEvent("addtrack", { track: track });
this.dispatchEvent(ev);
},

View File

@ -15,19 +15,33 @@
var pc1 = new RTCPeerConnection();
var pc2 = new RTCPeerConnection();
var pc2_haveRemoteOffer = new Promise(resolve => pc2.onsignalingstatechange =
e => (e.target.signalingState == "have-remote-offer") && resolve());
var pc1_stable = new Promise(resolve => pc1.onsignalingstatechange =
e => (e.target.signalingState == "stable") && resolve());
var add = (pc, can, failed) => can && pc.addIceCandidate(can).catch(failed);
pc1.onicecandidate = e => add(pc2, e.candidate, generateErrorCallback());
pc2.onicecandidate = e => add(pc1, e.candidate, generateErrorCallback());
pc1.onicecandidate = e => pc2_haveRemoteOffer.then(() => !e.candidate ||
pc2.addIceCandidate(e.candidate)).catch(generateErrorCallback());
pc2.onicecandidate = e => pc1_stable.then(() => !e.candidate ||
pc1.addIceCandidate(e.candidate)).catch(generateErrorCallback());
function mustThrowWith(msg, reason, f) {
try {
f();
ok(false, msg + " must throw");
} catch (e) {
is(e.name, reason, msg + " must throw: " + e.message);
}
};
var v1, v2;
var delivered = new Promise(resolve =>
pc2.onaddstream = e => resolve(v2.srcObject = e.stream));
var delivered = new Promise(resolve => pc2.ontrack = e => {
// Test RTCTrackEvent here.
ok(e.streams.length > 0, "has streams");
ok(e.streams[0].getTracks().some(track => track == e.track), "has track");
ok(pc2.getReceivers().some(receiver => receiver == e.receiver), "has receiver");
if (e.streams[0].getTracks().length == 2) {
// Test RTCTrackEvent required args here.
mustThrowWith("RTCTrackEvent wo/required args",
"TypeError", () => new RTCTrackEvent("track", {}));
v2.srcObject = e.streams[0];
resolve();
}
});
runNetworkTest(function() {
v1 = createMediaElement('video', 'v1');
@ -37,7 +51,7 @@
is(v2.currentTime, 0, "v2.currentTime is zero at outset");
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => pc1.addStream(v1.srcObject = stream))
.then(stream => (v1.srcObject = stream).getTracks().forEach(t => pc1.addTrack(t, stream)))
.then(() => pc1.createOffer({})) // check that createOffer accepts arg.
.then(offer => pc1.setLocalDescription(offer))
.then(() => pc2.setRemoteDescription(pc1.localDescription))

View File

@ -997,6 +997,8 @@ var interfaceNamesInGlobalScope =
"RTCSessionDescription",
// IMPORTANT: Do not change this list without review from a DOM peer!
"RTCStatsReport",
// IMPORTANT: Do not change this list without review from a DOM peer!
"RTCTrackEvent",
// IMPORTANT: Do not change this list without review from a DOM peer!
"Screen",
// IMPORTANT: Do not change this list without review from a DOM peer!

View File

@ -42,6 +42,6 @@ interface PeerConnectionObserver
/* Changes to MediaStreamTracks */
void onAddStream(MediaStream stream);
void onRemoveStream(MediaStream stream);
void onAddTrack(MediaStreamTrack track);
void onAddTrack(MediaStreamTrack track, sequence<MediaStream> streams);
void onRemoveTrack(MediaStreamTrack track);
};

View File

@ -141,8 +141,9 @@ interface RTCPeerConnection : EventTarget {
attribute EventHandler onnegotiationneeded;
attribute EventHandler onicecandidate;
attribute EventHandler onsignalingstatechange;
attribute EventHandler onaddstream;
attribute EventHandler onaddtrack; // replaces onaddstream; see AddTrackEvent
attribute EventHandler onaddstream; // obsolete
attribute EventHandler onaddtrack; // obsolete
attribute EventHandler ontrack; // replaces onaddtrack and onaddstream.
attribute EventHandler onremovestream;
attribute EventHandler oniceconnectionstatechange;

View File

@ -0,0 +1,27 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://w3c.github.io/webrtc-pc/#idl-def-RTCTrackEvent
*/
dictionary RTCTrackEventInit : EventInit {
required RTCRtpReceiver receiver;
required MediaStreamTrack track;
sequence<MediaStream> streams = [];
};
[Pref="media.peerconnection.enabled",
Constructor(DOMString type, RTCTrackEventInit eventInitDict)]
interface RTCTrackEvent : Event {
readonly attribute RTCRtpReceiver receiver;
readonly attribute MediaStreamTrack track;
// TODO: Use FrozenArray once available. (Bug 1236777)
// readonly attribute FrozenArray<MediaStream> streams;
[Frozen, Cached, Pure]
readonly attribute sequence<MediaStream> streams; // workaround
};

View File

@ -836,6 +836,7 @@ if CONFIG['MOZ_WEBRTC']:
'MediaStreamTrackEvent.webidl',
'RTCDataChannelEvent.webidl',
'RTCPeerConnectionIceEvent.webidl',
'RTCTrackEvent.webidl',
]
if CONFIG['MOZ_WEBSPEECH']:

View File

@ -187,6 +187,7 @@ public:
virtual void NotifyTracksAvailable(DOMMediaStream* aStream) override
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aStream);
PeerConnectionWrapper wrapper(mPcHandle);
@ -200,6 +201,13 @@ public:
std::string streamId = PeerConnectionImpl::GetStreamId(*aStream);
bool notifyStream = true;
Sequence<OwningNonNull<DOMMediaStream>> streams;
if (!streams.AppendElement(OwningNonNull<DOMMediaStream>(*aStream),
fallible)) {
MOZ_ASSERT(false);
return;
}
for (size_t i = 0; i < tracks.Length(); i++) {
std::string trackId;
// This is the first chance we get to set the string track id on this
@ -231,7 +239,7 @@ public:
JSErrorResult jrv;
CSFLogInfo(logTag, "Calling OnAddTrack(%s)", trackId.c_str());
mObserver->OnAddTrack(*tracks[i], jrv);
mObserver->OnAddTrack(*tracks[i], streams, jrv);
if (jrv.Failed()) {
CSFLogError(logTag, ": OnAddTrack(%u) failed! Error: %u",
static_cast<unsigned>(i),

View File

@ -36,9 +36,6 @@
[RTCPeerConnection interface: operation addTrack(MediaStreamTrack,MediaStream)]
expected: FAIL
[RTCPeerConnection interface: attribute ontrack]
expected: FAIL
[RTCPeerConnection interface: operation getStats(MediaStreamTrack,RTCStatsCallback,RTCPeerConnectionErrorCallback)]
expected: FAIL
@ -186,9 +183,6 @@
[RTCPeerConnection interface: operation addTrack(MediaStreamTrack,MediaStream)]
expected: FAIL
[RTCPeerConnection interface: attribute ontrack]
expected: FAIL
[RTCPeerConnection interface: operation createDTMFSender(MediaStreamTrack)]
expected: FAIL