Bug 1213517 - make getUserMedia store initial constraints on resulting tracks. r=jesup
☠☠ backed out by 97bad3c58567 ☠ ☠
authorJan-Ivar Bruaroey <jib@mozilla.com>
Tue, 24 Nov 2015 23:42:26 -0500
changeset 345271 0fc93ec9ccd7c1b0fa0a6ba73b5addec5a7648d9
parent 345270 015cb0829df5342ea5ec9b4c4d5ca10abba8bb52
child 345272 6ed917c7d94d4701e7eb78a396e836c899ac8678
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1213517
milestone50.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 1213517 - make getUserMedia store initial constraints on resulting tracks. r=jesup MozReview-Commit-ID: 291CrmVmq4x
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/webaudio/MediaStreamAudioDestinationNode.cpp
--- a/dom/media/AudioStreamTrack.h
+++ b/dom/media/AudioStreamTrack.h
@@ -11,18 +11,19 @@
 
 namespace mozilla {
 namespace dom {
 
 class AudioStreamTrack : public MediaStreamTrack {
 public:
   AudioStreamTrack(DOMMediaStream* aStream, TrackID aTrackID,
                    TrackID aInputTrackID,
-                   MediaStreamTrackSource* aSource)
-    : MediaStreamTrack(aStream, aTrackID, aInputTrackID, aSource) {}
+                   MediaStreamTrackSource* aSource,
+                   const MediaTrackConstraints& aConstraints = MediaTrackConstraints())
+    : MediaStreamTrack(aStream, aTrackID, aInputTrackID, aSource, aConstraints) {}
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   AudioStreamTrack* AsAudioStreamTrack() override { return this; }
 
   const AudioStreamTrack* AsAudioStreamTrack() const override { return this; }
 
   // WebIDL
@@ -30,16 +31,17 @@ public:
 
 protected:
   already_AddRefed<MediaStreamTrack> CloneInternal(DOMMediaStream* aOwningStream,
                                                    TrackID aTrackID) override
   {
     return do_AddRef(new AudioStreamTrack(aOwningStream,
                                           aTrackID,
                                           mInputTrackID,
-                                          mSource));
+                                          mSource,
+                                          mConstraints));
   }
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* AUDIOSTREAMTRACK_H_ */
--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -974,30 +974,31 @@ bool
 DOMMediaStream::RemovePrincipalChangeObserver(
   PrincipalChangeObserver<DOMMediaStream>* aObserver)
 {
   return mPrincipalChangeObservers.RemoveElement(aObserver);
 }
 
 MediaStreamTrack*
 DOMMediaStream::CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType,
-                               MediaStreamTrackSource* aSource)
+                               MediaStreamTrackSource* aSource,
+                               const MediaTrackConstraints& aConstraints)
 {
   MOZ_RELEASE_ASSERT(mInputStream);
   MOZ_RELEASE_ASSERT(mOwnedStream);
 
   MOZ_ASSERT(FindOwnedDOMTrack(GetInputStream(), aTrackID) == nullptr);
 
   MediaStreamTrack* track;
   switch (aType) {
   case MediaSegment::AUDIO:
-    track = new AudioStreamTrack(this, aTrackID, aTrackID, aSource);
+    track = new AudioStreamTrack(this, aTrackID, aTrackID, aSource, aConstraints);
     break;
   case MediaSegment::VIDEO:
-    track = new VideoStreamTrack(this, aTrackID, aTrackID, aSource);
+    track = new VideoStreamTrack(this, aTrackID, aTrackID, aSource, aConstraints);
     break;
   default:
     MOZ_CRASH("Unhandled track type");
   }
 
   LOG(LogLevel::Debug, ("DOMMediaStream %p Created new track %p with ID %u", this, track, aTrackID));
 
   mOwnedTracks.AppendElement(
--- a/dom/media/DOMMediaStream.h
+++ b/dom/media/DOMMediaStream.h
@@ -9,16 +9,17 @@
 #include "ImageContainer.h"
 
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "StreamTracks.h"
 #include "nsIDOMWindow.h"
 #include "nsIPrincipal.h"
+#include "MediaTrackConstraints.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "PrincipalChangeObserver.h"
 
 // X11 has a #define for CurrentTime. Unbelievable :-(.
 // See dom/media/webaudio/AudioContext.h for more fun!
 #ifdef CurrentTime
 #undef CurrentTime
 #endif
@@ -43,17 +44,16 @@ class MediaStreamTrack;
 class MediaStreamTrackSource;
 class AudioStreamTrack;
 class VideoStreamTrack;
 class AudioTrack;
 class VideoTrack;
 class AudioTrackList;
 class VideoTrackList;
 class MediaTrackListListener;
-struct MediaTrackConstraints;
 } // namespace dom
 
 namespace layers {
 class ImageContainer;
 class OverlayImage;
 } // namespace layers
 
 namespace media {
@@ -517,17 +517,18 @@ public:
    * 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.
    */
   MediaStreamTrack* CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType,
-                                   MediaStreamTrackSource* aSource);
+      MediaStreamTrackSource* aSource,
+      const MediaTrackConstraints& aConstraints = MediaTrackConstraints());
 
   /**
    * Creates a MediaStreamTrack cloned from aTrack, adds it to mTracks and
    * returns it.
    * aCloneTrackID is the TrackID the new track will get in mOwnedStream.
    */
   already_AddRefed<MediaStreamTrack> CloneDOMTrack(MediaStreamTrack& aTrack,
                                                    TrackID aCloneTrackID);
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -922,16 +922,28 @@ MediaOperationTask::ReturnCallbackError(
     NS_LITERAL_STRING("InternalError"), log);
   NS_DispatchToMainThread(do_AddRef(
     new ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>(onSuccess,
                                                                  mOnFailure,
                                                                  *error,
                                                                  mWindowID)));
 }
 
+static bool
+IsOn(const OwningBooleanOrMediaTrackConstraints &aUnion) {
+  return !aUnion.IsBoolean() || aUnion.GetAsBoolean();
+}
+
+static const MediaTrackConstraints&
+GetInvariant(const OwningBooleanOrMediaTrackConstraints &aUnion) {
+  static const MediaTrackConstraints empty;
+  return aUnion.IsMediaTrackConstraints() ?
+      aUnion.GetAsMediaTrackConstraints() : empty;
+}
+
 /**
  * This class is only needed since fake tracks are added dynamically.
  * Instead of refactoring to add them explicitly we let the DOMMediaStream
  * query us for the source as they become available.
  * Since they are used only for testing the API surface, we make them very
  * simple.
  */
 class FakeTrackSourceGetter : public MediaStreamTrackSourceGetter
@@ -986,20 +998,22 @@ class GetUserMediaStreamRunnable : publi
 {
 public:
   GetUserMediaStreamRunnable(
     nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
     nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
     uint64_t aWindowID,
     GetUserMediaCallbackMediaStreamListener* aListener,
     const nsCString& aOrigin,
+    const MediaStreamConstraints& aConstraints,
     AudioDevice* aAudioDevice,
     VideoDevice* aVideoDevice,
     PeerIdentity* aPeerIdentity)
-    : mAudioDevice(aAudioDevice)
+    : mConstraints(aConstraints)
+    , mAudioDevice(aAudioDevice)
     , mVideoDevice(aVideoDevice)
     , mWindowID(aWindowID)
     , mListener(aListener)
     , mOrigin(aOrigin)
     , mPeerIdentity(aPeerIdentity)
     , mManager(MediaManager::GetInstance())
   {
     mOnSuccess.swap(aOnSuccess);
@@ -1159,27 +1173,31 @@ public:
       if (mAudioDevice) {
         nsString audioDeviceName;
         mAudioDevice->GetName(audioDeviceName);
         const MediaSourceEnum source =
           mAudioDevice->GetSource()->GetMediaSource();
         RefPtr<MediaStreamTrackSource> audioSource =
           new LocalTrackSource(principal, audioDeviceName, mListener, source,
                                kAudioTrack, mPeerIdentity);
-        domStream->CreateDOMTrack(kAudioTrack, MediaSegment::AUDIO, audioSource);
+        MOZ_ASSERT(IsOn(mConstraints.mAudio));
+        domStream->CreateDOMTrack(kAudioTrack, MediaSegment::AUDIO, audioSource,
+                                  GetInvariant(mConstraints.mAudio));
       }
       if (mVideoDevice) {
         nsString videoDeviceName;
         mVideoDevice->GetName(videoDeviceName);
         const MediaSourceEnum source =
           mVideoDevice->GetSource()->GetMediaSource();
         RefPtr<MediaStreamTrackSource> videoSource =
           new LocalTrackSource(principal, videoDeviceName, mListener, source,
                                kVideoTrack, mPeerIdentity);
-        domStream->CreateDOMTrack(kVideoTrack, MediaSegment::VIDEO, videoSource);
+        MOZ_ASSERT(IsOn(mConstraints.mVideo));
+        domStream->CreateDOMTrack(kVideoTrack, MediaSegment::VIDEO, videoSource,
+                                  GetInvariant(mConstraints.mVideo));
       }
       stream = domStream->GetInputStream()->AsSourceStream();
     }
 
     if (!domStream || sInShutdown) {
       nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
       LOG(("Returning error for getUserMedia() - no stream"));
 
@@ -1223,37 +1241,26 @@ public:
       RefPtr<Pledge<nsCString>> p = media::GetOriginKey(mOrigin, false, true);
     }
     return NS_OK;
   }
 
 private:
   nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
   nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
+  MediaStreamConstraints mConstraints;
   RefPtr<AudioDevice> mAudioDevice;
   RefPtr<VideoDevice> mVideoDevice;
   uint64_t mWindowID;
   RefPtr<GetUserMediaCallbackMediaStreamListener> mListener;
   nsCString mOrigin;
   RefPtr<PeerIdentity> mPeerIdentity;
   RefPtr<MediaManager> mManager; // get ref to this when creating the runnable
 };
 
-static bool
-IsOn(const OwningBooleanOrMediaTrackConstraints &aUnion) {
-  return !aUnion.IsBoolean() || aUnion.GetAsBoolean();
-}
-
-static const MediaTrackConstraints&
-GetInvariant(const OwningBooleanOrMediaTrackConstraints &aUnion) {
-  static const MediaTrackConstraints empty;
-  return aUnion.IsMediaTrackConstraints() ?
-      aUnion.GetAsMediaTrackConstraints() : empty;
-}
-
 // Source getter returning full list
 
 template<class DeviceType>
 static void
 GetSources(MediaEngine *engine, MediaSourceEnum aSrcType,
            void (MediaEngine::* aEnumerate)(MediaSourceEnum,
                nsTArray<RefPtr<typename DeviceType::Source> >*),
            nsTArray<RefPtr<DeviceType>>& aResult,
@@ -1446,18 +1453,19 @@ public:
     }
     PeerIdentity* peerIdentity = nullptr;
     if (!mConstraints.mPeerIdentity.IsEmpty()) {
       peerIdentity = new PeerIdentity(mConstraints.mPeerIdentity);
     }
 
     NS_DispatchToMainThread(do_AddRef(
         new GetUserMediaStreamRunnable(mOnSuccess, mOnFailure, mWindowID,
-                                       mListener, mOrigin, mAudioDevice,
-                                       mVideoDevice, peerIdentity)));
+                                       mListener, mOrigin, mConstraints,
+                                       mAudioDevice, mVideoDevice,
+                                       peerIdentity)));
     MOZ_ASSERT(!mOnSuccess);
     MOZ_ASSERT(!mOnFailure);
     return NS_OK;
   }
 
   nsresult
   Denied(const nsAString& aName,
          const nsAString& aMessage = EmptyString())
--- a/dom/media/MediaStreamTrack.cpp
+++ b/dom/media/MediaStreamTrack.cpp
@@ -105,22 +105,24 @@ public:
 
 protected:
   // These fields may only be accessed on the main thread
   MediaStreamTrack* mTrack;
 };
 
 MediaStreamTrack::MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID,
                                    TrackID aInputTrackID,
-                                   MediaStreamTrackSource* aSource)
+                                   MediaStreamTrackSource* aSource,
+                                   const MediaTrackConstraints& aConstraints)
   : mOwningStream(aStream), mTrackID(aTrackID),
     mInputTrackID(aInputTrackID), mSource(aSource),
     mPrincipal(aSource->GetPrincipal()),
     mReadyState(MediaStreamTrackState::Live),
-    mEnabled(true), mRemote(aSource->IsRemote())
+    mEnabled(true), mRemote(aSource->IsRemote()),
+    mConstraints(aConstraints)
 {
 
   if (!gMediaStreamTrackLog) {
     gMediaStreamTrackLog = PR_NewLogModule("MediaStreamTrack");
   }
 
   GetSource().RegisterSink(this);
 
--- a/dom/media/MediaStreamTrack.h
+++ b/dom/media/MediaStreamTrack.h
@@ -127,17 +127,17 @@ public:
   typedef media::Pledge<bool, dom::MediaStreamError*> PledgeVoid;
 
   /**
    * We provide a fallback solution to ApplyConstraints() here.
    * Sources that support ApplyConstraints() will have to override it.
    */
   virtual already_AddRefed<PledgeVoid>
   ApplyConstraints(nsPIDOMWindowInner* aWindow,
-                   const dom::MediaTrackConstraints& aConstraints) = 0;
+                   const dom::MediaTrackConstraints& aConstraints);
 
   /**
    * Called by the source interface when all registered sinks have unregistered.
    */
   virtual void Stop() = 0;
 
   /**
    * Called by each MediaStreamTrack clone on initialization.
@@ -208,23 +208,16 @@ public:
                                        const MediaSourceEnum aMediaSource =
                                          MediaSourceEnum::Other)
     : MediaStreamTrackSource(aPrincipal, true, nsString())
     , mMediaSource(aMediaSource)
   {}
 
   MediaSourceEnum GetMediaSource() const override { return mMediaSource; }
 
-  already_AddRefed<PledgeVoid>
-  ApplyConstraints(nsPIDOMWindowInner* aWindow,
-                   const dom::MediaTrackConstraints& aConstraints) override
-  {
-    return nullptr;
-  }
-
   void Stop() override {}
 
 protected:
   ~BasicUnstoppableTrackSource() {}
 
   const MediaSourceEnum mMediaSource;
 };
 
@@ -247,18 +240,19 @@ class MediaStreamTrack : public DOMEvent
   class PrincipalHandleListener;
 
 public:
   /**
    * aTrackID is the MediaStreamGraph track ID for the track in the
    * MediaStream owned by aStream.
    */
   MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID,
-                   TrackID aInputTrackID,
-                   MediaStreamTrackSource* aSource);
+      TrackID aInputTrackID,
+      MediaStreamTrackSource* aSource,
+      const MediaTrackConstraints& aConstraints = MediaTrackConstraints());
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamTrack,
                                            DOMEventTargetHelper)
 
   nsPIDOMWindowInner* GetParentObject() const;
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override = 0;
 
--- a/dom/media/VideoStreamTrack.h
+++ b/dom/media/VideoStreamTrack.h
@@ -11,18 +11,19 @@
 
 namespace mozilla {
 namespace dom {
 
 class VideoStreamTrack : public MediaStreamTrack {
 public:
   VideoStreamTrack(DOMMediaStream* aStream, TrackID aTrackID,
                    TrackID aInputTrackID,
-                   MediaStreamTrackSource* aSource)
-    : MediaStreamTrack(aStream, aTrackID, aInputTrackID, aSource) {}
+                   MediaStreamTrackSource* aSource,
+                   const MediaTrackConstraints& aConstraints = MediaTrackConstraints())
+    : MediaStreamTrack(aStream, aTrackID, aInputTrackID, aSource, aConstraints) {}
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   VideoStreamTrack* AsVideoStreamTrack() override { return this; }
 
   const VideoStreamTrack* AsVideoStreamTrack() const override { return this; }
 
   // WebIDL
@@ -30,16 +31,17 @@ public:
 
 protected:
   already_AddRefed<MediaStreamTrack> CloneInternal(DOMMediaStream* aOwningStream,
                                                    TrackID aTrackID) override
   {
     return do_AddRef(new VideoStreamTrack(aOwningStream,
                                           aTrackID,
                                           mInputTrackID,
-                                          mSource));
+                                          mSource,
+                                          mConstraints));
   }
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* VIDEOSTREAMTRACK_H_ */
--- a/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
+++ b/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
@@ -35,17 +35,18 @@ MediaStreamAudioDestinationNode::MediaSt
                                                              aContext->Graph()))
 {
   // Ensure an audio track with the correct ID is exposed to JS
   nsIDocument* doc = aContext->GetParentObject()->GetExtantDoc();
   RefPtr<MediaStreamTrackSource> source =
     new BasicUnstoppableTrackSource(doc->NodePrincipal(),
                                     MediaSourceEnum::AudioCapture);
   mDOMStream->CreateDOMTrack(AudioNodeStream::AUDIO_TRACK,
-                             MediaSegment::AUDIO, source);
+                             MediaSegment::AUDIO, source,
+                             MediaTrackConstraints());
 
   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);
 }