Backed out 6 changesets (bug 1263312) for failures in test_exceptions_from_jsimplemented.html
authorPhil Ringnalda <philringnalda@gmail.com>
Fri, 09 Dec 2016 08:33:55 -0800
changeset 372781 a3fe137d4d47d0d8c897bcb81d6ed1201a5dde89
parent 372780 17ae85e95667253ed7cdef7f2f36d249e953b2d0
child 372782 34a1640010d698cb36b2ca74e4b0fffcdda6d4eb
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1263312
milestone53.0a1
backs out17ae85e95667253ed7cdef7f2f36d249e953b2d0
1814c92e203b853b7cf113711066b22b5ae30a3d
6b71306765d27a1b4f6117cde9723da6284654b2
33449a5d167632fb2eb731f81bcc8ac9305b33e4
b311b7e439e868049c07c53d82a759d962aaba2c
a667af08ffb5326c19321f5128d4b5227a7350aa
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
Backed out 6 changesets (bug 1263312) for failures in test_exceptions_from_jsimplemented.html Backed out changeset 17ae85e95667 (bug 1263312) Backed out changeset 1814c92e203b (bug 1263312) Backed out changeset 6b71306765d2 (bug 1263312) Backed out changeset 33449a5d1676 (bug 1263312) Backed out changeset b311b7e439e8 (bug 1263312) Backed out changeset a667af08ffb5 (bug 1263312)
dom/media/PeerConnection.js
dom/media/tests/mochitest/identity/test_fingerprints.html
dom/media/tests/mochitest/pc.js
dom/media/tests/mochitest/templates.js
dom/media/tests/mochitest/test_peerConnection_addIceCandidate.html
dom/media/tests/mochitest/test_peerConnection_closeDuringIce.html
dom/media/tests/mochitest/test_peerConnection_errorCallbacks.html
dom/media/tests/mochitest/test_peerConnection_iceFailure.html
dom/media/tests/mochitest/test_peerConnection_localReofferRollback.html
dom/media/tests/mochitest/test_peerConnection_localRollback.html
dom/media/tests/mochitest/test_peerConnection_remoteReofferRollback.html
dom/media/tests/mochitest/test_peerConnection_remoteRollback.html
dom/media/tests/mochitest/test_peerConnection_restartIceLocalAndRemoteRollback.html
dom/media/tests/mochitest/test_peerConnection_restartIceLocalRollback.html
dom/webidl/RTCIceCandidate.webidl
dom/webidl/RTCPeerConnection.webidl
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -224,28 +224,32 @@ GlobalPCList.prototype = {
   },
 
   _registerPeerConnectionLifecycleCallback: function(winID, cb) {
     this._lifecycleobservers[winID] = cb;
   },
 };
 var _globalPCList = new GlobalPCList();
 
-function RTCIceCandidate() {}
+function RTCIceCandidate() {
+  this.candidate = this.sdpMid = this.sdpMLineIndex = null;
+}
 RTCIceCandidate.prototype = {
   classDescription: "RTCIceCandidate",
   classID: PC_ICE_CID,
   contractID: PC_ICE_CONTRACT,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 
   init: function(win) { this._win = win; },
 
   __init: function(dict) {
-    Object.assign(this, dict);
+    this.candidate = dict.candidate;
+    this.sdpMid = dict.sdpMid;
+    this.sdpMLineIndex = ("sdpMLineIndex" in dict)? dict.sdpMLineIndex : null;
   }
 };
 
 function RTCSessionDescription() {}
 RTCSessionDescription.prototype = {
   classDescription: "RTCSessionDescription",
   classID: PC_SESSION_CID,
   contractID: PC_SESSION_CONTRACT,
@@ -725,17 +729,18 @@ RTCPeerConnection.prototype = {
       return this._chain(() => {
         let p = Promise.all([this.getPermission(), this._certificateReady])
           .then(() => new this._win.Promise((resolve, reject) => {
             this._onCreateOfferSuccess = resolve;
             this._onCreateOfferFailure = reject;
             this._impl.createOffer(options);
           }));
         p = this._addIdentityAssertion(p, origin);
-        return p.then(sdp => Cu.cloneInto({ type: "offer", sdp: sdp }, this._win));
+        return p.then(
+          sdp => new this._win.RTCSessionDescription({ type: "offer", sdp: sdp }));
       });
     });
   },
 
   createAnswer: function(optionsOrOnSuccess, onError) {
     // This entry-point handles both new and legacy call sig. Decipher which one
     let onSuccess, options;
     if (typeof optionsOrOnSuccess == "function") {
@@ -759,17 +764,19 @@ RTCPeerConnection.prototype = {
               throw new this._win.DOMException("No outstanding offer",
                                                "InvalidStateError");
             }
             this._onCreateAnswerSuccess = resolve;
             this._onCreateAnswerFailure = reject;
             this._impl.createAnswer();
           }));
         p = this._addIdentityAssertion(p, origin);
-        return p.then(sdp => Cu.cloneInto({ type: "answer", sdp: sdp }, this._win));
+        return p.then(sdp => {
+          return new this._win.RTCSessionDescription({ type: "answer", sdp: sdp });
+        });
       });
     });
   },
 
   getPermission: function() {
     if (this._havePermission) {
       return this._havePermission;
     }
@@ -969,25 +976,22 @@ RTCPeerConnection.prototype = {
     }
 
     let sections = desc.sdp.split(/(?:\r\n?|\n)m=/);
     let topSection = sections.shift();
     this._canTrickle =
       containsTrickle(topSection) || sections.every(containsTrickle);
   },
 
+
   addIceCandidate: function(c, onSuccess, onError) {
     return this._legacyCatchAndCloseGuard(onSuccess, onError, () => {
-      if (!c) {
-        // TODO: Implement processing for end-of-candidates (bug 1318167)
-        return Promise.resolve();
-      }
-      if (c.sdpMid === null && c.sdpMLineIndex === null) {
-        throw new this._win.DOMException("Invalid candidate (both sdpMid and sdpMLineIndex are null).",
-                                         "TypeError");
+      if (!c.candidate && !c.sdpMLineIndex) {
+        throw new this._win.DOMException("Invalid candidate passed to addIceCandidate!",
+                                         "InvalidParameterError");
       }
       return this._chain(() => new this._win.Promise((resolve, reject) => {
         this._onAddIceCandidateSuccess = resolve;
         this._onAddIceCandidateError = reject;
         this._impl.addIceCandidate(c.candidate, c.sdpMid || "", c.sdpMLineIndex);
       }));
     });
   },
@@ -1121,26 +1125,28 @@ RTCPeerConnection.prototype = {
 
   get localDescription() {
     this._checkClosed();
     let sdp = this._impl.localDescription;
     if (sdp.length == 0) {
       return null;
     }
 
-    return new this._win.RTCSessionDescription({ type: this._localType, sdp });
+    return new this._win.RTCSessionDescription({ type: this._localType,
+                                                    sdp: sdp });
   },
 
   get remoteDescription() {
     this._checkClosed();
     let sdp = this._impl.remoteDescription;
     if (sdp.length == 0) {
       return null;
     }
-    return new this._win.RTCSessionDescription({ type: this._remoteType, sdp });
+    return new this._win.RTCSessionDescription({ type: this._remoteType,
+                                                    sdp: sdp });
   },
 
   get peerIdentity() { return this._peerIdentity; },
   get idpLoginUrl() { return this._localIdp.idpLoginUrl; },
   get id() { return this._impl.id; },
   set id(s) { this._impl.id = s; },
   get iceGatheringState()  { return this._iceGatheringState; },
   get iceConnectionState() { return this._iceConnectionState; },
--- a/dom/media/tests/mochitest/identity/test_fingerprints.html
+++ b/dom/media/tests/mochitest/identity/test_fingerprints.html
@@ -81,17 +81,18 @@ function testMultipleFingerprints() {
     .then(assertion => {
       ok(assertion, 'Should have assertion');
 
       var sdp = offer.sdp.slice(0, match.index) +
           'a=identity:' + assertion + '\n' +
           fingerprintSdp(fingerprints.slice(1)) +
           offer.sdp.slice(match.index);
 
-      return pcStrict.setRemoteDescription({ type: 'offer', sdp });
+      var desc = new RTCSessionDescription({ type: 'offer', sdp: sdp });
+      return pcStrict.setRemoteDescription(desc);
     })
     .then(() => {
       ok(true, 'Modified fingerprints were accepted');
     }, error => {
       var e = SpecialPowers.wrap(error);
       ok(false, 'error in test: ' +
          (e.message ? (e.message + '\n' + e.stack) : e));
     })
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -329,17 +329,17 @@ PeerConnectionTest.prototype.createOffer
 };
 
 /**
  * Sets the local description for the specified peer connection instance
  * and automatically handles the failure case.
  *
  * @param {PeerConnectionWrapper} peer
           The peer connection wrapper to run the command on
- * @param {RTCSessionDescriptionInit} desc
+ * @param {RTCSessionDescription} desc
  *        Session description for the local description request
  */
 PeerConnectionTest.prototype.setLocalDescription =
 function(peer, desc, stateExpected) {
   var eventFired = new Promise(resolve => {
     peer.onsignalingstatechange = e => {
       info(peer + ": 'signalingstatechange' event received");
       var state = e.target.signalingState;
@@ -398,17 +398,17 @@ PeerConnectionTest.prototype.setOfferOpt
 };
 
 /**
  * Sets the remote description for the specified peer connection instance
  * and automatically handles the failure case.
  *
  * @param {PeerConnectionWrapper} peer
           The peer connection wrapper to run the command on
- * @param {RTCSessionDescriptionInit} desc
+ * @param {RTCSessionDescription} desc
  *        Session description for the remote description request
  */
 PeerConnectionTest.prototype.setRemoteDescription =
 function(peer, desc, stateExpected) {
   var eventFired = new Promise(resolve => {
     peer.onsignalingstatechange = e => {
       info(peer + ": 'signalingstatechange' event received");
       var state = e.target.signalingState;
@@ -1066,48 +1066,48 @@ PeerConnectionWrapper.prototype = {
       return answer;
     });
   },
 
   /**
    * Sets the local description and automatically handles the failure case.
    *
    * @param {object} desc
-   *        RTCSessionDescriptionInit for the local description request
+   *        RTCSessionDescription for the local description request
    */
   setLocalDescription : function(desc) {
     this.observedNegotiationNeeded = undefined;
     return this._pc.setLocalDescription(desc).then(() => {
       info(this + ": Successfully set the local description");
     });
   },
 
   /**
    * Tries to set the local description and expect failure. Automatically
    * causes the test case to fail if the call succeeds.
    *
    * @param {object} desc
-   *        RTCSessionDescriptionInit for the local description request
+   *        RTCSessionDescription for the local description request
    * @returns {Promise}
    *        A promise that resolves to the expected error
    */
   setLocalDescriptionAndFail : function(desc) {
     return this._pc.setLocalDescription(desc).then(
       generateErrorCallback("setLocalDescription should have failed."),
       err => {
         info(this + ": As expected, failed to set the local description");
         return err;
       });
   },
 
   /**
    * Sets the remote description and automatically handles the failure case.
    *
    * @param {object} desc
-   *        RTCSessionDescriptionInit for the remote description request
+   *        RTCSessionDescription for the remote description request
    */
   setRemoteDescription : function(desc) {
     this.observedNegotiationNeeded = undefined;
     return this._pc.setRemoteDescription(desc).then(() => {
       info(this + ": Successfully set remote description");
       if (desc.type == "rollback") {
         this.holdIceCandidates = new Promise(r => this.releaseIceCandidates = r);
 
@@ -1117,17 +1117,17 @@ PeerConnectionWrapper.prototype = {
     });
   },
 
   /**
    * Tries to set the remote description and expect failure. Automatically
    * causes the test case to fail if the call succeeds.
    *
    * @param {object} desc
-   *        RTCSessionDescriptionInit for the remote description request
+   *        RTCSessionDescription for the remote description request
    * @returns {Promise}
    *        a promise that resolve to the returned error
    */
   setRemoteDescriptionAndFail : function(desc) {
     return this._pc.setRemoteDescription(desc).then(
       generateErrorCallback("setRemoteDescription should have failed."),
       err => {
         info(this + ": As expected, failed to set the remote description");
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -113,17 +113,17 @@ var checkAllTrackStats = pc => {
 // Commands run once at the beginning of each test, even when performing a
 // renegotiation test.
 var commandsPeerConnectionInitial = [
   function PC_SETUP_SIGNALING_CLIENT(test) {
     if (test.testOptions.steeplechase) {
       test.setupSignalingClient();
       test.registerSignalingCallback("ice_candidate", function (message) {
         var pc = test.pcRemote ? test.pcRemote : test.pcLocal;
-        pc.storeOrAddIceCandidate(message.ice_candidate);
+        pc.storeOrAddIceCandidate(new RTCIceCandidate(message.ice_candidate));
       });
       test.registerSignalingCallback("end_of_trickle_ice", function (message) {
         test.signalingMessagesFinished();
       });
     }
   },
 
   function PC_LOCAL_SETUP_ICE_LOGGER(test) {
--- a/dom/media/tests/mochitest/test_peerConnection_addIceCandidate.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addIceCandidate.html
@@ -14,19 +14,19 @@
   var test;
   runNetworkTest(function () {
     test = new PeerConnectionTest();
     test.setMediaConstraints([{audio: true}], [{audio: true}]);
     test.chain.removeAfter("PC_LOCAL_GET_ANSWER");
 
     test.chain.insertAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION", [
       function PC_LOCAL_ADD_CANDIDATE_EARLY(test) {
-        var candidate = {
-          candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
-          sdpMLineIndex: 0};
+        var candidate = new RTCIceCandidate(
+          {candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
+           sdpMLineIndex: 0});
         return test.pcLocal._pc.addIceCandidate(candidate).then(
           generateErrorCallback("addIceCandidate should have failed."),
           err => {
             is(err.name, "InvalidStateError", "Error is InvalidStateError");
           });
         }
     ]);
     test.chain.insertAfter("PC_REMOTE_SET_LOCAL_DESCRIPTION", [
@@ -49,58 +49,55 @@
         return test.pcRemote._pc.addIceCandidate(bogus)
         .then(
           generateErrorCallback("addIceCandidate should have failed."),
           err => {
             is(err.name, "InvalidCandidateError", "Error is InvalidCandidateError");
           }
         );
       },
-      function PC_REMOTE_ADD_MISSING_MID_AND_MISSING_INDEX(test) {
+      function PC_REMOTE_ADD_CANDIDATE_MISSING_INDEX(test) {
+        // Note: it is probably not a good idea to automatically fill a missing
+        //       MLineIndex with a default value of zero, see bug 1157034
         var broken = new RTCIceCandidate(
           {candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host"});
         return test.pcRemote._pc.addIceCandidate(broken)
         .then(
-          generateErrorCallback("addIceCandidate should have failed."),
-          err => {
-            is(err.name, "TypeError", "Error is TypeError");
-          }
+          // FIXME this needs to be updated once bug 1157034 is fixed
+          todo(false, "Missing index in got automatically set to a valid value bz://1157034")
         );
       },
       function PC_REMOTE_ADD_VALID_CANDIDATE(test) {
-        var candidate = {
-          candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
-          sdpMLineIndex: 0};
+        var candidate = new RTCIceCandidate(
+          {candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
+           sdpMLineIndex: 0});
         return test.pcRemote._pc.addIceCandidate(candidate)
-        .then(() => ok(true, "Successfully added valid ICE candidate"));
+        .then(ok(true, "Successfully added valid ICE candidate"));
       },
       // bug 1095793
       function PC_REMOTE_ADD_MISMATCHED_MID_AND_LEVEL_CANDIDATE(test) {
         var bogus = new mozRTCIceCandidate(
           {candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
            sdpMLineIndex: 0,
            sdpMid: "sdparta_1"});
         return test.pcRemote._pc.addIceCandidate(bogus)
-        .then(generateErrorCallback("addIceCandidate should have failed."),
-              err => is(err.name, "InvalidCandidateError", "Error is InvalidCandidateError"));
-      },
-      function PC_REMOTE_ADD_MID_AND_MISSING_INDEX(test) {
-        var candidate = new RTCIceCandidate(
-          {candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
-           sdpMid: "sdparta_0"});
-        return test.pcRemote._pc.addIceCandidate(candidate)
-        .then(() => ok(true, "Successfully added valid ICE candidate"));
+        .then(
+          generateErrorCallback("addIceCandidate should have failed."),
+          err => {
+            is(err.name, "InvalidCandidateError", "Error is InvalidCandidateError");
+          }
+        );
       },
       function PC_REMOTE_ADD_MATCHING_MID_AND_LEVEL_CANDIDATE(test) {
-        var candidate = new RTCIceCandidate(
+        var candidate = new mozRTCIceCandidate(
           {candidate:"candidate:1 1 UDP 2130706431 192.168.2.1 50005 typ host",
            sdpMLineIndex: 0,
            sdpMid: "sdparta_0"});
         return test.pcRemote._pc.addIceCandidate(candidate)
-        .then(() => ok(true, "Successfully added valid ICE candidate with matching mid and level"));
+        .then(ok(true, "Successfully added valid ICE candidate with matching mid and level"));
       }
     ]);
     test.run();
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_peerConnection_closeDuringIce.html
+++ b/dom/media/tests/mochitest/test_peerConnection_closeDuringIce.html
@@ -16,22 +16,22 @@
 
 function PC_LOCAL_SETUP_NULL_ICE_HANDLER(test) {
   test.pcLocal.setupIceCandidateHandler(test, function() {}, function () {});
 }
 function PC_REMOTE_SETUP_NULL_ICE_HANDLER(test) {
   test.pcRemote.setupIceCandidateHandler(test, function() {}, function () {});
 }
 function PC_REMOTE_ADD_FAKE_ICE_CANDIDATE(test) {
-  var cand = {"candidate":"candidate:0 1 UDP 2130379007 192.0.2.1 12345 typ host","sdpMid":"","sdpMLineIndex":0};
+  var cand = new RTCIceCandidate({"candidate":"candidate:0 1 UDP 2130379007 192.0.2.1 12345 typ host","sdpMid":"","sdpMLineIndex":0});
   test.pcRemote.storeOrAddIceCandidate(cand);
   info(test.pcRemote + " Stored fake candidate: " + JSON.stringify(cand));
 }
 function PC_LOCAL_ADD_FAKE_ICE_CANDIDATE(test) {
-  var cand = {"candidate":"candidate:0 1 UDP 2130379007 192.0.2.2 56789 typ host","sdpMid":"","sdpMLineIndex":0};
+  var cand = new RTCIceCandidate({"candidate":"candidate:0 1 UDP 2130379007 192.0.2.2 56789 typ host","sdpMid":"","sdpMLineIndex":0});
     test.pcLocal.storeOrAddIceCandidate(cand);
   info(test.pcLocal + " Stored fake candidate: " + JSON.stringify(cand));
 }
 function PC_LOCAL_CLOSE_DURING_ICE(test) {
   return test.pcLocal.iceChecking.then(() => {
     test.pcLocal.onsignalingstatechange = function () {};
     test.pcLocal.close();
     });
--- a/dom/media/tests/mochitest/test_peerConnection_errorCallbacks.html
+++ b/dom/media/tests/mochitest/test_peerConnection_errorCallbacks.html
@@ -22,25 +22,27 @@
     return pc.createAnswer()
     .then(generateErrorCallback("createAnswer before offer should fail"),
           validateReason);
   };
 
   function testSetLocalDescriptionError() {
     var pc = new RTCPeerConnection();
     info ("Testing setLocalDescription error");
-    return pc.setLocalDescription({ sdp: "Picklechips!", type: "offer" })
+    return pc.setLocalDescription(new RTCSessionDescription({ sdp: "Picklechips!",
+                                                                 type: "offer" }))
     .then(generateErrorCallback("setLocalDescription with nonsense SDP should fail"),
           validateReason);
   };
 
   function testSetRemoteDescriptionError() {
     var pc = new RTCPeerConnection();
     info ("Testing setRemoteDescription error");
-    return pc.setRemoteDescription({ sdp: "Who?", type: "offer" })
+    return pc.setRemoteDescription(new RTCSessionDescription({ sdp: "Who?",
+                                                                  type: "offer" }))
     .then(generateErrorCallback("setRemoteDescription with nonsense SDP should fail"),
           validateReason);
   };
 
   // No test for createOffer errors -- there's nothing we can do at this
   // level to evoke an error in createOffer.
 
   runNetworkTest(function () {
--- a/dom/media/tests/mochitest/test_peerConnection_iceFailure.html
+++ b/dom/media/tests/mochitest/test_peerConnection_iceFailure.html
@@ -15,22 +15,22 @@
 
 function PC_LOCAL_SETUP_NULL_ICE_HANDLER(test) {
   test.pcLocal.setupIceCandidateHandler(test, function() {}, function () {});
 }
 function PC_REMOTE_SETUP_NULL_ICE_HANDLER(test) {
   test.pcRemote.setupIceCandidateHandler(test, function() {}, function () {});
 }
 function PC_REMOTE_ADD_FAKE_ICE_CANDIDATE(test) {
-  var cand = {"candidate":"candidate:0 1 UDP 2130379007 192.0.2.1 12345 typ host","sdpMid":"","sdpMLineIndex":0};
+  var cand = new RTCIceCandidate({"candidate":"candidate:0 1 UDP 2130379007 192.0.2.1 12345 typ host","sdpMid":"","sdpMLineIndex":0});
   test.pcRemote.storeOrAddIceCandidate(cand);
   info(test.pcRemote + " Stored fake candidate: " + JSON.stringify(cand));
 }
 function PC_LOCAL_ADD_FAKE_ICE_CANDIDATE(test) {
-  var cand = {"candidate":"candidate:0 1 UDP 2130379007 192.0.2.2 56789 typ host","sdpMid":"","sdpMLineIndex":0};
+  var cand = new RTCIceCandidate({"candidate":"candidate:0 1 UDP 2130379007 192.0.2.2 56789 typ host","sdpMid":"","sdpMLineIndex":0});
     test.pcLocal.storeOrAddIceCandidate(cand);
   info(test.pcLocal + " Stored fake candidate: " + JSON.stringify(cand));
 }
 function PC_LOCAL_WAIT_FOR_ICE_FAILURE(test) {
   return test.pcLocal.iceFailed.then(() => {
     ok(true, this.pcLocal + " Ice Failure Reached.");
 	});
 }
--- a/dom/media/tests/mochitest/test_peerConnection_localReofferRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_localReofferRollback.html
@@ -32,19 +32,20 @@
 
         function PC_REMOTE_CREATE_AND_SET_OFFER(test) {
           return test.createOffer(test.pcRemote).then(offer => {
             return test.setLocalDescription(test.pcRemote, offer, HAVE_LOCAL_OFFER);
           });
         },
 
         function PC_REMOTE_ROLLBACK(test) {
-          return test.setLocalDescription(test.pcRemote,
-                                          { type: "rollback", sdp: "" },
-                                          STABLE);
+          return test.setLocalDescription(
+              test.pcRemote,
+              new RTCSessionDescription({ type: "rollback", sdp: ""}),
+              STABLE);
         },
 
         // Rolling back should shut down gathering
         function PC_REMOTE_WAIT_FOR_END_OF_TRICKLE(test) {
           return test.pcRemote.endOfTrickleIce;
         },
     ]);
     test.setMediaConstraints([{audio: true}], [{audio: true}]);
--- a/dom/media/tests/mochitest/test_peerConnection_localRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_localRollback.html
@@ -18,19 +18,20 @@
     test.chain.insertBefore('PC_LOCAL_CREATE_OFFER', [
         function PC_REMOTE_CREATE_AND_SET_OFFER(test) {
           return test.createOffer(test.pcRemote).then(offer => {
             return test.setLocalDescription(test.pcRemote, offer, HAVE_LOCAL_OFFER);
           });
         },
 
         function PC_REMOTE_ROLLBACK(test) {
-          return test.setLocalDescription(test.pcRemote,
-                                          { type: "rollback", sdp: "" },
-                                          STABLE);
+          return test.setLocalDescription(
+              test.pcRemote,
+              new RTCSessionDescription({ type: "rollback", sdp: ""}),
+              STABLE);
         },
 
         // Rolling back should shut down gathering
         function PC_REMOTE_WAIT_FOR_END_OF_TRICKLE(test) {
           return test.pcRemote.endOfTrickleIce;
         },
 
         function PC_REMOTE_SETUP_ICE_HANDLER(test) {
--- a/dom/media/tests/mochitest/test_peerConnection_remoteReofferRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_remoteReofferRollback.html
@@ -30,18 +30,20 @@
           if (test.testOptions.steeplechase) {
             test.pcLocal.endOfTrickleIce.then(() => {
               send_message({"type": "end_of_trickle_ice"});
             });
           }
         },
 
         function PC_REMOTE_ROLLBACK(test) {
-          return test.setRemoteDescription(test.pcRemote, { type: "rollback" },
-                                           STABLE)
+          return test.setRemoteDescription(
+              test.pcRemote,
+              new RTCSessionDescription({ type: "rollback" }),
+              STABLE)
             .then(() => test.pcRemote.rollbackRemoteTracksIfNotNegotiated());
         },
 
         function PC_LOCAL_ROLLBACK(test) {
           // We haven't negotiated the new stream yet.
           test.pcLocal.expectNegotiationNeeded();
           return test.setLocalDescription(
               test.pcLocal,
--- a/dom/media/tests/mochitest/test_peerConnection_remoteRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_remoteRollback.html
@@ -15,18 +15,20 @@
   runNetworkTest(function (options) {
     test = new PeerConnectionTest(options);
     test.setMediaConstraints([{audio: true}], [{audio: true}]);
     test.chain.removeAfter('PC_REMOTE_CHECK_CAN_TRICKLE_SYNC');
     test.chain.append([
       function PC_REMOTE_ROLLBACK(test) {
         // We still haven't negotiated the tracks
         test.pcRemote.expectNegotiationNeeded();
-        return test.setRemoteDescription(test.pcRemote, { type: "rollback" },
-                                         STABLE)
+        return test.setRemoteDescription(
+          test.pcRemote,
+          new RTCSessionDescription({ type: "rollback" }),
+          STABLE)
           .then(() => test.pcRemote.rollbackRemoteTracksIfNotNegotiated());
       },
 
       function PC_REMOTE_CHECK_CAN_TRICKLE_REVERT_SYNC(test) {
         is(test.pcRemote._pc.canTrickleIceCandidates, null,
            "Remote canTrickleIceCandidates is reverted to null");
       },
 
--- a/dom/media/tests/mochitest/test_peerConnection_restartIceLocalAndRemoteRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIceLocalAndRemoteRollback.html
@@ -46,18 +46,20 @@
         function PC_LOCAL_EXPECT_ICE_CONNECTED(test) {
           test.pcLocal.iceCheckingIceRollbackExpected = true;
         },
         function PC_REMOTE_EXPECT_ICE_CONNECTED(test) {
           test.pcRemote.iceCheckingIceRollbackExpected = true;
         },
 
         function PC_REMOTE_ROLLBACK(test) {
-          return test.setRemoteDescription(test.pcRemote, { type: "rollback" },
-                                           STABLE);
+          return test.setRemoteDescription(
+              test.pcRemote,
+              new RTCSessionDescription({ type: "rollback" }),
+              STABLE);
         },
 
         function PC_LOCAL_ROLLBACK(test) {
           // We haven't negotiated the new stream yet.
           test.pcLocal.expectNegotiationNeeded();
           return test.setLocalDescription(
               test.pcLocal,
               new RTCSessionDescription({ type: "rollback", sdp: ""}),
--- a/dom/media/tests/mochitest/test_peerConnection_restartIceLocalRollback.html
+++ b/dom/media/tests/mochitest/test_peerConnection_restartIceLocalRollback.html
@@ -37,19 +37,21 @@
                                             offer,
                                             HAVE_LOCAL_OFFER);
           });
         },
         function PC_LOCAL_EXPECT_ICE_CONNECTED(test) {
           test.pcLocal.iceCheckingIceRollbackExpected = true;
         },
         function PC_LOCAL_ROLLBACK(test) {
-          return test.setLocalDescription(test.pcLocal,
-                                          { type: "rollback", sdp: ""},
-                                          STABLE);
+          return test.setLocalDescription(
+              test.pcLocal,
+              new RTCSessionDescription({ type: "rollback",
+                                          sdp: ""}),
+              STABLE);
         },
         // Rolling back should shut down gathering
         function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
           return test.pcLocal.endOfTrickleIce;
         },
         function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
           test.pcLocal.expectIceChecking();
         },
--- a/dom/webidl/RTCIceCandidate.webidl
+++ b/dom/webidl/RTCIceCandidate.webidl
@@ -3,23 +3,23 @@
  * 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://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceCandidate
  */
 
 dictionary RTCIceCandidateInit {
-  required DOMString candidate;
+  DOMString? candidate = null;
   DOMString? sdpMid = null;
-  unsigned short? sdpMLineIndex = null;
+  unsigned short sdpMLineIndex;
 };
 
 [Pref="media.peerconnection.enabled",
  JSImplementation="@mozilla.org/dom/rtcicecandidate;1",
- Constructor(RTCIceCandidateInit candidateInitDict)]
+ Constructor(optional RTCIceCandidateInit candidateInitDict)]
 interface RTCIceCandidate {
-  attribute DOMString       candidate;
+  attribute DOMString?      candidate;
   attribute DOMString?      sdpMid;
   attribute unsigned short? sdpMLineIndex;
 
   jsonifier;
 };
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -2,17 +2,17 @@
 /* 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/#interface-definition
  */
 
-callback RTCSessionDescriptionCallback = void (RTCSessionDescriptionInit description);
+callback RTCSessionDescriptionCallback = void (RTCSessionDescription sdp);
 callback RTCPeerConnectionErrorCallback = void (DOMError error);
 callback VoidFunction = void ();
 callback RTCStatsCallback = void (RTCStatsReport report);
 
 enum RTCSignalingState {
     "stable",
     "have-local-offer",
     "have-remote-offer",
@@ -77,24 +77,24 @@ interface RTCPeerConnection : EventTarge
   static Promise<RTCCertificate> generateCertificate (AlgorithmIdentifier keygenAlgorithm);
 
   [Pref="media.peerconnection.identity.enabled"]
   void setIdentityProvider (DOMString provider,
                             optional DOMString protocol,
                             optional DOMString username);
   [Pref="media.peerconnection.identity.enabled"]
   Promise<DOMString> getIdentityAssertion();
-  Promise<RTCSessionDescriptionInit> createOffer (optional RTCOfferOptions options);
-  Promise<RTCSessionDescriptionInit> createAnswer (optional RTCAnswerOptions options);
-  Promise<void> setLocalDescription (RTCSessionDescriptionInit description);
-  Promise<void> setRemoteDescription (RTCSessionDescriptionInit description);
+  Promise<RTCSessionDescription> createOffer (optional RTCOfferOptions options);
+  Promise<RTCSessionDescription> createAnswer (optional RTCAnswerOptions options);
+  Promise<void> setLocalDescription (RTCSessionDescription description);
+  Promise<void> setRemoteDescription (RTCSessionDescription description);
   readonly attribute RTCSessionDescription? localDescription;
   readonly attribute RTCSessionDescription? remoteDescription;
   readonly attribute RTCSignalingState signalingState;
-  Promise<void> addIceCandidate ((RTCIceCandidateInit or RTCIceCandidate)? candidate);
+  Promise<void> addIceCandidate (RTCIceCandidate candidate);
   readonly attribute boolean? canTrickleIceCandidates;
   readonly attribute RTCIceGatheringState iceGatheringState;
   readonly attribute RTCIceConnectionState iceConnectionState;
   [Pref="media.peerconnection.identity.enabled"]
   readonly attribute Promise<RTCIdentityAssertion> peerIdentity;
   [Pref="media.peerconnection.identity.enabled"]
   readonly attribute DOMString? idpLoginUrl;
 
@@ -149,20 +149,20 @@ partial interface RTCPeerConnection {
   // Dummy Promise<void> return values avoid "WebIDL.WebIDLError: error:
   // We have overloads with both Promise and non-Promise return types"
 
   Promise<void> createOffer (RTCSessionDescriptionCallback successCallback,
                              RTCPeerConnectionErrorCallback failureCallback,
                              optional RTCOfferOptions options);
   Promise<void> createAnswer (RTCSessionDescriptionCallback successCallback,
                               RTCPeerConnectionErrorCallback failureCallback);
-  Promise<void> setLocalDescription (RTCSessionDescriptionInit description,
+  Promise<void> setLocalDescription (RTCSessionDescription description,
                                      VoidFunction successCallback,
                                      RTCPeerConnectionErrorCallback failureCallback);
-  Promise<void> setRemoteDescription (RTCSessionDescriptionInit description,
+  Promise<void> setRemoteDescription (RTCSessionDescription description,
                                       VoidFunction successCallback,
                                       RTCPeerConnectionErrorCallback failureCallback);
   Promise<void> addIceCandidate (RTCIceCandidate candidate,
                                  VoidFunction successCallback,
                                  RTCPeerConnectionErrorCallback failureCallback);
   Promise<void> getStats (MediaStreamTrack? selector,
                           RTCStatsCallback successCallback,
                           RTCPeerConnectionErrorCallback failureCallback);