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