mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 694807: Implement PeerConnection DOM interface; r=jst
This commit is contained in:
parent
62ba9bbbc0
commit
1aff81d601
@ -266,6 +266,9 @@
|
||||
@BINPATH@/components/necko.xpt
|
||||
@BINPATH@/components/loginmgr.xpt
|
||||
@BINPATH@/components/parentalcontrols.xpt
|
||||
#ifdef MOZ_WEBRTC
|
||||
@BINPATH@/components/peerconnection.xpt
|
||||
#endif
|
||||
@BINPATH@/components/places.xpt
|
||||
@BINPATH@/components/plugin.xpt
|
||||
@BINPATH@/components/pref.xpt
|
||||
@ -490,6 +493,11 @@
|
||||
@BINPATH@/components/TCPSocketParentIntermediary.js
|
||||
@BINPATH@/components/TCPSocket.manifest
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
@BINPATH@/components/PeerConnection.js
|
||||
@BINPATH@/components/PeerConnection.manifest
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MARIONETTE
|
||||
@BINPATH@/chrome/marionette@JAREXT@
|
||||
@BINPATH@/chrome/marionette.manifest
|
||||
|
@ -19,8 +19,14 @@ FAIL_ON_WARNINGS := 1
|
||||
|
||||
include $(topsrcdir)/dom/dom-config.mk
|
||||
|
||||
EXTRA_COMPONENTS = \
|
||||
PeerConnection.js \
|
||||
PeerConnection.manifest \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIDOMMediaStream.idl \
|
||||
nsIDOMRTCPeerConnection.idl \
|
||||
nsIDOMNavigatorUserMedia.idl \
|
||||
$(NULL)
|
||||
|
||||
|
575
dom/media/PeerConnection.js
Normal file
575
dom/media/PeerConnection.js
Normal file
@ -0,0 +1,575 @@
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const PC_CONTRACT = "@mozilla.org/dom/peerconnection;1";
|
||||
const PC_ICE_CONTRACT = "@mozilla.org/dom/rtcicecandidate;1";
|
||||
const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
|
||||
|
||||
const PC_CID = Components.ID("{7cb2b368-b1ce-4560-acac-8e0dbda7d3d0}");
|
||||
const PC_ICE_CID = Components.ID("{8c5dbd70-2c8e-4ecb-a5ad-2fc919099f01}");
|
||||
const PC_SESSION_CID = Components.ID("{5f21ffd9-b73f-4ba0-a685-56b4667aaf1c}");
|
||||
|
||||
// Global list of PeerConnection objects, so they can be cleaned up when
|
||||
// a page is torn down. (Maps inner window ID to an array of PC objects).
|
||||
function GlobalPCList() {
|
||||
this._list = {};
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", true);
|
||||
}
|
||||
GlobalPCList.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
addPC: function(pc) {
|
||||
let winID = pc._winID;
|
||||
if (this._list[winID]) {
|
||||
this._list[winID].push(pc);
|
||||
} else {
|
||||
this._list[winID] = [pc];
|
||||
}
|
||||
},
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic != "inner-window-destroyed") {
|
||||
return;
|
||||
}
|
||||
let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (this._list[winID]) {
|
||||
this._list[winID].forEach(function(pc) {
|
||||
pc._pc.close();
|
||||
delete pc._observer;
|
||||
});
|
||||
delete this._list[winID];
|
||||
}
|
||||
}
|
||||
};
|
||||
let _globalPCList = new GlobalPCList();
|
||||
|
||||
function IceCandidate(candidate) {
|
||||
this.candidate = candidate;
|
||||
this.sdpMid = null;
|
||||
this.sdpMLineIndex = null;
|
||||
}
|
||||
IceCandidate.prototype = {
|
||||
classID: PC_ICE_CID,
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: PC_ICE_CID,
|
||||
contractID: PC_ICE_CONTRACT,
|
||||
classDescription: "IceCandidate",
|
||||
interfaces: [
|
||||
Ci.nsIDOMRTCIceCandidate
|
||||
],
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIDOMRTCIceCandidate, Ci.nsIDOMGlobalObjectConstructor
|
||||
]),
|
||||
|
||||
constructor: function(win, cand, mid, mline) {
|
||||
if (this._win) {
|
||||
throw new Error("Constructor already called");
|
||||
}
|
||||
this._win = win;
|
||||
this.candidate = cand;
|
||||
this.sdpMid = mid;
|
||||
this.sdpMLineIndex = mline;
|
||||
}
|
||||
};
|
||||
|
||||
function SessionDescription(type, sdp) {
|
||||
this.type = type;
|
||||
this.sdp = sdp;
|
||||
}
|
||||
SessionDescription.prototype = {
|
||||
classID: PC_SESSION_CID,
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: PC_SESSION_CID,
|
||||
contractID: PC_SESSION_CONTRACT,
|
||||
classDescription: "SessionDescription",
|
||||
interfaces: [
|
||||
Ci.nsIDOMRTCSessionDescription
|
||||
],
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIDOMRTCSessionDescription, Ci.nsIDOMGlobalObjectConstructor
|
||||
]),
|
||||
|
||||
constructor: function(win, type, sdp) {
|
||||
if (this._win) {
|
||||
throw new Error("Constructor already called");
|
||||
}
|
||||
this._win = win;
|
||||
this.type = type;
|
||||
this.sdp = sdp;
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return JSON.stringify({
|
||||
type: this.type, sdp: this.sdp
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function PeerConnection() {
|
||||
this._queue = [];
|
||||
|
||||
this._pc = null;
|
||||
this._observer = null;
|
||||
|
||||
this._onCreateOfferSuccess = null;
|
||||
this._onCreateOfferFailure = null;
|
||||
this._onCreateAnswerSuccess = null;
|
||||
this._onCreateAnswerFailure = null;
|
||||
|
||||
/**
|
||||
* Everytime we get a request from content, we put it in the queue. If
|
||||
* there are no pending operations though, we will execute it immediately.
|
||||
* In PeerConnectionObserver, whenever we are notified that an operation
|
||||
* has finished, we will check the queue for the next operation and execute
|
||||
* if neccesary. The _pending flag indicates whether an operation is currently
|
||||
* in progress.
|
||||
*/
|
||||
this._pending = false;
|
||||
|
||||
// Public attributes.
|
||||
this.onaddstream = null;
|
||||
this.onremovestream = null;
|
||||
this.onicecandidate = null;
|
||||
this.onstatechange = null;
|
||||
this.ongatheringchange = null;
|
||||
this.onicechange = null;
|
||||
}
|
||||
PeerConnection.prototype = {
|
||||
classID: PC_CID,
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: PC_CID,
|
||||
contractID: PC_CONTRACT,
|
||||
classDescription: "PeerConnection",
|
||||
interfaces: [
|
||||
Ci.nsIDOMRTCPeerConnection
|
||||
],
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIDOMRTCPeerConnection, Ci.nsIDOMGlobalObjectConstructor
|
||||
]),
|
||||
|
||||
// Constructor is an explicit function, because of nsIDOMGlobalObjectConstructor.
|
||||
constructor: function(win) {
|
||||
if (!Services.prefs.getBoolPref("media.peerconnection.enabled")) {
|
||||
throw new Error("PeerConnection not enabled (did you set the pref?)");
|
||||
}
|
||||
if (this._win) {
|
||||
throw new Error("Constructor already called");
|
||||
}
|
||||
|
||||
this._pc = Cc["@mozilla.org/peerconnection;1"].
|
||||
createInstance(Ci.IPeerConnection);
|
||||
this._observer = new PeerConnectionObserver(this);
|
||||
|
||||
// Nothing starts until ICE gathering completes.
|
||||
this._queueOrRun({
|
||||
func: this._pc.initialize,
|
||||
args: [this._observer, win, Services.tm.currentThread],
|
||||
wait: true
|
||||
});
|
||||
|
||||
this._win = win;
|
||||
this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
|
||||
|
||||
// Add a reference to the PeerConnection to global list.
|
||||
_globalPCList.addPC(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a function to the queue or run it immediately if the queue is empty.
|
||||
* Argument is an object with the func, args and wait properties; wait should
|
||||
* be set to true if the function has a success/error callback that will
|
||||
* call _executeNext, false if it doesn't have a callback.
|
||||
*/
|
||||
_queueOrRun: function(obj) {
|
||||
if (!this._pending) {
|
||||
obj.func.apply(this, obj.args);
|
||||
if (obj.wait) {
|
||||
this._pending = true;
|
||||
}
|
||||
} else {
|
||||
this._queue.push(obj);
|
||||
}
|
||||
},
|
||||
|
||||
// Pick the next item from the queue and run it.
|
||||
_executeNext: function() {
|
||||
if (this._queue.length) {
|
||||
let obj = this._queue.shift();
|
||||
obj.func.apply(this, obj.args);
|
||||
if (!obj.wait) {
|
||||
this._executeNext();
|
||||
}
|
||||
} else {
|
||||
this._pending = false;
|
||||
}
|
||||
},
|
||||
|
||||
createOffer: function(onSuccess, onError, constraints) {
|
||||
if (this._onCreateOfferSuccess) {
|
||||
if (onError) {
|
||||
onError.onCallback("createOffer already called");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._onCreateOfferSuccess = onSuccess;
|
||||
this._onCreateOfferFailure = onError;
|
||||
|
||||
// TODO: Implement constraints/hints.
|
||||
if (!constraints) {
|
||||
constraints = "";
|
||||
}
|
||||
|
||||
this._queueOrRun({
|
||||
func: this._pc.createOffer,
|
||||
args: [constraints],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
||||
createAnswer: function(offer, onSuccess, onError, constraints, provisional) {
|
||||
if (this._onCreateAnswerSuccess) {
|
||||
if (onError) {
|
||||
onError.onCallback("createAnswer already called");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._onCreateAnswerSuccess = onSuccess;
|
||||
this._onCreateAnswerFailure = onError;
|
||||
|
||||
if (offer.type != "offer") {
|
||||
if (onError) {
|
||||
onError.onCallback("Invalid type " + offer.type + " passed");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!offer.sdp) {
|
||||
if (onError) {
|
||||
onError.onCallback("SDP not provided to createAnswer");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!constraints) {
|
||||
constraints = "";
|
||||
}
|
||||
if (!provisional) {
|
||||
provisional = false;
|
||||
}
|
||||
|
||||
// TODO: Implement provisional answer & constraints.
|
||||
this._queueOrRun({
|
||||
func: this._pc.createAnswer,
|
||||
args: ["", offer.sdp],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
||||
setLocalDescription: function(desc, onSuccess, onError) {
|
||||
if (this._onSetLocalDescriptionSuccess) {
|
||||
if (onError) {
|
||||
onError.onCallback("setLocalDescription already called");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._onSetLocalDescriptionSuccess = onSuccess;
|
||||
this._onSetLocalDescriptionFailure = onError;
|
||||
|
||||
let type;
|
||||
switch (desc.type) {
|
||||
case "offer":
|
||||
type = Ci.IPeerConnection.kActionOffer;
|
||||
break;
|
||||
case "answer":
|
||||
type = Ci.IPeerConnection.kActionAnswer;
|
||||
break;
|
||||
default:
|
||||
if (onError) {
|
||||
onError.onCallback(
|
||||
"Invalid type " + desc.type + " provided to setLocalDescription"
|
||||
);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this._queueOrRun({
|
||||
func: this._pc.setLocalDescription,
|
||||
args: [type, desc.sdp],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
||||
setRemoteDescription: function(desc, onSuccess, onError) {
|
||||
if (this._onSetRemoteDescriptionSuccess) {
|
||||
if (onError) {
|
||||
onError.onCallback("setRemoteDescription already called");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._onSetRemoteDescriptionSuccess = onSuccess;
|
||||
this._onSetRemoteDescriptionFailure = onError;
|
||||
|
||||
let type;
|
||||
switch (desc.type) {
|
||||
case "offer":
|
||||
type = Ci.IPeerConnection.kActionOffer;
|
||||
break;
|
||||
case "answer":
|
||||
type = Ci.IPeerConnection.kActionAnswer;
|
||||
break;
|
||||
default:
|
||||
if (onError) {
|
||||
onError.onCallback(
|
||||
"Invalid type " + desc.type + " provided to setLocalDescription"
|
||||
);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this._queueOrRun({
|
||||
func: this._pc.setRemoteDescription,
|
||||
args: [type, desc.sdp],
|
||||
wait: true
|
||||
});
|
||||
},
|
||||
|
||||
updateIce: function(config, constraints, restart) {
|
||||
return Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
addIceCandidate: function(cand) {
|
||||
if (!cand) {
|
||||
throw "Invalid candidate passed to addIceCandidate!";
|
||||
}
|
||||
if (!cand.candidate || !cand.sdpMid || !cand.sdpMLineIndex) {
|
||||
throw "Invalid candidate passed to addIceCandidate!";
|
||||
}
|
||||
|
||||
this._queueOrRun({
|
||||
func: this._pc.addIceCandidate,
|
||||
args: [cand.candidate, cand.sdpMid, cand.sdpMLineIndex],
|
||||
wait: false
|
||||
});
|
||||
},
|
||||
|
||||
addStream: function(stream, constraints) {
|
||||
// TODO: Implement constraints.
|
||||
this._queueOrRun({
|
||||
func: this._pc.addStream,
|
||||
args: [stream],
|
||||
wait: false
|
||||
});
|
||||
},
|
||||
|
||||
removeStream: function(stream) {
|
||||
this._queueOrRun({
|
||||
func: this._pc.removeStream,
|
||||
args: [stream],
|
||||
wait: false
|
||||
});
|
||||
},
|
||||
|
||||
close: function() {
|
||||
this._queueOrRun({
|
||||
func: this._pc.close,
|
||||
args: [],
|
||||
wait: false
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// This is a seperate object because we don't want to expose it to DOM.
|
||||
function PeerConnectionObserver(dompc) {
|
||||
this._dompc = dompc;
|
||||
}
|
||||
PeerConnectionObserver.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.IPeerConnectionObserver]),
|
||||
|
||||
onCreateOfferSuccess: function(offer) {
|
||||
if (this._dompc._onCreateOfferSuccess) {
|
||||
try {
|
||||
this._dompc._onCreateOfferSuccess.onCallback({
|
||||
type: "offer", sdp: offer,
|
||||
__exposedProps__: { type: "rw", sdp: "rw" }
|
||||
});
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onCreateOfferError: function(code) {
|
||||
if (this._dompc._onCreateOfferFailure) {
|
||||
try {
|
||||
this._dompc._onCreateOfferFailure.onCallback(code);
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onCreateAnswerSuccess: function(answer) {
|
||||
if (this._dompc._onCreateAnswerSuccess) {
|
||||
try {
|
||||
this._dompc._onCreateAnswerSuccess.onCallback({
|
||||
type: "answer", sdp: answer,
|
||||
__exposedProps__: { type: "rw", sdp: "rw" }
|
||||
});
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onCreateAnswerError: function(code) {
|
||||
if (this._dompc._onCreateAnswerFailure) {
|
||||
try {
|
||||
this._dompc._onCreateAnswerFailure.onCallback(code);
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onSetLocalDescriptionSuccess: function(code) {
|
||||
if (this._dompc._onSetLocalDescriptionSuccess) {
|
||||
try {
|
||||
this._dompc._onSetLocalDescriptionSuccess.onCallback(code);
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onSetRemoteDescriptionSuccess: function(code) {
|
||||
if (this._dompc._onSetRemoteDescriptionSuccess) {
|
||||
try {
|
||||
this._dompc._onSetRemoteDescriptionSuccess.onCallback(code);
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onSetLocalDescriptionError: function(code) {
|
||||
if (this._dompc._onSetLocalDescriptionFailure) {
|
||||
try {
|
||||
this._dompc._onSetLocalDescriptionFailure.onCallback(code);
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onSetRemoteDescriptionError: function(code) {
|
||||
if (this._dompc._onSetRemoteDescriptionFailure) {
|
||||
this._dompc._onSetRemoteDescriptionFailure.onCallback(code);
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onStateChange: function(state) {
|
||||
if (state != Ci.IPeerConnectionObserver.kIceState) {
|
||||
return;
|
||||
}
|
||||
|
||||
let self = this;
|
||||
let iceCb = function() {};
|
||||
let iceGatherCb = function() {};
|
||||
if (this._dompc.onicechange) {
|
||||
iceCb = function(args) {
|
||||
try {
|
||||
self._dompc.onicechange(args);
|
||||
} catch(e) {}
|
||||
};
|
||||
}
|
||||
if (this._dompc.ongatheringchange) {
|
||||
iceGatherCb = function(args) {
|
||||
try {
|
||||
self._dompc.ongatheringchange(args);
|
||||
} catch(e) {}
|
||||
};
|
||||
}
|
||||
|
||||
switch (this._dompc._pc.iceState) {
|
||||
case Ci.IPeerConnection.kIceGathering:
|
||||
iceGatherCb("gathering");
|
||||
break;
|
||||
case Ci.IPeerConnection.kIceWaiting:
|
||||
iceCb("starting");
|
||||
this._dompc._executeNext();
|
||||
break;
|
||||
case Ci.IPeerConnection.kIceChecking:
|
||||
iceCb("checking");
|
||||
this._dompc._executeNext();
|
||||
break;
|
||||
case Ci.IPeerConnection.kIceConnected:
|
||||
// ICE gathering complete.
|
||||
iceCb("connected");
|
||||
iceGatherCb("complete");
|
||||
this._dompc._executeNext();
|
||||
break;
|
||||
case Ci.IPeerConnection.kIceFailed:
|
||||
iceCb("failed");
|
||||
break;
|
||||
default:
|
||||
// Unknown state!
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onAddStream: function(stream, type) {
|
||||
if (this._dompc.onaddstream) {
|
||||
try {
|
||||
this._dompc.onaddstream.onCallback({
|
||||
stream: stream, type: type,
|
||||
__exposedProps__: { stream: "r", type: "r" }
|
||||
});
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
onRemoveStream: function(stream, type) {
|
||||
if (this._dompc.onremovestream) {
|
||||
try {
|
||||
this._dompc.onremovestream.onCallback({
|
||||
stream: stream, type: type,
|
||||
__exposedProps__: { stream: "r", type: "r" }
|
||||
});
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
},
|
||||
|
||||
foundIceCandidate: function(cand) {
|
||||
if (this._dompc.onicecandidate) {
|
||||
try {
|
||||
this._dompc.onicecandidate.onCallback({
|
||||
candidate: cand,
|
||||
__exposedProps__: { candidate: "rw" }
|
||||
});
|
||||
} catch(e) {}
|
||||
}
|
||||
this._dompc._executeNext();
|
||||
}
|
||||
};
|
||||
|
||||
let NSGetFactory = XPCOMUtils.generateNSGetFactory(
|
||||
[IceCandidate, SessionDescription, PeerConnection]
|
||||
);
|
11
dom/media/PeerConnection.manifest
Normal file
11
dom/media/PeerConnection.manifest
Normal file
@ -0,0 +1,11 @@
|
||||
component {7cb2b368-b1ce-4560-acac-8e0dbda7d3d0} PeerConnection.js
|
||||
component {8c5dbd70-2c8e-4ecb-a5ad-2fc919099f01} PeerConnection.js
|
||||
component {5f21ffd9-b73f-4ba0-a685-56b4667aaf1c} PeerConnection.js
|
||||
|
||||
contract @mozilla.org/dom/peerconnection;1 {7cb2b368-b1ce-4560-acac-8e0dbda7d3d0}
|
||||
contract @mozilla.org/dom/rtcicecandidate;1 {8c5dbd70-2c8e-4ecb-a5ad-2fc919099f01}
|
||||
contract @mozilla.org/dom/rtcsessiondescription;1 {5f21ffd9-b73f-4ba0-a685-56b4667aaf1c}
|
||||
|
||||
category JavaScript-global-constructor mozRTCPeerConnection @mozilla.org/dom/peerconnection;1
|
||||
category JavaScript-global-constructor mozRTCIceCandidate @mozilla.org/dom/rtcicecandidate;1
|
||||
category JavaScript-global-constructor mozRTCSessionDescription @mozilla.org/dom/rtcsessiondescription;1
|
87
dom/media/nsIDOMRTCPeerConnection.idl
Normal file
87
dom/media/nsIDOMRTCPeerConnection.idl
Normal file
@ -0,0 +1,87 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIDOMMediaStream.idl"
|
||||
|
||||
[scriptable, function, uuid(eb9c563c-3b09-4565-9317-eca96ae0c538)]
|
||||
interface RTCPeerConnectionCallback : nsISupports
|
||||
{
|
||||
void onCallback(in jsval value);
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(55546efd-287b-4460-8283-0592875b890f)]
|
||||
interface RTCPeerConnectionCallbackVoid : nsISupports
|
||||
{
|
||||
void onCallback();
|
||||
};
|
||||
|
||||
[scriptable, uuid(05d7375e-b024-4951-a570-c6642105ad35)]
|
||||
interface nsIDOMRTCSessionDescription : nsISupports
|
||||
{
|
||||
attribute DOMString sdp;
|
||||
attribute DOMString type;
|
||||
};
|
||||
|
||||
[scriptable, uuid(df176474-e20a-4f42-a85b-b0414d634cf0)]
|
||||
interface nsIDOMRTCIceCandidate : nsISupports
|
||||
{
|
||||
attribute DOMString candidate;
|
||||
attribute DOMString sdpMid;
|
||||
attribute unsigned short sdpMLineIndex;
|
||||
};
|
||||
|
||||
/* See http://dev.w3.org/2011/webrtc/editor/webrtc.html */
|
||||
[scriptable, uuid(94628e70-e96f-4170-871c-f993a49f065a)]
|
||||
interface nsIDOMRTCPeerConnection : nsISupports
|
||||
{
|
||||
void createOffer(in RTCPeerConnectionCallback successCallback,
|
||||
[optional] in RTCPeerConnectionCallback failureCallback,
|
||||
[optional] in jsval constraints);
|
||||
|
||||
void createAnswer(in nsIDOMRTCSessionDescription offer,
|
||||
in RTCPeerConnectionCallback successCallback,
|
||||
[optional] in RTCPeerConnectionCallback failureCallback,
|
||||
[optional] in jsval constraints,
|
||||
[optional] in bool createProvisionalAnswer);
|
||||
|
||||
void setLocalDescription(in nsIDOMRTCSessionDescription desc,
|
||||
[optional] in RTCPeerConnectionCallback successCallback,
|
||||
[optional] in RTCPeerConnectionCallback failureCallback);
|
||||
|
||||
void setRemoteDescription(in nsIDOMRTCSessionDescription desc,
|
||||
[optional] in RTCPeerConnectionCallback successCallback,
|
||||
[optional] in RTCPeerConnectionCallback failureCallback);
|
||||
|
||||
void updateIce([optional] in jsval configuration,
|
||||
[optional] in jsval constraints,
|
||||
[optional] in bool restart);
|
||||
|
||||
void addIceCandidate(in nsIDOMRTCIceCandidate candidate);
|
||||
|
||||
void addStream(in nsIDOMMediaStream stream,
|
||||
[optional] in jsval constraints);
|
||||
|
||||
void removeStream(in nsIDOMMediaStream stream);
|
||||
void close();
|
||||
|
||||
/* Readonly attributes */
|
||||
readonly attribute DOMString iceState;
|
||||
readonly attribute DOMString iceGatheringState;
|
||||
|
||||
readonly attribute DOMString readyState;
|
||||
readonly attribute jsval localDescription;
|
||||
readonly attribute jsval remoteDescription;
|
||||
|
||||
readonly attribute jsval localStreams; // MediaStream[]
|
||||
readonly attribute jsval remoteStreams; // MediaStream[]
|
||||
|
||||
/* Event handlers. TODO: Use real EventTarget */
|
||||
attribute RTCPeerConnectionCallback onaddstream;
|
||||
attribute RTCPeerConnectionCallback onremovestream;
|
||||
attribute RTCPeerConnectionCallback onicecandidate;
|
||||
attribute RTCPeerConnectionCallback onstatechange;
|
||||
attribute RTCPeerConnectionCallback ongatheringchange;
|
||||
attribute RTCPeerConnectionCallback onicechange;
|
||||
};
|
@ -541,7 +541,10 @@ var interfaceNamesInGlobalScope =
|
||||
"DataChannel",
|
||||
"MozNetworkStatsManager",
|
||||
"MozNetworkStats",
|
||||
"MozNetworkStatsData"
|
||||
"MozNetworkStatsData",
|
||||
"RTCSessionDescription",
|
||||
"RTCIceCandidate",
|
||||
"RTCPeerConnection"
|
||||
]
|
||||
|
||||
for (var i in SpecialPowers.Components.interfaces) {
|
||||
|
@ -173,6 +173,7 @@ pref("media.h264.enabled", true);
|
||||
#endif
|
||||
#ifdef MOZ_WEBRTC
|
||||
pref("media.navigator.enabled", false);
|
||||
pref("media.peerconnection.enabled", false);
|
||||
#else
|
||||
#ifdef ANDROID
|
||||
pref("media.navigator.enabled", true);
|
||||
|
Loading…
Reference in New Issue
Block a user