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