LCOV - code coverage report
Current view: top level - dom/media - MediaStreamTrack.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 60 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 56 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       4             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef MEDIASTREAMTRACK_H_
       7             : #define MEDIASTREAMTRACK_H_
       8             : 
       9             : #include "MediaTrackConstraints.h"
      10             : #include "PrincipalChangeObserver.h"
      11             : #include "StreamTracks.h"
      12             : #include "mozilla/CORSMode.h"
      13             : #include "mozilla/DOMEventTargetHelper.h"
      14             : #include "mozilla/dom/MediaStreamTrackBinding.h"
      15             : #include "mozilla/dom/MediaTrackSettingsBinding.h"
      16             : #include "mozilla/media/MediaUtils.h"
      17             : #include "nsError.h"
      18             : #include "nsID.h"
      19             : #include "nsIPrincipal.h"
      20             : 
      21             : namespace mozilla {
      22             : 
      23             : class DOMMediaStream;
      24             : class MediaEnginePhotoCallback;
      25             : class MediaInputPort;
      26             : class MediaStream;
      27             : class MediaStreamGraph;
      28             : class MediaStreamGraphImpl;
      29             : class MediaStreamTrackListener;
      30             : class DirectMediaStreamTrackListener;
      31             : class PeerConnectionImpl;
      32             : class PeerConnectionMedia;
      33             : class PeerIdentity;
      34             : class ProcessedMediaStream;
      35             : class RemoteSourceStreamInfo;
      36             : class SourceStreamInfo;
      37             : 
      38             : namespace dom {
      39             : 
      40             : class AudioStreamTrack;
      41             : class VideoStreamTrack;
      42             : class MediaStreamError;
      43             : enum class CallerType : uint32_t;
      44             : 
      45             : /**
      46             :  * Common interface through which a MediaStreamTrack can communicate with its
      47             :  * producer on the main thread.
      48             :  *
      49             :  * Kept alive by a strong ref in all MediaStreamTracks (original and clones)
      50             :  * sharing this source.
      51             :  */
      52             : class MediaStreamTrackSource : public nsISupports
      53             : {
      54             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      55           0 :   NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackSource)
      56             : 
      57             : public:
      58           0 :   class Sink
      59             :   {
      60             :   public:
      61             :     virtual void PrincipalChanged() = 0;
      62             :   };
      63             : 
      64           0 :   MediaStreamTrackSource(nsIPrincipal* aPrincipal,
      65             :                          const nsString& aLabel)
      66           0 :     : mPrincipal(aPrincipal),
      67             :       mLabel(aLabel),
      68           0 :       mStopped(false)
      69             :   {
      70           0 :   }
      71             : 
      72             :   /**
      73             :    * Use to clean up any resources that have to be cleaned before the
      74             :    * destructor is called. It is often too late in the destructor because
      75             :    * of garbage collection having removed the members already.
      76             :    */
      77           0 :   virtual void Destroy() {}
      78             : 
      79             :   /**
      80             :    * Gets the source's MediaSourceEnum for usage by PeerConnections.
      81             :    */
      82             :   virtual MediaSourceEnum GetMediaSource() const = 0;
      83             : 
      84             :   /**
      85             :    * Get this TrackSource's principal.
      86             :    */
      87           0 :   nsIPrincipal* GetPrincipal() const { return mPrincipal; }
      88             : 
      89             :   /**
      90             :    * Get the source's current CORSMode. If not applicable CORS_NONE is returned.
      91             :    * The sink will be notified of changes to our CORSMode through
      92             :    * PrincipalChanged().
      93             :    */
      94           0 :   virtual CORSMode GetCORSMode() const { return CORS_NONE; }
      95             : 
      96             :   /**
      97             :    * This is used in WebRTC. A peerIdentity constrained MediaStreamTrack cannot
      98             :    * be sent across the network to anything other than a peer with the provided
      99             :    * identity. If this is set, then GetPrincipal() should return an instance of
     100             :    * NullPrincipal.
     101             :    *
     102             :    * A track's PeerIdentity is immutable and will not change during the track's
     103             :    * lifetime.
     104             :    */
     105           0 :   virtual const PeerIdentity* GetPeerIdentity() const { return nullptr; }
     106             : 
     107             :   /**
     108             :    * MediaStreamTrack::GetLabel (see spec) calls through to here.
     109             :    */
     110           0 :   void GetLabel(nsAString& aLabel) { aLabel.Assign(mLabel); }
     111             : 
     112             :   /**
     113             :    * Forwards a photo request to backends that support it. Other backends return
     114             :    * NS_ERROR_NOT_IMPLEMENTED to indicate that a MediaStreamGraph-based fallback
     115             :    * should be used.
     116             :    */
     117           0 :   virtual nsresult TakePhoto(MediaEnginePhotoCallback*) const { return NS_ERROR_NOT_IMPLEMENTED; }
     118             : 
     119             :   typedef media::Pledge<bool, dom::MediaStreamError*> PledgeVoid;
     120             : 
     121             :   /**
     122             :    * We provide a fallback solution to ApplyConstraints() here.
     123             :    * Sources that support ApplyConstraints() will have to override it.
     124             :    */
     125             :   virtual already_AddRefed<PledgeVoid>
     126             :   ApplyConstraints(nsPIDOMWindowInner* aWindow,
     127             :                    const dom::MediaTrackConstraints& aConstraints,
     128             :                    CallerType aCallerType);
     129             : 
     130             :   /**
     131             :    * Same for GetSettings (no-op).
     132             :    */
     133             :   virtual void
     134           0 :   GetSettings(dom::MediaTrackSettings& aResult) {};
     135             : 
     136             :   /**
     137             :    * Called by the source interface when all registered sinks have unregistered.
     138             :    */
     139             :   virtual void Stop() = 0;
     140             : 
     141             :   /**
     142             :    * Called by each MediaStreamTrack clone on initialization.
     143             :    */
     144           0 :   void RegisterSink(Sink* aSink)
     145             :   {
     146           0 :     MOZ_ASSERT(NS_IsMainThread());
     147           0 :     if (mStopped) {
     148           0 :       return;
     149             :     }
     150           0 :     mSinks.AppendElement(aSink);
     151             :   }
     152             : 
     153             :   /**
     154             :    * Called by each MediaStreamTrack clone on Stop() if supported by the
     155             :    * source (us) or destruction.
     156             :    */
     157           0 :   void UnregisterSink(Sink* aSink)
     158             :   {
     159           0 :     MOZ_ASSERT(NS_IsMainThread());
     160           0 :     if (mSinks.RemoveElement(aSink) && mSinks.IsEmpty()) {
     161           0 :       MOZ_ASSERT(!mStopped);
     162           0 :       Stop();
     163           0 :       mStopped = true;
     164             :     }
     165           0 :   }
     166             : 
     167             : protected:
     168           0 :   virtual ~MediaStreamTrackSource()
     169           0 :   {
     170           0 :   }
     171             : 
     172             :   /**
     173             :    * Called by a sub class when the principal has changed.
     174             :    * Notifies all sinks.
     175             :    */
     176           0 :   void PrincipalChanged()
     177             :   {
     178           0 :     for (Sink* sink : mSinks) {
     179           0 :       sink->PrincipalChanged();
     180             :     }
     181           0 :   }
     182             : 
     183             :   // Principal identifying who may access the contents of this source.
     184             :   nsCOMPtr<nsIPrincipal> mPrincipal;
     185             : 
     186             :   // Currently registered sinks.
     187             :   nsTArray<Sink*> mSinks;
     188             : 
     189             :   // The label of the track we are the source of per the MediaStreamTrack spec.
     190             :   const nsString mLabel;
     191             : 
     192             :   // True if all MediaStreamTrack users have unregistered from this source and
     193             :   // Stop() has been called.
     194             :   bool mStopped;
     195             : };
     196             : 
     197             : /**
     198             :  * Basic implementation of MediaStreamTrackSource that doesn't forward Stop().
     199             :  */
     200             : class BasicTrackSource : public MediaStreamTrackSource
     201             : {
     202             : public:
     203           0 :   explicit BasicTrackSource(nsIPrincipal* aPrincipal,
     204             :                             const MediaSourceEnum aMediaSource =
     205             :                             MediaSourceEnum::Other)
     206           0 :     : MediaStreamTrackSource(aPrincipal, nsString())
     207           0 :     , mMediaSource(aMediaSource)
     208           0 :   {}
     209             : 
     210           0 :   MediaSourceEnum GetMediaSource() const override { return mMediaSource; }
     211             : 
     212           0 :   void Stop() override {}
     213             : 
     214             : protected:
     215           0 :   ~BasicTrackSource() {}
     216             : 
     217             :   const MediaSourceEnum mMediaSource;
     218             : };
     219             : 
     220             : /**
     221             :  * Base class that consumers of a MediaStreamTrack can use to get notifications
     222             :  * about state changes in the track.
     223             :  */
     224           0 : class MediaStreamTrackConsumer : public nsISupports
     225             : {
     226             : public:
     227             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     228           0 :   NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackConsumer)
     229             : 
     230             :   /**
     231             :    * Called when the track's readyState transitions to "ended".
     232             :    * Unlike the "ended" event exposed to script this is called for any reason,
     233             :    * including MediaStreamTrack::Stop().
     234             :    */
     235           0 :   virtual void NotifyEnded(MediaStreamTrack* aTrack) {};
     236             : 
     237             : protected:
     238           0 :   virtual ~MediaStreamTrackConsumer() {}
     239             : };
     240             : 
     241             : /**
     242             :  * Class representing a track in a DOMMediaStream.
     243             :  */
     244             : class MediaStreamTrack : public DOMEventTargetHelper,
     245             :                          public MediaStreamTrackSource::Sink
     246             : {
     247             :   // DOMMediaStream owns MediaStreamTrack instances, and requires access to
     248             :   // some internal state, e.g., GetInputStream(), GetOwnedStream().
     249             :   friend class mozilla::DOMMediaStream;
     250             : 
     251             :   // PeerConnection and friends need to know our owning DOMStream and track id.
     252             :   friend class mozilla::PeerConnectionImpl;
     253             :   friend class mozilla::PeerConnectionMedia;
     254             :   friend class mozilla::SourceStreamInfo;
     255             :   friend class mozilla::RemoteSourceStreamInfo;
     256             : 
     257             :   class PrincipalHandleListener;
     258             : 
     259             : public:
     260             :   /**
     261             :    * aTrackID is the MediaStreamGraph track ID for the track in the
     262             :    * MediaStream owned by aStream.
     263             :    */
     264             :   MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID,
     265             :       TrackID aInputTrackID,
     266             :       MediaStreamTrackSource* aSource,
     267             :       const MediaTrackConstraints& aConstraints = MediaTrackConstraints());
     268             : 
     269             :   NS_DECL_ISUPPORTS_INHERITED
     270           0 :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamTrack,
     271             :                                            DOMEventTargetHelper)
     272             : 
     273             :   nsPIDOMWindowInner* GetParentObject() const;
     274             :   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override = 0;
     275             : 
     276           0 :   virtual AudioStreamTrack* AsAudioStreamTrack() { return nullptr; }
     277           0 :   virtual VideoStreamTrack* AsVideoStreamTrack() { return nullptr; }
     278             : 
     279           0 :   virtual const AudioStreamTrack* AsAudioStreamTrack() const { return nullptr; }
     280           0 :   virtual const VideoStreamTrack* AsVideoStreamTrack() const { return nullptr; }
     281             : 
     282             :   // WebIDL
     283             :   virtual void GetKind(nsAString& aKind) = 0;
     284             :   void GetId(nsAString& aID) const;
     285           0 :   void GetLabel(nsAString& aLabel) { GetSource().GetLabel(aLabel); }
     286           0 :   bool Enabled() { return mEnabled; }
     287             :   void SetEnabled(bool aEnabled);
     288             :   void Stop();
     289             :   void GetConstraints(dom::MediaTrackConstraints& aResult);
     290             :   void GetSettings(dom::MediaTrackSettings& aResult);
     291             : 
     292             :   already_AddRefed<Promise>
     293             :   ApplyConstraints(const dom::MediaTrackConstraints& aConstraints,
     294             :                    CallerType aCallerType, ErrorResult &aRv);
     295             :   already_AddRefed<MediaStreamTrack> Clone();
     296           0 :   MediaStreamTrackState ReadyState() { return mReadyState; }
     297             : 
     298           0 :   IMPL_EVENT_HANDLER(ended)
     299             : 
     300             :   /**
     301             :    * Convenience (and legacy) method for when ready state is "ended".
     302             :    */
     303           0 :   bool Ended() const { return mReadyState == MediaStreamTrackState::Ended; }
     304             : 
     305             :   /**
     306             :    * Forces the ready state to a particular value, for instance when we're
     307             :    * cloning an already ended track.
     308             :    */
     309             :   void SetReadyState(MediaStreamTrackState aState);
     310             : 
     311             :   /**
     312             :    * Notified by the MediaStreamGraph, through our owning MediaStream on the
     313             :    * main thread.
     314             :    *
     315             :    * Note that this sets the track to ended and raises the "ended" event
     316             :    * synchronously.
     317             :    */
     318             :   void OverrideEnded();
     319             : 
     320             :   /**
     321             :    * Get this track's principal.
     322             :    */
     323           0 :   nsIPrincipal* GetPrincipal() const { return mPrincipal; }
     324             : 
     325             :   /**
     326             :    * Called by the PrincipalHandleListener when this track's PrincipalHandle changes on
     327             :    * the MediaStreamGraph thread. When the PrincipalHandle matches the pending
     328             :    * principal we know that the principal change has propagated to consumers.
     329             :    */
     330             :   void NotifyPrincipalHandleChanged(const PrincipalHandle& aPrincipalHandle);
     331             : 
     332             :   /**
     333             :    * Called when this track's readyState transitions to "ended".
     334             :    * Notifies all MediaStreamTrackConsumers that this track ended.
     335             :    */
     336             :   void NotifyEnded();
     337             : 
     338             :   /**
     339             :    * Get this track's CORS mode.
     340             :    */
     341           0 :   CORSMode GetCORSMode() const { return GetSource().GetCORSMode(); }
     342             : 
     343             :   /**
     344             :    * Get this track's PeerIdentity.
     345             :    */
     346           0 :   const PeerIdentity* GetPeerIdentity() const { return GetSource().GetPeerIdentity(); }
     347             : 
     348             :   MediaStreamGraph* Graph();
     349             :   MediaStreamGraphImpl* GraphImpl();
     350             : 
     351           0 :   MediaStreamTrackSource& GetSource() const
     352             :   {
     353           0 :     MOZ_RELEASE_ASSERT(mSource, "The track source is only removed on destruction");
     354           0 :     return *mSource;
     355             :   }
     356             : 
     357             :   // Webrtc allows the remote side to name tracks whatever it wants, and we
     358             :   // need to surface this to content.
     359           0 :   void AssignId(const nsAString& aID) { mID = aID; }
     360             : 
     361             :   // Implementation of MediaStreamTrackSource::Sink
     362             :   void PrincipalChanged() override;
     363             : 
     364             :   /**
     365             :    * Add a PrincipalChangeObserver to this track.
     366             :    *
     367             :    * Returns true if it was successfully added.
     368             :    *
     369             :    * Ownership of the PrincipalChangeObserver remains with the caller, and it's
     370             :    * the caller's responsibility to remove the observer before it dies.
     371             :    */
     372             :   bool AddPrincipalChangeObserver(PrincipalChangeObserver<MediaStreamTrack>* aObserver);
     373             : 
     374             :   /**
     375             :    * Remove an added PrincipalChangeObserver from this track.
     376             :    *
     377             :    * Returns true if it was successfully removed.
     378             :    */
     379             :   bool RemovePrincipalChangeObserver(PrincipalChangeObserver<MediaStreamTrack>* aObserver);
     380             : 
     381             :   /**
     382             :    * Add a MediaStreamTrackConsumer to this track.
     383             :    *
     384             :    * Adding the same consumer multiple times is prohibited.
     385             :    */
     386             :   void AddConsumer(MediaStreamTrackConsumer* aConsumer);
     387             : 
     388             :   /**
     389             :    * Remove an added MediaStreamTrackConsumer from this track.
     390             :    */
     391             :   void RemoveConsumer(MediaStreamTrackConsumer* aConsumer);
     392             : 
     393             :   /**
     394             :    * Adds a MediaStreamTrackListener to the MediaStreamGraph representation of
     395             :    * this track.
     396             :    */
     397             :   virtual void AddListener(MediaStreamTrackListener* aListener);
     398             : 
     399             :   /**
     400             :    * Removes a MediaStreamTrackListener from the MediaStreamGraph representation
     401             :    * of this track.
     402             :    */
     403             :   void RemoveListener(MediaStreamTrackListener* aListener);
     404             : 
     405             :   /**
     406             :    * Attempts to add a direct track listener to this track.
     407             :    * Callers must listen to the NotifyInstalled event to know if installing
     408             :    * the listener succeeded (tracks originating from SourceMediaStreams) or
     409             :    * failed (e.g., WebAudio originated tracks).
     410             :    */
     411             :   virtual void AddDirectListener(DirectMediaStreamTrackListener *aListener);
     412             :   void RemoveDirectListener(DirectMediaStreamTrackListener  *aListener);
     413             : 
     414             :   /**
     415             :    * Sets up a MediaInputPort from the underlying track that this
     416             :    * MediaStreamTrack represents, to aStream, and returns it.
     417             :    */
     418             :   already_AddRefed<MediaInputPort> ForwardTrackContentsTo(ProcessedMediaStream* aStream,
     419             :                                                           TrackID aDestinationTrackID = TRACK_ANY);
     420             : 
     421             :   /**
     422             :    * Returns true if this track is connected to aPort and forwarded to aPort's
     423             :    * output stream.
     424             :    */
     425             :   bool IsForwardedThrough(MediaInputPort* aPort);
     426             : 
     427             :   void SetMediaStreamSizeListener(DirectMediaStreamTrackListener* aListener);
     428             : 
     429             : protected:
     430             :   virtual ~MediaStreamTrack();
     431             : 
     432             :   void Destroy();
     433             : 
     434             :   // Returns the original DOMMediaStream's underlying input stream.
     435             :   MediaStream* GetInputStream();
     436             : 
     437             :   // Returns the owning DOMMediaStream's underlying owned stream.
     438             :   ProcessedMediaStream* GetOwnedStream();
     439             : 
     440             :   // Returns the original DOMMediaStream. If this track is a clone,
     441             :   // the original track's owning DOMMediaStream is returned.
     442             :   DOMMediaStream* GetInputDOMStream();
     443             : 
     444             :   /**
     445             :    * Sets the principal and notifies PrincipalChangeObservers if it changes.
     446             :    */
     447             :   void SetPrincipal(nsIPrincipal* aPrincipal);
     448             : 
     449             :   /**
     450             :    * Creates a new MediaStreamTrack with the same type, input track ID and
     451             :    * source as this MediaStreamTrack.
     452             :    * aTrackID is the TrackID the new track will have in its owned stream.
     453             :    */
     454             :   virtual already_AddRefed<MediaStreamTrack> CloneInternal(DOMMediaStream* aOwningStream,
     455             :                                                            TrackID aTrackID) = 0;
     456             : 
     457             :   nsTArray<PrincipalChangeObserver<MediaStreamTrack>*> mPrincipalChangeObservers;
     458             : 
     459             :   nsTArray<RefPtr<MediaStreamTrackConsumer>> mConsumers;
     460             : 
     461             :   RefPtr<DOMMediaStream> mOwningStream;
     462             :   TrackID mTrackID;
     463             :   TrackID mInputTrackID;
     464             :   RefPtr<MediaStreamTrackSource> mSource;
     465             :   RefPtr<MediaStreamTrack> mOriginalTrack;
     466             :   nsCOMPtr<nsIPrincipal> mPrincipal;
     467             :   nsCOMPtr<nsIPrincipal> mPendingPrincipal;
     468             :   RefPtr<PrincipalHandleListener> mPrincipalHandleListener;
     469             :   // Keep tracking MediaStreamTrackListener and DirectMediaStreamTrackListener,
     470             :   // so we can remove them in |Destory|.
     471             :   nsTArray<RefPtr<MediaStreamTrackListener>> mTrackListeners;
     472             :   nsTArray<RefPtr<DirectMediaStreamTrackListener>> mDirectTrackListeners;
     473             :   nsString mID;
     474             :   MediaStreamTrackState mReadyState;
     475             :   bool mEnabled;
     476             :   dom::MediaTrackConstraints mConstraints;
     477             : };
     478             : 
     479             : } // namespace dom
     480             : } // namespace mozilla
     481             : 
     482             : #endif /* MEDIASTREAMTRACK_H_ */

Generated by: LCOV version 1.13