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