Bug 1291715 - Add RTCDTMFSender to PeerConnection.js; r=jib draft
authorDan Minor <dminor@mozilla.com>
Thu, 29 Sep 2016 13:26:04 -0400
changeset 420805 712b188c1b1f5cf599a2cda28aaa70914b652a83
parent 420804 1b8102930efba0fb0da855b02effd106370a1b8b
child 420806 69492c49b829848a5964e4915f4a10ecae378249
child 421276 50030970df4511eebaf6ab215cff7782ead5eb37
child 421324 7cb240f4678c886bf9b5580b66ede0a396607a6b
child 421559 6b4153e6bddb939a89b58961abcec4b1741a68d3
push id31303
push userdminor@mozilla.com
push dateTue, 04 Oct 2016 18:57:12 +0000
reviewersjib
bugs1291715
milestone52.0a1
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}