tor-browser

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

HTMLMediaElement.h (72311B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 #ifndef mozilla_dom_HTMLMediaElement_h
      7 #define mozilla_dom_HTMLMediaElement_h
      8 
      9 #include <utility>
     10 
     11 #include "AudioChannelService.h"
     12 #include "DecoderTraits.h"
     13 #include "MediaDecoderOwner.h"
     14 #include "MediaElementEventRunners.h"
     15 #include "MediaEventSource.h"
     16 #include "MediaPlaybackDelayPolicy.h"
     17 #include "MediaPromiseDefs.h"
     18 #include "MediaSegment.h"  // for PrincipalHandle, GraphTime
     19 #include "MediaTimer.h"
     20 #include "PrincipalChangeObserver.h"
     21 #include "SeekTarget.h"
     22 #include "TelemetryProbesReporter.h"
     23 #include "Visibility.h"
     24 #include "mozilla/Attributes.h"
     25 #include "mozilla/AwakeTimeStamp.h"
     26 #include "mozilla/CORSMode.h"
     27 #include "mozilla/StateWatching.h"
     28 #include "mozilla/WeakPtr.h"
     29 #include "mozilla/dom/DecoderDoctorNotificationBinding.h"
     30 #include "mozilla/dom/HTMLMediaElementBinding.h"
     31 #include "mozilla/dom/MediaDebugInfoBinding.h"
     32 #include "mozilla/dom/MediaKeys.h"
     33 #include "mozilla/dom/TextTrackManager.h"
     34 #include "nsCycleCollectionParticipant.h"
     35 #include "nsGenericHTMLElement.h"
     36 #include "nsGkAtoms.h"
     37 #include "nsStubMutationObserver.h"
     38 
     39 // X.h on Linux #defines CurrentTime as 0L, so we have to #undef it here.
     40 #ifdef CurrentTime
     41 #  undef CurrentTime
     42 #endif
     43 
     44 // Define to output information on decoding and painting framerate
     45 /* #define DEBUG_FRAME_RATE 1 */
     46 
     47 using nsMediaNetworkState = uint16_t;
     48 using nsMediaReadyState = uint16_t;
     49 using SuspendTypes = uint32_t;
     50 using AudibleChangedReasons = uint32_t;
     51 
     52 class nsIStreamListener;
     53 
     54 namespace mozilla {
     55 class AbstractThread;
     56 class ChannelMediaDecoder;
     57 class DecoderDoctorDiagnostics;
     58 class DOMMediaStream;
     59 class ErrorResult;
     60 class FirstFrameVideoOutput;
     61 class MediaResource;
     62 class MediaDecoder;
     63 class MediaInputPort;
     64 class MediaTrack;
     65 class MediaTrackGraph;
     66 class MediaStreamWindowCapturer;
     67 struct SharedDummyTrack;
     68 class VideoFrameContainer;
     69 class VideoOutput;
     70 namespace dom {
     71 class HTMLSourceElement;
     72 class MediaKeys;
     73 class TextTrack;
     74 class TimeRanges;
     75 class WakeLock;
     76 class MediaStreamTrack;
     77 class MediaStreamTrackSource;
     78 class MediaTrack;
     79 class VideoStreamTrack;
     80 }  // namespace dom
     81 }  // namespace mozilla
     82 
     83 class AudioDeviceInfo;
     84 class nsIChannel;
     85 class nsIHttpChannel;
     86 class nsILoadGroup;
     87 class nsIRunnable;
     88 class nsISerialEventTarget;
     89 class nsITimer;
     90 class nsRange;
     91 
     92 namespace mozilla::dom {
     93 
     94 // Number of milliseconds between timeupdate events as defined by spec
     95 #define TIMEUPDATE_MS 250
     96 
     97 class HTMLVideoElement;
     98 class MediaError;
     99 class MediaSource;
    100 class PlayPromise;
    101 class Promise;
    102 class TextTrackList;
    103 class AudioTrackList;
    104 class VideoTrackList;
    105 
    106 enum class StreamCaptureType : uint8_t { CAPTURE_ALL_TRACKS, CAPTURE_AUDIO };
    107 
    108 enum class StreamCaptureBehavior : uint8_t {
    109  CONTINUE_WHEN_ENDED,
    110  FINISH_WHEN_ENDED
    111 };
    112 
    113 /**
    114 * Possible values of the 'preload' attribute.
    115 */
    116 enum MediaPreloadAttrValue : uint8_t {
    117  PRELOAD_ATTR_NONE,      // set to "none"
    118  PRELOAD_ATTR_METADATA,  // set to "metadata"
    119  PRELOAD_ATTR_AUTO       // set to "auto"
    120 };
    121 
    122 // Mappings from 'preload' attribute strings to an enumeration.
    123 static const nsAttrValue::EnumTableEntry kPreloadTable[] = {
    124    {"none", MediaPreloadAttrValue::PRELOAD_ATTR_NONE},
    125    {"metadata", MediaPreloadAttrValue::PRELOAD_ATTR_METADATA},
    126    {"auto", MediaPreloadAttrValue::PRELOAD_ATTR_AUTO},
    127 };
    128 
    129 static constexpr const nsAttrValue::EnumTableEntry* kPreloadDefaultType =
    130    &kPreloadTable[std::size(kPreloadTable) - 1];
    131 
    132 class HTMLMediaElement : public nsGenericHTMLElement,
    133                         public MediaDecoderOwner,
    134                         public PrincipalChangeObserver<MediaStreamTrack>,
    135                         public SupportsWeakPtr,
    136                         public nsStubMutationObserver,
    137                         public TelemetryProbesReporterOwner {
    138 public:
    139  using TimeStamp = mozilla::TimeStamp;
    140  using ImageContainer = mozilla::layers::ImageContainer;
    141  using VideoFrameContainer = mozilla::VideoFrameContainer;
    142  using MediaResource = mozilla::MediaResource;
    143  using MediaDecoderOwner = mozilla::MediaDecoderOwner;
    144  using MetadataTags = mozilla::MetadataTags;
    145 
    146  // Helper struct to keep track of the MediaStreams returned by
    147  // mozCaptureStream(). For each OutputMediaStream, dom::MediaTracks get
    148  // captured into MediaStreamTracks which get added to
    149  // OutputMediaStream::mStream.
    150  struct OutputMediaStream {
    151    OutputMediaStream(RefPtr<DOMMediaStream> aStream, bool aCapturingAudioOnly,
    152                      bool aFinishWhenEnded);
    153    ~OutputMediaStream();
    154 
    155    RefPtr<DOMMediaStream> mStream;
    156    nsTArray<RefPtr<MediaStreamTrack>> mLiveTracks;
    157    const bool mCapturingAudioOnly;
    158    const bool mFinishWhenEnded;
    159    // If mFinishWhenEnded is true, this is the URI of the first resource
    160    // mStream got tracks for.
    161    nsCOMPtr<nsIURI> mFinishWhenEndedLoadingSrc;
    162    // If mFinishWhenEnded is true, this is the first MediaStream mStream got
    163    // tracks for.
    164    RefPtr<DOMMediaStream> mFinishWhenEndedAttrStream;
    165    // If mFinishWhenEnded is true, this is the MediaSource being played.
    166    RefPtr<MediaSource> mFinishWhenEndedMediaSource;
    167  };
    168 
    169  NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
    170 
    171  CORSMode GetCORSMode() { return mCORSMode; }
    172 
    173  explicit HTMLMediaElement(
    174      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
    175  void Init();
    176 
    177  virtual HTMLVideoElement* AsHTMLVideoElement() { return nullptr; };
    178 
    179  // `eMandatory`: `timeupdate` occurs according to the spec requirement.
    180  // Eg.
    181  // https://html.spec.whatwg.org/multipage/media.html#seeking:event-media-timeupdate
    182  // `ePeriodic` : `timeupdate` occurs regularly and should follow the rule
    183  // of not dispatching that event within 250 ms. Eg.
    184  // https://html.spec.whatwg.org/multipage/media.html#offsets-into-the-media-resource:event-media-timeupdate
    185  enum class TimeupdateType : bool {
    186    eMandatory = false,
    187    ePeriodic = true,
    188  };
    189 
    190  // This is used for event runner creation. Currently only timeupdate needs
    191  // that, but it can be used to extend for other events in the future if
    192  // necessary.
    193  enum class EventFlag : uint8_t {
    194    eNone = 0,
    195    eMandatory = 1,
    196  };
    197 
    198  /**
    199   * This is used when the browser is constructing a video element to play
    200   * a channel that we've already started loading. The src attribute and
    201   * <source> children are ignored.
    202   * @param aChannel the channel to use
    203   * @param aListener returns a stream listener that should receive
    204   * notifications for the stream
    205   */
    206  nsresult LoadWithChannel(nsIChannel* aChannel, nsIStreamListener** aListener);
    207 
    208  // nsISupports
    209  NS_DECL_ISUPPORTS_INHERITED
    210  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLMediaElement,
    211                                           nsGenericHTMLElement)
    212  NS_IMPL_FROMNODE_HELPER(HTMLMediaElement,
    213                          IsAnyOfHTMLElements(nsGkAtoms::video,
    214                                              nsGkAtoms::audio))
    215 
    216  NS_DECL_ADDSIZEOFEXCLUDINGTHIS
    217 
    218  // EventTarget
    219  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
    220 
    221  void NodeInfoChanged(Document* aOldDoc) override;
    222 
    223  bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
    224                      const nsAString& aValue,
    225                      nsIPrincipal* aMaybeScriptedPrincipal,
    226                      nsAttrValue& aResult) override;
    227 
    228  nsresult BindToTree(BindContext&, nsINode& aParent) override;
    229  void UnbindFromTree(UnbindContext&) override;
    230  void DoneCreatingElement() override;
    231 
    232  bool IsHTMLFocusable(IsFocusableFlags, bool* aIsFocusable,
    233                       int32_t* aTabIndex) override;
    234  int32_t TabIndexDefault() override;
    235 
    236  // Called by the video decoder object, on the main thread,
    237  // when it has read the metadata containing video dimensions,
    238  // etc.
    239  void MetadataLoaded(const MediaInfo* aInfo,
    240                      UniquePtr<const MetadataTags> aTags) final;
    241 
    242  // Called by the decoder object, on the main thread,
    243  // when it has read the first frame of the video or audio.
    244  void FirstFrameLoaded() final;
    245 
    246  // Called by the video decoder object, on the main thread,
    247  // when the resource has a network error during loading.
    248  void NetworkError(const MediaResult& aError) final;
    249 
    250  // Called by the video decoder object, on the main thread, when the
    251  // resource has a decode error during metadata loading or decoding.
    252  void DecodeError(const MediaResult& aError) final;
    253 
    254  // Called by the decoder object, on the main thread, when the
    255  // resource has a decode issue during metadata loading or decoding, but can
    256  // continue decoding.
    257  void DecodeWarning(const MediaResult& aError) final;
    258 
    259  // Return true if error attribute is not null.
    260  bool HasError() const final;
    261 
    262  // Called by the video decoder object, on the main thread, when the
    263  // resource load has been cancelled.
    264  void LoadAborted() final;
    265 
    266  // Called by the video decoder object, on the main thread,
    267  // when the video playback has ended.
    268  void PlaybackEnded() final;
    269 
    270  // Called by the video decoder object, on the main thread,
    271  // when the resource has started seeking.
    272  void SeekStarted() final;
    273 
    274  // Called by the video decoder object, on the main thread,
    275  // when the resource has completed seeking.
    276  void SeekCompleted() final;
    277 
    278  // Called by the video decoder object, on the main thread,
    279  // when the resource has aborted seeking.
    280  void SeekAborted() final;
    281 
    282  // Called by the media stream, on the main thread, when the download
    283  // has been suspended by the cache or because the element itself
    284  // asked the decoder to suspend the download.
    285  void DownloadSuspended() final;
    286 
    287  // Called by the media stream, on the main thread, when the download
    288  // has been resumed by the cache or because the element itself
    289  // asked the decoder to resumed the download.
    290  void DownloadResumed();
    291 
    292  // Called to indicate the download is progressing.
    293  void DownloadProgressed() final;
    294 
    295  // Called by the media decoder to indicate whether the media cache has
    296  // suspended the channel.
    297  void NotifySuspendedByCache(bool aSuspendedByCache) final;
    298 
    299  // Return true if the media element is actually invisible to users.
    300  bool IsActuallyInvisible() const override;
    301 
    302  // Return true if the element is in the view port.
    303  bool IsInViewPort() const;
    304 
    305  // Called by the media decoder and the video frame to get the
    306  // ImageContainer containing the video data.
    307  VideoFrameContainer* GetVideoFrameContainer() final;
    308  layers::ImageContainer* GetImageContainer();
    309 
    310  /**
    311   * Call this to reevaluate whether we should start/stop due to our owner
    312   * document being active, inactive, visible or hidden.
    313   */
    314  void NotifyOwnerDocumentActivityChanged();
    315 
    316  // Called when the media element enters or leaves the fullscreen.
    317  void NotifyFullScreenChanged();
    318 
    319  bool IsInFullScreen() const;
    320 
    321  // From PrincipalChangeObserver<MediaStreamTrack>.
    322  void PrincipalChanged(MediaStreamTrack* aTrack) override;
    323 
    324  void UpdateSrcStreamVideoPrincipal(const PrincipalHandle& aPrincipalHandle);
    325 
    326  // Called after the MediaStream we're playing rendered a frame to aContainer
    327  // with a different principalHandle than the previous frame.
    328  void PrincipalHandleChangedForVideoFrameContainer(
    329      VideoFrameContainer* aContainer,
    330      const PrincipalHandle& aNewPrincipalHandle) override;
    331 
    332  // Queue a media element task to fire an event targeted at the media element.
    333  void QueueEvent(const nsAString& aName) final;
    334  // Queue a media element task.
    335  // The task is blocked while the document is in B/F cache.
    336  void QueueTask(RefPtr<nsMediaEventRunner> aRunner);
    337 
    338  // Triggers a recomputation of readyState.
    339  void UpdateReadyState() override {
    340    mWatchManager.ManualNotify(&HTMLMediaElement::UpdateReadyStateInternal);
    341  }
    342 
    343  // Dispatch events that were raised while in the bfcache
    344  nsresult DispatchPendingMediaEvents();
    345 
    346  // Return true if we can activate autoplay assuming enough data has arrived.
    347  // https://html.spec.whatwg.org/multipage/media.html#eligible-for-autoplay
    348  bool IsEligibleForAutoplay();
    349 
    350  // Notify that state has changed that might cause an autoplay element to
    351  // start playing.
    352  // If the element is 'autoplay' and is ready to play back (not paused,
    353  // autoplay pref enabled, etc), it should start playing back.
    354  void CheckAutoplayDataReady();
    355 
    356  void RunAutoplay();
    357 
    358  // Start listening for async GV autoplay permission request results.
    359  void StartObservingGVAutoplayIfNeeded();
    360 
    361  // Stops listening for async GV autoplay permissions if observer exists.
    362  void StopObservingGVAutoplayIfNeeded();
    363 
    364  // Check if the media element had crossorigin set when loading started
    365  bool ShouldCheckAllowOrigin();
    366 
    367  // Returns true if the currently loaded resource is CORS same-origin with
    368  // respect to the document.
    369  bool IsCORSSameOrigin();
    370 
    371  // Is the media element potentially playing as defined by the HTML 5
    372  // specification.
    373  // http://www.whatwg.org/specs/web-apps/current-work/#potentially-playing
    374  bool IsPotentiallyPlaying() const;
    375 
    376  // Has playback ended as defined by the HTML 5 specification.
    377  // http://www.whatwg.org/specs/web-apps/current-work/#ended
    378  bool IsPlaybackEnded() const;
    379 
    380  // principal of the currently playing resource. Anything accessing the
    381  // contents of this element must have a principal that subsumes this
    382  // principal. Returns null if nothing is playing.
    383  already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
    384 
    385  // Return true if the loading of this resource required cross-origin
    386  // redirects.
    387  bool HadCrossOriginRedirects();
    388 
    389  bool ShouldResistFingerprinting(RFPTarget aTarget) const override;
    390 
    391  // Principal of the currently playing video resource. Anything accessing the
    392  // image container of this element must have a principal that subsumes this
    393  // principal. If there are no live video tracks but content has been rendered
    394  // to the image container, we return the last video principal we had. Should
    395  // the image container be empty with no live video tracks, we return nullptr.
    396  already_AddRefed<nsIPrincipal> GetCurrentVideoPrincipal();
    397 
    398  // called to notify that the principal of the decoder's media resource has
    399  // changed.
    400  void NotifyDecoderPrincipalChanged() final;
    401 
    402  void GetEMEInfo(dom::EMEDebugInfo& aInfo);
    403 
    404  // Update the visual size of the media. Called from the decoder on the
    405  // main thread when/if the size changes.
    406  virtual void UpdateMediaSize(const nsIntSize& aSize);
    407 
    408  void Invalidate(ImageSizeChanged aImageSizeChanged,
    409                  const Maybe<nsIntSize>& aNewIntrinsicSize,
    410                  ForceInvalidate aForceInvalidate) override;
    411 
    412  // Returns the CanPlayStatus indicating if we can handle the
    413  // full MIME type including the optional codecs parameter.
    414  static CanPlayStatus GetCanPlay(const nsAString& aType,
    415                                  DecoderDoctorDiagnostics* aDiagnostics);
    416 
    417  /**
    418   * Called when a child source element is added to this media element. This
    419   * may queue a task to run the select resource algorithm if appropriate.
    420   */
    421  void NotifyAddedSource();
    422 
    423  /**
    424   * Called when there's been an error fetching the resource. This decides
    425   * whether it's appropriate to fire an error event.
    426   */
    427  void NotifyLoadError(const nsACString& aErrorDetails = nsCString());
    428 
    429  /**
    430   * Called by one of our associated MediaTrackLists (audio/video) when a
    431   * MediaTrack is added.
    432   */
    433  void NotifyMediaTrackAdded(dom::MediaTrack* aTrack);
    434 
    435  /**
    436   * Called by one of our associated MediaTrackLists (audio/video) when a
    437   * MediaTrack is removed.
    438   */
    439  void NotifyMediaTrackRemoved(dom::MediaTrack* aTrack);
    440 
    441  /**
    442   * Called by one of our associated MediaTrackLists (audio/video) when an
    443   * AudioTrack is enabled or a VideoTrack is selected.
    444   */
    445  void NotifyMediaTrackEnabled(dom::MediaTrack* aTrack);
    446 
    447  /**
    448   * Called by one of our associated MediaTrackLists (audio/video) when an
    449   * AudioTrack is disabled or a VideoTrack is unselected.
    450   */
    451  void NotifyMediaTrackDisabled(dom::MediaTrack* aTrack);
    452 
    453  /**
    454   * Returns the current load ID. Asynchronous events store the ID that was
    455   * current when they were enqueued, and if it has changed when they come to
    456   * fire, they consider themselves cancelled, and don't fire.
    457   */
    458  uint32_t GetCurrentLoadID() const { return mCurrentLoadID; }
    459 
    460  /**
    461   * Returns the load group for this media element's owner document.
    462   * XXX XBL2 issue.
    463   */
    464  already_AddRefed<nsILoadGroup> GetDocumentLoadGroup();
    465 
    466  /**
    467   * Returns true if the media has played or completed a seek.
    468   * Used by video frame to determine whether to paint the poster.
    469   */
    470  bool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; }
    471 
    472  nsresult CopyInnerTo(Element* aDest);
    473 
    474  /**
    475   * Sets the Accept header on the HTTP channel to the required
    476   * video or audio MIME types.
    477   */
    478  virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) = 0;
    479 
    480  /**
    481   * Sets the required request headers on the HTTP channel for
    482   * video or audio requests.
    483   */
    484  void SetRequestHeaders(nsIHttpChannel* aChannel);
    485 
    486  /**
    487   * Asynchronously awaits a stable state, whereupon aRunnable runs on the main
    488   * thread. This adds an event which run aRunnable to the appshell's list of
    489   * sections synchronous the next time control returns to the event loop.
    490   */
    491  void RunInStableState(nsIRunnable* aRunnable);
    492 
    493  /**
    494   * Fires a timeupdate event. If aPeriodic is true, the event will only
    495   * be fired if we've not fired a timeupdate event (for any reason) in the
    496   * last 250ms, as required by the spec when the current time is periodically
    497   * increasing during playback.
    498   */
    499  void FireTimeUpdate(TimeupdateType aType);
    500 
    501  void MaybeQueueTimeupdateEvent() final {
    502    FireTimeUpdate(TimeupdateType::ePeriodic);
    503  }
    504 
    505  const TimeStamp& LastTimeupdateDispatchTime() const;
    506  void UpdateLastTimeupdateDispatchTime();
    507 
    508  // WebIDL
    509 
    510  MediaError* GetError() const;
    511 
    512  void GetSrc(nsAString& aSrc) { GetURIAttr(nsGkAtoms::src, nullptr, aSrc); }
    513  void SetSrc(const nsAString& aSrc, ErrorResult& aError) {
    514    SetHTMLAttr(nsGkAtoms::src, aSrc, aError);
    515  }
    516  void SetSrc(const nsAString& aSrc, nsIPrincipal* aTriggeringPrincipal,
    517              ErrorResult& aError) {
    518    SetHTMLAttr(nsGkAtoms::src, aSrc, aTriggeringPrincipal, aError);
    519  }
    520 
    521  void GetCurrentSrc(nsAString& aCurrentSrc);
    522 
    523  void GetCrossOrigin(nsAString& aResult) {
    524    // Null for both missing and invalid defaults is ok, since we
    525    // always parse to an enum value, so we don't need an invalid
    526    // default, and we _want_ the missing default to be null.
    527    GetEnumAttr(nsGkAtoms::crossorigin, nullptr, aResult);
    528  }
    529  void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError) {
    530    SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
    531  }
    532 
    533  uint16_t NetworkState() const { return mNetworkState; }
    534 
    535  void NotifyXPCOMShutdown() final;
    536 
    537  // Called by media decoder when the audible state changed or when input is
    538  // a media stream.
    539  void SetAudibleState(bool aAudible) final;
    540 
    541  // Notify agent when the MediaElement changes its audible state.
    542  void NotifyAudioPlaybackChanged(AudibleChangedReasons aReason);
    543 
    544  void GetPreload(nsAString& aValue) {
    545    if (mSrcAttrStream) {
    546      nsGkAtoms::none->ToString(aValue);
    547      return;
    548    }
    549    GetEnumAttr(nsGkAtoms::preload, kPreloadDefaultType->tag, aValue);
    550  }
    551  void SetPreload(const nsAString& aValue, ErrorResult& aRv) {
    552    if (mSrcAttrStream) {
    553      return;
    554    }
    555    SetHTMLAttr(nsGkAtoms::preload, aValue, aRv);
    556  }
    557 
    558  already_AddRefed<TimeRanges> Buffered() const;
    559 
    560  void Load();
    561 
    562  void CanPlayType(const nsAString& aType, nsAString& aResult);
    563 
    564  uint16_t ReadyState() const { return mReadyState; }
    565 
    566  bool Seeking() const;
    567 
    568  double CurrentTime() const;
    569 
    570  void SetCurrentTime(double aCurrentTime, ErrorResult& aRv);
    571  void SetCurrentTime(double aCurrentTime) {
    572    SetCurrentTime(aCurrentTime, IgnoreErrors());
    573  }
    574 
    575  void FastSeek(double aTime, ErrorResult& aRv);
    576 
    577  already_AddRefed<Promise> SeekToNextFrame(ErrorResult& aRv);
    578 
    579  double Duration() const;
    580 
    581  bool HasAudio() const { return mMediaInfo.HasAudio(); }
    582 
    583  virtual bool IsVideo() const { return false; }
    584 
    585  bool HasVideo() const { return mMediaInfo.HasVideo(); }
    586 
    587  bool IsEncrypted() const override { return mIsEncrypted; }
    588 
    589 #ifdef MOZ_WMF_CDM
    590  bool IsUsingWMFCDM() const override;
    591 
    592  CDMProxy* GetCDMProxy() const override;
    593 #endif
    594 
    595  bool Paused() const { return mPaused; }
    596 
    597  double DefaultPlaybackRate() const {
    598    if (mSrcAttrStream) {
    599      return 1.0;
    600    }
    601    return mDefaultPlaybackRate;
    602  }
    603 
    604  void SetDefaultPlaybackRate(double aDefaultPlaybackRate, ErrorResult& aRv);
    605 
    606  double PlaybackRate() const {
    607    if (mSrcAttrStream) {
    608      return 1.0;
    609    }
    610    return mPlaybackRate;
    611  }
    612 
    613  void SetPlaybackRate(double aPlaybackRate, ErrorResult& aRv);
    614 
    615  already_AddRefed<TimeRanges> Played();
    616 
    617  already_AddRefed<TimeRanges> Seekable() const;
    618 
    619  bool Ended();
    620 
    621  bool Autoplay() const { return GetBoolAttr(nsGkAtoms::autoplay); }
    622 
    623  void SetAutoplay(bool aValue, ErrorResult& aRv) {
    624    SetHTMLBoolAttr(nsGkAtoms::autoplay, aValue, aRv);
    625  }
    626 
    627  bool Loop() const { return GetBoolAttr(nsGkAtoms::loop); }
    628 
    629  void SetLoop(bool aValue, ErrorResult& aRv) {
    630    SetHTMLBoolAttr(nsGkAtoms::loop, aValue, aRv);
    631  }
    632 
    633  already_AddRefed<Promise> Play(ErrorResult& aRv);
    634  void Play() {
    635    IgnoredErrorResult dummy;
    636    RefPtr<Promise> toBeIgnored = Play(dummy);
    637  }
    638 
    639  void Pause(ErrorResult& aRv);
    640  void Pause() { Pause(IgnoreErrors()); }
    641 
    642  bool Controls() const { return GetBoolAttr(nsGkAtoms::controls); }
    643 
    644  void SetControls(bool aValue, ErrorResult& aRv) {
    645    SetHTMLBoolAttr(nsGkAtoms::controls, aValue, aRv);
    646  }
    647 
    648  double Volume() const { return mVolume; }
    649 
    650  void SetVolume(double aVolume, ErrorResult& aRv);
    651 
    652  bool Muted() const { return mMuted & MUTED_BY_CONTENT; }
    653  void SetMuted(bool aMuted);
    654 
    655  bool DefaultMuted() const { return GetBoolAttr(nsGkAtoms::muted); }
    656 
    657  void SetDefaultMuted(bool aMuted, ErrorResult& aRv) {
    658    SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv);
    659  }
    660 
    661  bool MozAllowCasting() const { return mAllowCasting; }
    662 
    663  void SetMozAllowCasting(bool aShow) { mAllowCasting = aShow; }
    664 
    665  bool MozIsCasting() const { return mIsCasting; }
    666 
    667  void SetMozIsCasting(bool aShow) { mIsCasting = aShow; }
    668 
    669  // Returns whether a call to Play() would be rejected with NotAllowedError.
    670  // This assumes "worst case" for unknowns. So if prompting for permission is
    671  // enabled and no permission is stored, this behaves as if the user would
    672  // opt to block.
    673  bool AllowedToPlay() const;
    674 
    675  already_AddRefed<MediaSource> GetMozMediaSourceObject() const;
    676 
    677  // Returns a promise which will be resolved after collecting debugging
    678  // data from decoder/reader/MDSM. Used for debugging purposes.
    679  already_AddRefed<Promise> MozRequestDebugInfo(ErrorResult& aRv);
    680 
    681  // Enables DecoderDoctorLogger logging. Used for debugging purposes.
    682  static void MozEnableDebugLog(const GlobalObject&);
    683 
    684  // Returns a promise which will be resolved after collecting debugging
    685  // log associated with this element. Used for debugging purposes.
    686  already_AddRefed<Promise> MozRequestDebugLog(ErrorResult& aRv);
    687 
    688  // For use by mochitests. Enabling pref "media.test.video-suspend"
    689  void SetVisible(bool aVisible);
    690 
    691  // For use by mochitests. Enabling pref "media.test.video-suspend"
    692  bool HasSuspendTaint() const;
    693 
    694  // For use by mochitests.
    695  bool IsVideoDecodingSuspended() const;
    696 
    697  // These functions return accumulated time, which are used for the telemetry
    698  // usage. Return -1 for error.
    699  double TotalVideoPlayTime() const;
    700  double TotalVideoHDRPlayTime() const;
    701  double VisiblePlayTime() const;
    702  double InvisiblePlayTime() const;
    703  double TotalAudioPlayTime() const;
    704  double AudiblePlayTime() const;
    705  double InaudiblePlayTime() const;
    706  double MutedPlayTime() const;
    707 
    708  // Test methods for decoder doctor.
    709  void SetFormatDiagnosticsReportForMimeType(const nsAString& aMimeType,
    710                                             DecoderDoctorReportType aType);
    711  void SetDecodeError(const nsAString& aError, ErrorResult& aRv);
    712  void SetAudioSinkFailedStartup();
    713 
    714  // Synchronously, return the next video frame and mark the element unable to
    715  // participate in decode suspending.
    716  //
    717  // This function is synchronous for cases where decoding has been suspended
    718  // and JS needs a frame to use in, eg., nsLayoutUtils::SurfaceFromElement()
    719  // via drawImage().
    720  already_AddRefed<layers::Image> GetCurrentImage();
    721 
    722  already_AddRefed<DOMMediaStream> GetSrcObject() const;
    723  void SetSrcObject(DOMMediaStream& aValue);
    724  void SetSrcObject(DOMMediaStream* aValue);
    725 
    726  bool PreservesPitch() const { return mPreservesPitch; }
    727  void SetPreservesPitch(bool aPreservesPitch);
    728 
    729  MediaKeys* GetMediaKeys() const;
    730 
    731  already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
    732                                         ErrorResult& aRv);
    733 
    734  mozilla::dom::EventHandlerNonNull* GetOnencrypted();
    735  void SetOnencrypted(mozilla::dom::EventHandlerNonNull* aCallback);
    736 
    737  mozilla::dom::EventHandlerNonNull* GetOnwaitingforkey();
    738  void SetOnwaitingforkey(mozilla::dom::EventHandlerNonNull* aCallback);
    739 
    740  void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
    741                         const nsAString& aInitDataType) override;
    742 
    743  bool IsEventAttributeNameInternal(nsAtom* aName) override;
    744 
    745  bool ContainsRestrictedContent() const;
    746 
    747  void NotifyWaitingForKey() override;
    748 
    749  already_AddRefed<DOMMediaStream> CaptureAudio(ErrorResult& aRv,
    750                                                MediaTrackGraph* aGraph);
    751 
    752  already_AddRefed<DOMMediaStream> MozCaptureStream(ErrorResult& aRv);
    753 
    754  already_AddRefed<DOMMediaStream> MozCaptureStreamUntilEnded(ErrorResult& aRv);
    755 
    756  bool MozAudioCaptured() const { return mAudioCaptured; }
    757 
    758  void MozGetMetadata(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
    759                      ErrorResult& aRv);
    760 
    761  double MozFragmentEnd();
    762 
    763  AudioTrackList* AudioTracks();
    764 
    765  VideoTrackList* VideoTracks();
    766 
    767  TextTrackList* GetTextTracks();
    768 
    769  already_AddRefed<TextTrack> AddTextTrack(TextTrackKind aKind,
    770                                           const nsAString& aLabel,
    771                                           const nsAString& aLanguage);
    772 
    773  void AddTextTrack(TextTrack* aTextTrack) {
    774    GetOrCreateTextTrackManager()->AddTextTrack(aTextTrack);
    775  }
    776 
    777  void RemoveTextTrack(TextTrack* aTextTrack, bool aPendingListOnly = false) {
    778    if (mTextTrackManager) {
    779      mTextTrackManager->RemoveTextTrack(aTextTrack, aPendingListOnly);
    780    }
    781  }
    782 
    783  void NotifyCueAdded(TextTrackCue& aCue) {
    784    if (mTextTrackManager) {
    785      mTextTrackManager->NotifyCueAdded(aCue);
    786    }
    787  }
    788  void NotifyCueRemoved(TextTrackCue& aCue) {
    789    if (mTextTrackManager) {
    790      mTextTrackManager->NotifyCueRemoved(aCue);
    791    }
    792  }
    793  void NotifyCueUpdated(TextTrackCue* aCue) {
    794    if (mTextTrackManager) {
    795      mTextTrackManager->NotifyCueUpdated(aCue);
    796    }
    797  }
    798 
    799  void NotifyCueDisplayStatesChanged();
    800 
    801  bool IsBlessed() const { return mIsBlessed; }
    802 
    803  // A method to check whether we are currently playing.
    804  bool IsCurrentlyPlaying() const;
    805 
    806  // Returns true if the media element is being destroyed. Used in
    807  // dormancy checks to prevent dormant processing for an element
    808  // that will soon be gone.
    809  bool IsBeingDestroyed();
    810 
    811  virtual void OnVisibilityChange(Visibility aNewVisibility);
    812 
    813  // Begin testing only methods
    814  float ComputedVolume() const;
    815  bool ComputedMuted() const;
    816 
    817  // Return true if the media has been suspended media due to an inactive
    818  // document or prohibiting by the docshell.
    819  bool IsSuspendedByInactiveDocOrDocShell() const;
    820  // End testing only methods
    821 
    822  void SetMediaInfo(const MediaInfo& aInfo);
    823  MediaInfo GetMediaInfo() const override;
    824 
    825  // Gives access to the decoder's frame statistics, if present.
    826  FrameStatistics* GetFrameStatistics() const override;
    827 
    828  void DispatchAsyncTestingEvent(const nsAString& aName) override;
    829 
    830  // Log the usage of a {visible / invisible} video element as
    831  // the source of {drawImage(), createPattern(), createImageBitmap() and
    832  // captureStream()} APIs. This function can be used to collect telemetries for
    833  // bug 1352007.
    834  enum class CallerAPI {
    835    DRAW_IMAGE,
    836    CREATE_PATTERN,
    837    CREATE_IMAGEBITMAP,
    838    CAPTURE_STREAM,
    839    CREATE_VIDEOFRAME,
    840  };
    841  void LogVisibility(CallerAPI aAPI);
    842 
    843  Document* GetDocument() const override;
    844 
    845  already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() override;
    846 
    847  // Set the sink id (of the output device) that the audio will play. If aSinkId
    848  // is empty the default device will be set.
    849  already_AddRefed<Promise> SetSinkId(const nsAString& aSinkId,
    850                                      ErrorResult& aRv);
    851  // Get the sink id of the device that audio is being played. Initial value is
    852  // empty and the default device is being used.
    853  void GetSinkId(nsString& aSinkId) const {
    854    MOZ_ASSERT(NS_IsMainThread());
    855    aSinkId = mSink.first;
    856  }
    857 
    858  // This is used to notify MediaElementAudioSourceNode that media element is
    859  // allowed to play when media element is used as a source for web audio, so
    860  // that we can start AudioContext if it was not allowed to start.
    861  RefPtr<GenericNonExclusivePromise> GetAllowedToPlayPromise();
    862 
    863  bool GetShowPosterFlag() const { return mShowPoster; }
    864 
    865  bool IsAudible() const;
    866 
    867  // Return key system in use if we have one, otherwise return nothing.
    868  Maybe<nsAutoString> GetKeySystem() const override;
    869 
    870 protected:
    871  virtual ~HTMLMediaElement();
    872 
    873  class AudioChannelAgentCallback;
    874  class ChannelLoader;
    875  class ErrorSink;
    876  class GVAutoplayObserver;
    877  class MediaElementTrackSource;
    878  class MediaLoadListener;
    879  class MediaStreamRenderer;
    880  class MediaStreamTrackListener;
    881  class ShutdownObserver;
    882  class TitleChangeObserver;
    883  class MediaControlKeyListener;
    884 
    885  MediaDecoderOwner::NextFrameStatus NextFrameStatus();
    886 
    887  void SetDecoder(MediaDecoder* aDecoder);
    888 
    889  void PlayInternal(bool aHandlingUserInput);
    890 
    891  // See spec, https://html.spec.whatwg.org/#internal-pause-steps
    892  void PauseInternal();
    893 
    894  /** Use this method to change the mReadyState member, so required
    895   * events can be fired.
    896   */
    897  void ChangeReadyState(nsMediaReadyState aState);
    898 
    899  /**
    900   * Use this method to change the mNetworkState member, so required
    901   * actions will be taken during the transition.
    902   */
    903  void ChangeNetworkState(nsMediaNetworkState aState);
    904 
    905  /**
    906   * The MediaElement will be responsible for creating and releasing the audio
    907   * wakelock depending on the playing and audible state.
    908   */
    909  virtual void WakeLockRelease();
    910  virtual void UpdateWakeLock();
    911 
    912  void CreateAudioWakeLockIfNeeded();
    913  void ReleaseAudioWakeLockIfExists();
    914  void ReleaseAudioWakeLockInternal();
    915  RefPtr<WakeLock> mWakeLock;
    916 
    917  /**
    918   * Logs a warning message to the web console to report various failures.
    919   * aMsg is the localized message identifier, aParams is the parameters to
    920   * be substituted into the localized message, and aParamCount is the number
    921   * of parameters in aParams.
    922   */
    923  void ReportLoadError(const char* aMsg, const nsTArray<nsString>& aParams =
    924                                             nsTArray<nsString>());
    925 
    926  /**
    927   * Log message to web console.
    928   */
    929  void ReportToConsole(
    930      uint32_t aErrorFlags, const char* aMsg,
    931      const nsTArray<nsString>& aParams = nsTArray<nsString>()) const;
    932 
    933  /**
    934   * Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes
    935   * we'll force a reflow so that the video frame gets reflowed to reflect
    936   * the poster hiding or showing immediately.
    937   */
    938  void SetPlayedOrSeeked(bool aValue);
    939 
    940  /**
    941   * Initialize the media element for playback of aStream
    942   */
    943  void SetupSrcMediaStreamPlayback(DOMMediaStream* aStream);
    944  /**
    945   * Stop playback on mSrcStream.
    946   */
    947  void EndSrcMediaStreamPlayback();
    948  /**
    949   * Ensure we're playing mSrcStream if and only if we're not paused.
    950   */
    951  enum { REMOVING_SRC_STREAM = 0x1 };
    952  void UpdateSrcMediaStreamPlaying(uint32_t aFlags = 0);
    953 
    954  /**
    955   * Ensure currentTime progresses if and only if we're potentially playing
    956   * mSrcStream. Called by the watch manager while we're playing mSrcStream, and
    957   * one of the inputs to the potentially playing algorithm changes.
    958   */
    959  void UpdateSrcStreamPotentiallyPlaying();
    960 
    961  /**
    962   * mSrcStream's graph's CurrentTime() has been updated. It might be time to
    963   * fire "timeupdate".
    964   */
    965  void UpdateSrcStreamTime();
    966 
    967  /**
    968   * Called after a tail dispatch when playback of mSrcStream ended, to comply
    969   * with the spec where we must start reporting true for the ended attribute
    970   * after the event loop returns to step 1. A MediaStream could otherwise be
    971   * manipulated to end a HTMLMediaElement synchronously.
    972   */
    973  void UpdateSrcStreamReportPlaybackEnded();
    974 
    975  /**
    976   * Called by our DOMMediaStream::TrackListener when a new MediaStreamTrack has
    977   * been added to the playback stream of |mSrcStream|.
    978   */
    979  void NotifyMediaStreamTrackAdded(const RefPtr<MediaStreamTrack>& aTrack);
    980 
    981  /**
    982   * Called by our DOMMediaStream::TrackListener when a MediaStreamTrack in
    983   * |mSrcStream|'s playback stream has ended.
    984   */
    985  void NotifyMediaStreamTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack);
    986 
    987  /**
    988   * Convenience method to get in a single list all enabled AudioTracks and, if
    989   * this is a video element, the selected VideoTrack.
    990   */
    991  void GetAllEnabledMediaTracks(nsTArray<RefPtr<MediaTrack>>& aTracks);
    992 
    993  /**
    994   * Enables or disables all tracks forwarded from mSrcStream to all
    995   * OutputMediaStreams. We do this for muting the tracks when pausing,
    996   * and unmuting when playing the media element again.
    997   */
    998  void SetCapturedOutputStreamsEnabled(bool aEnabled);
    999 
   1000  /**
   1001   * Returns true if output tracks should be muted, based on the state of this
   1002   * media element.
   1003   */
   1004  enum class OutputMuteState { Muted, Unmuted };
   1005  OutputMuteState OutputTracksMuted();
   1006 
   1007  /**
   1008   * Sets the muted state of all output track sources. They are muted when we're
   1009   * paused and unmuted otherwise.
   1010   */
   1011  void UpdateOutputTracksMuting();
   1012 
   1013  /**
   1014   * Create a new MediaStreamTrack for the TrackSource corresponding to aTrack
   1015   * and add it to the DOMMediaStream in aOutputStream. This automatically sets
   1016   * the output track to enabled or disabled depending on our current playing
   1017   * state.
   1018   */
   1019  enum class AddTrackMode { ASYNC, SYNC };
   1020  void AddOutputTrackSourceToOutputStream(
   1021      MediaElementTrackSource* aSource, OutputMediaStream& aOutputStream,
   1022      AddTrackMode aMode = AddTrackMode::ASYNC);
   1023 
   1024  /**
   1025   * Creates output track sources when this media element is captured, tracks
   1026   * exist, playback is not ended and readyState is >= HAVE_METADATA.
   1027   */
   1028  void UpdateOutputTrackSources();
   1029 
   1030  /**
   1031   * Returns an DOMMediaStream containing the played contents of this
   1032   * element. When aBehavior is FINISH_WHEN_ENDED, when this element ends
   1033   * playback we will finish the stream and not play any more into it.  When
   1034   * aType is CONTINUE_WHEN_ENDED, ending playback does not finish the stream.
   1035   * The stream will never finish.
   1036   *
   1037   * When aType is CAPTURE_AUDIO, we stop playout of audio and instead route it
   1038   * to the DOMMediaStream. Volume and mute state will be applied to the audio
   1039   * reaching the stream. No video tracks will be captured in this case.
   1040   *
   1041   * aGraph may be null if the stream's tracks do not need to use a
   1042   * specific graph.
   1043   */
   1044  already_AddRefed<DOMMediaStream> CaptureStreamInternal(
   1045      StreamCaptureBehavior aFinishBehavior,
   1046      StreamCaptureType aStreamCaptureType, MediaTrackGraph* aGraph);
   1047 
   1048  /**
   1049   * Initialize a decoder as a clone of an existing decoder in another
   1050   * element.
   1051   * mLoadingSrc must already be set.
   1052   */
   1053  nsresult InitializeDecoderAsClone(ChannelMediaDecoder* aOriginal);
   1054 
   1055  /**
   1056   * Call Load() and FinishDecoderSetup() on the decoder. It also handle
   1057   * resource cloning if DecoderType is ChannelMediaDecoder.
   1058   */
   1059  template <typename DecoderType, typename... LoadArgs>
   1060  nsresult SetupDecoder(DecoderType* aDecoder, LoadArgs&&... aArgs);
   1061 
   1062  /**
   1063   * Initialize a decoder to load the given channel. The decoder's stream
   1064   * listener is returned via aListener.
   1065   * mLoadingSrc must already be set.
   1066   */
   1067  nsresult InitializeDecoderForChannel(nsIChannel* aChannel,
   1068                                       nsIStreamListener** aListener);
   1069 
   1070  /**
   1071   * Finish setting up the decoder after Load() has been called on it.
   1072   * Called by InitializeDecoderForChannel/InitializeDecoderAsClone.
   1073   */
   1074  nsresult FinishDecoderSetup(MediaDecoder* aDecoder);
   1075 
   1076  /**
   1077   * Call this after setting up mLoadingSrc and mDecoder.
   1078   */
   1079  void AddMediaElementToURITable();
   1080  /**
   1081   * Call this before modifying mLoadingSrc.
   1082   */
   1083  void RemoveMediaElementFromURITable();
   1084  /**
   1085   * Call this to find a media element with the same NodePrincipal and
   1086   * mLoadingSrc set to aURI, and with a decoder on which Load() has been
   1087   * called.
   1088   */
   1089  HTMLMediaElement* LookupMediaElementURITable(nsIURI* aURI);
   1090 
   1091  /**
   1092   * Shutdown and clear mDecoder and maintain associated invariants.
   1093   */
   1094  void ShutdownDecoder();
   1095  /**
   1096   * Execute the initial steps of the load algorithm that ensure existing
   1097   * loads are aborted, the element is emptied, and a new load ID is
   1098   * created.
   1099   */
   1100  void AbortExistingLoads();
   1101 
   1102  /**
   1103   * This is the dedicated media source failure steps.
   1104   * Called when all potential resources are exhausted. Changes network
   1105   * state to NETWORK_NO_SOURCE, and sends error event with code
   1106   * MEDIA_ERR_SRC_NOT_SUPPORTED.
   1107   */
   1108  void NoSupportedMediaSourceError(const nsACString& aErrorDetails);
   1109 
   1110  /**
   1111   * Per spec, Failed with elements: Queue a task, using the DOM manipulation
   1112   * task source, to fire a simple event named error at the candidate element.
   1113   * So dispatch |QueueLoadFromSourceTask| to main thread to make sure the task
   1114   * will be executed later than loadstart event.
   1115   */
   1116  void DealWithFailedElement(nsIContent* aSourceElement);
   1117 
   1118  /**
   1119   * Attempts to load resources from the <source> children. This is a
   1120   * substep of the resource selection algorithm. Do not call this directly,
   1121   * call QueueLoadFromSourceTask() instead.
   1122   */
   1123  void LoadFromSourceChildren(const JSCallingLocation& aCallingLocation);
   1124 
   1125  /**
   1126   * Asynchronously awaits a stable state, and then causes
   1127   * LoadFromSourceChildren() to be called on the main threads' event loop.
   1128   */
   1129  void QueueLoadFromSourceTask();
   1130 
   1131  /**
   1132   * Runs the media resource selection algorithm.
   1133   */
   1134  void SelectResource(const JSCallingLocation& aCallingLocation);
   1135 
   1136  /**
   1137   * A wrapper function that allows us to cleanly reset flags after a call
   1138   * to SelectResource()
   1139   */
   1140  void SelectResourceWrapper(const JSCallingLocation& aCallingLocation);
   1141 
   1142  /**
   1143   * Asynchronously awaits a stable state, and then causes SelectResource()
   1144   * to be run on the main thread's event loop.
   1145   */
   1146  void QueueSelectResourceTask();
   1147 
   1148  /**
   1149   * When loading a new source on an existing media element, make sure to reset
   1150   * everything that is accessible using the media element API.
   1151   */
   1152  virtual void ResetState();
   1153 
   1154  /**
   1155   * The resource-fetch algorithm step of the load algorithm.
   1156   */
   1157  MediaResult LoadResource(const JSCallingLocation& aCallingLocation);
   1158 
   1159  /**
   1160   * Selects the next <source> child from which to load a resource. Called
   1161   * during the resource selection algorithm. Stores the return value in
   1162   * mSourceLoadCandidate before returning.
   1163   */
   1164  HTMLSourceElement* GetNextSource();
   1165 
   1166  /**
   1167   * Changes mDelayingLoadEvent, and will call BlockOnLoad()/UnblockOnLoad()
   1168   * on the owning document, so it can delay the load event firing.
   1169   */
   1170  void ChangeDelayLoadStatus(bool aDelay);
   1171 
   1172  /**
   1173   * If we suspended downloading after the first frame, unsuspend now.
   1174   */
   1175  void StopSuspendingAfterFirstFrame();
   1176 
   1177  /**
   1178   * Called when our channel is redirected to another channel.
   1179   * Updates our mChannel reference to aNewChannel.
   1180   */
   1181  nsresult OnChannelRedirect(nsIChannel* aChannel, nsIChannel* aNewChannel,
   1182                             uint32_t aFlags);
   1183 
   1184  /**
   1185   * Call this to reevaluate whether we should be holding a self-reference.
   1186   */
   1187  void AddRemoveSelfReference();
   1188 
   1189  /**
   1190   * Called when "xpcom-shutdown" event is received.
   1191   */
   1192  void NotifyShutdownEvent();
   1193 
   1194  /**
   1195   * The preloading action to perform. These dictate how we react to the
   1196   * preload attribute. See mPreloadAction.
   1197   */
   1198  enum PreloadAction {
   1199    PRELOAD_UNDEFINED = 0,  // not determined - used only for initialization
   1200    PRELOAD_NONE = 1,       // do not preload
   1201    PRELOAD_METADATA = 2,   // preload only the metadata (and first frame)
   1202    PRELOAD_ENOUGH = 3      // preload enough data to allow uninterrupted
   1203                            // playback
   1204  };
   1205 
   1206  /**
   1207   * The guts of Load(). Load() acts as a wrapper around this which sets
   1208   * mIsDoingExplicitLoad to true so that when script calls 'load()'
   1209   * preload-none will be automatically upgraded to preload-metadata.
   1210   */
   1211  void DoLoad();
   1212 
   1213  /**
   1214   * Suspends the load of mLoadingSrc, so that it can be resumed later
   1215   * by ResumeLoad(). This is called when we have a media with a 'preload'
   1216   * attribute value of 'none', during the resource selection algorithm.
   1217   */
   1218  void SuspendLoad();
   1219 
   1220  /**
   1221   * Resumes a previously suspended load (suspended by SuspendLoad(uri)).
   1222   * Will continue running the resource selection algorithm.
   1223   * Sets mPreloadAction to aAction.
   1224   */
   1225  void ResumeLoad(PreloadAction aAction,
   1226                  const JSCallingLocation& aCallingLocation);
   1227 
   1228  /**
   1229   * Handle a change to the preload attribute. Should be called whenever the
   1230   * value (or presence) of the preload attribute changes. The change in
   1231   * attribute value may cause a change in the mPreloadAction of this
   1232   * element. If there is a change then this method will initiate any
   1233   * behaviour that is necessary to implement the action.
   1234   */
   1235  void UpdatePreloadAction(const JSCallingLocation& aCallingLocation);
   1236 
   1237  /**
   1238   * Fire progress events if needed according to the time and byte constraints
   1239   * outlined in the specification. aHaveNewProgress is true if progress has
   1240   * just been detected.  Otherwise the method is called as a result of the
   1241   * progress timer.
   1242   */
   1243  void CheckProgress(bool aHaveNewProgress);
   1244  static void ProgressTimerCallback(nsITimer* aTimer, void* aClosure);
   1245  /**
   1246   * Start timer to update download progress.
   1247   */
   1248  void StartProgressTimer();
   1249  /**
   1250   * Start sending progress and/or stalled events.
   1251   */
   1252  void StartProgress();
   1253  /**
   1254   * Stop progress information timer and events.
   1255   */
   1256  void StopProgress();
   1257 
   1258  /**
   1259   * Dispatches an error event to a child source element.
   1260   */
   1261  void DispatchAsyncSourceError(nsIContent* aSourceElement,
   1262                                const nsACString& aErrorDetails);
   1263 
   1264  /**
   1265   * Resets the media element for an error condition as per aErrorCode.
   1266   * aErrorCode must be one of WebIDL HTMLMediaElement error codes.
   1267   */
   1268  void Error(uint16_t aErrorCode,
   1269             const Maybe<MediaResult>& aResult = Nothing());
   1270 
   1271  /**
   1272   * Returns the URL spec of the currentSrc.
   1273   **/
   1274  void GetCurrentSpec(nsCString& aString);
   1275 
   1276  /**
   1277   * Process any media fragment entries in the URI
   1278   */
   1279  void ProcessMediaFragmentURI();
   1280 
   1281  /**
   1282   * Mute or unmute the audio and change the value that the |muted| map.
   1283   */
   1284  void SetMutedInternal(uint32_t aMuted);
   1285  /**
   1286   * Update the volume of the output audio stream to match the element's
   1287   * current mMuted/mVolume/mAudioChannelFaded state.
   1288   */
   1289  void SetVolumeInternal();
   1290 
   1291  /**
   1292   * Suspend or resume element playback and resource download.  When we suspend
   1293   * playback, event delivery would also be suspended (and events queued) until
   1294   * the element is resumed.
   1295   */
   1296  void SuspendOrResumeElement(bool aSuspendElement);
   1297 
   1298  // Get the HTMLMediaElement object if the decoder is being used from an
   1299  // HTML media element, and null otherwise.
   1300  HTMLMediaElement* GetMediaElement() final { return this; }
   1301 
   1302  // Return true if decoding should be paused
   1303  bool GetPaused() final { return Paused(); }
   1304 
   1305  // Seeks to aTime seconds. aSeekType can be Exact to seek to exactly the
   1306  // seek target, or PrevSyncPoint if a quicker but less precise seek is
   1307  // desired, and we'll seek to the sync point (keyframe and/or start of the
   1308  // next block of audio samples) preceeding seek target.
   1309  void Seek(double aTime, SeekTarget::Type aSeekType, ErrorResult& aRv);
   1310 
   1311  // Update the audio channel playing state
   1312  void UpdateAudioChannelPlayingState();
   1313 
   1314  // Adds to the element's list of pending text tracks each text track
   1315  // in the element's list of text tracks whose text track mode is not disabled
   1316  // and whose text track readiness state is loading.
   1317  void PopulatePendingTextTrackList();
   1318 
   1319  // Gets a reference to the MediaElement's TextTrackManager. If the
   1320  // MediaElement doesn't yet have one then it will create it.
   1321  TextTrackManager* GetOrCreateTextTrackManager();
   1322 
   1323  // Recomputes ready state and fires events as necessary based on current
   1324  // state.
   1325  void UpdateReadyStateInternal();
   1326 
   1327  // Create or destroy the captured stream.
   1328  void AudioCaptureTrackChange(bool aCapture);
   1329 
   1330  // If the network state is empty and then we would trigger DoLoad().
   1331  void MaybeDoLoad();
   1332 
   1333  // Anything we need to check after played success and not related with spec.
   1334  void UpdateCustomPolicyAfterPlayed();
   1335 
   1336  // Returns a StreamCaptureType populated with the right bits, depending on the
   1337  // tracks this HTMLMediaElement has.
   1338  StreamCaptureType CaptureTypeForElement();
   1339 
   1340  // True if this element can be captured, false otherwise.
   1341  bool CanBeCaptured(StreamCaptureType aCaptureType);
   1342 
   1343  using nsGenericHTMLElement::DispatchEvent;
   1344  // For nsAsyncEventRunner.
   1345  // The event is blocked while the document is in B/F cache.
   1346  MOZ_CAN_RUN_SCRIPT nsresult FireEvent(const nsAString& aName);
   1347 
   1348  already_AddRefed<nsMediaEventRunner> GetEventRunner(
   1349      const nsAString& aName, EventFlag aFlag = EventFlag::eNone);
   1350 
   1351  // This method moves the mPendingPlayPromises into a temperate object. So the
   1352  // mPendingPlayPromises is cleared after this method call.
   1353  nsTArray<RefPtr<PlayPromise>> TakePendingPlayPromises();
   1354 
   1355  // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
   1356  // and queues a task to resolve them.
   1357  void AsyncResolvePendingPlayPromises();
   1358 
   1359  // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
   1360  // and queues a task to reject them.
   1361  void AsyncRejectPendingPlayPromises(nsresult aError);
   1362 
   1363  // This method snapshots the mPendingPlayPromises by TakePendingPlayPromises()
   1364  // and queues a task to resolve them also to dispatch a "playing" event.
   1365  void NotifyAboutPlaying();
   1366 
   1367  already_AddRefed<Promise> CreateDOMPromise(ErrorResult& aRv) const;
   1368 
   1369  // Pass information for deciding the video decode mode to decoder.
   1370  void NotifyDecoderActivityChanges() const;
   1371 
   1372  // Constructs an AudioTrack in mAudioTrackList if aInfo reports that audio is
   1373  // available, and a VideoTrack in mVideoTrackList if aInfo reports that video
   1374  // is available.
   1375  void ConstructMediaTracks(const MediaInfo* aInfo);
   1376 
   1377  // Removes all MediaTracks from mAudioTrackList and mVideoTrackList and fires
   1378  // "removetrack" on the lists accordingly.
   1379  // Note that by spec, this should not fire "removetrack". However, it appears
   1380  // other user agents do, per
   1381  // https://wpt.fyi/results/media-source/mediasource-avtracks.html.
   1382  void RemoveMediaTracks();
   1383 
   1384  // Mark the decoder owned by the element as tainted so that the
   1385  // suspend-video-decoder is disabled.
   1386  void MarkAsTainted();
   1387 
   1388  virtual void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
   1389                            const nsAttrValue* aValue,
   1390                            const nsAttrValue* aOldValue,
   1391                            nsIPrincipal* aMaybeScriptedPrincipal,
   1392                            bool aNotify) override;
   1393  virtual void OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName,
   1394                                      const nsAttrValueOrString& aValue,
   1395                                      bool aNotify) override;
   1396 
   1397  bool DetachExistingMediaKeys();
   1398  bool TryRemoveMediaKeysAssociation();
   1399  void RemoveMediaKeys();
   1400  bool AttachNewMediaKeys();
   1401  bool TryMakeAssociationWithCDM(CDMProxy* aProxy);
   1402  void MakeAssociationWithCDMResolved();
   1403  void SetCDMProxyFailure(const MediaResult& aResult);
   1404  void ResetSetMediaKeysTempVariables();
   1405 
   1406  void PauseIfShouldNotBePlaying();
   1407 
   1408  WatchManager<HTMLMediaElement> mWatchManager;
   1409 
   1410  // When the play is not allowed, dispatch related events which are used for
   1411  // testing or changing control UI.
   1412  void DispatchEventsWhenPlayWasNotAllowed();
   1413 
   1414  // When the doc is blocked permanantly, we would dispatch event to notify
   1415  // front-end side to show blocking icon.
   1416  void MaybeNotifyAutoplayBlocked();
   1417 
   1418  // Dispatch event for video control when video gets blocked in order to show
   1419  // the click-to-play icon.
   1420  void DispatchBlockEventForVideoControl();
   1421 
   1422  // When playing state change, we have to notify MediaControl in the chrome
   1423  // process in order to keep its playing state correct.
   1424  void NotifyMediaControlPlaybackStateChanged();
   1425 
   1426  // Clear the timer when we want to continue listening to the media control
   1427  // key events.
   1428  void ClearStopMediaControlTimerIfNeeded();
   1429 
   1430  // Sets a secondary renderer for mSrcStream, so this media element can be
   1431  // rendered in Picture-in-Picture mode when playing a MediaStream. A null
   1432  // aContainer will unset the secondary renderer. aFirstFrameOutput allows
   1433  // for injecting a listener of the callers choice for rendering the first
   1434  // frame.
   1435  void SetSecondaryMediaStreamRenderer(
   1436      VideoFrameContainer* aContainer,
   1437      FirstFrameVideoOutput* aFirstFrameOutput = nullptr);
   1438 
   1439  // This function is used to update the status of media control when the media
   1440  // changes its status of being used in the Picture-in-Picture mode.
   1441  void UpdateMediaControlAfterPictureInPictureModeChanged();
   1442 
   1443  // Return true if the element has pending callbacks that should prevent the
   1444  // suspension of video playback.
   1445  virtual bool HasPendingCallbacks() const { return false; }
   1446 
   1447  // The current decoder. Load() has been called on this decoder.
   1448  // At most one of mDecoder and mSrcStream can be non-null.
   1449  RefPtr<MediaDecoder> mDecoder;
   1450 
   1451  // A reference to the VideoFrameContainer which contains the current frame
   1452  // of video to display.
   1453  RefPtr<VideoFrameContainer> mVideoFrameContainer;
   1454 
   1455  // Holds a reference to the MediaStream that has been set in the src
   1456  // attribute.
   1457  RefPtr<DOMMediaStream> mSrcAttrStream;
   1458 
   1459  // Holds the triggering principal for the src attribute.
   1460  nsCOMPtr<nsIPrincipal> mSrcAttrTriggeringPrincipal;
   1461 
   1462  // Holds a reference to the MediaStream that we're actually playing.
   1463  // At most one of mDecoder and mSrcStream can be non-null.
   1464  RefPtr<DOMMediaStream> mSrcStream;
   1465 
   1466  // The MediaStreamRenderer handles rendering of our selected video track, and
   1467  // enabled audio tracks, while mSrcStream is set.
   1468  RefPtr<MediaStreamRenderer> mMediaStreamRenderer;
   1469 
   1470  // The secondary MediaStreamRenderer handles rendering of our selected video
   1471  // track to a secondary VideoFrameContainer, while mSrcStream is set.
   1472  RefPtr<MediaStreamRenderer> mSecondaryMediaStreamRenderer;
   1473 
   1474  // True once PlaybackEnded() is called and we're playing a MediaStream.
   1475  // Reset to false if we start playing mSrcStream again.
   1476  Watchable<bool> mSrcStreamPlaybackEnded = {
   1477      false, "HTMLMediaElement::mSrcStreamPlaybackEnded"};
   1478 
   1479  // Mirrors mSrcStreamPlaybackEnded after a tail dispatch when set to true,
   1480  // but may be be forced to false directly. To accomodate when an application
   1481  // ends playback synchronously by manipulating mSrcStream or its tracks,
   1482  // e.g., through MediaStream.removeTrack(), or MediaStreamTrack.stop().
   1483  bool mSrcStreamReportPlaybackEnded = false;
   1484 
   1485  // Holds a reference to the stream connecting this stream to the window
   1486  // capture sink.
   1487  RefPtr<MediaStreamWindowCapturer> mStreamWindowCapturer;
   1488 
   1489  // Holds references to the DOM wrappers for the MediaStreams that we're
   1490  // writing to.
   1491  nsTArray<OutputMediaStream> mOutputStreams;
   1492 
   1493  // Mapping for output tracks, from dom::MediaTrack ids to the
   1494  // MediaElementTrackSource that represents the source of all corresponding
   1495  // MediaStreamTracks captured from this element.
   1496  nsRefPtrHashtable<nsStringHashKey, MediaElementTrackSource>
   1497      mOutputTrackSources;
   1498 
   1499  // The currently selected video stream track.
   1500  RefPtr<VideoStreamTrack> mSelectedVideoStreamTrack;
   1501 
   1502  // Created in Init() and AfterSetAttr(), released in deconstructor
   1503  RefPtr<GVAutoplayObserver> mGVAutoplayObserver;
   1504 
   1505  const RefPtr<ShutdownObserver> mShutdownObserver;
   1506 
   1507  const RefPtr<TitleChangeObserver> mTitleChangeObserver;
   1508 
   1509  // Holds a reference to the MediaSource, if any, referenced by the src
   1510  // attribute on the media element.
   1511  RefPtr<MediaSource> mSrcMediaSource;
   1512 
   1513  // Holds a reference to the MediaSource supplying data for playback.  This
   1514  // may either match mSrcMediaSource or come from Source element children.
   1515  // This is set when and only when mLoadingSrc corresponds to an object url
   1516  // that resolved to a MediaSource.
   1517  RefPtr<MediaSource> mMediaSource;
   1518 
   1519  RefPtr<ChannelLoader> mChannelLoader;
   1520 
   1521  // Points to the child source elements, used to iterate through the children
   1522  // when selecting a resource to load.  This is the previous sibling of the
   1523  // child considered the current 'candidate' in:
   1524  // https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm
   1525  //
   1526  // mSourcePointer == nullptr, we will next try to load |GetFirstChild()|.
   1527  // mSourcePointer == GetLastChild(), we've exhausted all sources, waiting
   1528  // for new elements to be appended.
   1529  nsCOMPtr<nsIContent> mSourcePointer;
   1530 
   1531  // Points to the document whose load we're blocking. This is the document
   1532  // we're bound to when loading starts.
   1533  nsCOMPtr<Document> mLoadBlockedDoc;
   1534 
   1535  // This is used to help us block/resume the event delivery.
   1536  class EventBlocker;
   1537  RefPtr<EventBlocker> mEventBlocker;
   1538 
   1539  // Media loading flags. See:
   1540  //   http://www.whatwg.org/specs/web-apps/current-work/#video)
   1541  nsMediaNetworkState mNetworkState = HTMLMediaElement_Binding::NETWORK_EMPTY;
   1542  Watchable<nsMediaReadyState> mReadyState = {
   1543      HTMLMediaElement_Binding::HAVE_NOTHING, "HTMLMediaElement::mReadyState"};
   1544 
   1545  enum LoadAlgorithmState {
   1546    // No load algorithm instance is waiting for a source to be added to the
   1547    // media in order to continue loading.
   1548    NOT_WAITING,
   1549    // We've run the load algorithm, and we tried all source children of the
   1550    // media element, and failed to load any successfully. We're waiting for
   1551    // another source element to be added to the media element, and will try
   1552    // to load any such element when its added.
   1553    WAITING_FOR_SOURCE
   1554  };
   1555 
   1556  // The current media load ID. This is incremented every time we start a
   1557  // new load. Async events note the ID when they're first sent, and only fire
   1558  // if the ID is unchanged when they come to fire.
   1559  uint32_t mCurrentLoadID = 0;
   1560 
   1561  // Denotes the waiting state of a load algorithm instance. When the load
   1562  // algorithm is waiting for a source element child to be added, this is set
   1563  // to WAITING_FOR_SOURCE, otherwise it's NOT_WAITING.
   1564  LoadAlgorithmState mLoadWaitStatus = NOT_WAITING;
   1565 
   1566  // Current audio volume
   1567  double mVolume = 1.0;
   1568 
   1569  // True if the audio track is not silent.
   1570  bool mIsAudioTrackAudible = false;
   1571 
   1572  enum MutedReasons {
   1573    MUTED_BY_CONTENT = 0x01,
   1574    MUTED_BY_INVALID_PLAYBACK_RATE = 0x02,
   1575    MUTED_BY_AUDIO_CHANNEL = 0x04,
   1576    MUTED_BY_AUDIO_TRACK = 0x08
   1577  };
   1578 
   1579  uint32_t mMuted = 0;
   1580 
   1581  UniquePtr<const MetadataTags> mTags;
   1582 
   1583  // URI of the resource we're attempting to load. This stores the value we
   1584  // return in the currentSrc attribute. Use GetCurrentSrc() to access the
   1585  // currentSrc attribute.
   1586  // This is always the original URL we're trying to load --- before
   1587  // redirects etc.
   1588  nsCOMPtr<nsIURI> mLoadingSrc;
   1589 
   1590  // The triggering principal for the current source.
   1591  nsCOMPtr<nsIPrincipal> mLoadingSrcTriggeringPrincipal;
   1592 
   1593  // Stores the current preload action for this element. Initially set to
   1594  // PRELOAD_UNDEFINED, its value is changed by calling
   1595  // UpdatePreloadAction().
   1596  PreloadAction mPreloadAction = PRELOAD_UNDEFINED;
   1597 
   1598  // Time that the last timeupdate event was queued. Read/Write from the
   1599  // main thread only.
   1600  TimeStamp mQueueTimeUpdateRunnerTime;
   1601 
   1602  // Time that the last timeupdate event was fired. Read/Write from the
   1603  // main thread only.
   1604  TimeStamp mLastTimeUpdateDispatchTime;
   1605 
   1606  // Time that the last progress event was fired. Read/Write from the
   1607  // main thread only.
   1608  TimeStamp mProgressTime;
   1609 
   1610  // Time that data was last read from the media resource. Used for
   1611  // computing if the download has stalled and to rate limit progress events
   1612  // when data is arriving slower than PROGRESS_MS.
   1613  // Read/Write from the main thread only.
   1614  TimeStamp mDataTime;
   1615 
   1616  // Media 'currentTime' value when the last timeupdate event was queued.
   1617  // Read/Write from the main thread only.
   1618  double mLastCurrentTime = 0.0;
   1619 
   1620  // Logical start time of the media resource in seconds as obtained
   1621  // from any media fragments. A negative value indicates that no
   1622  // fragment time has been set. Read/Write from the main thread only.
   1623  double mFragmentStart = -1.0;
   1624 
   1625  // Logical end time of the media resource in seconds as obtained
   1626  // from any media fragments. A negative value indicates that no
   1627  // fragment time has been set. Read/Write from the main thread only.
   1628  double mFragmentEnd = -1.0;
   1629 
   1630  // The defaultPlaybackRate attribute gives the desired speed at which the
   1631  // media resource is to play, as a multiple of its intrinsic speed.
   1632  double mDefaultPlaybackRate = 1.0;
   1633 
   1634  // The playbackRate attribute gives the speed at which the media resource
   1635  // plays, as a multiple of its intrinsic speed. If it is not equal to the
   1636  // defaultPlaybackRate, then the implication is that the user is using a
   1637  // feature such as fast forward or slow motion playback.
   1638  double mPlaybackRate = 1.0;
   1639 
   1640  // True if pitch correction is applied when playbackRate is set to a
   1641  // non-intrinsic value.
   1642  bool mPreservesPitch = true;
   1643 
   1644  // Reference to the source element last returned by GetNextSource().
   1645  // This is the child source element which we're trying to load from.
   1646  nsCOMPtr<nsIContent> mSourceLoadCandidate;
   1647 
   1648  // Range of time played.
   1649  RefPtr<TimeRanges> mPlayed;
   1650 
   1651  // Timer used for updating progress events.
   1652  nsCOMPtr<nsITimer> mProgressTimer;
   1653 
   1654  // Encrypted Media Extension media keys.
   1655  RefPtr<MediaKeys> mMediaKeys;
   1656  RefPtr<MediaKeys> mIncomingMediaKeys;
   1657  // The dom promise is used for HTMLMediaElement::SetMediaKeys.
   1658  RefPtr<DetailedPromise> mSetMediaKeysDOMPromise;
   1659  // Used to indicate if the MediaKeys attaching operation is on-going or not.
   1660  bool mAttachingMediaKey = false;
   1661  MozPromiseRequestHolder<SetCDMPromise> mSetCDMRequest;
   1662 
   1663  // Stores the time at the start of the current 'played' range.
   1664  double mCurrentPlayRangeStart = 1.0;
   1665 
   1666  // True if loadeddata has been fired.
   1667  bool mLoadedDataFired = false;
   1668 
   1669  // One of the factors determines whether a media element with 'autoplay'
   1670  // attribute is allowed to start playing.
   1671  // https://html.spec.whatwg.org/multipage/media.html#can-autoplay-flag
   1672  bool mCanAutoplayFlag = true;
   1673 
   1674  // Playback of the video is paused either due to calling the
   1675  // 'Pause' method, or playback not yet having started.
   1676  Watchable<bool> mPaused = {true, "HTMLMediaElement::mPaused"};
   1677 
   1678  // The following two fields are here for the private storage of the builtin
   1679  // video controls, and control 'casting' of the video to external devices
   1680  // (TVs, projectors etc.)
   1681  // True if casting is currently allowed
   1682  bool mAllowCasting = false;
   1683  // True if currently casting this video
   1684  bool mIsCasting = false;
   1685 
   1686  // Set while there are some OutputMediaStreams this media element's enabled
   1687  // and selected tracks are captured into. When set, all tracks are captured
   1688  // into the graph of this dummy track.
   1689  // NB: This is a SharedDummyTrack to allow non-default graphs (AudioContexts
   1690  // with an explicit sampleRate defined) to capture this element. When
   1691  // cross-graph tracks are supported, this can become a bool.
   1692  Watchable<RefPtr<SharedDummyTrack>> mTracksCaptured;
   1693 
   1694  // True if the sound is being captured.
   1695  bool mAudioCaptured = false;
   1696 
   1697  // If TRUE then the media element was actively playing before the currently
   1698  // in progress seeking. If FALSE then the media element is either not seeking
   1699  // or was not actively playing before the current seek. Used to decide whether
   1700  // to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
   1701  bool mPlayingBeforeSeek = false;
   1702 
   1703  // True if this element is suspended because the document is inactive or the
   1704  // inactive docshell is not allowing media to play.
   1705  bool mSuspendedByInactiveDocOrDocshell = false;
   1706 
   1707  // True if we're running the "load()" method.
   1708  bool mIsRunningLoadMethod = false;
   1709 
   1710  // True if we're running or waiting to run queued tasks due to an explicit
   1711  // call to "load()".
   1712  bool mIsDoingExplicitLoad = false;
   1713 
   1714  // True if we're loading the resource from the child source elements.
   1715  bool mIsLoadingFromSourceChildren = false;
   1716 
   1717  // True if we're delaying the "load" event. They are delayed until either
   1718  // an error occurs, or the first frame is loaded.
   1719  bool mDelayingLoadEvent = false;
   1720 
   1721  // True when we've got a task queued to call SelectResource(),
   1722  // or while we're running SelectResource().
   1723  bool mIsRunningSelectResource = false;
   1724 
   1725  // True when we already have select resource call queued
   1726  bool mHaveQueuedSelectResource = false;
   1727 
   1728  // True if we suspended the decoder because we were paused,
   1729  // preloading metadata is enabled, autoplay was not enabled, and we loaded
   1730  // the first frame.
   1731  bool mSuspendedAfterFirstFrame = false;
   1732 
   1733  // True if we are allowed to suspend the decoder because we were paused,
   1734  // preloading metdata was enabled, autoplay was not enabled, and we loaded
   1735  // the first frame.
   1736  bool mAllowSuspendAfterFirstFrame = true;
   1737 
   1738  // True if we've played or completed a seek. We use this to determine
   1739  // when the poster frame should be shown.
   1740  bool mHasPlayedOrSeeked = false;
   1741 
   1742  // True if we've added a reference to ourselves to keep the element
   1743  // alive while no-one is referencing it but the element may still fire
   1744  // events of its own accord.
   1745  bool mHasSelfReference = false;
   1746 
   1747  // True if we've received a notification that the engine is shutting
   1748  // down.
   1749  bool mShuttingDown = false;
   1750 
   1751  // True if we've suspended a load in the resource selection algorithm
   1752  // due to loading a preload:none media. When true, the resource we'll
   1753  // load when the user initiates either playback or an explicit load is
   1754  // stored in mPreloadURI.
   1755  bool mSuspendedForPreloadNone = false;
   1756 
   1757  // True if we've connected mSrcStream to the media element output.
   1758  bool mSrcStreamIsPlaying = false;
   1759 
   1760  // True if we should set nsIClassOfService::UrgentStart to the channel to
   1761  // get the response ASAP for better user responsiveness.
   1762  bool mUseUrgentStartForChannel = false;
   1763 
   1764  // The CORS mode when loading the media element
   1765  CORSMode mCORSMode = CORS_NONE;
   1766 
   1767  // Info about the played media.
   1768  MediaInfo mMediaInfo;
   1769 
   1770  // True if the media has encryption information.
   1771  bool mIsEncrypted = false;
   1772 
   1773  enum WaitingForKeyState {
   1774    NOT_WAITING_FOR_KEY = 0,
   1775    WAITING_FOR_KEY = 1,
   1776    WAITING_FOR_KEY_DISPATCHED = 2
   1777  };
   1778 
   1779  // True when the CDM cannot decrypt the current block due to lacking a key.
   1780  // Note: the "waitingforkey" event is not dispatched until all decoded data
   1781  // has been rendered.
   1782  WaitingForKeyState mWaitingForKey = NOT_WAITING_FOR_KEY;
   1783 
   1784  // Listens for waitingForKey events from the owned decoder.
   1785  MediaEventListener mWaitingForKeyListener;
   1786 
   1787  // Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
   1788  EncryptionInfo mPendingEncryptedInitData;
   1789 
   1790  // True if the media's channel's download has been suspended.
   1791  Watchable<bool> mDownloadSuspendedByCache = {
   1792      false, "HTMLMediaElement::mDownloadSuspendedByCache"};
   1793 
   1794  // Disable the video playback by track selection. This flag might not be
   1795  // enough if we ever expand the ability of supporting multi-tracks video
   1796  // playback.
   1797  bool mDisableVideo = false;
   1798 
   1799  RefPtr<TextTrackManager> mTextTrackManager;
   1800 
   1801  RefPtr<AudioTrackList> mAudioTrackList;
   1802 
   1803  RefPtr<VideoTrackList> mVideoTrackList;
   1804 
   1805  RefPtr<MediaStreamTrackListener> mMediaStreamTrackListener;
   1806 
   1807  // The principal guarding mVideoFrameContainer access when playing a
   1808  // MediaStream.
   1809  nsCOMPtr<nsIPrincipal> mSrcStreamVideoPrincipal;
   1810 
   1811  // True if the autoplay media was blocked because it hadn't loaded metadata
   1812  // yet.
   1813  bool mBlockedAsWithoutMetadata = false;
   1814 
   1815  // This promise is used to notify MediaElementAudioSourceNode that media
   1816  // element is allowed to play when MediaElement is used as a source for web
   1817  // audio.
   1818  MozPromiseHolder<GenericNonExclusivePromise> mAllowedToPlayPromise;
   1819 
   1820  // True if media has ever been blocked for autoplay, it's used to notify front
   1821  // end to show the correct blocking icon when the document goes back from
   1822  // bfcache.
   1823  bool mHasEverBeenBlockedForAutoplay = false;
   1824 
   1825  // True if we have dispatched a task for text track changed, will be unset
   1826  // when we starts processing text track changed.
   1827  // https://html.spec.whatwg.org/multipage/media.html#pending-text-track-change-notification-flag
   1828  bool mPendingTextTrackChanged = false;
   1829 
   1830 public:
   1831  // This function will be called whenever a text track that is in a media
   1832  // element's list of text tracks has its text track mode change value
   1833  void NotifyTextTrackModeChanged();
   1834 
   1835 private:
   1836  friend class nsMediaEventRunner;
   1837  friend class nsResolveOrRejectPendingPlayPromisesRunner;
   1838 
   1839  already_AddRefed<PlayPromise> CreatePlayPromise(ErrorResult& aRv) const;
   1840 
   1841  virtual void MaybeBeginCloningVisually() {};
   1842 
   1843  uint32_t GetPreloadDefault() const;
   1844  uint32_t GetPreloadDefaultAuto() const;
   1845 
   1846  bool ShouldSuspendDownloadAfterFirstFrameLoaded() const;
   1847 
   1848  /**
   1849   * This function is called by AfterSetAttr and OnAttrSetButNotChanged.
   1850   * It will not be called if the value is being unset.
   1851   *
   1852   * @param aNamespaceID the namespace of the attr being set
   1853   * @param aName the localname of the attribute being set
   1854   * @param aNotify Whether we plan to notify document observers.
   1855   */
   1856  void AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName, bool aNotify);
   1857 
   1858  // True if Init() has been called after construction
   1859  bool mInitialized = false;
   1860 
   1861  // True if user has called load(), seek() or element has started playing
   1862  // before. It's *only* use for `click-to-play` blocking autoplay policy.
   1863  // In addition, we would reset this once media aborts current load.
   1864  bool mIsBlessed = false;
   1865 
   1866  // True if the first frame has been successfully loaded.
   1867  Watchable<bool> mFirstFrameLoaded = {false,
   1868                                       "HTMLMediaElement::mFirstFrameLoaded"};
   1869 
   1870  // Media elements also have a default playback start position, which must
   1871  // initially be set to zero seconds. This time is used to allow the element to
   1872  // be seeked even before the media is loaded.
   1873  double mDefaultPlaybackStartPosition = 0.0;
   1874 
   1875  // True if media element has been marked as 'tainted' and can't
   1876  // participate in video decoder suspending.
   1877  bool mHasSuspendTaint = false;
   1878 
   1879  // True if media element has been forced into being considered 'hidden'.
   1880  // For use by mochitests. Enabling pref "media.test.video-suspend"
   1881  bool mForcedHidden = false;
   1882 
   1883  Visibility mVisibilityState = Visibility::Untracked;
   1884 
   1885  UniquePtr<ErrorSink> mErrorSink;
   1886 
   1887  // This wrapper will handle all audio channel related stuffs, eg. the
   1888  // operations of tab audio indicator, Fennec's media control. Note:
   1889  // mAudioChannelWrapper might be null after GC happened.
   1890  RefPtr<AudioChannelAgentCallback> mAudioChannelWrapper;
   1891 
   1892  // A list of pending play promises. The elements are pushed during the play()
   1893  // method call and are resolved/rejected during further playback steps.
   1894  nsTArray<RefPtr<PlayPromise>> mPendingPlayPromises;
   1895 
   1896  // A list of already-dispatched but not yet run
   1897  // nsResolveOrRejectPendingPlayPromisesRunners.
   1898  // Runners whose Run() method is called remove themselves from this list.
   1899  // We keep track of these because the load algorithm resolves/rejects all
   1900  // already-dispatched pending play promises.
   1901  nsTArray<nsResolveOrRejectPendingPlayPromisesRunner*>
   1902      mPendingPlayPromisesRunners;
   1903 
   1904  // A pending seek promise which is created at Seek() method call and is
   1905  // resolved/rejected at AsyncResolveSeekDOMPromiseIfExists()/
   1906  // AsyncRejectSeekDOMPromiseIfExists() methods.
   1907  RefPtr<dom::Promise> mSeekDOMPromise;
   1908 
   1909  // Return true if the docshell is inactive and explicitly wants to stop media
   1910  // playing in that shell.
   1911  bool ShouldBeSuspendedByInactiveDocShell() const;
   1912 
   1913  // For debugging bug 1407148.
   1914  void AssertReadyStateIsNothing();
   1915 
   1916  // Contains the unique id of the sink device and the device info.
   1917  // The initial value is ("", nullptr) and the default output device is used.
   1918  // It can contain an invalid id and info if the device has been
   1919  // unplugged. It can be set to ("", nullptr). It follows the spec attribute:
   1920  // https://w3c.github.io/mediacapture-output/#htmlmediaelement-extensions
   1921  // Read/Write from the main thread only.
   1922  std::pair<nsString, RefPtr<AudioDeviceInfo>> mSink;
   1923 
   1924  // This flag is used to control when the user agent is to show a poster frame
   1925  // for a video element instead of showing the video contents.
   1926  // https://html.spec.whatwg.org/multipage/media.html#show-poster-flag
   1927  bool mShowPoster;
   1928 
   1929  // We may delay starting playback of a media for an unvisited tab until it's
   1930  // going to foreground. We would create ResumeDelayedMediaPlaybackAgent to
   1931  // handle related operations at the time whenever delaying media playback is
   1932  // needed.
   1933  void CreateResumeDelayedMediaPlaybackAgentIfNeeded();
   1934  void ClearResumeDelayedMediaPlaybackAgentIfNeeded();
   1935  RefPtr<ResumeDelayedPlaybackAgent> mResumeDelayedPlaybackAgent;
   1936  MozPromiseRequestHolder<ResumeDelayedPlaybackAgent::ResumePromise>
   1937      mResumePlaybackRequest;
   1938 
   1939  // Return true if we have already a decoder or a src stream and don't have any
   1940  // error.
   1941  bool IsPlayable() const;
   1942 
   1943  // Return true if the media qualifies for being controlled by media control
   1944  // keys.
   1945  bool ShouldStartMediaControlKeyListener() const;
   1946 
   1947  // Start the listener if media fits the requirement of being able to be
   1948  // controlled be media control keys.
   1949  void StartMediaControlKeyListenerIfNeeded();
   1950 
   1951  // It's used to listen media control key, by which we would play or pause
   1952  // media element.
   1953  RefPtr<MediaControlKeyListener> mMediaControlKeyListener;
   1954 
   1955  // Method to update audio stream name
   1956  void UpdateStreamName();
   1957 
   1958  // Return true if the media element is being used in picture in picture mode.
   1959  bool IsBeingUsedInPictureInPictureMode() const;
   1960 
   1961  // Return true if we should queue a 'timeupdate' event runner to main thread.
   1962  bool ShouldQueueTimeupdateAsyncTask(TimeupdateType aType) const;
   1963 
   1964  // In order to avoid the back-button intervention resulting in history
   1965  // entries with autoplayed videos from being skipped, we make sure that an
   1966  // entry which has played a video is considered to have been interacted
   1967  // with. See bug 1946547.
   1968  void MaybeMarkSHEntryAsUserInteracted();
   1969 
   1970 #ifdef MOZ_WMF_CDM
   1971  // It's used to record telemetry probe for WMFCDM playback.
   1972  bool mIsUsingWMFCDM = false;
   1973 #endif
   1974 
   1975  Maybe<DelayedScheduler<AwakeTimeStamp>> mAudioWakelockReleaseScheduler;
   1976 };
   1977 
   1978 // Check if the context is chrome or has the debugger or tabs permission
   1979 bool HasDebuggerOrTabsPrivilege(JSContext* aCx, JSObject* aObj);
   1980 
   1981 }  // namespace mozilla::dom
   1982 
   1983 inline nsISupports* ToSupports(mozilla::dom::HTMLMediaElement* aElement) {
   1984  return static_cast<mozilla::dom::EventTarget*>(aElement);
   1985 }
   1986 
   1987 #endif  // mozilla_dom_HTMLMediaElement_h