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