Backed out 5 changesets (bug 1208328) for frequent failures in test_peerConnection_addtrack_removetrack_events.html on Android 4.3 debug. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Tue, 14 Jun 2016 11:04:28 +0200
changeset 326796 e8017df8752dc1bb7862dbdfe2fc0c99bfa2c146
parent 326795 127e74cb33c31192517e414f003715469b2d4b30
child 326797 57453dbd063c0711348d6631cd7fc330346ef5f0
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1208328
milestone50.0a1
backs out3160ce8f87590a3a611267595cb478479dfdb2f3
aa209325161f45a5607982af76ef1784208690a5
d48bc6eca9c32c8fd9cf095e650febb09e0affce
945141b1f8da8de66d90728f9f1a10ce498d8420
48da132353c7da5bfaa59d524a3d3bec54a4346e
Backed out 5 changesets (bug 1208328) for frequent failures in test_peerConnection_addtrack_removetrack_events.html on Android 4.3 debug. r=backout Backed out changeset 3160ce8f8759 (bug 1208328) Backed out changeset aa209325161f (bug 1208328) Backed out changeset d48bc6eca9c3 (bug 1208328) Backed out changeset 945141b1f8da (bug 1208328) Backed out changeset 48da132353c7 (bug 1208328)
dom/events/test/test_all_synthetic_events.html
dom/media/DOMMediaStream.cpp
dom/media/DOMMediaStream.h
dom/media/tests/mochitest/head.js
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/test_getUserMedia_addtrack_removetrack_events.html
dom/media/tests/mochitest/test_peerConnection_addtrack_removetrack_events.html
dom/webidl/MediaStream.webidl
dom/webidl/MediaStreamTrackEvent.webidl
--- a/dom/events/test/test_all_synthetic_events.html
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -298,18 +298,19 @@ const kEventConstructors = {
   MediaKeyMessageEvent:                          { create: function (aName, aProps) {
                                                          return new MediaKeyMessageEvent(aName, aProps);
                                                        },
                                              },
   MediaStreamEvent:                          { create: function (aName, aProps) {
                                                          return new MediaStreamEvent(aName, aProps);
                                                        },
                                              },
-  MediaStreamTrackEvent:                     {
-                                               // Difficult to test required arguments.
+  MediaStreamTrackEvent:                     { create: function (aName, aProps) {
+                                                         return new MediaStreamTrackEvent(aName, aProps);
+                                                       },
                                              },
   MessageEvent:                              { create: function (aName, aProps) {
                                                          var e = new MessageEvent("messageevent", { bubbles: aProps.bubbles,
                                                              cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin,
                                                              lastEventId: aProps.lastEventId, source: aProps.source });
                                                          return e;
                                                        },
                                              },
--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -5,17 +5,16 @@
 
 #include "DOMMediaStream.h"
 #include "nsContentUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIScriptError.h"
 #include "nsIUUIDGenerator.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/dom/MediaStreamBinding.h"
-#include "mozilla/dom/MediaStreamTrackEvent.h"
 #include "mozilla/dom/LocalMediaStreamBinding.h"
 #include "mozilla/dom/AudioNode.h"
 #include "AudioChannelAgent.h"
 #include "mozilla/dom/AudioTrack.h"
 #include "mozilla/dom/AudioTrackList.h"
 #include "mozilla/dom/VideoTrack.h"
 #include "mozilla/dom/VideoTrackList.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
@@ -595,21 +594,17 @@ DOMMediaStream::RemoveTrack(MediaStreamT
     LOG(LogLevel::Debug, ("DOMMediaStream %p does not contain track %p", this, &aTrack));
     return;
   }
 
   // If the track comes from a TRACK_ANY input port (i.e., mOwnedPort), we need
   // to block it in the port. Doing this for a locked track is still OK as it
   // will first block the track, then destroy the port. Both cause the track to
   // end.
-  // If the track has already ended, it's input port might be gone, so in those
-  // cases blocking the underlying track should be avoided.
-  if (!aTrack.Ended()) {
-    BlockPlaybackTrack(toRemove);
-  }
+  BlockPlaybackTrack(toRemove);
 
   DebugOnly<bool> removed = mTracks.RemoveElement(toRemove);
   MOZ_ASSERT(removed);
 
   NotifyTrackRemoved(&aTrack);
 
   LOG(LogLevel::Debug, ("DOMMediaStream %p Removed track %p", this, &aTrack));
 }
@@ -1002,19 +997,16 @@ DOMMediaStream::CreateDOMTrack(TrackID a
 
   mOwnedTracks.AppendElement(
     new TrackPort(mOwnedPort, track, TrackPort::InputPortOwnership::EXTERNAL));
 
   mTracks.AppendElement(
     new TrackPort(mPlaybackPort, track, TrackPort::InputPortOwnership::EXTERNAL));
 
   NotifyTrackAdded(track);
-
-  DispatchTrackEvent(NS_LITERAL_STRING("addtrack"), track);
-
   return track;
 }
 
 already_AddRefed<MediaStreamTrack>
 DOMMediaStream::CloneDOMTrack(MediaStreamTrack& aTrack,
                               TrackID aCloneTrackID)
 {
   MOZ_RELEASE_ASSERT(mOwnedStream);
@@ -1244,32 +1236,16 @@ DOMMediaStream::NotifyTrackRemoved(const
     mTrackListeners[i]->NotifyTrackRemoved(aTrack);
   }
 
   // Don't call RecomputePrincipal here as the track may still exist in the
   // playback stream in the MediaStreamGraph. It will instead be called when the
   // track has been confirmed removed by the graph. See BlockPlaybackTrack().
 }
 
-nsresult
-DOMMediaStream::DispatchTrackEvent(const nsAString& aName,
-                                   const RefPtr<MediaStreamTrack>& aTrack)
-{
-  MOZ_ASSERT(aName == NS_LITERAL_STRING("addtrack"),
-             "Only 'addtrack' is supported at this time");
-
-  MediaStreamTrackEventInit init;
-  init.mTrack = aTrack;
-
-  RefPtr<MediaStreamTrackEvent> event =
-    MediaStreamTrackEvent::Constructor(this, aName, init);
-
-  return DispatchTrustedEvent(event);
-}
-
 void
 DOMMediaStream::CreateAndAddPlaybackStreamListener(MediaStream* aStream)
 {
   MOZ_ASSERT(GetCameraStream(), "I'm a hack. Only DOMCameraControl may use me.");
   mPlaybackListener = new PlaybackStreamListener(this);
   aStream->AddListener(mPlaybackListener);
 }
 
--- a/dom/media/DOMMediaStream.h
+++ b/dom/media/DOMMediaStream.h
@@ -358,18 +358,16 @@ public:
   void GetTracks(nsTArray<RefPtr<MediaStreamTrack> >& aTracks) const;
   MediaStreamTrack* GetTrackById(const nsAString& aId) const;
   void AddTrack(MediaStreamTrack& aTrack);
   void RemoveTrack(MediaStreamTrack& aTrack);
 
   /** Identical to CloneInternal(TrackForwardingOption::EXPLICIT) */
   already_AddRefed<DOMMediaStream> Clone();
 
-  IMPL_EVENT_HANDLER(addtrack)
-
   // NON-WebIDL
 
   /**
    * Option to provide to CloneInternal() of which tracks should be forwarded
    * from the source stream (`this`) to the returned stream clone.
    *
    * CURRENT forwards the tracks currently in the source stream's track set.
    * ALL     forwards like EXPLICIT plus any and all future tracks originating
@@ -520,22 +518,17 @@ public:
   {
     mLogicalStreamStartTime = aTime;
   }
 
   /**
    * Called for each track in our owned stream to indicate to JS that we
    * are carrying that track.
    *
-   * Creates a MediaStreamTrack, adds it to mTracks, raises "addtrack" and
-   * returns it.
-   *
-   * Note that "addtrack" is raised synchronously and only has an effect if
-   * this MediaStream is already exposed to script. For spec compliance this is
-   * to be called from an async task.
+   * Creates a MediaStreamTrack, adds it to mTracks and returns it.
    */
   MediaStreamTrack* CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType,
                                    MediaStreamTrackSource* aSource);
 
   /**
    * Creates a MediaStreamTrack cloned from aTrack, adds it to mTracks and
    * returns it.
    * aCloneTrackID is the TrackID the new track will get in mOwnedStream.
@@ -606,20 +599,16 @@ protected:
   void NotifyTracksCreated();
 
   // Dispatches NotifyTrackAdded() to all registered track listeners.
   void NotifyTrackAdded(const RefPtr<MediaStreamTrack>& aTrack);
 
   // Dispatches NotifyTrackRemoved() to all registered track listeners.
   void NotifyTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack);
 
-  // Dispatches "addtrack" or "removetrack".
-  nsresult DispatchTrackEvent(const nsAString& aName,
-                              const RefPtr<MediaStreamTrack>& aTrack);
-
   class OwnedStreamListener;
   friend class OwnedStreamListener;
 
   class PlaybackStreamListener;
   friend class PlaybackStreamListener;
 
   // XXX Bug 1124630. Remove with CameraPreviewMediaStream.
   void CreateAndAddPlaybackStreamListener(MediaStream*);
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -436,18 +436,18 @@ function checkMediaStreamTrackCloneAgain
      "Track clone's kind should be same as the original's");
   is(clone.enabled, original.enabled,
      "Track clone's kind should be same as the original's");
 }
 
 /*** Utility methods */
 
 /** The dreadful setTimeout, use sparingly */
-function wait(time, message) {
-  return new Promise(r => setTimeout(() => r(message), time));
+function wait(time) {
+  return new Promise(r => setTimeout(r, time));
 }
 
 /** The even more dreadful setInterval, use even more sparingly */
 function waitUntil(func, time) {
   return new Promise(resolve => {
     var interval = setInterval(() => {
       if (func())  {
         clearInterval(interval);
@@ -477,18 +477,18 @@ var addFinallyToPromise = promise => {
     );
   }
   return promise;
 }
 
 /** Use event listener to call passed-in function on fire until it returns true */
 var listenUntil = (target, eventName, onFire) => {
   return new Promise(resolve => target.addEventListener(eventName,
-                                                        function callback(event) {
-    var result = onFire(event);
+                                                        function callback() {
+    var result = onFire();
     if (result) {
       target.removeEventListener(eventName, callback, false);
       resolve(result);
     }
   }, false));
 };
 
 /* Test that a function throws the right error */
@@ -604,17 +604,18 @@ function createOneShotEventWrapper(wrapp
  *        so we can avoid logging results after a test has finished.
  */
 function haveEvent(target, name, cancelPromise) {
   var listener;
   var p = Promise.race([
     (cancelPromise || new Promise()).then(e => Promise.reject(e)),
     new Promise(resolve => target.addEventListener(name, listener = resolve))
   ]);
-  return p.then(event => (target.removeEventListener(name, listener), event));
+  p.then(() => target.removeEventListener(name, listener));
+  return p;
 };
 
 /**
  * This class executes a series of functions in a continuous sequence.
  * Promise-bearing functions are executed after the previous promise completes.
  *
  * @constructor
  * @param {object} framework
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -39,17 +39,16 @@ skip-if = toolkit == 'gonk' || buildapp 
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g emulator seems to be too slow (Bug 1016498 and 1008080)
 [test_dataChannel_noOffer.html]
 [test_enumerateDevices.html]
 skip-if = buildapp == 'mulet'
 [test_getUserMedia_audioCapture.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g emulator seems to be too slow (Bug 1016498 and 1008080), android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_addTrackRemoveTrack.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
-[test_getUserMedia_addtrack_removetrack_events.html]
 [test_getUserMedia_basicAudio.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_basicVideo.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_basicVideo_playAfterLoadedmetadata.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_basicScreenshare.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' # no screenshare on b2g/android # Bug 1141029 Mulet parity with B2G Desktop for TC
@@ -79,17 +78,16 @@ skip-if = (toolkit == 'gonk' || buildapp
 [test_getUserMedia_stopVideoAudioStream.html]
 [test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html]
 [test_getUserMedia_stopVideoStream.html]
 [test_getUserMedia_stopVideoStreamWithFollowupVideo.html]
 [test_getUserMedia_trackEnded.html]
 [test_getUserMedia_peerIdentity.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 1021776, too --ing slow on b2g)
 [test_peerConnection_addIceCandidate.html]
-[test_peerConnection_addtrack_removetrack_events.html]
 [test_peerConnection_basicAudio.html]
 skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
 [test_peerConnection_basicAudioNATSrflx.html]
 skip-if = toolkit == 'gonk' || toolkit == 'android' # B2G emulator is too slow to handle a two-way audio call reliably, websockets don't work on android (bug 1266217)
 [test_peerConnection_basicAudioNATRelay.html]
 skip-if = toolkit == 'gonk' || toolkit == 'android' # B2G emulator is too slow to handle a two-way audio call reliably, websockets don't work on android (bug 1266217)
 [test_peerConnection_basicAudioNATRelayTCP.html]
 skip-if = toolkit == 'gonk' || toolkit == 'android' # B2G emulator is too slow to handle a two-way audio call reliably, websockets don't work on android (bug 1266217)
deleted file mode 100644
--- a/dom/media/tests/mochitest/test_getUserMedia_addtrack_removetrack_events.html
+++ /dev/null
@@ -1,109 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
-</head>
-<body>
-<pre id="test">
-<script type="application/javascript">
-"use strict";
-
-createHTML({
-  title: "MediaStream's 'addtrack' and 'removetrack' events shouldn't fire on manual operations",
-  bug: "1208328"
-});
-
-var spinEventLoop = () => new Promise(r => setTimeout(r, 0));
-
-var stream;
-var clone;
-var newStream;
-
-var addTrack = track => {
-  info("Adding track " + track.id);
-  stream.addTrack(track);
-};
-var removeTrack = track => {
-  info("Removing track " + track.id);
-  stream.removeTrack(track);
-};
-var stopTrack = track => {
-  if (track.readyState == "live") {
-    info("Stopping track " + track.id);
-  }
-  track.stop();
-};
-
-runTest(() => getUserMedia({audio: true, video: true})
-  .then(s => {
-    stream = s;
-    clone = s.clone();
-    stream.addEventListener("addtrack", function onAddtrack(event) {
-      ok(false, "addtrack fired unexpectedly for track " + event.track.id);
-    });
-    stream.addEventListener("removetrack", function onRemovetrack(event) {
-      ok(false, "removetrack fired unexpectedly for track " + event.track.id);
-    });
-
-    return getUserMedia({audio: true, video: true});
-  })
-  .then(s => {
-    newStream = s;
-
-    info("Stopping an original track");
-    stopTrack(stream.getTracks()[0]);
-
-    return spinEventLoop();
-  })
-  .then(() => {
-    info("Removing original tracks");
-    stream.getTracks().forEach(t => stream.removeTrack(t));
-
-    return spinEventLoop();
-  })
-  .then(() => {
-    info("Adding other gUM tracks");
-    newStream.getTracks().forEach(t => addTrack(t))
-
-    return spinEventLoop();
-  })
-  .then(() => {
-    info("Adding cloned tracks");
-    let clone = stream.clone();
-    clone.getTracks().forEach(t => addTrack(t));
-
-    return spinEventLoop();
-  })
-  .then(() => {
-    info("Removing a clone");
-    removeTrack(clone.getTracks()[0]);
-
-    return spinEventLoop();
-  })
-  .then(() => {
-    info("Stopping clones");
-    clone.getTracks().forEach(t => stopTrack(t));
-
-    return spinEventLoop();
-  })
-  .then(() => {
-    info("Stopping originals");
-    stream.getTracks().forEach(t => stopTrack(t));
-
-    return spinEventLoop();
-  })
-  .then(() => {
-    info("Removing remaining tracks");
-    stream.getTracks().forEach(t => removeTrack(t));
-
-    return spinEventLoop();
-  })
-  .then(() => {
-      // Test MediaStreamTrackEvent required args here.
-      mustThrowWith("MediaStreamTrackEvent without required args",
-                    "TypeError", () => new MediaStreamTrackEvent("addtrack", {}));
-  }));
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/media/tests/mochitest/test_peerConnection_addtrack_removetrack_events.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <script type="application/javascript" src="pc.js"></script>
-</head>
-<body>
-<pre id="test">
-<script type="application/javascript">
-"use strict";
-
-createHTML({
-  title: "MediaStream's 'addtrack' and 'removetrack' events with gUM",
-  bug: "1208328"
-});
-
-runNetworkTest(function (options) {
-  let test = new PeerConnectionTest(options);
-  let eventsPromise;
-  addRenegotiation(test.chain,
-    [
-      function PC_LOCAL_SWAP_VIDEO_TRACKS(test) {
-        return getUserMedia({video: true}).then(stream => {
-          let localStream = test.pcLocal._pc.getLocalStreams()[0];
-          let remoteStream = test.pcRemote._pc.getRemoteStreams()[0];
-
-          let newTrack = stream.getTracks()[0];
-
-          let videoSenderIndex =
-            test.pcLocal._pc.getSenders().findIndex(s => s.track.kind == "video");
-          isnot(videoSenderIndex, -1, "Should have video sender");
-
-          test.pcLocal.removeSender(videoSenderIndex);
-          test.pcLocal.attachLocalTrack(stream.getTracks()[0], localStream);
-
-          let onNextLoop = wait(0);
-          eventsPromise = haveEvent(remoteStream, "addtrack", wait(50000, "No addtrack event"))
-            .then(trackEvent => {
-              ok(trackEvent instanceof MediaStreamTrackEvent,
-                 "Expected event to be instance of MediaStreamTrackEvent");
-              is(trackEvent.type, "addtrack",
-                 "Expected addtrack event type");
-              is(trackEvent.track.id, newTrack.id, "Expected track in event");
-              is(trackEvent.track.readyState, "live",
-                 "added track should be live");
-            })
-            .then(() => haveEvent(remoteStream, "addtrack", onNextLoop)
-              .then(() => Promise.reject("Unexpected addtrack event for remote stream " + remoteStream.id),
-                    () => Promise.resolve())
-            );
-          remoteStream.addEventListener("removetrack",
-                                        function onRemovetrack(trackEvent) {
-            ok(false, "UA shouldn't raise 'removetrack' when receiving peer connection");
-          })
-        });
-      },
-    ],
-    [
-      function PC_REMOTE_CHECK_EVENTS(test) {
-        return eventsPromise;
-      },
-    ]
-  );
-
-  test.setMediaConstraints([{audio: true, video: true}], []);
-  test.run();
-});
-</script>
-</pre>
-</body>
-</html>
--- a/dom/webidl/MediaStream.webidl
+++ b/dom/webidl/MediaStream.webidl
@@ -38,12 +38,12 @@ interface MediaStream : EventTarget {
     sequence<MediaStreamTrack> getTracks ();
     MediaStreamTrack?          getTrackById (DOMString trackId);
     void                       addTrack (MediaStreamTrack track);
     void                       removeTrack (MediaStreamTrack track);
     MediaStream                clone ();
     // readonly    attribute boolean      active;
     //             attribute EventHandler onactive;
     //             attribute EventHandler oninactive;
-                attribute EventHandler onaddtrack;
+    //             attribute EventHandler onaddtrack;
     //             attribute EventHandler onremovetrack;
     readonly attribute double currentTime;
 };
--- a/dom/webidl/MediaStreamTrackEvent.webidl
+++ b/dom/webidl/MediaStreamTrackEvent.webidl
@@ -3,17 +3,20 @@
  * 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#mediastreamevent
  */
 
 dictionary MediaStreamTrackEventInit : EventInit {
-    required MediaStreamTrack track;
+  MediaStreamTrack? track = null;
+  RTCRtpReceiver? receiver = null;
+  MediaStream? stream = null;
 };
 
-[Exposed=Window,
- Constructor (DOMString type, MediaStreamTrackEventInit eventInitDict)]
+[Pref="media.peerconnection.enabled",
+ Constructor(DOMString type, optional MediaStreamTrackEventInit eventInitDict)]
 interface MediaStreamTrackEvent : Event {
-    [SameObject]
-    readonly        attribute MediaStreamTrack track;
+  readonly attribute RTCRtpReceiver? receiver;
+  readonly attribute MediaStreamTrack? track;
+  readonly attribute MediaStream? stream;
 };