Bug 866513 - Non-empty MediaStreamTrack labels. r=jib
authorEmilio Cobos Álvarez <ecoal95@gmail.com>
Sat, 16 Jan 2016 13:39:00 +0100
changeset 280356 76ba09e7504c5b8b20749354b4d79f6c0b55421c
parent 280355 f4384563b945a517c61999ae0eb59a14f8d80bac
child 280357 1246e76eaeb9e9e965ac28f7ba59a351ac9e94af
push id70414
push usercbook@mozilla.com
push dateMon, 18 Jan 2016 09:12:33 +0000
treeherdermozilla-inbound@76ba09e7504c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib
bugs866513
milestone46.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 866513 - Non-empty MediaStreamTrack labels. r=jib
dom/camera/DOMCameraControl.cpp
dom/html/HTMLCanvasElement.cpp
dom/html/HTMLMediaElement.cpp
dom/media/AudioStreamTrack.h
dom/media/DOMMediaStream.cpp
dom/media/DOMMediaStream.h
dom/media/MediaManager.cpp
dom/media/MediaStreamTrack.cpp
dom/media/MediaStreamTrack.h
dom/media/VideoStreamTrack.h
dom/media/tests/mochitest/test_enumerateDevices.html
dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -524,17 +524,17 @@ nsDOMCameraControl::GetCameraStream() co
   return mInput;
 }
 
 void
 nsDOMCameraControl::TrackCreated(TrackID aTrackID) {
   // This track is not connected through a port.
   MediaInputPort* inputPort = nullptr;
   dom::VideoStreamTrack* track =
-    new dom::VideoStreamTrack(this, aTrackID);
+    new dom::VideoStreamTrack(this, aTrackID, nsString());
   RefPtr<TrackPort> port =
     new TrackPort(inputPort, track,
                   TrackPort::InputPortOwnership::OWNED);
   mTracks.AppendElement(port.forget());
   NotifyTrackAdded(track);
 }
 
 #define THROW_IF_NO_CAMERACONTROL(...)                                          \
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -677,17 +677,17 @@ HTMLCanvasElement::CaptureStream(const O
 
   TrackID videoTrackId = 1;
   nsresult rv = stream->Init(aFrameRate, videoTrackId);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  stream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO);
+  stream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO, nsString());
 
   rv = RegisterFrameCaptureListener(stream->FrameCaptureListener());
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
   return stream.forget();
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1885,21 +1885,21 @@ HTMLMediaElement::CaptureStreamInternal(
   mAudioCaptured = true;
   if (mDecoder) {
     mDecoder->AddOutputStream(out->mStream->GetInputStream()->AsProcessedStream(),
                               aFinishWhenEnded);
     if (mReadyState >= HAVE_METADATA) {
       // Expose the tracks to JS directly.
       if (HasAudio()) {
         TrackID audioTrackId = mMediaInfo.mAudio.mTrackId;
-        out->mStream->CreateOwnDOMTrack(audioTrackId, MediaSegment::AUDIO);
+        out->mStream->CreateOwnDOMTrack(audioTrackId, MediaSegment::AUDIO, nsString());
       }
       if (HasVideo()) {
         TrackID videoTrackId = mMediaInfo.mVideo.mTrackId;
-        out->mStream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO);
+        out->mStream->CreateOwnDOMTrack(videoTrackId, MediaSegment::VIDEO, nsString());
       }
     }
   }
   RefPtr<DOMMediaStream> result = out->mStream;
   return result.forget();
 }
 
 already_AddRefed<DOMMediaStream>
--- a/dom/media/AudioStreamTrack.h
+++ b/dom/media/AudioStreamTrack.h
@@ -9,18 +9,18 @@
 #include "MediaStreamTrack.h"
 #include "DOMMediaStream.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioStreamTrack : public MediaStreamTrack {
 public:
-  AudioStreamTrack(DOMMediaStream* aStream, TrackID aTrackID)
-    : MediaStreamTrack(aStream, aTrackID) {}
+  AudioStreamTrack(DOMMediaStream* aStream, TrackID aTrackID, const nsString& aLabel)
+    : MediaStreamTrack(aStream, aTrackID, aLabel) {}
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   virtual AudioStreamTrack* AsAudioStreamTrack() override { return this; }
 
   // WebIDL
   virtual void GetKind(nsAString& aKind) override { aKind.AssignLiteral("audio"); }
 };
--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -123,17 +123,17 @@ public:
     if (track) {
       // This track has already been manually created. Abort.
       return;
     }
 
     NS_WARN_IF_FALSE(!mStream->mTracks.IsEmpty(),
                      "A new track was detected on the input stream; creating a corresponding MediaStreamTrack. "
                      "Initial tracks should be added manually to immediately and synchronously be available to JS.");
-    mStream->CreateOwnDOMTrack(aTrackId, aType);
+    mStream->CreateOwnDOMTrack(aTrackId, aType, nsString());
   }
 
   void DoNotifyTrackEnded(TrackID aTrackId)
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (!mStream) {
       return;
@@ -614,17 +614,17 @@ DOMMediaStream::InitAudioCaptureStream(n
 {
   mWindow = aWindow;
 
   const TrackID AUDIO_TRACK = 1;
 
   InitInputStreamCommon(aGraph->CreateAudioCaptureStream(this, AUDIO_TRACK), aGraph);
   InitOwnedStreamCommon(aGraph);
   InitPlaybackStreamCommon(aGraph);
-  CreateOwnDOMTrack(AUDIO_TRACK, MediaSegment::AUDIO);
+  CreateOwnDOMTrack(AUDIO_TRACK, MediaSegment::AUDIO, nsString());
 }
 
 void
 DOMMediaStream::InitInputStreamCommon(MediaStream* aStream,
                                       MediaStreamGraph* aGraph)
 {
   MOZ_ASSERT(!mOwnedStream, "Input stream must be initialized before owned stream");
 
@@ -775,30 +775,30 @@ DOMMediaStream::AddPrincipalChangeObserv
 
 bool
 DOMMediaStream::RemovePrincipalChangeObserver(PrincipalChangeObserver* aObserver)
 {
   return mPrincipalChangeObservers.RemoveElement(aObserver);
 }
 
 MediaStreamTrack*
-DOMMediaStream::CreateOwnDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
+DOMMediaStream::CreateOwnDOMTrack(TrackID aTrackID, MediaSegment::Type aType, const nsString& aLabel)
 {
   MOZ_RELEASE_ASSERT(mInputStream);
   MOZ_RELEASE_ASSERT(mOwnedStream);
 
   MOZ_ASSERT(FindOwnedDOMTrack(GetOwnedStream(), aTrackID) == nullptr);
 
   MediaStreamTrack* track;
   switch (aType) {
   case MediaSegment::AUDIO:
-    track = new AudioStreamTrack(this, aTrackID);
+    track = new AudioStreamTrack(this, aTrackID, aLabel);
     break;
   case MediaSegment::VIDEO:
-    track = new VideoStreamTrack(this, aTrackID);
+    track = new VideoStreamTrack(this, aTrackID, aLabel);
     break;
   default:
     MOZ_CRASH("Unhandled track type");
   }
 
   LOG(LogLevel::Debug, ("DOMMediaStream %p Created new track %p with ID %u", this, track, aTrackID));
 
   RefPtr<TrackPort> ownedTrackPort =
--- a/dom/media/DOMMediaStream.h
+++ b/dom/media/DOMMediaStream.h
@@ -471,17 +471,17 @@ public:
   }
 
   /**
    * 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 and returns it.
    */
-  MediaStreamTrack* CreateOwnDOMTrack(TrackID aTrackID, MediaSegment::Type aType);
+  MediaStreamTrack* CreateOwnDOMTrack(TrackID aTrackID, MediaSegment::Type aType, const nsString& aLabel);
 
   class OnTracksAvailableCallback {
   public:
     virtual ~OnTracksAvailableCallback() {}
     virtual void NotifyTracksAvailable(DOMMediaStream* aStream) = 0;
   };
   // When the initial set of tracks has been added, run
   // aCallback->NotifyTracksAvailable.
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1020,20 +1020,24 @@ public:
     } else {
       // Normal case, connect the source stream to the track union stream to
       // avoid us blocking
       domStream = nsDOMUserMediaStream::CreateSourceStream(window, mListener,
                                                            mAudioDevice, mVideoDevice,
                                                            msg);
 
       if (mAudioDevice) {
-        domStream->CreateOwnDOMTrack(kAudioTrack, MediaSegment::AUDIO);
+        nsString audioDeviceName;
+        mAudioDevice->GetName(audioDeviceName);
+        domStream->CreateOwnDOMTrack(kAudioTrack, MediaSegment::AUDIO, audioDeviceName);
       }
       if (mVideoDevice) {
-        domStream->CreateOwnDOMTrack(kVideoTrack, MediaSegment::VIDEO);
+        nsString videoDeviceName;
+        mVideoDevice->GetName(videoDeviceName);
+        domStream->CreateOwnDOMTrack(kVideoTrack, MediaSegment::VIDEO, videoDeviceName);
       }
 
       nsCOMPtr<nsIPrincipal> principal;
       if (mPeerIdentity) {
         principal = nsNullPrincipal::Create();
         domStream->SetPeerIdentity(mPeerIdentity.forget());
       } else {
         principal = window->GetExtantDoc()->NodePrincipal();
--- a/dom/media/MediaStreamTrack.cpp
+++ b/dom/media/MediaStreamTrack.cpp
@@ -7,18 +7,18 @@
 
 #include "DOMMediaStream.h"
 #include "nsIUUIDGenerator.h"
 #include "nsServiceManagerUtils.h"
 
 namespace mozilla {
 namespace dom {
 
-MediaStreamTrack::MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID)
-  : mOwningStream(aStream), mTrackID(aTrackID), mEnded(false), mEnabled(true)
+MediaStreamTrack::MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID, const nsString& aLabel)
+  : mOwningStream(aStream), mTrackID(aTrackID), mLabel(aLabel), mEnded(false), mEnabled(true)
 {
 
   nsresult rv;
   nsCOMPtr<nsIUUIDGenerator> uuidgen =
     do_GetService("@mozilla.org/uuid-generator;1", &rv);
 
   nsID uuid;
   memset(&uuid, 0, sizeof(uuid));
--- a/dom/media/MediaStreamTrack.h
+++ b/dom/media/MediaStreamTrack.h
@@ -24,17 +24,17 @@ class VideoStreamTrack;
  * Class representing a track in a DOMMediaStream.
  */
 class MediaStreamTrack : public DOMEventTargetHelper {
 public:
   /**
    * aTrackID is the MediaStreamGraph track ID for the track in the
    * MediaStream owned by aStream.
    */
-  MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID);
+  MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID, const nsString& aLabel);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamTrack,
                                            DOMEventTargetHelper)
 
   DOMMediaStream* GetParentObject() const { return mOwningStream; }
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override = 0;
 
@@ -49,17 +49,17 @@ public:
    */
   TrackID GetTrackID() const { return mTrackID; }
   virtual AudioStreamTrack* AsAudioStreamTrack() { return nullptr; }
   virtual VideoStreamTrack* AsVideoStreamTrack() { return nullptr; }
 
   // WebIDL
   virtual void GetKind(nsAString& aKind) = 0;
   void GetId(nsAString& aID) const;
-  void GetLabel(nsAString& aLabel) { aLabel.Truncate(); }
+  void GetLabel(nsAString& aLabel) { aLabel.Assign(mLabel); }
   bool Enabled() { return mEnabled; }
   void SetEnabled(bool aEnabled);
   void Stop();
   already_AddRefed<Promise>
   ApplyConstraints(const dom::MediaTrackConstraints& aConstraints, ErrorResult &aRv);
 
   bool Ended() const { return mEnded; }
   // Notifications from the MediaStreamGraph
@@ -70,16 +70,17 @@ public:
   void AssignId(const nsAString& aID) { mID = aID; }
 
 protected:
   virtual ~MediaStreamTrack();
 
   RefPtr<DOMMediaStream> mOwningStream;
   TrackID mTrackID;
   nsString mID;
+  nsString mLabel;
   bool mEnded;
   bool mEnabled;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* MEDIASTREAMTRACK_H_ */
--- a/dom/media/VideoStreamTrack.h
+++ b/dom/media/VideoStreamTrack.h
@@ -9,18 +9,18 @@
 #include "MediaStreamTrack.h"
 #include "DOMMediaStream.h"
 
 namespace mozilla {
 namespace dom {
 
 class VideoStreamTrack : public MediaStreamTrack {
 public:
-  VideoStreamTrack(DOMMediaStream* aStream, TrackID aTrackID)
-    : MediaStreamTrack(aStream, aTrackID) {}
+  VideoStreamTrack(DOMMediaStream* aStream, TrackID aTrackID, const nsString& aLabel)
+    : MediaStreamTrack(aStream, aTrackID, aLabel) {}
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   virtual VideoStreamTrack* AsVideoStreamTrack() override { return this; }
 
   // WebIDL
   virtual void GetKind(nsAString& aKind) override { aKind.AssignLiteral("video"); }
 };
--- a/dom/media/tests/mochitest/test_enumerateDevices.html
+++ b/dom/media/tests/mochitest/test_enumerateDevices.html
@@ -27,25 +27,35 @@ function mustFailWith(msg, reason, const
 
 var pushPrefs = (...p) => new Promise(r => SpecialPowers.pushPrefEnv({set: p}, r));
 
 runTest(() =>
   pushPrefs(["media.navigator.streams.fake", true])
   .then(() => navigator.mediaDevices.enumerateDevices())
   .then(devices => {
     ok(devices.length > 0, "At least one device found");
-    devices.forEach(d => {
+    var jsoned = JSON.parse(JSON.stringify(devices));
+    is(jsoned[0].kind, devices[0].kind, "kind survived serializer");
+    is(jsoned[0].deviceId, devices[0].deviceId, "deviceId survived serializer");
+    return devices.reduce((p, d) => {
       ok(d.kind == "videoinput" || d.kind == "audioinput", "Known device kind");
       is(d.deviceId.length, 44, "Correct device id length");
       ok(d.label.length !== undefined, "Device label: " + d.label);
       is(d.groupId, "", "Don't support groupId yet");
-    });
-    var jsoned = JSON.parse(JSON.stringify(devices));
-    is(jsoned[0].kind, devices[0].kind, "kind survived serializer");
-    is(jsoned[0].deviceId, devices[0].deviceId, "deviceId survived serializer");
+      var c = {};
+      c[d.kind == "videoinput" ? "video" : "audio"] = { deviceId: d.deviceId };
+      return p
+        .then(() => navigator.mediaDevices.getUserMedia(c))
+        .then(stream => {
+          stream.getTracks().forEach(track => {
+            is(typeof(track.label), "string", "Label is a string")
+            is(track.label, d.label, "Label is the device label")
+          })
+        });
+    }, Promise.resolve());
   })
   // Check deviceId failure paths for video.
   .then(() => mustSucceed("unknown plain deviceId on video",
                           () => navigator.mediaDevices.getUserMedia({
     video: { deviceId: "unknown9qHr8B0JIbcHlbl9xR+jMbZZ8WyoPfpCXPfc=" },
   })))
   .then(() => mustSucceed("unknown plain deviceId on audio",
                           () => navigator.mediaDevices.getUserMedia({
--- a/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
+++ b/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
@@ -29,17 +29,17 @@ MediaStreamAudioDestinationNode::MediaSt
               ChannelCountMode::Explicit,
               ChannelInterpretation::Speakers)
   , mDOMStream(
       DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(),
                                                       this,
                                                       aContext->Graph()))
 {
   // Ensure an audio track with the correct ID is exposed to JS
-  mDOMStream->CreateOwnDOMTrack(AudioNodeStream::AUDIO_TRACK, MediaSegment::AUDIO);
+  mDOMStream->CreateOwnDOMTrack(AudioNodeStream::AUDIO_TRACK, MediaSegment::AUDIO, nsString());
 
   ProcessedMediaStream* outputStream = mDOMStream->GetInputStream()->AsProcessedStream();
   MOZ_ASSERT(!!outputStream);
   AudioNodeEngine* engine = new AudioNodeEngine(this);
   mStream = AudioNodeStream::Create(aContext, engine,
                                     AudioNodeStream::EXTERNAL_OUTPUT);
   mPort = outputStream->AllocateInputPort(mStream, AudioNodeStream::AUDIO_TRACK);