tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaStreamTrack.h (22389B)


      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 "PerformanceRecorder.h"
     11 #include "PrincipalChangeObserver.h"
     12 #include "PrincipalHandle.h"
     13 #include "mozilla/DOMEventTargetHelper.h"
     14 #include "mozilla/WeakPtr.h"
     15 #include "mozilla/dom/MediaStreamTrackBinding.h"
     16 #include "mozilla/dom/MediaTrackCapabilitiesBinding.h"
     17 #include "mozilla/dom/MediaTrackSettingsBinding.h"
     18 #include "mozilla/media/MediaUtils.h"
     19 #include "nsError.h"
     20 #include "nsID.h"
     21 #include "nsIPrincipal.h"
     22 
     23 namespace mozilla {
     24 
     25 class DOMMediaStream;
     26 class MediaEnginePhotoCallback;
     27 class MediaInputPort;
     28 class MediaTrack;
     29 class MediaTrackGraph;
     30 class MediaTrackGraphImpl;
     31 class MediaTrackListener;
     32 class DirectMediaTrackListener;
     33 class PeerConnectionImpl;
     34 class PeerIdentity;
     35 class ProcessedMediaTrack;
     36 class RemoteSourceStreamInfo;
     37 class SourceStreamInfo;
     38 class MediaMgrError;
     39 
     40 namespace dom {
     41 
     42 class AudioStreamTrack;
     43 class VideoStreamTrack;
     44 class RTCStatsTimestampMaker;
     45 enum class CallerType : uint32_t;
     46 
     47 /**
     48 * Common interface through which a MediaStreamTrack can communicate with its
     49 * producer on the main thread.
     50 *
     51 * Kept alive by a strong ref in all MediaStreamTracks (original and clones)
     52 * sharing this source.
     53 */
     54 class MediaStreamTrackSource : public nsISupports {
     55  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     56  NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackSource)
     57 
     58 public:
     59  class Sink : public SupportsWeakPtr {
     60   public:
     61    /**
     62     * Must be constant throughout the Sink's lifetime.
     63     *
     64     * Return true to keep the MediaStreamTrackSource where this sink is
     65     * registered alive.
     66     * Return false to allow the source to stop.
     67     *
     68     * Typically MediaStreamTrack::Sink returns true and other Sinks
     69     * (like HTMLMediaElement::StreamCaptureTrackSource) return false.
     70     */
     71    virtual bool KeepsSourceAlive() const = 0;
     72 
     73    /**
     74     * Return true to ensure that the MediaStreamTrackSource where this Sink is
     75     * registered is kept turned on and active.
     76     * Return false to allow the source to pause, and any underlying devices to
     77     * temporarily stop.
     78     *
     79     * When the underlying enabled state of the sink changes,
     80     * call MediaStreamTrackSource::SinkEnabledStateChanged().
     81     *
     82     * Typically MediaStreamTrack returns the track's enabled state and other
     83     * Sinks (like HTMLMediaElement::StreamCaptureTrackSource) return false so
     84     * control over device state remains with tracks and their enabled state.
     85     */
     86    virtual bool Enabled() const = 0;
     87 
     88    /**
     89     * Called when the principal of the MediaStreamTrackSource where this sink
     90     * is registered has changed.
     91     */
     92    virtual void PrincipalChanged() = 0;
     93 
     94    /**
     95     * Called when the muted state of the MediaStreamTrackSource where this sink
     96     * is registered has changed.
     97     */
     98    virtual void MutedChanged(bool aNewState) = 0;
     99 
    100    /**
    101     * Called when the constraints of the MediaStreamTrackSource where this sink
    102     * is registered has changed.
    103     */
    104    virtual void ConstraintsChanged(
    105        const MediaTrackConstraints& aConstraints) = 0;
    106 
    107    /**
    108     * Called when the MediaStreamTrackSource where this sink is registered has
    109     * stopped producing data for good, i.e., it has ended.
    110     */
    111    virtual void OverrideEnded() = 0;
    112 
    113   protected:
    114    virtual ~Sink() = default;
    115  };
    116 
    117  MediaStreamTrackSource(nsIPrincipal* aPrincipal, const nsString& aLabel,
    118                         TrackingId aTrackingId)
    119      : mPrincipal(aPrincipal),
    120        mLabel(aLabel),
    121        mTrackingId(std::move(aTrackingId)),
    122        mStopped(false) {}
    123 
    124  /**
    125   * Use to clean up any resources that have to be cleaned before the
    126   * destructor is called. It is often too late in the destructor because
    127   * of garbage collection having removed the members already.
    128   */
    129  virtual void Destroy() {}
    130 
    131  struct CloneResult {
    132    RefPtr<MediaStreamTrackSource> mSource;
    133    RefPtr<mozilla::MediaTrack> mInputTrack;
    134  };
    135 
    136  /**
    137   * Clone this MediaStreamTrackSource. Cloned sources allow independent track
    138   * settings. Not supported by all source types. A source not supporting
    139   * cloning returns nullptr.
    140   */
    141  virtual CloneResult Clone();
    142 
    143  /**
    144   * Gets the source's MediaSourceEnum for usage by PeerConnections.
    145   */
    146  virtual MediaSourceEnum GetMediaSource() const = 0;
    147 
    148  /**
    149   * Get this TrackSource's principal.
    150   */
    151  nsIPrincipal* GetPrincipal() const { return mPrincipal; }
    152 
    153  /**
    154   * This is used in WebRTC. A peerIdentity constrained MediaStreamTrack cannot
    155   * be sent across the network to anything other than a peer with the provided
    156   * identity. If this is set, then GetPrincipal() should return an instance of
    157   * NullPrincipal.
    158   *
    159   * A track's PeerIdentity is immutable and will not change during the track's
    160   * lifetime.
    161   */
    162  virtual const PeerIdentity* GetPeerIdentity() const { return nullptr; }
    163 
    164  /**
    165   * This is used in WebRTC. The timestampMaker can convert between different
    166   * timestamp types used during the session.
    167   */
    168  virtual const RTCStatsTimestampMaker* GetTimestampMaker() const {
    169    return nullptr;
    170  }
    171 
    172  /**
    173   * MediaStreamTrack::GetLabel (see spec) calls through to here.
    174   */
    175  void GetLabel(nsAString& aLabel) { aLabel.Assign(mLabel); }
    176 
    177  /**
    178   * Whether this TrackSource provides video frames with an alpha channel. Only
    179   * applies to video sources. Used by HTMLVideoElement.
    180   */
    181  virtual bool HasAlpha() const { return false; }
    182 
    183  /**
    184   * Forwards a photo request to backends that support it. Other backends return
    185   * NS_ERROR_NOT_IMPLEMENTED to indicate that a MediaTrackGraph-based fallback
    186   * should be used.
    187   */
    188  virtual nsresult TakePhoto(MediaEnginePhotoCallback*) const {
    189    return NS_ERROR_NOT_IMPLEMENTED;
    190  }
    191 
    192  typedef MozPromise<bool /* aIgnored */, RefPtr<MediaMgrError>, false>
    193      ApplyConstraintsPromise;
    194 
    195  /**
    196   * We provide a fallback solution to ApplyConstraints() here.
    197   * Sources that support ApplyConstraints() will have to override it.
    198   */
    199  virtual RefPtr<ApplyConstraintsPromise> ApplyConstraints(
    200      const dom::MediaTrackConstraints& aConstraints, CallerType aCallerType);
    201 
    202  /**
    203   * Same for GetSettings (no-op).
    204   */
    205  virtual void GetSettings(dom::MediaTrackSettings& aResult) = 0;
    206 
    207  virtual void GetCapabilities(dom::MediaTrackCapabilities& aResult) {};
    208 
    209  /**
    210   * Called by the source interface when all registered sinks with
    211   * KeepsSourceAlive() == true have unregistered.
    212   */
    213  virtual void Stop() = 0;
    214 
    215  /**
    216   * Called by the source interface when all registered sinks with
    217   * KeepsSourceAlive() == true become disabled.
    218   */
    219  virtual void Disable() = 0;
    220 
    221  /**
    222   * Called by the source interface when at least one registered sink with
    223   * KeepsSourceAlive() == true become enabled.
    224   */
    225  virtual void Enable() = 0;
    226 
    227  /**
    228   * Called when a Sink's Enabled() state changed. Will iterate through all
    229   * sinks and notify the source of the aggregated enabled state.
    230   *
    231   * Note that a Sink with KeepsSourceAlive() == false counts as disabled.
    232   */
    233  void SinkEnabledStateChanged() {
    234    if (IsEnabled()) {
    235      Enable();
    236    } else {
    237      Disable();
    238    }
    239  }
    240 
    241  /**
    242   * Called by each MediaStreamTrack clone on initialization.
    243   */
    244  void RegisterSink(Sink* aSink) {
    245    MOZ_ASSERT(NS_IsMainThread());
    246    if (mStopped) {
    247      return;
    248    }
    249    mSinks.RemoveElementsBy([](const WeakPtr<Sink>& aElem) {
    250      MOZ_ASSERT(aElem, "Sink was not explicitly removed");
    251      return !aElem;
    252    });
    253    mSinks.AppendElement(aSink);
    254  }
    255 
    256  /**
    257   * Called by each MediaStreamTrack clone on Stop() if supported by the
    258   * source (us) or destruction.
    259   */
    260  void UnregisterSink(Sink* aSink) {
    261    MOZ_ASSERT(NS_IsMainThread());
    262    mSinks.RemoveElementsBy([](const WeakPtr<Sink>& aElem) {
    263      MOZ_ASSERT(aElem, "Sink was not explicitly removed");
    264      return !aElem;
    265    });
    266    if (mSinks.RemoveElement(aSink) && !IsActive()) {
    267      MOZ_ASSERT(!aSink->KeepsSourceAlive() || !mStopped,
    268                 "When the last sink keeping the source alive is removed, "
    269                 "we should still be live");
    270      Stop();
    271      mStopped = true;
    272    }
    273    if (!mStopped) {
    274      SinkEnabledStateChanged();
    275    }
    276  }
    277 
    278 protected:
    279  virtual ~MediaStreamTrackSource() = default;
    280 
    281  bool IsActive() {
    282    for (const WeakPtr<Sink>& sink : mSinks) {
    283      if (sink && sink->KeepsSourceAlive()) {
    284        return true;
    285      }
    286    }
    287    return false;
    288  }
    289 
    290  bool IsEnabled() {
    291    for (const WeakPtr<Sink>& sink : mSinks) {
    292      if (sink && sink->KeepsSourceAlive() && sink->Enabled()) {
    293        return true;
    294      }
    295    }
    296    return false;
    297  }
    298 
    299  /**
    300   * Called by a sub class when the principal has changed.
    301   * Notifies all sinks.
    302   */
    303  void PrincipalChanged() {
    304    MOZ_ASSERT(NS_IsMainThread());
    305    mSinks.RemoveElementsBy([](const WeakPtr<Sink>& aElem) {
    306      MOZ_ASSERT(aElem, "Sink was not explicitly removed");
    307      return !aElem;
    308    });
    309    for (const auto& sink : mSinks.Clone()) {
    310      sink->PrincipalChanged();
    311    }
    312  }
    313 
    314  /**
    315   * Called by a sub class when the source's muted state has changed. Note that
    316   * the source is responsible for making the content black/silent during mute.
    317   * Notifies all sinks.
    318   */
    319  void MutedChanged(bool aNewState) {
    320    MOZ_ASSERT(NS_IsMainThread());
    321    mSinks.RemoveElementsBy([](const WeakPtr<Sink>& aElem) {
    322      MOZ_ASSERT(aElem, "Sink was not explicitly removed");
    323      return !aElem;
    324    });
    325    for (const auto& sink : mSinks.Clone()) {
    326      sink->MutedChanged(aNewState);
    327    }
    328  }
    329 
    330  /**
    331   * Called by a sub class when the source's applied constraints has changed.
    332   * Notifies all sinks.
    333   */
    334  void ConstraintsChanged(const MediaTrackConstraints& aConstraints) {
    335    MOZ_ASSERT(NS_IsMainThread());
    336    mSinks.RemoveElementsBy([](const WeakPtr<Sink>& aElem) {
    337      MOZ_ASSERT(aElem, "Sink was not explicitly removed");
    338      return !aElem;
    339    });
    340    for (const auto& sink : mSinks.Clone()) {
    341      sink->ConstraintsChanged(aConstraints);
    342    }
    343  }
    344 
    345  /**
    346   * Called by a sub class when the source has stopped producing data for good,
    347   * i.e., it has ended. Notifies all sinks.
    348   */
    349  void OverrideEnded() {
    350    MOZ_ASSERT(NS_IsMainThread());
    351    mSinks.RemoveElementsBy([](const WeakPtr<Sink>& aElem) {
    352      MOZ_ASSERT(aElem, "Sink was not explicitly removed");
    353      return !aElem;
    354    });
    355    for (const auto& sink : mSinks.Clone()) {
    356      sink->OverrideEnded();
    357    }
    358  }
    359 
    360  // Principal identifying who may access the contents of this source.
    361  RefPtr<nsIPrincipal> mPrincipal;
    362 
    363  // Currently registered sinks.
    364  nsTArray<WeakPtr<Sink>> mSinks;
    365 
    366 public:
    367  // The label of the track we are the source of per the MediaStreamTrack spec.
    368  const nsString mLabel;
    369 
    370  // Set for all video sources; an id for tracking the source of the video
    371  // frames for this track.
    372  const TrackingId mTrackingId;
    373 
    374 protected:
    375  // True if all MediaStreamTrack users have unregistered from this source and
    376  // Stop() has been called.
    377  bool mStopped;
    378 };
    379 
    380 /**
    381 * Base class that consumers of a MediaStreamTrack can use to get notifications
    382 * about state changes in the track.
    383 */
    384 class MediaStreamTrackConsumer : public SupportsWeakPtr {
    385 public:
    386  /**
    387   * Called when the track's readyState transitions to "ended".
    388   * Unlike the "ended" event exposed to script this is called for any reason,
    389   * including MediaStreamTrack::Stop().
    390   */
    391  virtual void NotifyEnded(MediaStreamTrack* aTrack) {};
    392 
    393  /**
    394   * Called when the track's enabled state changes.
    395   */
    396  virtual void NotifyEnabledChanged(MediaStreamTrack* aTrack, bool aEnabled) {};
    397 };
    398 
    399 // clang-format off
    400 /**
    401 * DOM wrapper for MediaTrackGraph-MediaTracks.
    402 *
    403 * To account for cloning, a MediaStreamTrack wraps two internal (and chained)
    404 * MediaTracks:
    405 *   1. mInputTrack
    406 *      - Controlled by the producer of the data in the track. The producer
    407 *        decides on lifetime of the MediaTrack and the track inside it.
    408 *      - It can be any type of MediaTrack.
    409 *      - Contains one track only.
    410 *   2. mTrack
    411 *      - A ForwardedInputTrack representing this MediaStreamTrack.
    412 *      - Its data is piped from mInputTrack through mPort.
    413 *      - Contains one track only.
    414 *      - When this MediaStreamTrack is enabled/disabled this is reflected in
    415 *        the chunks in the track in mTrack.
    416 *      - When this MediaStreamTrack has ended, mTrack gets destroyed.
    417 *        Note that mInputTrack is unaffected, such that any clones of mTrack
    418 *        can live on. When all clones are ended, this is signaled to the
    419 *        producer via our MediaStreamTrackSource. It is then likely to destroy
    420 *        mInputTrack.
    421 *
    422 * A graphical representation of how tracks are connected when cloned follows:
    423 *
    424 * MediaStreamTrack A
    425 *       mInputTrack     mTrack
    426 *            t1 ---------> t1
    427 *               \
    428 *                -----
    429 * MediaStreamTrack B  \  (clone of A)
    430 *       mInputTrack   \ mTrack
    431 *            *          -> t1
    432 *
    433 *   (*) is a copy of A's mInputTrack
    434 */
    435 // clang-format on
    436 class MediaStreamTrack : public DOMEventTargetHelper, public SupportsWeakPtr {
    437  // PeerConnection and friends need to know our owning DOMStream and track id.
    438  friend class mozilla::PeerConnectionImpl;
    439  friend class mozilla::SourceStreamInfo;
    440  friend class mozilla::RemoteSourceStreamInfo;
    441 
    442  class MTGListener;
    443  class TrackSink;
    444 
    445 public:
    446  MediaStreamTrack(
    447      nsPIDOMWindowInner* aWindow, mozilla::MediaTrack* aInputTrack,
    448      MediaStreamTrackSource* aSource,
    449      MediaStreamTrackState aReadyState = MediaStreamTrackState::Live,
    450      bool aMuted = false,
    451      const MediaTrackConstraints& aConstraints = MediaTrackConstraints());
    452 
    453  NS_DECL_ISUPPORTS_INHERITED
    454  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamTrack,
    455                                           DOMEventTargetHelper)
    456 
    457  nsPIDOMWindowInner* GetParentObject() const { return mWindow; }
    458  JSObject* WrapObject(JSContext* aCx,
    459                       JS::Handle<JSObject*> aGivenProto) override;
    460 
    461  virtual AudioStreamTrack* AsAudioStreamTrack() { return nullptr; }
    462  virtual VideoStreamTrack* AsVideoStreamTrack() { return nullptr; }
    463 
    464  virtual const AudioStreamTrack* AsAudioStreamTrack() const { return nullptr; }
    465  virtual const VideoStreamTrack* AsVideoStreamTrack() const { return nullptr; }
    466 
    467  // WebIDL
    468  virtual void GetKind(nsAString& aKind) = 0;
    469  void GetId(nsAString& aID) const;
    470  virtual void GetLabel(nsAString& aLabel, CallerType /* aCallerType */) {
    471    GetSource().GetLabel(aLabel);
    472  }
    473  bool Enabled() const { return mEnabled; }
    474  void SetEnabled(bool aEnabled);
    475  bool Muted() { return mMuted; }
    476  void Stop();
    477  void GetCapabilities(MediaTrackCapabilities& aResult, CallerType aCallerType);
    478  void GetConstraints(dom::MediaTrackConstraints& aResult);
    479  void GetSettings(dom::MediaTrackSettings& aResult, CallerType aCallerType);
    480 
    481  already_AddRefed<Promise> ApplyConstraints(
    482      const dom::MediaTrackConstraints& aConstraints, CallerType aCallerType,
    483      ErrorResult& aRv);
    484  virtual already_AddRefed<MediaStreamTrack> Clone() = 0;
    485  MediaStreamTrackState ReadyState() { return mReadyState; }
    486 
    487  IMPL_EVENT_HANDLER(mute)
    488  IMPL_EVENT_HANDLER(unmute)
    489  IMPL_EVENT_HANDLER(ended)
    490 
    491  /**
    492   * Convenience (and legacy) method for when ready state is "ended".
    493   */
    494  bool Ended() const { return mReadyState == MediaStreamTrackState::Ended; }
    495 
    496  /**
    497   * Get this track's principal.
    498   */
    499  nsIPrincipal* GetPrincipal() const { return mPrincipal; }
    500 
    501  /**
    502   * Get this track's PeerIdentity.
    503   */
    504  const PeerIdentity* GetPeerIdentity() const {
    505    return GetSource().GetPeerIdentity();
    506  }
    507 
    508  /**
    509   * Get this track's RTCStatsTimestampMaker.
    510   */
    511  const RTCStatsTimestampMaker* GetTimestampMaker() const {
    512    return GetSource().GetTimestampMaker();
    513  }
    514 
    515  ProcessedMediaTrack* GetTrack() const;
    516  MediaTrackGraph* Graph() const;
    517  MediaTrackGraphImpl* GraphImpl() const;
    518 
    519  MediaStreamTrackSource& GetSource() const {
    520    MOZ_RELEASE_ASSERT(mSource,
    521                       "The track source is only removed on destruction");
    522    return *mSource;
    523  }
    524 
    525  // Webrtc allows the remote side to name tracks whatever it wants, and we
    526  // need to surface this to content.
    527  void AssignId(const nsAString& aID) { mID = aID; }
    528 
    529  /**
    530   * Add a PrincipalChangeObserver to this track.
    531   *
    532   * Returns true if it was successfully added.
    533   *
    534   * Ownership of the PrincipalChangeObserver remains with the caller, and it's
    535   * the caller's responsibility to remove the observer before it dies.
    536   */
    537  bool AddPrincipalChangeObserver(
    538      PrincipalChangeObserver<MediaStreamTrack>* aObserver);
    539 
    540  /**
    541   * Remove an added PrincipalChangeObserver from this track.
    542   *
    543   * Returns true if it was successfully removed.
    544   */
    545  bool RemovePrincipalChangeObserver(
    546      PrincipalChangeObserver<MediaStreamTrack>* aObserver);
    547 
    548  /**
    549   * Add a MediaStreamTrackConsumer to this track.
    550   *
    551   * Adding the same consumer multiple times is prohibited.
    552   */
    553  void AddConsumer(MediaStreamTrackConsumer* aConsumer);
    554 
    555  /**
    556   * Remove an added MediaStreamTrackConsumer from this track.
    557   */
    558  void RemoveConsumer(MediaStreamTrackConsumer* aConsumer);
    559 
    560  /**
    561   * Adds a MediaTrackListener to the MediaTrackGraph representation of
    562   * this track.
    563   */
    564  virtual void AddListener(MediaTrackListener* aListener);
    565 
    566  /**
    567   * Removes a MediaTrackListener from the MediaTrackGraph representation
    568   * of this track.
    569   */
    570  void RemoveListener(MediaTrackListener* aListener);
    571 
    572  /**
    573   * Attempts to add a direct track listener to this track.
    574   * Callers must listen to the NotifyInstalled event to know if installing
    575   * the listener succeeded (tracks originating from SourceMediaTracks) or
    576   * failed (e.g., WebAudio originated tracks).
    577   */
    578  virtual void AddDirectListener(DirectMediaTrackListener* aListener);
    579  void RemoveDirectListener(DirectMediaTrackListener* aListener);
    580 
    581  /**
    582   * Sets up a MediaInputPort from the underlying track that this
    583   * MediaStreamTrack represents, to aTrack, and returns it.
    584   */
    585  already_AddRefed<MediaInputPort> ForwardTrackContentsTo(
    586      ProcessedMediaTrack* aTrack);
    587 
    588 protected:
    589  virtual ~MediaStreamTrack();
    590 
    591  /**
    592   * Forces the ready state to a particular value, for instance when we're
    593   * cloning an already ended track.
    594   */
    595  virtual void SetReadyState(MediaStreamTrackState aState);
    596 
    597  /**
    598   * Notified by the MediaTrackGraph, through our owning MediaStream on the
    599   * main thread.
    600   *
    601   * Note that this sets the track to ended and raises the "ended" event
    602   * synchronously.
    603   */
    604  void OverrideEnded();
    605 
    606  /**
    607   * Called by the MTGListener when this track's PrincipalHandle changes on
    608   * the MediaTrackGraph thread. When the PrincipalHandle matches the pending
    609   * principal we know that the principal change has propagated to consumers.
    610   */
    611  void NotifyPrincipalHandleChanged(const PrincipalHandle& aNewPrincipalHandle);
    612 
    613  /**
    614   * Called when this track's readyState transitions to "ended".
    615   * Notifies all MediaStreamTrackConsumers that this track ended.
    616   */
    617  void NotifyEnded();
    618 
    619  /**
    620   * Called when this track's enabled state has changed.
    621   * Notifies all MediaStreamTrackConsumers.
    622   */
    623  void NotifyEnabledChanged();
    624 
    625  /**
    626   * Called when mSource's principal has changed.
    627   */
    628  void PrincipalChanged();
    629 
    630  /**
    631   * Called when mSource's muted state has changed.
    632   */
    633  void MutedChanged(bool aNewState);
    634 
    635  /**
    636   * Called when mSource's applied constraints has changed.
    637   */
    638  void ConstraintsChanged(const MediaTrackConstraints& aConstraints);
    639 
    640  /**
    641   * Sets this track's muted state without raising any events.
    642   * Only really set by cloning. See MutedChanged for runtime changes.
    643   */
    644  void SetMuted(bool aMuted) { mMuted = aMuted; }
    645 
    646  virtual void Destroy();
    647 
    648  /**
    649   * Sets the principal and notifies PrincipalChangeObservers if it changes.
    650   */
    651  void SetPrincipal(nsIPrincipal* aPrincipal);
    652 
    653  /**
    654   * Creates a new MediaStreamTrack with the same kind, input track, input
    655   * track ID and source as this MediaStreamTrack.
    656   */
    657 
    658  template <typename TrackType>
    659  already_AddRefed<MediaStreamTrack> CloneInternal() {
    660    auto cloneRes = mSource->Clone();
    661    MOZ_ASSERT(!!cloneRes.mSource == !!cloneRes.mInputTrack);
    662    if (!cloneRes.mSource || !cloneRes.mInputTrack) {
    663      cloneRes.mSource = mSource;
    664      cloneRes.mInputTrack = mInputTrack;
    665    }
    666    auto newTrack =
    667        MakeRefPtr<TrackType>(mWindow, cloneRes.mInputTrack, cloneRes.mSource,
    668                              ReadyState(), Muted(), mConstraints);
    669    newTrack->SetEnabled(Enabled());
    670    newTrack->SetMuted(Muted());
    671    return newTrack.forget();
    672  }
    673 
    674  nsTArray<PrincipalChangeObserver<MediaStreamTrack>*>
    675      mPrincipalChangeObservers;
    676 
    677  nsTArray<WeakPtr<MediaStreamTrackConsumer>> mConsumers;
    678 
    679  // We need this to track our parent object.
    680  nsCOMPtr<nsPIDOMWindowInner> mWindow;
    681 
    682  // The input MediaTrack assigned us by the data producer.
    683  // Owned by the producer.
    684  const RefPtr<mozilla::MediaTrack> mInputTrack;
    685  // The MediaTrack representing this MediaStreamTrack in the MediaTrackGraph.
    686  // Set on construction if we're live. Valid until we end. Owned by us.
    687  RefPtr<ProcessedMediaTrack> mTrack;
    688  // The MediaInputPort connecting mInputTrack to mTrack. Set on construction
    689  // if mInputTrack is non-destroyed and we're live. Valid until we end. Owned
    690  // by us.
    691  RefPtr<MediaInputPort> mPort;
    692  RefPtr<MediaStreamTrackSource> mSource;
    693  const UniquePtr<TrackSink> mSink;
    694  nsCOMPtr<nsIPrincipal> mPrincipal;
    695  nsCOMPtr<nsIPrincipal> mPendingPrincipal;
    696  RefPtr<MTGListener> mMTGListener;
    697  // Keep tracking MediaTrackListener and DirectMediaTrackListener,
    698  // so we can remove them in |Destory|.
    699  nsTArray<RefPtr<MediaTrackListener>> mTrackListeners;
    700  nsTArray<RefPtr<DirectMediaTrackListener>> mDirectTrackListeners;
    701  nsString mID;
    702  MediaStreamTrackState mReadyState;
    703  bool mEnabled;
    704  bool mMuted;
    705  dom::MediaTrackConstraints mConstraints;
    706 };
    707 
    708 }  // namespace dom
    709 }  // namespace mozilla
    710 
    711 #endif /* MEDIASTREAMTRACK_H_ */