Bug 1291715 - Add RTCDTMFSender to PeerConnection.js; r=jib
☠☠ backed out by d4b05bd42e20 ☠ ☠
authorDan Minor <dminor@mozilla.com>
Thu, 29 Sep 2016 13:26:04 -0400
changeset 316535 50497f2cdd2835221a0b21661ed6cb8b006131a8
parent 316534 903fa45a9d6c45fe0a833396d8fae019360798c6
child 316536 5505acbab65951a624420095d4002981c85cfd3a
push id32865
push userdminor@mozilla.com
push dateWed, 05 Oct 2016 14:36:22 +0000
treeherderautoland@078248a9fdbc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib
bugs1291715
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1291715 - Add RTCDTMFSender to PeerConnection.js; r=jib MozReview-Commit-ID: 4vm6c5Chjof
dom/media/PeerConnection.js
dom/media/PeerConnection.manifest
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -21,27 +21,29 @@ const PC_OBS_CONTRACT = "@mozilla.org/do
 const PC_ICE_CONTRACT = "@mozilla.org/dom/rtcicecandidate;1";
 const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
 const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
 const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
 const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
 const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
 const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
 const PC_COREQUEST_CONTRACT = "@mozilla.org/dom/createofferrequest;1";
+const PC_DTMF_SENDER_CONTRACT = "@mozilla.org/dom/rtcdtmfsender;1";
 
 const PC_CID = Components.ID("{bdc2e533-b308-4708-ac8e-a8bfade6d851}");
 const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
 const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
 const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
 const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
 const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
 const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
 const PC_SENDER_CID = Components.ID("{4fff5d46-d827-4cd4-a970-8fd53977440e}");
 const PC_RECEIVER_CID = Components.ID("{d974b814-8fde-411c-8c45-b86791b81030}");
 const PC_COREQUEST_CID = Components.ID("{74b2122d-65a8-4824-aa9e-3d664cb75dc2}");
+const PC_DTMF_SENDER_CID = Components.ID("{3610C242-654E-11E6-8EC0-6D1BE389A607}");
 
 // 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 = {};
   this._networkdown = false; // XXX Need to query current state somehow
   this._lifecycleobservers = {};
   this._nextId = 1;
@@ -1061,16 +1063,24 @@ RTCPeerConnection.prototype = {
     this._checkClosed();
     var i = this._senders.indexOf(sender);
     if (i >= 0) {
       this._senders.splice(i, 1);
       this._impl.removeTrack(sender.track); // fires negotiation needed
     }
   },
 
+  _insertDTMF: function(sender, tones, duration, interToneGap) {
+    return this._impl.insertDTMF(sender.__DOM_IMPL__, tones, duration, interToneGap);
+  },
+
+  _getDTMFToneBuffer: function(sender) {
+    return this._impl.getDTMFToneBuffer(sender.__DOM_IMPL__);
+  },
+
   _replaceTrack: function(sender, withTrack) {
     // TODO: Do a (sender._stream.getTracks().indexOf(track) < 0) check
     //       on both track args someday.
     //
     // The proposed API will be that both tracks must already be in the same
     // stream. However, since our MediaStreams currently are limited to one
     // track per type, we allow replacement with an outside track not already
     // in the same stream.
@@ -1555,17 +1565,21 @@ PeerConnectionObserver.prototype = {
                                                                       { candidate: cand } ));
   },
 
   notifyDataChannel: function(channel) {
     this.dispatchEvent(new this._dompc._win.RTCDataChannelEvent("datachannel",
                                                                 { channel: channel }));
   },
 
-  onDTMFToneChangeEvent: function(trackId, tone) {
+  onDTMFToneChange: function(trackId, tone) {
+    var pc = this._dompc;
+    var sender = pc._senders.find(sender => sender.track.id == trackId)
+    sender.dtmf.dispatchEvent(new pc._win.RTCDTMFToneChangeEvent("tonechange",
+                                                                 { tone: tone }));
   }
 };
 
 function RTCPeerConnectionStatic() {
 }
 RTCPeerConnectionStatic.prototype = {
   classDescription: "RTCPeerConnectionStatic",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
@@ -1579,20 +1593,68 @@ RTCPeerConnectionStatic.prototype = {
       .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
   },
 
   registerPeerConnectionLifecycleCallback: function(cb) {
     _globalPCList._registerPeerConnectionLifecycleCallback(this._winID, cb);
   },
 };
 
+function RTCDTMFSender(sender) {
+  this._sender = sender;
+  this.duration = 100;
+  this.interToneGap = 70;
+}
+RTCDTMFSender.prototype = {
+  classDescription: "RTCDTMFSender",
+  classID: PC_DTMF_SENDER_CID,
+  contractID: PC_DTMF_SENDER_CONTRACT,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
+
+  get toneBuffer() {
+    return this._sender._pc._getDTMFToneBuffer(this._sender);
+  },
+
+  get ontonechange() {
+    return this.__DOM_IMPL__.getEventHandler("ontonechange");
+  },
+
+  set ontonechange(handler) {
+    this.__DOM_IMPL__.setEventHandler("ontonechange", handler);
+  },
+
+  insertDTMF: function(tones, duration, interToneGap) {
+    this._sender._pc._checkClosed();
+
+    if (this._sender._pc._senders.indexOf(this._sender.__DOM_IMPL__) == -1) {
+      throw new this._sender._pc._win.DOMException("RTCRtpSender is stopped",
+                                                   "InvalidStateError");
+    }
+
+    this.duration = Math.max(40, Math.min(duration, 6000));
+
+    if (interToneGap < 30) interToneGap = 30;
+    this.interToneGap = interToneGap;
+
+    tones = tones.toUpperCase();
+
+    if (tones.match(/[^0-9A-D#*,]/)) {
+      throw new this._sender._pc._win.DOMException("Invalid DTMF characters",
+                                                   "InvalidCharacterError");
+    }
+
+    this._sender._pc._insertDTMF(this._sender, tones, duration, interToneGap);
+  },
+};
+
 function RTCRtpSender(pc, track, stream) {
   this._pc = pc;
   this.track = track;
   this._stream = stream;
+  this.dtmf = pc._win.RTCDTMFSender._create(pc._win, new RTCDTMFSender(this));
 }
 RTCRtpSender.prototype = {
   classDescription: "RTCRtpSender",
   classID: PC_SENDER_CID,
   contractID: PC_SENDER_CONTRACT,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
 
   replaceTrack: function(withTrack) {
@@ -1630,16 +1692,17 @@ CreateOfferRequest.prototype = {
   classDescription: "CreateOfferRequest",
   classID: PC_COREQUEST_CID,
   contractID: PC_COREQUEST_CONTRACT,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
 };
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
   [GlobalPCList,
+   RTCDTMFSender,
    RTCIceCandidate,
    RTCSessionDescription,
    RTCPeerConnection,
    RTCPeerConnectionStatic,
    RTCRtpReceiver,
    RTCRtpSender,
    RTCStatsReport,
    PeerConnectionObserver,
--- a/dom/media/PeerConnection.manifest
+++ b/dom/media/PeerConnection.manifest
@@ -3,19 +3,21 @@ component {d1748d4c-7f6a-4dc5-add6-d55b7
 component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
 component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
 component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
 component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
 component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
 component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
 component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
 component {74b2122d-65a8-4824-aa9e-3d664cb75dc2} PeerConnection.js
+component {3610C242-654E-11E6-8EC0-6D1BE389A607} PeerConnection.js
 
 contract @mozilla.org/dom/peerconnection;1 {bdc2e533-b308-4708-ac8e-a8bfade6d851}
 contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
+contract @mozilla.org/dom/rtcdtmfsender;1 {3610C242-654E-11E6-8EC0-6D1BE389A607}
 contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
 contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
 contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
 contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
 contract @mozilla.org/dom/peerconnectionstatic;1 {0fb47c47-a205-4583-a9fc-cbadf8c95880}
 contract @mozilla.org/dom/rtpsender;1 {4fff5d46-d827-4cd4-a970-8fd53977440e}
 contract @mozilla.org/dom/rtpreceiver;1 {d974b814-8fde-411c-8c45-b86791b81030}
 contract @mozilla.org/dom/createofferrequest;1 {74b2122d-65a8-4824-aa9e-3d664cb75dc2}