Coverage Report

Created: 2018-09-25 14:53

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