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