Implement the Remote Playback API.
[WebKit-https.git] / Source / WebCore / html / HTMLMediaElement.h
1 /*
2  * Copyright (C) 2007-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #if ENABLE(VIDEO)
29
30 #include "ActiveDOMObject.h"
31 #include "ApplicationStateChangeListener.h"
32 #include "AutoplayEvent.h"
33 #include "DeferrableTask.h"
34 #include "GenericEventQueue.h"
35 #include "HTMLElement.h"
36 #include "HTMLMediaElementEnums.h"
37 #include "MediaCanStartListener.h"
38 #include "MediaControllerInterface.h"
39 #include "MediaElementSession.h"
40 #include "MediaPlayer.h"
41 #include "MediaProducer.h"
42 #include "VisibilityChangeClient.h"
43 #include <wtf/Function.h>
44 #include <wtf/LoggerHelper.h>
45 #include <wtf/WeakPtr.h>
46
47 #if ENABLE(VIDEO_TRACK)
48 #include "AudioTrack.h"
49 #include "CaptionUserPreferences.h"
50 #include "PODIntervalTree.h"
51 #include "TextTrack.h"
52 #include "TextTrackCue.h"
53 #include "VTTCue.h"
54 #include "VideoTrack.h"
55 #endif
56
57 #if USE(AUDIO_SESSION) && PLATFORM(MAC)
58 #include "AudioSession.h"
59 #endif
60
61 #if ENABLE(ENCRYPTED_MEDIA)
62 #include "CDMClient.h"
63 #endif
64
65 #ifndef NDEBUG
66 #include <wtf/StringPrintStream.h>
67 #endif
68
69 namespace PAL {
70 class SleepDisabler;
71 }
72
73 namespace WebCore {
74
75 class AudioSourceProvider;
76 class AudioTrackList;
77 class AudioTrackPrivate;
78 class Blob;
79 class DOMException;
80 class DOMWrapperWorld;
81 class DeferredPromise;
82 class Event;
83 class HTMLSourceElement;
84 class HTMLTrackElement;
85 class InbandTextTrackPrivate;
86 class JSDOMGlobalObject;
87 class MediaController;
88 class MediaControls;
89 class MediaControlsHost;
90 class MediaElementAudioSourceNode;
91 class MediaError;
92 class MediaKeys;
93 class MediaResourceLoader;
94 class MediaSession;
95 class MediaSource;
96 class MediaStream;
97 class RenderMedia;
98 class ScriptController;
99 class ScriptExecutionContext;
100 class SourceBuffer;
101 class TextTrackList;
102 class TimeRanges;
103 class VideoPlaybackQuality;
104 class VideoTrackList;
105 class VideoTrackPrivate;
106 class WebKitMediaKeys;
107
108 template<typename> class DOMPromiseDeferred;
109
110 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
111 class RemotePlayback;
112 #endif
113
114 #if ENABLE(VIDEO_TRACK)
115 using CueIntervalTree = PODIntervalTree<MediaTime, TextTrackCue*>;
116 using CueInterval = CueIntervalTree::IntervalType;
117 using CueList = Vector<CueInterval>;
118 #endif
119
120 using MediaProvider = Optional<Variant<
121 #if ENABLE(MEDIA_STREAM)
122     RefPtr<MediaStream>,
123 #endif
124 #if ENABLE(MEDIA_SOURCE)
125     RefPtr<MediaSource>,
126 #endif
127     RefPtr<Blob>>>;
128
129 class HTMLMediaElement
130     : public HTMLElement
131     , public ActiveDOMObject
132     , public MediaControllerInterface
133     , public PlatformMediaSessionClient
134     , private MediaCanStartListener
135     , private MediaPlayerClient
136     , private MediaProducer
137     , private VisibilityChangeClient
138     , private ApplicationStateChangeListener
139 #if ENABLE(VIDEO_TRACK)
140     , private AudioTrackClient
141     , private TextTrackClient
142     , private VideoTrackClient
143 #endif
144 #if USE(AUDIO_SESSION) && PLATFORM(MAC)
145     , private AudioSession::MutedStateObserver
146 #endif
147 #if ENABLE(ENCRYPTED_MEDIA)
148     , private CDMClient
149 #endif
150 #if !RELEASE_LOG_DISABLED
151     , private LoggerHelper
152 #endif
153 {
154     WTF_MAKE_ISO_ALLOCATED(HTMLMediaElement);
155 public:
156     using WeakValueType = HTMLElement::WeakValueType;
157     using HTMLElement::weakPtrFactory;
158
159     RefPtr<MediaPlayer> player() const { return m_player; }
160
161     virtual bool isVideo() const { return false; }
162     bool hasVideo() const override { return false; }
163     bool hasAudio() const override;
164
165     static HashSet<HTMLMediaElement*>& allMediaElements();
166
167     WEBCORE_EXPORT static RefPtr<HTMLMediaElement> bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose);
168
169     static bool isRunningDestructor();
170
171     WEBCORE_EXPORT void rewind(double timeDelta);
172     WEBCORE_EXPORT void returnToRealtime() override;
173
174     // Eventually overloaded in HTMLVideoElement
175     bool supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) const override { return false; };
176
177     bool supportsScanning() const override;
178
179     bool canSaveMediaData() const;
180
181     bool doesHaveAttribute(const AtomString&, AtomString* value = nullptr) const override;
182
183     PlatformLayer* platformLayer() const;
184     bool isVideoLayerInline();
185     void setPreparedToReturnVideoLayerToInline(bool);
186     void waitForPreparedForInlineThen(WTF::Function<void()>&& completionHandler = [] { });
187 #if PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
188     void setVideoFullscreenLayer(PlatformLayer*, WTF::Function<void()>&& completionHandler = [] { });
189 #ifdef __OBJC__
190     PlatformLayer* videoFullscreenLayer() const { return m_videoFullscreenLayer.get(); }
191 #endif
192     virtual void setVideoFullscreenFrame(FloatRect);
193     void setVideoFullscreenGravity(MediaPlayerEnums::VideoGravity);
194     MediaPlayerEnums::VideoGravity videoFullscreenGravity() const { return m_videoFullscreenGravity; }
195 #endif
196
197     void scheduleCheckPlaybackTargetCompatability();
198     void checkPlaybackTargetCompatablity();
199     void scheduleResolvePendingPlayPromises();
200     void scheduleRejectPendingPlayPromises(Ref<DOMException>&&);
201     using PlayPromiseVector = Vector<DOMPromiseDeferred<void>>;
202     void rejectPendingPlayPromises(PlayPromiseVector&&, Ref<DOMException>&&);
203     void resolvePendingPlayPromises(PlayPromiseVector&&);
204     void scheduleNotifyAboutPlaying();
205     void notifyAboutPlaying(PlayPromiseVector&&);
206     
207     MediaPlayerEnums::MovieLoadType movieLoadType() const;
208     
209     bool inActiveDocument() const { return m_inActiveDocument; }
210
211     Document* hostingDocument() const final { return &document(); }
212
213 // DOM API
214 // error state
215     WEBCORE_EXPORT MediaError* error() const;
216
217     const URL& currentSrc() const { return m_currentSrc; }
218
219     const MediaProvider& srcObject() const { return m_mediaProvider; }
220     void setSrcObject(MediaProvider&&);
221
222     WEBCORE_EXPORT void setCrossOrigin(const AtomString&);
223     WEBCORE_EXPORT String crossOrigin() const;
224
225 // network state
226     using HTMLMediaElementEnums::NetworkState;
227     WEBCORE_EXPORT NetworkState networkState() const;
228
229     WEBCORE_EXPORT String preload() const;
230     WEBCORE_EXPORT void setPreload(const String&);
231
232     Ref<TimeRanges> buffered() const override;
233     WEBCORE_EXPORT void load();
234     WEBCORE_EXPORT String canPlayType(const String& mimeType) const;
235
236 // ready state
237     using HTMLMediaElementEnums::ReadyState;
238     ReadyState readyState() const override;
239     WEBCORE_EXPORT bool seeking() const;
240
241 // playback state
242     WEBCORE_EXPORT double currentTime() const override;
243     WEBCORE_EXPORT void setCurrentTime(double) override;
244     void setCurrentTimeWithTolerance(double, double toleranceBefore, double toleranceAfter);
245     double currentTimeForBindings() const { return currentTime(); }
246     WEBCORE_EXPORT ExceptionOr<void> setCurrentTimeForBindings(double);
247     WEBCORE_EXPORT double getStartDate() const;
248     WEBCORE_EXPORT double duration() const override;
249     WEBCORE_EXPORT bool paused() const override;
250     double defaultPlaybackRate() const override;
251     void setDefaultPlaybackRate(double) override;
252     WEBCORE_EXPORT double playbackRate() const override;
253     void setPlaybackRate(double) override;
254
255 // MediaTime versions of playback state
256     MediaTime currentMediaTime() const;
257     void setCurrentTime(const MediaTime&);
258     MediaTime durationMediaTime() const;
259     WEBCORE_EXPORT void fastSeek(const MediaTime&);
260
261     void updatePlaybackRate();
262     WEBCORE_EXPORT bool webkitPreservesPitch() const;
263     WEBCORE_EXPORT void setWebkitPreservesPitch(bool);
264     Ref<TimeRanges> played() override;
265     Ref<TimeRanges> seekable() const override;
266     double seekableTimeRangesLastModifiedTime() const;
267     double liveUpdateInterval() const;
268     WEBCORE_EXPORT bool ended() const;
269     bool autoplay() const;
270     bool isAutoplaying() const { return m_autoplaying; }
271     bool loop() const;
272     void setLoop(bool b);
273
274     void play(DOMPromiseDeferred<void>&&);
275
276     WEBCORE_EXPORT void play() override;
277     WEBCORE_EXPORT void pause() override;
278     WEBCORE_EXPORT void fastSeek(double);
279     double minFastReverseRate() const;
280     double maxFastForwardRate() const;
281
282     using HTMLMediaElementEnums::BufferingPolicy;
283     void setBufferingPolicy(BufferingPolicy);
284     WEBCORE_EXPORT BufferingPolicy bufferingPolicy() const;
285     WEBCORE_EXPORT void purgeBufferedDataIfPossible();
286
287 // captions
288     WEBCORE_EXPORT bool webkitHasClosedCaptions() const;
289     WEBCORE_EXPORT bool webkitClosedCaptionsVisible() const;
290     WEBCORE_EXPORT void setWebkitClosedCaptionsVisible(bool);
291
292     bool elementIsHidden() const { return m_elementIsHidden; }
293
294 #if ENABLE(MEDIA_STATISTICS)
295 // Statistics
296     unsigned webkitAudioDecodedByteCount() const;
297     unsigned webkitVideoDecodedByteCount() const;
298 #endif
299
300 #if ENABLE(MEDIA_SOURCE)
301 //  Media Source.
302     void detachMediaSource();
303     void incrementDroppedFrameCount() { ++m_droppedVideoFrames; }
304     size_t maximumSourceBufferSize(const SourceBuffer&) const;
305 #endif
306
307 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
308     WebKitMediaKeys* webkitKeys() const { return m_webKitMediaKeys.get(); }
309     void webkitSetMediaKeys(WebKitMediaKeys*);
310
311     void keyAdded();
312 #endif
313
314 #if ENABLE(ENCRYPTED_MEDIA)
315     MediaKeys* mediaKeys() const;
316
317     void setMediaKeys(MediaKeys*, Ref<DeferredPromise>&&);
318 #endif
319
320 // controls
321     WEBCORE_EXPORT bool controls() const;
322     WEBCORE_EXPORT void setControls(bool);
323     WEBCORE_EXPORT double volume() const override;
324     WEBCORE_EXPORT ExceptionOr<void> setVolume(double) override;
325     WEBCORE_EXPORT bool muted() const override;
326     WEBCORE_EXPORT void setMuted(bool) override;
327
328     WEBCORE_EXPORT void togglePlayState();
329     WEBCORE_EXPORT void beginScrubbing() override;
330     WEBCORE_EXPORT void endScrubbing() override;
331
332     void beginScanning(ScanDirection) override;
333     void endScanning() override;
334     double nextScanRate();
335
336     WEBCORE_EXPORT bool canPlay() const override;
337
338     double percentLoaded() const;
339
340     bool shouldForceControlsDisplay() const;
341
342 #if ENABLE(VIDEO_TRACK)
343     ExceptionOr<TextTrack&> addTextTrack(const String& kind, const String& label, const String& language);
344
345     AudioTrackList& ensureAudioTracks();
346     TextTrackList& ensureTextTracks();
347     VideoTrackList& ensureVideoTracks();
348     AudioTrackList* audioTracks() const { return m_audioTracks.get(); }
349     TextTrackList* textTracks() const { return m_textTracks.get(); }
350     VideoTrackList* videoTracks() const { return m_videoTracks.get(); }
351
352     CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
353
354     void addAudioTrack(Ref<AudioTrack>&&);
355     void addTextTrack(Ref<TextTrack>&&);
356     void addVideoTrack(Ref<VideoTrack>&&);
357     void removeAudioTrack(Ref<AudioTrack>&&);
358     void removeTextTrack(Ref<TextTrack>&&, bool scheduleEvent = true);
359     void removeVideoTrack(Ref<VideoTrack>&&);
360     void forgetResourceSpecificTracks();
361     void closeCaptionTracksChanged();
362     void notifyMediaPlayerOfTextTrackChanges();
363
364     virtual void didAddTextTrack(HTMLTrackElement&);
365     virtual void didRemoveTextTrack(HTMLTrackElement&);
366
367     void mediaPlayerDidAddAudioTrack(AudioTrackPrivate&) final;
368     void mediaPlayerDidAddTextTrack(InbandTextTrackPrivate&) final;
369     void mediaPlayerDidAddVideoTrack(VideoTrackPrivate&) final;
370     void mediaPlayerDidRemoveAudioTrack(AudioTrackPrivate&) final;
371     void mediaPlayerDidRemoveTextTrack(InbandTextTrackPrivate&) final;
372     void mediaPlayerDidRemoveVideoTrack(VideoTrackPrivate&) final;
373
374 #if ENABLE(AVF_CAPTIONS)
375     Vector<RefPtr<PlatformTextTrack>> outOfBandTrackSources() final;
376 #endif
377
378     struct TrackGroup;
379     void configureTextTrackGroupForLanguage(const TrackGroup&) const;
380     void scheduleConfigureTextTracks();
381     void configureTextTracks();
382     void configureTextTrackGroup(const TrackGroup&);
383
384     void setSelectedTextTrack(TextTrack*);
385
386     bool textTracksAreReady() const;
387     using HTMLMediaElementEnums::TextTrackVisibilityCheckType;
388     void configureTextTrackDisplay(TextTrackVisibilityCheckType checkType = CheckTextTrackVisibility);
389     void updateTextTrackDisplay();
390
391     // AudioTrackClient
392     void audioTrackEnabledChanged(AudioTrack&) final;
393
394     void textTrackReadyStateChanged(TextTrack*);
395
396     // TextTrackClient
397     void textTrackKindChanged(TextTrack&) override;
398     void textTrackModeChanged(TextTrack&) override;
399     void textTrackAddCues(TextTrack&, const TextTrackCueList&) override;
400     void textTrackRemoveCues(TextTrack&, const TextTrackCueList&) override;
401     void textTrackAddCue(TextTrack&, TextTrackCue&) override;
402     void textTrackRemoveCue(TextTrack&, TextTrackCue&) override;
403
404     // VideoTrackClient
405     void videoTrackSelectedChanged(VideoTrack&) final;
406
407     bool requiresTextTrackRepresentation() const;
408     void setTextTrackRepresentation(TextTrackRepresentation*);
409     void syncTextTrackBounds();
410 #endif
411
412 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
413     void webkitShowPlaybackTargetPicker();
414     bool addEventListener(const AtomString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
415     bool removeEventListener(const AtomString& eventType, EventListener&, const ListenerOptions&) override;
416
417     void wirelessRoutesAvailableDidChange() override;
418     void setWirelessPlaybackTarget(Ref<MediaPlaybackTarget>&&) override;
419     void setShouldPlayToPlaybackTarget(bool) override;
420     void playbackTargetPickerWasDismissed() override;
421 #endif
422     bool isPlayingToWirelessPlaybackTarget() const override { return m_isPlayingToWirelessTarget; };
423     void setIsPlayingToWirelessTarget(bool);
424     bool webkitCurrentPlaybackTargetIsWireless() const;
425
426     void setPlayingOnSecondScreen(bool value);
427     bool isPlayingOnSecondScreen() const override { return m_playingOnSecondScreen; }
428
429     bool isPlayingToExternalTarget() const { return isPlayingToWirelessPlaybackTarget() || isPlayingOnSecondScreen(); }
430
431     // EventTarget function.
432     // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
433     // causes an ambiguity error at compile time. This class's constructor
434     // ensures that both implementations return document, so return the result
435     // of one of them here.
436     using HTMLElement::scriptExecutionContext;
437
438     bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
439     bool didPassCORSAccessCheck() const { return m_player && m_player->didPassCORSAccessCheck(); }
440     bool wouldTaintOrigin(const SecurityOrigin& origin) const { return m_player && m_player->wouldTaintOrigin(origin); }
441     
442     WEBCORE_EXPORT bool isFullscreen() const override;
443     bool isStandardFullscreen() const;
444     void toggleStandardFullscreenState();
445
446     using MediaPlayerEnums::VideoFullscreenMode;
447     VideoFullscreenMode fullscreenMode() const { return m_videoFullscreenMode; }
448     virtual void fullscreenModeChanged(VideoFullscreenMode);
449
450     void enterFullscreen(VideoFullscreenMode);
451     void enterFullscreen() override;
452     WEBCORE_EXPORT void exitFullscreen();
453     WEBCORE_EXPORT void setVideoFullscreenStandby(bool);
454
455     bool hasClosedCaptions() const override;
456     bool closedCaptionsVisible() const override;
457     void setClosedCaptionsVisible(bool) override;
458
459     MediaControls* mediaControls() const;
460
461     void sourceWasRemoved(HTMLSourceElement&);
462     void sourceWasAdded(HTMLSourceElement&);
463
464     void privateBrowsingStateDidChange(PAL::SessionID) override;
465
466     // Media cache management.
467     WEBCORE_EXPORT static void setMediaCacheDirectory(const String&);
468     WEBCORE_EXPORT static const String& mediaCacheDirectory();
469     WEBCORE_EXPORT static HashSet<RefPtr<SecurityOrigin>> originsInMediaCache(const String&);
470     WEBCORE_EXPORT static void clearMediaCache(const String&, WallTime modifiedSince = { });
471     WEBCORE_EXPORT static void clearMediaCacheForOrigins(const String&, const HashSet<RefPtr<SecurityOrigin>>&);
472     static void resetMediaEngines();
473
474     bool isPlaying() const { return m_playing; }
475
476     bool hasPendingActivity() const override;
477
478 #if ENABLE(WEB_AUDIO)
479     MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
480     void setAudioSourceNode(MediaElementAudioSourceNode*);
481
482     AudioSourceProvider* audioSourceProvider();
483 #endif
484
485     using HTMLMediaElementEnums::InvalidURLAction;
486     bool isSafeToLoadURL(const URL&, InvalidURLAction);
487
488     const String& mediaGroup() const;
489     void setMediaGroup(const String&);
490
491     MediaController* controller() const;
492     void setController(RefPtr<MediaController>&&);
493
494     MediaController* controllerForBindings() const { return controller(); }
495     void setControllerForBindings(MediaController*);
496
497     void enteredOrExitedFullscreen() { configureMediaControls(); }
498
499     unsigned long long fileSize() const;
500
501     void mediaLoadingFailed(MediaPlayerEnums::NetworkState);
502     void mediaLoadingFailedFatally(MediaPlayerEnums::NetworkState);
503
504 #if ENABLE(MEDIA_SESSION)
505     WEBCORE_EXPORT double playerVolume() const;
506
507     const String& kind() const { return m_kind; }
508     void setKind(const String& kind) { m_kind = kind; }
509
510     MediaSession* session() const;
511     void setSession(MediaSession*);
512
513     void setShouldDuck(bool);
514
515     static HTMLMediaElement* elementWithID(uint64_t);
516     uint64_t elementID() const { return m_elementID; }
517 #endif
518
519     RefPtr<VideoPlaybackQuality> getVideoPlaybackQuality();
520
521     MediaPlayerEnums::Preload preloadValue() const { return m_preload; }
522     MediaElementSession& mediaSession() const { return *m_mediaSession; }
523
524 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
525     void pageScaleFactorChanged();
526     void userInterfaceLayoutDirectionChanged();
527     WEBCORE_EXPORT String getCurrentMediaControlsStatus();
528
529     MediaControlsHost* mediaControlsHost() { return m_mediaControlsHost.get(); }
530 #endif
531
532     bool isDisablingSleep() const { return m_sleepDisabler.get(); }
533
534     double maxBufferedTime() const;
535
536     MediaProducer::MediaStateFlags mediaState() const override;
537
538     void layoutSizeChanged();
539     void visibilityDidChange();
540
541     void allowsMediaDocumentInlinePlaybackChanged();
542     void updateShouldPlay();
543
544     RenderMedia* renderer() const;
545
546     void resetPlaybackSessionState();
547     bool isVisibleInViewport() const;
548     bool hasEverNotifiedAboutPlaying() const;
549     void setShouldDelayLoadEvent(bool);
550
551     bool hasEverHadAudio() const { return m_hasEverHadAudio; }
552     bool hasEverHadVideo() const { return m_hasEverHadVideo; }
553
554     double playbackStartedTime() const { return m_playbackStartedTime; }
555
556     bool isTemporarilyAllowingInlinePlaybackAfterFullscreen() const {return m_temporarilyAllowingInlinePlaybackAfterFullscreen; }
557
558     void isVisibleInViewportChanged();
559     void updateRateChangeRestrictions();
560
561     WEBCORE_EXPORT const MediaResourceLoader* lastMediaResourceLoaderForTesting() const;
562
563 #if ENABLE(MEDIA_STREAM)
564     void mediaStreamCaptureStarted() { resumeAutoplaying(); }
565     bool hasMediaStreamSrcObject() const { return m_mediaProvider && WTF::holds_alternative<RefPtr<MediaStream>>(*m_mediaProvider); }
566 #endif
567
568     bool supportsSeeking() const override;
569
570 #if !RELEASE_LOG_DISABLED
571     const Logger& logger() const final { return *m_logger.get(); }
572     const void* logIdentifier() const final { return m_logIdentifier; }
573     const char* logClassName() const final { return "HTMLMediaElement"; }
574     WTFLogChannel& logChannel() const final;
575 #endif
576
577     bool willLog(WTFLogLevel) const;
578
579     bool isSuspended() const final;
580
581     WEBCORE_EXPORT void didBecomeFullscreenElement() override;
582     WEBCORE_EXPORT void willExitFullscreen();
583
584 #if ENABLE(PICTURE_IN_PICTURE_API)
585     void scheduleEvent(Ref<Event>&&);
586 #endif
587
588     enum class AutoplayEventPlaybackState { None, PreventedAutoplay, StartedWithUserGesture, StartedWithoutUserGesture };
589
590 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
591     RemotePlayback& remote() { return m_remote; }
592     void remoteHasAvailabilityCallbacksChanged();
593 #endif
594
595 protected:
596     HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
597     virtual void finishInitialization();
598     virtual ~HTMLMediaElement();
599
600     void parseAttribute(const QualifiedName&, const AtomString&) override;
601     void finishParsingChildren() override;
602     bool isURLAttribute(const Attribute&) const override;
603     void willAttachRenderers() override;
604     void didAttachRenderers() override;
605     void willDetachRenderers() override;
606     void didDetachRenderers() override;
607
608     void didMoveToNewDocument(Document& oldDocument, Document& newDocument) override;
609
610     enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
611     DisplayMode displayMode() const { return m_displayMode; }
612     virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
613     
614     bool isMediaElement() const final { return true; }
615
616 #if ENABLE(VIDEO_TRACK)
617     bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); }
618     void beginIgnoringTrackDisplayUpdateRequests();
619     void endIgnoringTrackDisplayUpdateRequests();
620 #endif
621
622     RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
623
624 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
625     bool mediaControlsDependOnPageScaleFactor() const { return m_mediaControlsDependOnPageScaleFactor; }
626     void setMediaControlsDependOnPageScaleFactor(bool);
627     void updateMediaControlsAfterPresentationModeChange();
628 #endif
629
630     void scheduleEvent(const AtomString&);
631
632 private:
633     void createMediaPlayer();
634
635     bool supportsFocus() const override;
636     bool isMouseFocusable() const override;
637     bool rendererIsNeeded(const RenderStyle&) override;
638     bool childShouldCreateRenderer(const Node&) const override;
639     InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) override;
640     void didFinishInsertingNode() override;
641     void removedFromAncestor(RemovalType, ContainerNode&) override;
642     void didRecalcStyle(Style::Change) override;
643     bool isInteractiveContent() const override;
644
645     void willBecomeFullscreenElement() override;
646     void willStopBeingFullscreenElement() override;
647
648     // ActiveDOMObject API.
649     const char* activeDOMObjectName() const override;
650     void suspend(ReasonForSuspension) override;
651     void resume() override;
652     void stop() override;
653     void stopWithoutDestroyingMediaPlayer();
654     void contextDestroyed() override;
655     
656     void mediaVolumeDidChange() override;
657
658     void visibilityStateChanged() override;
659
660     virtual void updateDisplayState() { }
661     
662     void setReadyState(MediaPlayerEnums::ReadyState);
663     void setNetworkState(MediaPlayerEnums::NetworkState);
664
665     double effectivePlaybackRate() const;
666     double requestedPlaybackRate() const;
667
668     void mediaPlayerNetworkStateChanged(MediaPlayer*) override;
669     void mediaPlayerReadyStateChanged(MediaPlayer*) override;
670     void mediaPlayerTimeChanged(MediaPlayer*) override;
671     void mediaPlayerVolumeChanged(MediaPlayer*) override;
672     void mediaPlayerMuteChanged(MediaPlayer*) override;
673     void mediaPlayerDurationChanged(MediaPlayer*) override;
674     void mediaPlayerRateChanged(MediaPlayer*) override;
675     void mediaPlayerPlaybackStateChanged(MediaPlayer*) override;
676     void mediaPlayerSawUnsupportedTracks(MediaPlayer*) override;
677     void mediaPlayerResourceNotSupported(MediaPlayer*) override;
678     void mediaPlayerRepaint(MediaPlayer*) override;
679     void mediaPlayerSizeChanged(MediaPlayer*) override;
680     bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*) override;
681     void mediaPlayerRenderingModeChanged(MediaPlayer*) override;
682     bool mediaPlayerAcceleratedCompositingEnabled() override;
683     void mediaPlayerEngineUpdated(MediaPlayer*) override;
684
685     void scheduleMediaEngineWasUpdated();
686     void mediaEngineWasUpdated();
687
688     void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*) override;
689     void mediaPlayerCharacteristicChanged(MediaPlayer*) override;
690
691 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
692     RefPtr<ArrayBuffer> mediaPlayerCachedKeyForKeyId(const String& keyId) const override;
693     bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*) override;
694     String mediaPlayerMediaKeysStorageDirectory() const override;
695 #endif
696
697 #if ENABLE(ENCRYPTED_MEDIA)
698     void mediaPlayerInitializationDataEncountered(const String&, RefPtr<ArrayBuffer>&&) final;
699     void mediaPlayerWaitingForKeyChanged() final;
700
701     void attemptToDecrypt();
702     void attemptToResumePlaybackIfNecessary();
703
704     // CDMClient
705     void cdmClientAttemptToResumePlaybackIfNecessary() final;
706 #endif
707     
708 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
709     void mediaPlayerCurrentPlaybackTargetIsWirelessChanged(MediaPlayer*) override;
710     void enqueuePlaybackTargetAvailabilityChangedEvent();
711
712     using EventTarget::dispatchEvent;
713     void dispatchEvent(Event&) override;
714 #endif
715
716 #if ENABLE(MEDIA_SESSION)
717     void setSessionInternal(MediaSession&);
718 #endif
719
720     String mediaPlayerReferrer() const override;
721     String mediaPlayerUserAgent() const override;
722
723     void mediaPlayerEnterFullscreen() override;
724     void mediaPlayerExitFullscreen() override;
725     bool mediaPlayerIsFullscreen() const override;
726     bool mediaPlayerIsFullscreenPermitted() const override;
727     bool mediaPlayerIsVideo() const override;
728     LayoutRect mediaPlayerContentBoxRect() const override;
729     float mediaPlayerContentsScale() const override;
730     void mediaPlayerSetSize(const IntSize&) override;
731     void mediaPlayerPause() override;
732     void mediaPlayerPlay() override;
733     bool mediaPlayerPlatformVolumeConfigurationRequired() const override;
734     bool mediaPlayerIsPaused() const override;
735     bool mediaPlayerIsLooping() const override;
736     CachedResourceLoader* mediaPlayerCachedResourceLoader() override;
737     RefPtr<PlatformMediaResourceLoader> mediaPlayerCreateResourceLoader() override;
738     bool mediaPlayerShouldUsePersistentCache() const override;
739     const String& mediaPlayerMediaCacheDirectory() const override;
740
741 #if PLATFORM(WIN) && USE(AVFOUNDATION)
742     GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const override;
743 #endif
744
745     void mediaPlayerActiveSourceBuffersChanged(const MediaPlayer*) override;
746
747     void mediaPlayerHandlePlaybackCommand(PlatformMediaSession::RemoteControlCommandType command) override { didReceiveRemoteControlCommand(command, nullptr); }
748     String sourceApplicationIdentifier() const override;
749     String mediaPlayerSourceApplicationIdentifier() const override { return sourceApplicationIdentifier(); }
750     Vector<String> mediaPlayerPreferredAudioCharacteristics() const override;
751
752 #if PLATFORM(IOS_FAMILY)
753     String mediaPlayerNetworkInterfaceName() const override;
754     bool mediaPlayerGetRawCookies(const URL&, Vector<Cookie>&) const override;
755 #endif
756
757     bool mediaPlayerIsInMediaDocument() const final;
758     void mediaPlayerEngineFailedToLoad() const final;
759
760     double mediaPlayerRequestedPlaybackRate() const final;
761     VideoFullscreenMode mediaPlayerFullscreenMode() const final { return fullscreenMode(); }
762     bool mediaPlayerIsVideoFullscreenStandby() const final { return m_videoFullscreenStandby; }
763     bool mediaPlayerShouldDisableSleep() const final { return shouldDisableSleep() == SleepType::Display; }
764     bool mediaPlayerShouldCheckHardwareSupport() const final;
765     const Vector<ContentType>& mediaContentTypesRequiringHardwareSupport() const final;
766
767 #if USE(GSTREAMER)
768     void requestInstallMissingPlugins(const String& details, const String& description, MediaPlayerRequestInstallMissingPluginsCallback&) final;
769 #endif
770
771     void pendingActionTimerFired();
772     void progressEventTimerFired();
773     void playbackProgressTimerFired();
774     void scanTimerFired();
775     void seekTask();
776     void startPlaybackProgressTimer();
777     void startProgressEventTimer();
778     void stopPeriodicTimers();
779     void cancelPendingTasks();
780     void closeTaskQueues();
781
782     void seek(const MediaTime&);
783     void seekInternal(const MediaTime&);
784     void seekWithTolerance(const MediaTime&, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance, bool fromDOM);
785     void finishSeek();
786     void clearSeeking();
787     void addPlayedRange(const MediaTime& start, const MediaTime& end);
788     
789     void scheduleTimeupdateEvent(bool periodicEvent);
790     virtual void scheduleResizeEvent() { }
791     virtual void scheduleResizeEventIfSizeChanged() { }
792
793     void selectMediaResource();
794     void loadResource(const URL&, ContentType&, const String& keySystem);
795     void scheduleNextSourceChild();
796     void loadNextSourceChild();
797     void userCancelledLoad();
798     void clearMediaPlayer();
799     bool havePotentialSourceChild();
800     void noneSupported();
801     void cancelPendingEventsAndCallbacks();
802     void waitForSourceChange();
803     void prepareToPlay();
804
805     URL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
806
807 #if ENABLE(VIDEO_TRACK)
808     void updateActiveTextTrackCues(const MediaTime&);
809     HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
810
811     enum ReconfigureMode {
812         Immediately,
813         AfterDelay,
814     };
815     void markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode);
816     void captionPreferencesChanged() override;
817     CaptionUserPreferences::CaptionDisplayMode captionDisplayMode();
818 #endif
819
820     // These "internal" functions do not check user gesture restrictions.
821     void playInternal();
822     void pauseInternal();
823
824     void prepareForLoad();
825     void allowVideoRendering();
826
827     bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
828     void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
829     void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
830
831     void scheduleUpdatePlayState();
832     void updatePlayState();
833
834     void updateVolume();
835     void setPlaying(bool);
836     bool potentiallyPlaying() const;
837     bool endedPlayback() const;
838     bool stoppedDueToErrors() const;
839     bool pausedForUserInteraction() const;
840     bool couldPlayIfEnoughData() const;
841     void dispatchPlayPauseEventsIfNeedsQuirks();
842     SuccessOr<MediaPlaybackDenialReason> canTransitionFromAutoplayToPlay() const;
843
844     void setAutoplayEventPlaybackState(AutoplayEventPlaybackState);
845     void userDidInterfereWithAutoplay();
846     void handleAutoplayEvent(AutoplayEvent);
847
848     MediaTime minTimeSeekable() const;
849     MediaTime maxTimeSeekable() const;
850
851     // Pauses playback without changing any states or generating events
852     void setPausedInternal(bool);
853
854     void setPlaybackRateInternal(double);
855
856     void mediaCanStart(Document&) final;
857
858     void invalidateCachedTime() const;
859     void refreshCachedTime() const;
860
861     bool hasMediaControls() const;
862     bool createMediaControls();
863     void configureMediaControls();
864
865     void prepareMediaFragmentURI();
866     void applyMediaFragmentURI();
867
868     void changeNetworkStateFromLoadingToIdle();
869
870     void removeBehaviorRestrictionsAfterFirstUserGesture(MediaElementSession::BehaviorRestrictions mask = MediaElementSession::AllRestrictions);
871
872     void updateMediaController();
873     bool isBlocked() const;
874     bool isBlockedOnMediaController() const;
875     bool hasCurrentSrc() const override { return !m_currentSrc.isEmpty(); }
876     bool isLiveStream() const override { return movieLoadType() == MediaPlayerEnums::LiveStream; }
877
878     void updateSleepDisabling();
879     enum class SleepType {
880         None,
881         Display,
882         System,
883     };
884     SleepType shouldDisableSleep() const;
885
886 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
887     void didAddUserAgentShadowRoot(ShadowRoot&) override;
888     DOMWrapperWorld& ensureIsolatedWorld();
889     bool ensureMediaControlsInjectedScript();
890 #endif
891
892     PlatformMediaSession::MediaType mediaType() const override;
893     PlatformMediaSession::MediaType presentationType() const override;
894     PlatformMediaSession::DisplayType displayType() const override;
895     PlatformMediaSession::CharacteristicsFlags characteristics() const final;
896
897     void suspendPlayback() override;
898     void resumeAutoplaying() override;
899     void mayResumePlayback(bool shouldResume) override;
900     uint64_t mediaSessionUniqueIdentifier() const final;
901     String mediaSessionTitle() const override;
902     double mediaSessionDuration() const override { return duration(); }
903     double mediaSessionCurrentTime() const override { return currentTime(); }
904     bool canReceiveRemoteControlCommands() const override { return true; }
905     void didReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument*) override;
906     bool shouldOverrideBackgroundPlaybackRestriction(PlatformMediaSession::InterruptionType) const override;
907     bool shouldOverrideBackgroundLoadingRestriction() const override;
908     bool canProduceAudio() const final;
909     bool processingUserGestureForMedia() const final;
910     bool hasMediaStreamSource() const final;
911     void processIsSuspendedChanged() final;
912
913     void pageMutedStateDidChange() override;
914
915 #if USE(AUDIO_SESSION) && PLATFORM(MAC)
916     void hardwareMutedStateDidChange(AudioSession*) final;
917 #endif
918
919     bool effectiveMuted() const;
920     double effectiveVolume() const;
921
922     void registerWithDocument(Document&);
923     void unregisterWithDocument(Document&);
924
925     void updateCaptionContainer();
926     void ensureMediaControlsShadowRoot();
927
928     using JSSetupFunction = WTF::Function<bool(JSDOMGlobalObject&, JSC::JSGlobalObject&, ScriptController&, DOMWrapperWorld&)>;
929     bool setupAndCallJS(const JSSetupFunction&);
930
931 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
932     void prepareForDocumentSuspension() final;
933     void resumeFromDocumentSuspension() final;
934
935     void scheduleUpdateMediaState();
936     void updateMediaState();
937     bool hasPlaybackTargetAvailabilityListeners() const { return m_hasPlaybackTargetAvailabilityListeners; }
938 #endif
939
940     bool isVideoTooSmallForInlinePlayback();
941     void updateShouldAutoplay();
942
943     void pauseAfterDetachedTask();
944     void updatePlaybackControlsManager();
945     void schedulePlaybackControlsManagerUpdate();
946     void playbackControlsManagerBehaviorRestrictionsTimerFired();
947
948     void updateRenderer();
949
950     void updatePageScaleFactorJSProperty();
951     void updateUsesLTRUserInterfaceLayoutDirectionJSProperty();
952     void setControllerJSProperty(const char*, JSC::JSValue);
953
954     void addBehaviorRestrictionsOnEndIfNecessary();
955     void handleSeekToPlaybackPosition(double);
956     void seekToPlaybackPositionEndedTimerFired();
957
958     void applicationWillResignActive() final;
959     void applicationDidBecomeActive() final;
960
961     void setInActiveDocument(bool);
962
963 #if !RELEASE_LOG_DISABLED
964     const void* mediaPlayerLogIdentifier() final { return logIdentifier(); }
965     const Logger& mediaPlayerLogger() final { return logger(); }
966 #endif
967
968     Timer m_progressEventTimer;
969     Timer m_playbackProgressTimer;
970     Timer m_scanTimer;
971     Timer m_playbackControlsManagerBehaviorRestrictionsTimer;
972     Timer m_seekToPlaybackPositionEndedTimer;
973     DeferrableTask<Timer> m_configureTextTracksTask;
974     DeferrableTask<Timer> m_checkPlaybackTargetCompatablityTask;
975     DeferrableTask<Timer> m_updateMediaStateTask;
976     DeferrableTask<Timer> m_mediaEngineUpdatedTask;
977     DeferrableTask<Timer> m_updatePlayStateTask;
978     DeferrableTask<Timer> m_resumeTaskQueue;
979     DeferrableTask<Timer> m_seekTaskQueue;
980     DeferrableTask<Timer> m_playbackControlsManagerBehaviorRestrictionsQueue;
981     GenericTaskQueue<Timer> m_promiseTaskQueue;
982     GenericTaskQueue<Timer> m_pauseAfterDetachedTaskQueue;
983     GenericTaskQueue<Timer> m_resourceSelectionTaskQueue;
984     GenericTaskQueue<Timer> m_visibilityChangeTaskQueue;
985     GenericTaskQueue<Timer> m_fullscreenTaskQueue;
986     GenericTaskQueue<Timer> m_playbackTargetIsWirelessQueue;
987     RefPtr<TimeRanges> m_playedTimeRanges;
988     UniqueRef<MainThreadGenericEventQueue> m_asyncEventQueue;
989 #if PLATFORM(IOS_FAMILY)
990     DeferrableTask<Timer> m_volumeRevertTaskQueue;
991 #endif
992
993     PlayPromiseVector m_pendingPlayPromises;
994
995     double m_requestedPlaybackRate { 1 };
996     double m_reportedPlaybackRate { 1 };
997     double m_defaultPlaybackRate { 1 };
998     bool m_webkitPreservesPitch { true };
999     NetworkState m_networkState { NETWORK_EMPTY };
1000     ReadyState m_readyState { HAVE_NOTHING };
1001     ReadyState m_readyStateMaximum { HAVE_NOTHING };
1002     URL m_currentSrc;
1003
1004     RefPtr<MediaError> m_error;
1005
1006     struct PendingSeek {
1007         WTF_MAKE_STRUCT_FAST_ALLOCATED;
1008         PendingSeek(const MediaTime& now, const MediaTime& targetTime, const MediaTime& negativeTolerance, const MediaTime& positiveTolerance)
1009             : now(now)
1010             , targetTime(targetTime)
1011             , negativeTolerance(negativeTolerance)
1012             , positiveTolerance(positiveTolerance)
1013         {
1014         }
1015         MediaTime now;
1016         MediaTime targetTime;
1017         MediaTime negativeTolerance;
1018         MediaTime positiveTolerance;
1019     };
1020     std::unique_ptr<PendingSeek> m_pendingSeek;
1021     SeekType m_pendingSeekType { NoSeek };
1022
1023     double m_volume { 1 };
1024     bool m_volumeInitialized { false };
1025     MediaTime m_lastSeekTime;
1026     
1027     MonotonicTime m_previousProgressTime { MonotonicTime::infinity() };
1028     double m_playbackStartedTime { 0 };
1029
1030     // The last time a timeupdate event was sent (based on monotonic clock).
1031     MonotonicTime m_clockTimeAtLastUpdateEvent;
1032
1033     // The last time a timeupdate event was sent in movie time.
1034     MediaTime m_lastTimeUpdateEventMovieTime;
1035     
1036     // Loading state.
1037     enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
1038     LoadState m_loadState { WaitingForSource };
1039     RefPtr<HTMLSourceElement> m_currentSourceNode;
1040     RefPtr<HTMLSourceElement> m_nextChildNodeToConsider;
1041
1042     VideoFullscreenMode m_videoFullscreenMode { VideoFullscreenModeNone };
1043     bool m_videoFullscreenStandby { false };
1044     bool m_preparedForInline;
1045     WTF::Function<void()> m_preparedForInlineCompletionHandler;
1046
1047     bool m_temporarilyAllowingInlinePlaybackAfterFullscreen { false };
1048
1049 #if PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
1050     RetainPtr<PlatformLayer> m_videoFullscreenLayer;
1051     FloatRect m_videoFullscreenFrame;
1052     MediaPlayerEnums::VideoGravity m_videoFullscreenGravity { MediaPlayer::VideoGravityResizeAspect };
1053 #endif
1054
1055     RefPtr<MediaPlayer> m_player;
1056
1057     MediaPlayerEnums::Preload m_preload { MediaPlayer::Auto };
1058
1059     DisplayMode m_displayMode { Unknown };
1060
1061     // Counter incremented while processing a callback from the media player, so we can avoid
1062     // calling the media engine recursively.
1063     int m_processingMediaPlayerCallback { 0 };
1064
1065 #if ENABLE(MEDIA_SESSION)
1066     String m_kind;
1067     RefPtr<MediaSession> m_session;
1068     bool m_shouldDuck { false };
1069     uint64_t m_elementID;
1070 #endif
1071
1072 #if ENABLE(MEDIA_SOURCE)
1073     RefPtr<MediaSource> m_mediaSource;
1074     unsigned m_droppedVideoFrames { 0 };
1075 #endif
1076
1077     mutable MediaTime m_cachedTime;
1078     mutable MonotonicTime m_clockTimeAtLastCachedTimeUpdate;
1079     mutable MonotonicTime m_minimumClockTimeToUpdateCachedTime;
1080
1081     MediaTime m_fragmentStartTime;
1082     MediaTime m_fragmentEndTime;
1083
1084     using PendingActionFlags = unsigned;
1085     PendingActionFlags m_pendingActionFlags { 0 };
1086
1087     enum ActionAfterScanType { Nothing, Play, Pause };
1088     ActionAfterScanType m_actionAfterScan { Nothing };
1089
1090     enum ScanType { Seek, Scan };
1091     ScanType m_scanType { Scan };
1092     ScanDirection m_scanDirection { Forward };
1093
1094     BufferingPolicy m_bufferingPolicy { BufferingPolicy::Default };
1095
1096     bool m_firstTimePlaying : 1;
1097     bool m_playing : 1;
1098     bool m_isWaitingUntilMediaCanStart : 1;
1099     bool m_shouldDelayLoadEvent : 1;
1100     bool m_haveFiredLoadedData : 1;
1101     bool m_inActiveDocument : 1;
1102     bool m_autoplaying : 1;
1103     bool m_muted : 1;
1104     bool m_explicitlyMuted : 1;
1105     bool m_initiallyMuted : 1;
1106     bool m_paused : 1;
1107     bool m_seeking : 1;
1108     bool m_seekRequested : 1;
1109
1110     // data has not been loaded since sending a "stalled" event
1111     bool m_sentStalledEvent : 1;
1112
1113     // time has not changed since sending an "ended" event
1114     bool m_sentEndEvent : 1;
1115
1116     bool m_pausedInternal : 1;
1117
1118     bool m_closedCaptionsVisible : 1;
1119     bool m_webkitLegacyClosedCaptionOverride : 1;
1120     bool m_completelyLoaded : 1;
1121     bool m_havePreparedToPlay : 1;
1122     bool m_parsingInProgress : 1;
1123     bool m_elementIsHidden : 1;
1124     bool m_elementWasRemovedFromDOM : 1;
1125     bool m_creatingControls : 1;
1126     bool m_receivedLayoutSizeChanged : 1;
1127     bool m_hasEverNotifiedAboutPlaying : 1;
1128
1129     bool m_hasEverHadAudio : 1;
1130     bool m_hasEverHadVideo : 1;
1131
1132 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1133     bool m_mediaControlsDependOnPageScaleFactor : 1;
1134     bool m_haveSetUpCaptionContainer : 1;
1135 #endif
1136
1137     bool m_isScrubbingRemotely : 1;
1138     bool m_waitingToEnterFullscreen : 1;
1139
1140 #if ENABLE(VIDEO_TRACK)
1141     bool m_tracksAreReady : 1;
1142     bool m_haveVisibleTextTrack : 1;
1143     bool m_processingPreferenceChange : 1;
1144
1145     AutoplayEventPlaybackState m_autoplayEventPlaybackState { AutoplayEventPlaybackState::None };
1146
1147     String m_subtitleTrackLanguage;
1148     MediaTime m_lastTextTrackUpdateTime { -1, 1 };
1149
1150     Optional<CaptionUserPreferences::CaptionDisplayMode> m_captionDisplayMode;
1151
1152     RefPtr<AudioTrackList> m_audioTracks;
1153     RefPtr<TextTrackList> m_textTracks;
1154     RefPtr<VideoTrackList> m_videoTracks;
1155     Vector<RefPtr<TextTrack>> m_textTracksWhenResourceSelectionBegan;
1156
1157     CueIntervalTree m_cueTree;
1158
1159     CueList m_currentlyActiveCues;
1160     int m_ignoreTrackDisplayUpdate { 0 };
1161
1162     bool m_requireCaptionPreferencesChangedCallbacks { false };
1163 #endif
1164
1165 #if ENABLE(WEB_AUDIO)
1166     // This is a weak reference, since m_audioSourceNode holds a reference to us.
1167     // The value is set just after the MediaElementAudioSourceNode is created.
1168     // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
1169     MediaElementAudioSourceNode* m_audioSourceNode { nullptr };
1170 #endif
1171
1172     String m_mediaGroup;
1173     friend class MediaController;
1174     RefPtr<MediaController> m_mediaController;
1175
1176     std::unique_ptr<PAL::SleepDisabler> m_sleepDisabler;
1177
1178     WeakPtr<const MediaResourceLoader> m_lastMediaResourceLoaderForTesting;
1179
1180     friend class TrackDisplayUpdateScope;
1181
1182     RefPtr<Blob> m_blob;
1183     MediaProvider m_mediaProvider;
1184
1185 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
1186     RefPtr<WebKitMediaKeys> m_webKitMediaKeys;
1187 #endif
1188 #if ENABLE(ENCRYPTED_MEDIA)
1189     RefPtr<MediaKeys> m_mediaKeys;
1190     bool m_attachingMediaKeys { false };
1191     bool m_playbackBlockedWaitingForKey { false };
1192     GenericTaskQueue<Timer> m_encryptedMediaQueue;
1193 #endif
1194
1195 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
1196     Ref<RemotePlayback> m_remote;
1197 #endif
1198
1199     std::unique_ptr<MediaElementSession> m_mediaSession;
1200     size_t m_reportedExtraMemoryCost { 0 };
1201
1202 #if !RELEASE_LOG_DISABLED
1203     RefPtr<Logger> m_logger;
1204     const void* m_logIdentifier;
1205 #endif
1206
1207 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1208     friend class MediaControlsHost;
1209     RefPtr<MediaControlsHost> m_mediaControlsHost;
1210     RefPtr<DOMWrapperWorld> m_isolatedWorld;
1211 #endif
1212
1213 #if ENABLE(MEDIA_STREAM)
1214     RefPtr<MediaStream> m_mediaStreamSrcObject;
1215     bool m_settingMediaStreamSrcObject { false };
1216 #endif
1217
1218 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
1219     MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
1220     bool m_hasPlaybackTargetAvailabilityListeners { false };
1221     bool m_failedToPlayToWirelessTarget { false };
1222 #endif
1223
1224     bool m_isPlayingToWirelessTarget { false };
1225     bool m_playingOnSecondScreen { false };
1226     bool m_removedBehaviorRestrictionsAfterFirstUserGesture { false };
1227 };
1228
1229 String convertEnumerationToString(HTMLMediaElement::AutoplayEventPlaybackState);
1230
1231 } // namespace WebCore
1232
1233 namespace WTF {
1234
1235 template<> struct LogArgument<WebCore::HTMLMediaElement::AutoplayEventPlaybackState> {
1236     static String toString(WebCore::HTMLMediaElement::AutoplayEventPlaybackState reason) { return convertEnumerationToString(reason); }
1237 };
1238
1239 #if ENABLE(VIDEO_TRACK) && !defined(NDEBUG)
1240
1241 // Template specialization required by PodIntervalTree in debug mode.
1242 template<> struct ValueToString<WebCore::TextTrackCue*> {
1243     static String string(const WebCore::TextTrackCue* cue) { return cue->debugString(); }
1244 };
1245
1246 #endif
1247
1248 #ifndef NDEBUG
1249
1250 template<> struct ValueToString<MediaTime> {
1251     static String string(const MediaTime& time) { return toString(time); }
1252 };
1253
1254 #endif
1255
1256 } // namespace WTF
1257
1258 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLMediaElement)
1259     static bool isType(const WebCore::Element& element) { return element.isMediaElement(); }
1260     static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
1261 SPECIALIZE_TYPE_TRAITS_END()
1262
1263 #endif