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