1/*
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 COMPUTER, 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 COMPUTER, 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#ifndef HTMLMediaElement_h
27#define HTMLMediaElement_h
28
29#if ENABLE(VIDEO)
30#include "HTMLElement.h"
31#include "ActiveDOMObject.h"
32#include "GenericEventQueue.h"
33#include "MediaCanStartListener.h"
34#include "MediaControllerInterface.h"
35#include "MediaPlayer.h"
36
37#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
38#include "MediaPlayerProxy.h"
39#endif
40
41#if ENABLE(VIDEO_TRACK)
42#include "AudioTrack.h"
43#include "CaptionUserPreferences.h"
44#include "PODIntervalTree.h"
45#include "TextTrack.h"
46#include "TextTrackCue.h"
47#include "VideoTrack.h"
48#endif
49
50namespace WebCore {
51
52#if USE(AUDIO_SESSION)
53class AudioSessionManagerToken;
54#endif
55#if ENABLE(WEB_AUDIO)
56class AudioSourceProvider;
57class MediaElementAudioSourceNode;
58#endif
59class Event;
60class HTMLSourceElement;
61class HTMLTrackElement;
62class KURL;
63class MediaController;
64class MediaControls;
65class MediaError;
66class PageActivityAssertionToken;
67class TimeRanges;
68#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
69class Widget;
70#endif
71#if PLATFORM(MAC)
72class DisplaySleepDisabler;
73#endif
74#if ENABLE(ENCRYPTED_MEDIA_V2)
75class MediaKeys;
76#endif
77
78#if ENABLE(VIDEO_TRACK)
79class AudioTrackList;
80class AudioTrackPrivate;
81class InbandTextTrackPrivate;
82class TextTrackList;
83class VideoTrackList;
84class VideoTrackPrivate;
85
86typedef PODIntervalTree<double, TextTrackCue*> CueIntervalTree;
87typedef CueIntervalTree::IntervalType CueInterval;
88typedef Vector<CueInterval> CueList;
89#endif
90
91// FIXME: The inheritance from MediaPlayerClient here should be private inheritance.
92// But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
93// no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
94
95class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, public MediaPlayerSupportsTypeClient, private MediaCanStartListener, public ActiveDOMObject, public MediaControllerInterface
96#if ENABLE(VIDEO_TRACK)
97    , private AudioTrackClient
98    , private TextTrackClient
99    , private VideoTrackClient
100#endif
101#if USE(PLATFORM_TEXT_TRACK_MENU)
102    , public PlatformTextTrackMenuClient
103#endif
104{
105public:
106    MediaPlayer* player() const { return m_player.get(); }
107
108    virtual bool isVideo() const = 0;
109    virtual bool hasVideo() const { return false; }
110    virtual bool hasAudio() const;
111
112    void rewind(double timeDelta);
113    void returnToRealtime();
114
115    // Eventually overloaded in HTMLVideoElement
116    virtual bool supportsFullscreen() const { return false; };
117
118    virtual bool supportsSave() const;
119    virtual bool supportsScanning() const;
120
121    virtual bool doesHaveAttribute(const AtomicString&) const override;
122
123    PlatformMedia platformMedia() const;
124#if USE(ACCELERATED_COMPOSITING)
125    PlatformLayer* platformLayer() const;
126#endif
127
128    enum DelayedActionType {
129        LoadMediaResource = 1 << 0,
130        ConfigureTextTracks = 1 << 1,
131        TextTrackChangesNotification = 1 << 2,
132        ConfigureTextTrackDisplay = 1 << 3,
133    };
134    void scheduleDelayedAction(DelayedActionType);
135
136    MediaPlayer::MovieLoadType movieLoadType() const;
137
138    bool inActiveDocument() const { return m_inActiveDocument; }
139
140// DOM API
141// error state
142    PassRefPtr<MediaError> error() const;
143
144// network state
145    void setSrc(const String&);
146    const KURL& currentSrc() const { return m_currentSrc; }
147
148    enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
149    NetworkState networkState() const;
150
151    String preload() const;
152    void setPreload(const String&);
153
154    PassRefPtr<TimeRanges> buffered() const;
155    void load();
156    String canPlayType(const String& mimeType, const String& keySystem = String(), const KURL& = KURL()) const;
157
158// ready state
159    ReadyState readyState() const;
160    bool seeking() const;
161
162// playback state
163    double currentTime() const;
164    void setCurrentTime(double, ExceptionCode&);
165    double initialTime() const;
166    double startTime() const;
167    double duration() const;
168    bool paused() const;
169    double defaultPlaybackRate() const;
170    void setDefaultPlaybackRate(double);
171    double playbackRate() const;
172    void setPlaybackRate(double);
173    void updatePlaybackRate();
174    bool webkitPreservesPitch() const;
175    void setWebkitPreservesPitch(bool);
176    PassRefPtr<TimeRanges> played();
177    PassRefPtr<TimeRanges> seekable() const;
178    bool ended() const;
179    bool autoplay() const;
180    void setAutoplay(bool b);
181    bool loop() const;
182    void setLoop(bool b);
183    void play();
184    void pause();
185
186// captions
187    bool webkitHasClosedCaptions() const;
188    bool webkitClosedCaptionsVisible() const;
189    void setWebkitClosedCaptionsVisible(bool);
190
191#if ENABLE(MEDIA_STATISTICS)
192// Statistics
193    unsigned webkitAudioDecodedByteCount() const;
194    unsigned webkitVideoDecodedByteCount() const;
195#endif
196
197#if ENABLE(MEDIA_SOURCE)
198//  Media Source.
199    void setSourceState(const String&);
200#endif
201
202#if ENABLE(ENCRYPTED_MEDIA)
203    void webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionCode&);
204    void webkitGenerateKeyRequest(const String& keySystem, ExceptionCode&);
205    void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionCode&);
206    void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionCode&);
207    void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionCode&);
208
209    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded);
210    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror);
211    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage);
212#endif
213#if ENABLE(ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA_V2)
214    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey);
215#endif
216
217#if ENABLE(ENCRYPTED_MEDIA_V2)
218    MediaKeys* keys() const { return m_mediaKeys.get(); }
219    void setMediaKeys(MediaKeys*);
220#endif
221
222// controls
223    bool controls() const;
224    void setControls(bool);
225    double volume() const;
226    void setVolume(double, ExceptionCode&);
227    bool muted() const;
228    void setMuted(bool);
229
230    void togglePlayState();
231    void beginScrubbing();
232    void endScrubbing();
233
234    bool canPlay() const;
235
236    double percentLoaded() const;
237
238#if ENABLE(VIDEO_TRACK)
239    PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, const String& language, ExceptionCode&);
240    PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, ExceptionCode& ec) { return addTextTrack(kind, label, emptyString(), ec); }
241    PassRefPtr<TextTrack> addTextTrack(const String& kind, ExceptionCode& ec) { return addTextTrack(kind, emptyString(), emptyString(), ec); }
242
243    AudioTrackList* audioTracks();
244    TextTrackList* textTracks();
245    VideoTrackList* videoTracks();
246
247    CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
248
249    void addAudioTrack(PassRefPtr<AudioTrack>);
250    void addTextTrack(PassRefPtr<TextTrack>);
251    void addVideoTrack(PassRefPtr<VideoTrack>);
252    void removeAudioTrack(AudioTrack*);
253    void removeTextTrack(TextTrack*);
254    void removeVideoTrack(VideoTrack*);
255    void removeAllInbandTracks();
256    void closeCaptionTracksChanged();
257    void notifyMediaPlayerOfTextTrackChanges();
258
259    virtual void didAddTextTrack(HTMLTrackElement*);
260    virtual void didRemoveTextTrack(HTMLTrackElement*);
261
262    virtual void mediaPlayerDidAddAudioTrack(PassRefPtr<AudioTrackPrivate>) OVERRIDE;
263    virtual void mediaPlayerDidAddTextTrack(PassRefPtr<InbandTextTrackPrivate>) OVERRIDE;
264    virtual void mediaPlayerDidAddVideoTrack(PassRefPtr<VideoTrackPrivate>) OVERRIDE;
265    virtual void mediaPlayerDidRemoveAudioTrack(PassRefPtr<AudioTrackPrivate>) OVERRIDE;
266    virtual void mediaPlayerDidRemoveTextTrack(PassRefPtr<InbandTextTrackPrivate>) OVERRIDE;
267    virtual void mediaPlayerDidRemoveVideoTrack(PassRefPtr<VideoTrackPrivate>) OVERRIDE;
268
269#if USE(PLATFORM_TEXT_TRACK_MENU)
270    virtual void setSelectedTextTrack(PassRefPtr<PlatformTextTrack>) OVERRIDE;
271    virtual Vector<RefPtr<PlatformTextTrack> > platformTextTracks() OVERRIDE;
272    PlatformTextTrackMenuInterface* platformTextTrackMenu();
273#endif
274
275    struct TrackGroup {
276        enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
277
278        TrackGroup(GroupKind kind)
279            : visibleTrack(0)
280            , defaultTrack(0)
281            , kind(kind)
282            , hasSrcLang(false)
283        {
284        }
285
286        Vector<RefPtr<TextTrack> > tracks;
287        RefPtr<TextTrack> visibleTrack;
288        RefPtr<TextTrack> defaultTrack;
289        GroupKind kind;
290        bool hasSrcLang;
291    };
292
293    void configureTextTrackGroupForLanguage(const TrackGroup&) const;
294    void configureTextTracks();
295    void configureTextTrackGroup(const TrackGroup&);
296
297    void setSelectedTextTrack(TextTrack*);
298
299    bool textTracksAreReady() const;
300    void configureTextTrackDisplay();
301    void updateTextTrackDisplay();
302
303    // AudioTrackClient
304    virtual void audioTrackEnabledChanged(AudioTrack*);
305
306    // TextTrackClient
307    virtual void textTrackReadyStateChanged(TextTrack*);
308    virtual void textTrackKindChanged(TextTrack*);
309    virtual void textTrackModeChanged(TextTrack*);
310    virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*);
311    virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*);
312    virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>);
313    virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>);
314
315    // VideoTrackClient
316    virtual void videoTrackSelectedChanged(VideoTrack*);
317
318    bool requiresTextTrackRepresentation() const;
319    void setTextTrackRepresentation(TextTrackRepresentation*);
320#endif
321
322#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
323    void allocateMediaPlayerIfNecessary();
324    void setNeedWidgetUpdate(bool needWidgetUpdate) { m_needWidgetUpdate = needWidgetUpdate; }
325    void deliverNotification(MediaPlayerProxyNotificationType notification);
326    void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
327    void getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values);
328    void createMediaPlayerProxy();
329    void updateWidget(PluginCreationOption);
330#endif
331
332    // EventTarget function.
333    // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
334    // causes an ambiguity error at compile time. This class's constructor
335    // ensures that both implementations return document, so return the result
336    // of one of them here.
337    virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE { return HTMLElement::scriptExecutionContext(); }
338
339    bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
340
341    bool isFullscreen() const;
342    void toggleFullscreenState();
343    void enterFullscreen();
344    void exitFullscreen();
345
346    bool hasClosedCaptions() const;
347    bool closedCaptionsVisible() const;
348    void setClosedCaptionsVisible(bool);
349
350    MediaControls* mediaControls() const;
351
352    void sourceWasRemoved(HTMLSourceElement*);
353    void sourceWasAdded(HTMLSourceElement*);
354
355    void privateBrowsingStateDidChange();
356
357    // Media cache management.
358    static void getSitesInMediaCache(Vector<String>&);
359    static void clearMediaCache();
360    static void clearMediaCacheForSite(const String&);
361    static void resetMediaEngines();
362
363    bool isPlaying() const { return m_playing; }
364
365    virtual bool hasPendingActivity() const;
366
367#if ENABLE(WEB_AUDIO)
368    MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
369    void setAudioSourceNode(MediaElementAudioSourceNode*);
370
371    AudioSourceProvider* audioSourceProvider();
372#endif
373
374    enum InvalidURLAction { DoNothing, Complain };
375    bool isSafeToLoadURL(const KURL&, InvalidURLAction);
376
377    const String& mediaGroup() const;
378    void setMediaGroup(const String&);
379
380    MediaController* controller() const;
381    void setController(PassRefPtr<MediaController>);
382
383    virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
384
385    virtual bool willRespondToMouseClickEvents() OVERRIDE;
386
387protected:
388    HTMLMediaElement(const QualifiedName&, Document*, bool);
389    virtual ~HTMLMediaElement();
390
391    virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
392    virtual void finishParsingChildren();
393    virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
394    virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
395
396    virtual void didMoveToNewDocument(Document* oldDocument) OVERRIDE;
397
398    enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
399    DisplayMode displayMode() const { return m_displayMode; }
400    virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
401
402    virtual bool isMediaElement() const { return true; }
403
404    // Restrictions to change default behaviors.
405    enum BehaviorRestrictionFlags {
406        NoRestrictions = 0,
407        RequireUserGestureForLoadRestriction = 1 << 0,
408        RequireUserGestureForRateChangeRestriction = 1 << 1,
409        RequireUserGestureForFullscreenRestriction = 1 << 2,
410        RequirePageConsentToLoadMediaRestriction = 1 << 3,
411        RequirePageConsentToResumeMediaRestriction = 1 << 4,
412    };
413    typedef unsigned BehaviorRestrictions;
414
415    bool userGestureRequiredForLoad() const { return m_restrictions & RequireUserGestureForLoadRestriction; }
416    bool userGestureRequiredForRateChange() const { return m_restrictions & RequireUserGestureForRateChangeRestriction; }
417    bool userGestureRequiredForFullscreen() const { return m_restrictions & RequireUserGestureForFullscreenRestriction; }
418    bool pageConsentRequiredForLoad() const { return m_restrictions & RequirePageConsentToLoadMediaRestriction; }
419    bool pageConsentRequiredForResume() const { return m_restrictions & RequirePageConsentToResumeMediaRestriction; }
420
421    void addBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions |= restriction; }
422    void removeBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions &= ~restriction; }
423
424#if ENABLE(VIDEO_TRACK)
425    bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0 || !m_textTracks || !m_cueTree.size(); }
426    void beginIgnoringTrackDisplayUpdateRequests();
427    void endIgnoringTrackDisplayUpdateRequests();
428#endif
429
430private:
431    void createMediaPlayer();
432
433    virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return true; }
434    virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
435
436    virtual bool hasCustomFocusLogic() const OVERRIDE;
437    virtual bool supportsFocus() const OVERRIDE;
438    virtual bool isMouseFocusable() const OVERRIDE;
439    virtual bool rendererIsNeeded(const NodeRenderingContext&);
440    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
441    virtual bool childShouldCreateRenderer(const NodeRenderingContext&) const OVERRIDE;
442    virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
443    virtual void removedFrom(ContainerNode*) OVERRIDE;
444    virtual void didRecalcStyle(StyleChange);
445
446    virtual void defaultEventHandler(Event*);
447
448    virtual void didBecomeFullscreenElement();
449    virtual void willStopBeingFullscreenElement();
450
451    // ActiveDOMObject functions.
452    virtual bool canSuspend() const;
453    virtual void suspend(ReasonForSuspension);
454    virtual void resume();
455    virtual void stop();
456
457    virtual void mediaVolumeDidChange();
458
459    virtual void updateDisplayState() { }
460
461    void setReadyState(MediaPlayer::ReadyState);
462    void setNetworkState(MediaPlayer::NetworkState);
463
464    virtual Document* mediaPlayerOwningDocument();
465    virtual void mediaPlayerNetworkStateChanged(MediaPlayer*);
466    virtual void mediaPlayerReadyStateChanged(MediaPlayer*);
467    virtual void mediaPlayerTimeChanged(MediaPlayer*);
468    virtual void mediaPlayerVolumeChanged(MediaPlayer*);
469    virtual void mediaPlayerMuteChanged(MediaPlayer*);
470    virtual void mediaPlayerDurationChanged(MediaPlayer*);
471    virtual void mediaPlayerRateChanged(MediaPlayer*);
472    virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*);
473    virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
474    virtual void mediaPlayerResourceNotSupported(MediaPlayer*);
475    virtual void mediaPlayerRepaint(MediaPlayer*);
476    virtual void mediaPlayerSizeChanged(MediaPlayer*);
477#if USE(ACCELERATED_COMPOSITING)
478    virtual bool mediaPlayerRenderingCanBeAccelerated(MediaPlayer*);
479    virtual void mediaPlayerRenderingModeChanged(MediaPlayer*);
480#endif
481    virtual void mediaPlayerEngineUpdated(MediaPlayer*);
482
483    virtual void mediaPlayerFirstVideoFrameAvailable(MediaPlayer*);
484    virtual void mediaPlayerCharacteristicChanged(MediaPlayer*);
485
486#if ENABLE(ENCRYPTED_MEDIA)
487    virtual void mediaPlayerKeyAdded(MediaPlayer*, const String& keySystem, const String& sessionId) OVERRIDE;
488    virtual void mediaPlayerKeyError(MediaPlayer*, const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) OVERRIDE;
489    virtual void mediaPlayerKeyMessage(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL) OVERRIDE;
490    virtual bool mediaPlayerKeyNeeded(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) OVERRIDE;
491#endif
492
493#if ENABLE(ENCRYPTED_MEDIA_V2)
494    virtual bool mediaPlayerKeyNeeded(MediaPlayer*, Uint8Array*);
495#endif
496
497    virtual String mediaPlayerReferrer() const OVERRIDE;
498    virtual String mediaPlayerUserAgent() const OVERRIDE;
499    virtual CORSMode mediaPlayerCORSMode() const OVERRIDE;
500
501    virtual bool mediaPlayerNeedsSiteSpecificHacks() const OVERRIDE;
502    virtual String mediaPlayerDocumentHost() const OVERRIDE;
503
504    virtual void mediaPlayerEnterFullscreen() OVERRIDE;
505    virtual void mediaPlayerExitFullscreen() OVERRIDE;
506    virtual bool mediaPlayerIsFullscreen() const OVERRIDE;
507    virtual bool mediaPlayerIsFullscreenPermitted() const OVERRIDE;
508    virtual bool mediaPlayerIsVideo() const OVERRIDE;
509    virtual LayoutRect mediaPlayerContentBoxRect() const OVERRIDE;
510    virtual void mediaPlayerSetSize(const IntSize&) OVERRIDE;
511    virtual void mediaPlayerPause() OVERRIDE;
512    virtual void mediaPlayerPlay() OVERRIDE;
513    virtual bool mediaPlayerIsPaused() const OVERRIDE;
514    virtual bool mediaPlayerIsLooping() const OVERRIDE;
515    virtual HostWindow* mediaPlayerHostWindow() OVERRIDE;
516    virtual IntRect mediaPlayerWindowClipRect() OVERRIDE;
517    virtual CachedResourceLoader* mediaPlayerCachedResourceLoader() OVERRIDE;
518
519#if PLATFORM(WIN) && USE(AVFOUNDATION)
520    virtual GraphicsDeviceAdapter* mediaPlayerGraphicsDeviceAdapter(const MediaPlayer*) const OVERRIDE;
521#endif
522
523    void loadTimerFired(Timer<HTMLMediaElement>*);
524    void progressEventTimerFired(Timer<HTMLMediaElement>*);
525    void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
526    void startPlaybackProgressTimer();
527    void startProgressEventTimer();
528    void stopPeriodicTimers();
529
530    void seek(double time, ExceptionCode&);
531    void finishSeek();
532    void checkIfSeekNeeded();
533    void addPlayedRange(double start, double end);
534
535    void scheduleTimeupdateEvent(bool periodicEvent);
536    void scheduleEvent(const AtomicString& eventName);
537
538    // loading
539    void selectMediaResource();
540    void loadResource(const KURL&, ContentType&, const String& keySystem);
541    void scheduleNextSourceChild();
542    void loadNextSourceChild();
543    void userCancelledLoad();
544    void clearMediaPlayer(int flags);
545    bool havePotentialSourceChild();
546    void noneSupported();
547    void mediaEngineError(PassRefPtr<MediaError> err);
548    void cancelPendingEventsAndCallbacks();
549    void waitForSourceChange();
550    void prepareToPlay();
551
552    KURL selectNextSourceChild(ContentType*, String* keySystem, InvalidURLAction);
553
554    void mediaLoadingFailed(MediaPlayer::NetworkState);
555
556#if ENABLE(VIDEO_TRACK)
557    void updateActiveTextTrackCues(double);
558    HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
559
560    enum ReconfigureMode {
561        Immediately,
562        AfterDelay,
563    };
564    void markCaptionAndSubtitleTracksAsUnconfigured(ReconfigureMode);
565    virtual void captionPreferencesChanged() OVERRIDE;
566#endif
567
568    // These "internal" functions do not check user gesture restrictions.
569    void loadInternal();
570    void playInternal();
571    void pauseInternal();
572
573    void prepareForLoad();
574    void allowVideoRendering();
575
576    bool processingMediaPlayerCallback() const { return m_processingMediaPlayerCallback > 0; }
577    void beginProcessingMediaPlayerCallback() { ++m_processingMediaPlayerCallback; }
578    void endProcessingMediaPlayerCallback() { ASSERT(m_processingMediaPlayerCallback); --m_processingMediaPlayerCallback; }
579
580    void updateVolume();
581    void updatePlayState();
582    bool potentiallyPlaying() const;
583    bool endedPlayback() const;
584    bool stoppedDueToErrors() const;
585    bool pausedForUserInteraction() const;
586    bool couldPlayIfEnoughData() const;
587
588    double minTimeSeekable() const;
589    double maxTimeSeekable() const;
590
591    // Pauses playback without changing any states or generating events
592    void setPausedInternal(bool);
593
594    void setPlaybackRateInternal(double);
595
596    virtual void mediaCanStart();
597
598    void setShouldDelayLoadEvent(bool);
599    void invalidateCachedTime();
600    void refreshCachedTime() const;
601
602    bool hasMediaControls() const;
603    bool createMediaControls();
604    void configureMediaControls();
605
606    void prepareMediaFragmentURI();
607    void applyMediaFragmentURI();
608
609    virtual void* preDispatchEventHandler(Event*);
610
611    void changeNetworkStateFromLoadingToIdle();
612
613    void removeBehaviorsRestrictionsAfterFirstUserGesture();
614
615#if ENABLE(MICRODATA)
616    virtual String itemValueText() const;
617    virtual void setItemValueText(const String&, ExceptionCode&);
618#endif
619
620    void updateMediaController();
621    bool isBlocked() const;
622    bool isBlockedOnMediaController() const;
623    bool hasCurrentSrc() const { return !m_currentSrc.isEmpty(); }
624    bool isLiveStream() const { return movieLoadType() == MediaPlayer::LiveStream; }
625    bool isAutoplaying() const { return m_autoplaying; }
626
627#if PLATFORM(MAC)
628    void updateDisableSleep();
629    bool shouldDisableSleep() const;
630#endif
631
632    void registerWithDocument(Document*);
633    void unregisterWithDocument(Document*);
634
635    Timer<HTMLMediaElement> m_loadTimer;
636    Timer<HTMLMediaElement> m_progressEventTimer;
637    Timer<HTMLMediaElement> m_playbackProgressTimer;
638    RefPtr<TimeRanges> m_playedTimeRanges;
639    OwnPtr<GenericEventQueue> m_asyncEventQueue;
640
641    double m_playbackRate;
642    double m_defaultPlaybackRate;
643    bool m_webkitPreservesPitch;
644    NetworkState m_networkState;
645    ReadyState m_readyState;
646    ReadyState m_readyStateMaximum;
647    KURL m_currentSrc;
648
649    RefPtr<MediaError> m_error;
650
651    double m_volume;
652    double m_lastSeekTime;
653
654    unsigned m_previousProgress;
655    double m_previousProgressTime;
656
657    // The last time a timeupdate event was sent (wall clock).
658    double m_lastTimeUpdateEventWallTime;
659
660    // The last time a timeupdate event was sent in movie time.
661    double m_lastTimeUpdateEventMovieTime;
662
663    // Loading state.
664    enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
665    LoadState m_loadState;
666    RefPtr<HTMLSourceElement> m_currentSourceNode;
667    RefPtr<Node> m_nextChildNodeToConsider;
668
669    OwnPtr<MediaPlayer> m_player;
670#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
671    RefPtr<Widget> m_proxyWidget;
672#endif
673
674    BehaviorRestrictions m_restrictions;
675
676    MediaPlayer::Preload m_preload;
677
678    DisplayMode m_displayMode;
679
680    // Counter incremented while processing a callback from the media player, so we can avoid
681    // calling the media engine recursively.
682    int m_processingMediaPlayerCallback;
683
684#if ENABLE(MEDIA_SOURCE)
685    RefPtr<MediaSource> m_mediaSource;
686#endif
687
688    mutable double m_cachedTime;
689    mutable double m_cachedTimeWallClockUpdateTime;
690    mutable double m_minimumWallClockTimeToCacheMediaTime;
691
692    double m_fragmentStartTime;
693    double m_fragmentEndTime;
694
695    typedef unsigned PendingActionFlags;
696    PendingActionFlags m_pendingActionFlags;
697
698    bool m_playing : 1;
699    bool m_isWaitingUntilMediaCanStart : 1;
700    bool m_shouldDelayLoadEvent : 1;
701    bool m_haveFiredLoadedData : 1;
702    bool m_inActiveDocument : 1;
703    bool m_autoplaying : 1;
704    bool m_muted : 1;
705    bool m_paused : 1;
706    bool m_seeking : 1;
707
708    // data has not been loaded since sending a "stalled" event
709    bool m_sentStalledEvent : 1;
710
711    // time has not changed since sending an "ended" event
712    bool m_sentEndEvent : 1;
713
714    bool m_pausedInternal : 1;
715
716    // Not all media engines provide enough information about a file to be able to
717    // support progress events so setting m_sendProgressEvents disables them
718    bool m_sendProgressEvents : 1;
719
720    bool m_isFullscreen : 1;
721    bool m_closedCaptionsVisible : 1;
722    bool m_webkitLegacyClosedCaptionOverride : 1;
723
724#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
725    bool m_needWidgetUpdate : 1;
726#endif
727
728    bool m_dispatchingCanPlayEvent : 1;
729    bool m_loadInitiatedByUserGesture : 1;
730    bool m_completelyLoaded : 1;
731    bool m_havePreparedToPlay : 1;
732    bool m_parsingInProgress : 1;
733
734#if ENABLE(VIDEO_TRACK)
735    bool m_tracksAreReady : 1;
736    bool m_haveVisibleTextTrack : 1;
737    bool m_processingPreferenceChange : 1;
738
739    String m_subtitleTrackLanguage;
740    float m_lastTextTrackUpdateTime;
741
742    CaptionUserPreferences::CaptionDisplayMode m_captionDisplayMode;
743
744    RefPtr<AudioTrackList> m_audioTracks;
745    RefPtr<TextTrackList> m_textTracks;
746    RefPtr<VideoTrackList> m_videoTracks;
747    Vector<RefPtr<TextTrack> > m_textTracksWhenResourceSelectionBegan;
748
749    CueIntervalTree m_cueTree;
750
751    CueList m_currentlyActiveCues;
752    int m_ignoreTrackDisplayUpdate;
753#endif
754
755#if ENABLE(WEB_AUDIO)
756    // This is a weak reference, since m_audioSourceNode holds a reference to us.
757    // The value is set just after the MediaElementAudioSourceNode is created.
758    // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
759    MediaElementAudioSourceNode* m_audioSourceNode;
760#endif
761
762    String m_mediaGroup;
763    friend class MediaController;
764    RefPtr<MediaController> m_mediaController;
765
766#if PLATFORM(MAC)
767    OwnPtr<DisplaySleepDisabler> m_sleepDisabler;
768#endif
769
770    friend class TrackDisplayUpdateScope;
771
772#if ENABLE(ENCRYPTED_MEDIA_V2)
773    RefPtr<MediaKeys> m_mediaKeys;
774#endif
775
776#if USE(PLATFORM_TEXT_TRACK_MENU)
777    RefPtr<PlatformTextTrackMenuInterface> m_platformMenu;
778#endif
779
780#if USE(AUDIO_SESSION)
781    OwnPtr<AudioSessionManagerToken> m_audioSessionManagerToken;
782#endif
783
784    OwnPtr<PageActivityAssertionToken> m_activityToken;
785    size_t m_reportedExtraMemoryCost;
786};
787
788#if ENABLE(VIDEO_TRACK)
789#ifndef NDEBUG
790// Template specializations required by PodIntervalTree in debug mode.
791template <>
792struct ValueToString<double> {
793    static String string(const double value)
794    {
795        return String::number(value);
796    }
797};
798
799template <>
800struct ValueToString<TextTrackCue*> {
801    static String string(TextTrackCue* const& cue)
802    {
803        return String::format("%p id=%s interval=%f-->%f cue=%s)", cue, cue->id().utf8().data(), cue->startTime(), cue->endTime(), cue->text().utf8().data());
804    }
805};
806#endif
807#endif
808
809inline bool isMediaElement(Node* node)
810{
811    return node && node->isElementNode() && toElement(node)->isMediaElement();
812}
813
814inline HTMLMediaElement* toMediaElement(Node* node)
815{
816    ASSERT_WITH_SECURITY_IMPLICATION(!node || isMediaElement(node));
817    return static_cast<HTMLMediaElement*>(node);
818}
819
820} //namespace
821
822#endif
823#endif
824