[M120 Migration][MM] Handle live stream duration and currenttime
[platform/framework/web/chromium-efl.git] / third_party / blink / renderer / core / html / media / html_media_element.h
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
3  * reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_
28 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_
29
30 #include <memory>
31
32 #include "base/synchronization/lock.h"
33 #include "base/thread_annotations.h"
34 #include "base/time/time.h"
35 #include "base/timer/elapsed_timer.h"
36 #include "media/mojo/mojom/media_player.mojom-blink.h"
37 #include "third_party/abseil-cpp/absl/types/optional.h"
38 #include "third_party/abseil-cpp/absl/types/variant.h"
39 #include "third_party/blink/public/common/media/display_type.h"
40 #include "third_party/blink/public/platform/web_media_player_client.h"
41 #include "third_party/blink/public/platform/webaudiosourceprovider_impl.h"
42 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
43 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
44 #include "third_party/blink/renderer/core/core_export.h"
45 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
46 #include "third_party/blink/renderer/core/html/html_element.h"
47 #include "third_party/blink/renderer/core/html/media/media_controls.h"
48 #include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
49 #include "third_party/blink/renderer/core/speech/speech_synthesis_base.h"
50 #include "third_party/blink/renderer/platform/audio/audio_source_provider.h"
51 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
52 #include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h"
53 #include "third_party/blink/renderer/platform/heap/prefinalizer.h"
54 #include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
55 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h"
56 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
57 #include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_set.h"
58 #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
59 #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
60 #include "third_party/blink/renderer/platform/supplementable.h"
61 #include "third_party/blink/renderer/platform/timer.h"
62 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
63 #include "third_party/blink/renderer/platform/wtf/vector.h"
64 #include "third_party/webrtc_overrides/low_precision_timer.h"
65
66 namespace cc {
67 class Layer;
68 }
69
70 namespace media {
71 enum class MediaContentType;
72 }  // namespace media
73
74 namespace blink {
75
76 class AudioSourceProviderClient;
77 class AudioTrack;
78 class AudioTrackList;
79 class AutoplayPolicy;
80 class ContentType;
81 class CueTimeline;
82 class Event;
83 class EventQueue;
84 class ExceptionState;
85 class HTMLMediaElementControlsList;
86 class HTMLSourceElement;
87 class HTMLTrackElement;
88 class MediaError;
89 class MediaSourceAttachment;
90 class MediaSourceHandle;
91 class MediaSourceTracer;
92 class MediaStreamDescriptor;
93 class ScriptPromiseResolver;
94 class ScriptState;
95 class TextTrack;
96 class TextTrackContainer;
97 class TextTrackList;
98 class TimeRanges;
99 class VideoTrack;
100 class VideoTrackList;
101 class WebRemotePlaybackClient;
102
103 class CORE_EXPORT HTMLMediaElement
104     : public HTMLElement,
105       public Supplementable<HTMLMediaElement>,
106       public ActiveScriptWrappable<HTMLMediaElement>,
107       public ExecutionContextLifecycleStateObserver,
108       public media::mojom::blink::MediaPlayer,
109       private WebMediaPlayerClient {
110   DEFINE_WRAPPERTYPEINFO();
111   USING_PRE_FINALIZER(HTMLMediaElement, Dispose);
112
113  public:
114   // Limits the range of media playback rate.
115   static constexpr double kMinPlaybackRate = 0.0625;
116   static constexpr double kMaxPlaybackRate = 16.0;
117
118   enum class PlayPromiseError {
119     kNotSupported,
120     kPaused_Unknown,
121     kPaused_PauseCalled,
122     kPaused_EndOfPlayback,
123     kPaused_RemovedFromDocument,
124     kPaused_AutoplayAutoPause,
125     kPaused_BackgroundVideoOptimization,
126     kPaused_SuspendedPlayerIdleTimeout,
127     kPaused_RemotePlayStateChange,
128     kPaused_PauseRequestedByUser,
129     kPaused_PauseRequestedInternally,
130   };
131
132   bool IsMediaElement() const override { return true; }
133
134   static MIMETypeRegistry::SupportsType GetSupportsType(const ContentType&);
135
136   enum class RecordMetricsBehavior { kDoNotRecord, kDoRecord };
137
138   static bool IsHLSURL(const KURL&);
139
140   // Notify the HTMLMediaElement that the media controls settings have changed
141   // for the given document.
142   static void OnMediaControlsEnabledChange(Document*);
143
144   // Binds |pending_receiver| and adds it to |media_player_receiver_set_|. Also
145   // called from other Blink classes (e.g. PictureInPictureControllerImpl).
146   void BindMediaPlayerReceiver(
147       mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayer>
148           pending_receiver);
149
150   void Trace(Visitor*) const override;
151
152   WebMediaPlayer* GetWebMediaPlayer() const { return web_media_player_.get(); }
153
154   // Returns true if the loaded media has a video track.
155   // Note that even an audio element can have video track in cases such as
156   // <audio src="video.webm">, in which case this function will return true.
157   bool HasVideo() const;
158
159   // Returns true if loaded media has an audio track.
160   bool HasAudio() const;
161
162   // Whether the media element has encrypted audio or video streams.
163   bool IsEncrypted() const;
164
165   bool SupportsSave() const;
166   bool SupportsLoop() const;
167
168   cc::Layer* CcLayer() const;
169
170   enum DelayedActionType {
171     kLoadMediaResource = 1 << 0,
172     kLoadTextTrackResource = 1 << 1
173   };
174   void ScheduleTextTrackResourceLoad();
175
176   // error state
177   MediaError* error() const;
178
179   // network state
180   void SetSrc(const AtomicString&);
181   const KURL& currentSrc() const { return current_src_.GetSourceIfVisible(); }
182
183   // Return the URL to be used for downloading the media.
184   const KURL& downloadURL() const {
185     // If we didn't get a redirected URL from the player, then use the original.
186     if (current_src_after_redirects_.IsNull() ||
187         current_src_after_redirects_.IsEmpty()) {
188       return currentSrc();
189     }
190     return current_src_after_redirects_;
191   }
192
193   using SrcObjectVariant =
194       absl::variant<MediaStreamDescriptor*, MediaSourceHandle*>;
195   void SetSrcObjectVariant(SrcObjectVariant src_object_variant);
196   SrcObjectVariant GetSrcObjectVariant() const;
197
198   enum NetworkState {
199     kNetworkEmpty,
200     kNetworkIdle,
201     kNetworkLoading,
202     kNetworkNoSource
203   };
204   NetworkState getNetworkState() const;
205
206   String preload() const;
207   void setPreload(const AtomicString&);
208   WebMediaPlayer::Preload PreloadType() const;
209   String EffectivePreload() const;
210   WebMediaPlayer::Preload EffectivePreloadType() const;
211
212   WebTimeRanges BufferedInternal() const;
213   TimeRanges* buffered() const;
214   void load();
215   String canPlayType(const String& mime_type) const;
216
217   // ready state
218   enum ReadyState {
219     kHaveNothing,
220     kHaveMetadata,
221     kHaveCurrentData,
222     kHaveFutureData,
223     kHaveEnoughData
224   };
225   ReadyState getReadyState() const;
226   bool seeking() const;
227
228   // playback state
229   double currentTime() const;
230   void setCurrentTime(double);
231   double duration() const;
232   bool paused() const;
233   double defaultPlaybackRate() const;
234   void setDefaultPlaybackRate(double);
235   double playbackRate() const;
236   void setPlaybackRate(double, ExceptionState& = ASSERT_NO_EXCEPTION);
237   TimeRanges* played();
238   WebTimeRanges SeekableInternal() const;
239   TimeRanges* seekable() const;
240   bool ended() const;
241   bool Autoplay() const;
242   bool Loop() const;
243   void SetLoop(bool);
244   ScriptPromise playForBindings(ScriptState*);
245   absl::optional<DOMExceptionCode> Play();
246
247   // Called when the video should pause to let audio descriptions finish.
248   void PauseToLetDescriptionFinish();
249
250   void pause();
251   double latencyHint() const;
252   void setLatencyHint(double);
253   bool preservesPitch() const;
254   void setPreservesPitch(bool);
255   void FlingingStarted();
256   void FlingingStopped();
257
258   // statistics
259   uint64_t webkitAudioDecodedByteCount() const;
260   uint64_t webkitVideoDecodedByteCount() const;
261
262   // media source extensions
263   void CloseMediaSource();
264   void DurationChanged(double duration, bool request_seek);
265
266   // controls
267   bool ShouldShowControls(
268       const RecordMetricsBehavior = RecordMetricsBehavior::kDoNotRecord) const;
269   bool ShouldShowAllControls() const;
270   DOMTokenList* controlsList() const;
271   HTMLMediaElementControlsList* ControlsListInternal() const;
272   double volume() const;
273   void setVolume(double, ExceptionState& = ASSERT_NO_EXCEPTION);
274   bool muted() const;
275   void setMuted(bool);
276   virtual bool SupportsPictureInPicture() const { return false; }
277   void SetUserWantsControlsVisible(bool visible);
278   bool UserWantsControlsVisible() const;
279
280   void TogglePlayState();
281
282   AudioTrackList& audioTracks();
283   void AudioTrackChanged(AudioTrack*);
284
285   VideoTrackList& videoTracks();
286   void SelectedVideoTrackChanged(VideoTrack*);
287
288   TextTrack* addTextTrack(const AtomicString& kind,
289                           const AtomicString& label,
290                           const AtomicString& language,
291                           ExceptionState&);
292
293   TextTrackList* textTracks();
294   CueTimeline& GetCueTimeline();
295
296   // Implements the "forget the media element's media-resource-specific tracks"
297   // algorithm in the HTML5 spec.
298   void ForgetResourceSpecificTracks();
299
300   void DidAddTrackElement(HTMLTrackElement*);
301   void DidRemoveTrackElement(HTMLTrackElement*);
302
303   void HonorUserPreferencesForAutomaticTextTrackSelection();
304
305   bool TextTracksAreReady() const;
306   void ConfigureTextTrackDisplay();
307   void UpdateTextTrackDisplay();
308
309   // Get a SpeechSynthesis interface to use for generating speech for audio
310   // descriptions.
311   SpeechSynthesisBase* SpeechSynthesis();
312   double LastSeekTime() const { return last_seek_time_; }
313   void TextTrackReadyStateChanged(TextTrack*);
314
315   void TextTrackModeChanged(TextTrack*);
316   void DisableAutomaticTextTrackSelection();
317
318   // EventTarget function.
319   // Both Node (via HTMLElement) and ExecutionContextLifecycleStateObserver
320   // define this method, which causes an ambiguity error at compile time. This
321   // class's constructor ensures that both implementations return document, so
322   // return the result of one of them here.
323   using HTMLElement::GetExecutionContext;
324
325   bool IsFullscreen() const;
326   virtual bool UsesOverlayFullscreenVideo() const { return false; }
327
328   bool HasClosedCaptions() const;
329   bool TextTracksVisible() const;
330
331   static void SetTextTrackKindUserPreferenceForAllMediaElements(Document*);
332   void AutomaticTrackSelectionForUpdatedUserPreference();
333
334   // Returns the MediaControls, or null if they have not been added yet.
335   // Note that this can be non-null even if there is no controls attribute.
336   MediaControls* GetMediaControls() const;
337
338   // Notifies the media element that the media controls became visible, so
339   // that text track layout may be updated to avoid overlapping them.
340   void MediaControlsDidBecomeVisible();
341
342   void SourceWasRemoved(HTMLSourceElement*);
343   void SourceWasAdded(HTMLSourceElement*);
344
345   // ScriptWrappable functions.
346   bool HasPendingActivity() const override;
347
348   AudioSourceProviderClient* AudioSourceNode() {
349     return audio_source_node_.Get();
350   }
351   void SetAudioSourceNode(AudioSourceProviderClient*);
352
353   AudioSourceProvider& GetAudioSourceProvider() {
354     return audio_source_provider_;
355   }
356
357   enum InvalidURLAction { kDoNothing, kComplain };
358   bool IsSafeToLoadURL(const KURL&, InvalidURLAction);
359
360   // Checks to see if current media data is CORS-same-origin.
361   bool IsMediaDataCorsSameOrigin() const;
362
363   void ScheduleEvent(Event*);
364
365   // Returns the "effective media volume" value as specified in the HTML5 spec.
366   double EffectiveMediaVolume() const;
367
368   // Predicates also used when dispatching wrapper creation (cf.
369   // [SpecialWrapFor] IDL attribute usage.)
370   virtual bool IsHTMLAudioElement() const { return false; }
371   virtual bool IsHTMLVideoElement() const { return false; }
372
373   void VideoWillBeDrawnToCanvas() const;
374
375   const WebRemotePlaybackClient* RemotePlaybackClient() const {
376     return remote_playback_client_;
377   }
378
379   const AutoplayPolicy& GetAutoplayPolicy() const { return *autoplay_policy_; }
380
381   WebMediaPlayer::LoadType GetLoadType() const;
382
383 #if BUILDFLAG(IS_TIZEN_TV)
384   WebString GetContentMIMEType() override;
385   void RequestReload(const KURL& new_url);
386   void SetTranslatedURL(const String&) override;
387   bool IsHTMLMediaElement() const override { return true; }
388   WTF::String GetUrl() const override { return current_src_.GetSource(); }
389   void SetParentalRatingResult(bool is_pass) override;
390 #endif
391
392 #if defined(TIZEN_MULTIMEDIA)
393   void OnLivePlaybackComplete() override;
394 #endif
395
396   bool HasMediaSource() const { return media_source_attachment_.get(); }
397
398   // Return true if element is paused and won't resume automatically if it
399   // becomes visible again.
400   bool PausedWhenVisible() const;
401
402   void DidAudioOutputSinkChanged(const String& hashed_device_id);
403
404   void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); }
405
406   // This should be called directly after creation.
407   void SetMediaPlayerHostForTesting(
408       mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerHost> host);
409
410   bool IsShowPosterFlagSet() const { return show_poster_flag_; }
411
412   // What LocalFrame should own our player?  Normally, players are tied to their
413   // HTMLMediaElement's LocalFrame for metrics, network fetch, etc.  This has
414   // the side-effect of requiring that a player is destroyed when the element's
415   // frame changes.  That causes playback to be user-visibly interrupted,
416   // potentially for multiple seconds.
417   //
418   // In some very restricted cases, related to picture-in-picture playback, it
419   // is okay to keep the player even when the element is moved to a new
420   // document.  It requires that everything is same-origin, and that lifetimes
421   // are looked after carefully so that the player does not outlive the frame
422   // that owns it.  However, it permits seamless playback when transitioning to
423   // picture in picture.  In this case, this function will return a different
424   // frame than our own.
425   //
426   // Note that new players can be created in this frame as well, so that a
427   // transfer back to the original opener frame when picture in picture is
428   // closed can be seamless too, even if the player was recreated for some
429   // reason while in picture in picture mode.
430   LocalFrame* LocalFrameForPlayer();
431
432  protected:
433   // Assert the correct order of the children in shadow dom when DCHECK is on.
434   static void AssertShadowRootChildren(ShadowRoot&);
435
436   HTMLMediaElement(const QualifiedName&, Document&);
437   ~HTMLMediaElement() override;
438   void Dispose();
439
440   // Returns a constant reference to the HeapMojoAssociatedRemoteSet holding all
441   // the bound remotes for the media::mojom::blink::MediaPlayerObserver
442   // interface. Needed to allow sending messages directly from
443   // HTMLMediaElement's subclasses.
444   const HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>&
445   GetMediaPlayerObserverRemoteSet() {
446     return media_player_observer_remote_set_->Value();
447   }
448
449   void ParseAttribute(const AttributeModificationParams&) override;
450   void FinishParsingChildren() final;
451   bool IsURLAttribute(const Attribute&) const override;
452   void AttachLayoutTree(AttachContext&) override;
453   void ParserDidSetAttributes() override;
454   void CloneNonAttributePropertiesFrom(const Element&,
455                                        NodeCloningData&) override;
456
457   InsertionNotificationRequest InsertedInto(ContainerNode&) override;
458   void RemovedFrom(ContainerNode&) override;
459
460   // Return true if media is cross origin from the current document
461   // and has not passed a cors check, meaning that we should return
462   // as little information as possible about it.
463   bool MediaShouldBeOpaque() const;
464
465   void DidMoveToNewDocument(Document& old_document) override;
466   virtual KURL PosterImageURL() const { return KURL(); }
467
468   // Called after the creation of |web_media_player_|.
469   virtual void OnWebMediaPlayerCreated() {}
470   virtual void OnWebMediaPlayerCleared() {}
471
472   void UpdateLayoutObject();
473
474  private:
475   // Friend class for testing.
476   friend class ContextMenuControllerTest;
477   friend class HTMLMediaElementTest;
478   friend class PictureInPictureControllerTestWithWidget;
479   friend class VideoWakeLockTest;
480
481   class SourceMetadata {
482     DISALLOW_NEW();
483
484    public:
485     enum class SourceVisibility { kVisibleToApp, kInvisibleToApp };
486     SourceMetadata() = default;
487     void SetSource(const KURL& src, SourceVisibility visibility) {
488       src_ = src;
489       invisible_to_app_ = visibility == SourceVisibility::kInvisibleToApp;
490     }
491     const KURL& GetSourceIfVisible() const {
492       return invisible_to_app_ ? NullURL() : src_;
493     }
494     const KURL& GetSource() const { return src_; }
495
496    private:
497     KURL src_;
498
499     // If true, then |current_src| is used only for internal loading and safety
500     // checks, and for logging that is not visible to apps, either. For example,
501     // when loading from a MediaSourceHandle as srcObject, this would be true.
502     bool invisible_to_app_ = false;
503   };
504
505   bool HasPendingActivityInternal() const;
506
507   void ResetMediaPlayerAndMediaSource();
508
509   bool AlwaysCreateUserAgentShadowRoot() const final { return true; }
510   bool AreAuthorShadowsAllowed() const final { return false; }
511
512   bool SupportsFocus() const final;
513   bool IsFocusable(
514       bool disallow_layout_updates_for_accessibility_only = false) const final;
515   bool IsKeyboardFocusable() const final;
516   int DefaultTabIndex() const final;
517   bool LayoutObjectIsNeeded(const DisplayStyle&) const override;
518   LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
519   void DidNotifySubtreeInsertionsToDocument() override;
520   void DidRecalcStyle(const StyleRecalcChange) final;
521
522   bool CanStartSelection() const override { return false; }
523
524   bool IsInteractiveContent() const final;
525
526   // ExecutionContextLifecycleStateObserver functions.
527   void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
528   void ContextDestroyed() override;
529
530   virtual void OnPlay() {}
531   virtual void OnLoadStarted() {}
532   virtual void OnLoadFinished() {}
533
534   // Handles playing of media element when audio descriptions are finished
535   // speaking.
536   void OnSpeakingCompleted();
537
538   void SetShowPosterFlag(bool value);
539
540   void SetReadyState(ReadyState);
541   void SetNetworkState(WebMediaPlayer::NetworkState);
542
543   // WebMediaPlayerClient implementation.
544   void NetworkStateChanged() final;
545   void ReadyStateChanged() final;
546   void TimeChanged() final;
547   void Repaint() final;
548   void DurationChanged() final;
549   void SizeChanged() final;
550   void OnFirstFrame(base::TimeTicks frame_time,
551                     size_t bytes_to_first_frame) override {}
552
553   void SetCcLayer(cc::Layer*) final;
554   WebMediaPlayer::TrackId AddAudioTrack(const WebString&,
555                                         WebMediaPlayerClient::AudioTrackKind,
556                                         const WebString&,
557                                         const WebString&,
558                                         bool) final;
559   void RemoveAudioTrack(WebMediaPlayer::TrackId) final;
560   WebMediaPlayer::TrackId AddVideoTrack(const WebString&,
561                                         WebMediaPlayerClient::VideoTrackKind,
562                                         const WebString&,
563                                         const WebString&,
564                                         bool) final;
565   void RemoveVideoTrack(WebMediaPlayer::TrackId) final;
566   void MediaSourceOpened(WebMediaSource*) final;
567   void RemotePlaybackCompatibilityChanged(const WebURL&,
568                                           bool is_compatible) final;
569   bool HasSelectedVideoTrack() final;
570   WebMediaPlayer::TrackId GetSelectedVideoTrackId() final;
571   bool WasAlwaysMuted() final;
572   bool HasNativeControls() final;
573   bool IsAudioElement() final;
574   DisplayType GetDisplayType() const override;
575   WebRemotePlaybackClient* RemotePlaybackClient() final {
576     return remote_playback_client_;
577   }
578   gfx::ColorSpace TargetColorSpace() override;
579   bool WasAutoplayInitiated() override;
580   bool IsInAutoPIP() const override { return false; }
581   void ResumePlayback() final;
582   void PausePlayback(PauseReason) final;
583   void DidPlayerStartPlaying() override;
584   void DidPlayerPaused(bool stream_ended) override;
585   void DidPlayerMutedStatusChange(bool muted) override;
586   void DidMediaMetadataChange(bool has_audio,
587                               bool has_video,
588                               media::AudioCodec audio_codec,
589                               media::VideoCodec video_codec,
590                               media::MediaContentType media_content_type,
591                               bool is_encrypted_media) override;
592   void DidPlayerMediaPositionStateChange(double playback_rate,
593                                          base::TimeDelta duration,
594                                          base::TimeDelta position,
595                                          bool end_of_media) override;
596   void DidDisableAudioOutputSinkChanges() override;
597   void DidUseAudioServiceChange(bool uses_audio_service) override;
598   void DidPlayerSizeChange(const gfx::Size& size) override;
599   void OnRemotePlaybackDisabled(bool disabled) override;
600 #if defined(TIZEN_MULTIMEDIA)
601   void SuspendPlayer() override;
602 #endif
603
604   // Returns a reference to the mojo remote for the MediaPlayerHost interface,
605   // requesting it first from the BrowserInterfaceBroker if needed. It is an
606   // error to call this method before having access to the document's frame.
607   media::mojom::blink::MediaPlayerHost& GetMediaPlayerHostRemote();
608
609   // media::mojom::MediaPlayer  implementation.
610   void RequestPlay() override;
611   void RequestPause(bool triggered_by_user) override;
612   void RequestSeekForward(base::TimeDelta seek_time) override;
613   void RequestSeekBackward(base::TimeDelta seek_time) override;
614   void RequestSeekTo(base::TimeDelta seek_time) override;
615   void RequestEnterPictureInPicture() override {}
616   void RequestMute(bool mute) override;
617   void SetVolumeMultiplier(double multiplier) override;
618   void SetPersistentState(bool persistent) override {}
619   void SetPowerExperimentState(bool enabled) override;
620   void SetAudioSinkId(const String&) override;
621   void SuspendForFrameClosed() override;
622   void RequestMediaRemoting() override {}
623
624 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
625   void MediaPlayerHidden() final;
626   void MediaPlayerShown() final;
627   void Suspend();
628   void Resume();
629   void NotifyPlayingUrl();
630 #endif
631
632   void LoadTimerFired(TimerBase*);
633   void ProgressEventTimerFired();
634   void PlaybackProgressTimerFired();
635   void ScheduleTimeupdateEvent(bool periodic_event);
636   void StartPlaybackProgressTimer();
637   void StartProgressEventTimer();
638   void StopPeriodicTimers();
639
640   void Seek(double time);
641   void FinishSeek();
642   void AddPlayedRange(double start, double end);
643
644   // FIXME: Rename to scheduleNamedEvent for clarity.
645   void ScheduleEvent(const AtomicString& event_name);
646
647   // loading
648   void InvokeLoadAlgorithm();
649   void InvokeResourceSelectionAlgorithm();
650   void LoadInternal();
651   void SelectMediaResource();
652   void LoadResource(const WebMediaPlayerSource&, const String& content_type);
653   void StartPlayerLoad();
654   void SetPlayerPreload();
655   void ScheduleNextSourceChild();
656   void LoadSourceFromObject();
657   void LoadSourceFromAttribute();
658   void LoadNextSourceChild();
659   void ClearMediaPlayer();
660   void ClearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
661   bool HavePotentialSourceChild();
662   void NoneSupported(const String&);
663   void MediaEngineError(MediaError*);
664   void CancelPendingEventsAndCallbacks();
665   void WaitForSourceChange();
666   void SetIgnorePreloadNone();
667
668   KURL SelectNextSourceChild(String* content_type, InvalidURLAction);
669
670   void MediaLoadingFailed(WebMediaPlayer::NetworkState, const String&);
671
672   // deferred loading (preload=none)
673   bool LoadIsDeferred() const;
674   void DeferLoad();
675   void CancelDeferredLoad();
676   void StartDeferredLoad();
677   void ExecuteDeferredLoad();
678   void DeferredLoadTimerFired(TimerBase*);
679
680   void MarkCaptionAndSubtitleTracksAsUnconfigured();
681
682   // This does not check user gesture restrictions.
683   void PlayInternal();
684
685   // This does not stop autoplay visibility observation.
686   // By default, will pause the video and speech.
687   void PauseInternal(PlayPromiseError code, bool pause_speech = true);
688
689   // By default, will pause the video and speech.
690   void UpdatePlayState(bool pause_speech = true);
691
692   bool PotentiallyPlaying() const;
693   bool StoppedDueToErrors() const;
694   bool CouldPlayIfEnoughData() const override;
695
696   // Generally the presence of the loop attribute should be considered to mean
697   // playback has not "ended", as "ended" and "looping" are mutually exclusive.
698   // See
699   // https://html.spec.whatwg.org/C/#ended-playback
700   enum class LoopCondition { kIncluded, kIgnored };
701   bool EndedPlayback(LoopCondition = LoopCondition::kIncluded) const;
702
703   void SetShouldDelayLoadEvent(bool);
704
705   double EarliestPossiblePosition() const;
706   double CurrentPlaybackPosition() const;
707   double OfficialPlaybackPosition() const;
708   void SetOfficialPlaybackPosition(double) const;
709   void RequireOfficialPlaybackPositionUpdate() const;
710
711   void EnsureMediaControls();
712   void UpdateControlsVisibility();
713
714   TextTrackContainer& EnsureTextTrackContainer();
715
716   void ChangeNetworkStateFromLoadingToIdle();
717
718   WebMediaPlayer::CorsMode CorsMode() const;
719
720   // Returns the "direction of playback" value as specified in the HTML5 spec.
721   enum DirectionOfPlayback { kBackward, kForward };
722   DirectionOfPlayback GetDirectionOfPlayback() const;
723
724   // Creates placeholder AudioTrack and/or VideoTrack objects when
725   // WebMediaPlayer objects advertise they have audio and/or video, but don't
726   // explicitly signal them via addAudioTrack() and addVideoTrack().
727   // FIXME: Remove this once all WebMediaPlayer implementations properly report
728   // their track info.
729   void CreatePlaceholderTracksIfNecessary();
730
731   void SetNetworkState(NetworkState, bool update_media_controls = true);
732
733   void AudioTracksTimerFired(TimerBase*);
734
735   void ScheduleResolvePlayPromises();
736   void ScheduleRejectPlayPromises(PlayPromiseError);
737   void ScheduleNotifyPlaying();
738   void ResolveScheduledPlayPromises();
739   void RejectScheduledPlayPromises();
740   void RejectPlayPromises(DOMExceptionCode, const String&);
741   void RejectPlayPromisesInternal(DOMExceptionCode, const String&);
742
743   void OnRemovedFromDocumentTimerFired(TimerBase*);
744
745   void SetError(MediaError* error);
746   void ReportCurrentTimeToMediaSource();
747
748   void ResetMojoState();
749   void OnRemotePlaybackMetadataChange();
750
751   // Determine if we should reuse the player when moving the element from
752   // |old_document| to |new_document|
753   bool ShouldReusePlayer(Document& old_document, Document& new_document) const;
754
755   // Adds a new MediaPlayerObserver remote that will be notified about media
756   // player events and returns a receiver that an observer implementation can
757   // bind to.
758   mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayerObserver>
759   AddMediaPlayerObserverAndPassReceiver();
760
761   // Timers used to schedule one-shot tasks with no delay.
762   HeapTaskRunnerTimer<HTMLMediaElement> load_timer_;
763   HeapTaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_;
764   HeapTaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_;
765   // Use a low precision timer for repeating tasks to avoid excessive Idle Wake
766   // Up frequency, especially when WebRTC is used and the page contains many
767   // HTMLMediaElements.
768   LowPrecisionTimer progress_event_timer_;
769   LowPrecisionTimer playback_progress_timer_;
770
771   Member<TimeRanges> played_time_ranges_;
772   Member<EventQueue> async_event_queue_;
773
774   double playback_rate_;
775   double default_playback_rate_;
776   NetworkState network_state_;
777   ReadyState ready_state_;
778   ReadyState ready_state_maximum_;
779
780   SourceMetadata current_src_;
781   KURL current_src_after_redirects_;
782
783   Member<MediaStreamDescriptor> src_object_stream_descriptor_;
784   Member<MediaSourceHandle> src_object_media_source_handle_;
785
786   // To prevent potential regression when extended by the MSE API, do not set
787   // |error_| outside of constructor and SetError().
788   Member<MediaError> error_;
789
790   double volume_;
791   double last_seek_time_;
792
793   absl::optional<base::ElapsedTimer> previous_progress_time_;
794
795   // Cached duration to suppress duplicate events if duration unchanged.
796   double duration_;
797
798   // The last time a timeupdate event was sent in movie time.
799   double last_time_update_event_media_time_;
800
801   // The default playback start position.
802   double default_playback_start_position_;
803
804   // Loading state.
805   enum LoadState {
806     kWaitingForSource,
807     kLoadingFromSrcObject,
808     kLoadingFromSrcAttr,
809     kLoadingFromSourceElement
810   };
811   LoadState load_state_;
812   Member<HTMLSourceElement> current_source_node_;
813   Member<Node> next_child_node_to_consider_;
814
815   // "Deferred loading" state (for preload=none).
816   enum DeferredLoadState {
817     // The load is not deferred.
818     kNotDeferred,
819     // The load is deferred, and waiting for the task to set the
820     // delaying-the-load-event flag (to false).
821     kWaitingForStopDelayingLoadEventTask,
822     // The load is the deferred, and waiting for a triggering event.
823     kWaitingForTrigger,
824     // The load is deferred, and waiting for the task to set the
825     // delaying-the-load-event flag, after which the load will be executed.
826     kExecuteOnStopDelayingLoadEventTask
827   };
828   DeferredLoadState deferred_load_state_;
829   HeapTaskRunnerTimer<HTMLMediaElement> deferred_load_timer_;
830
831   std::unique_ptr<WebMediaPlayer> web_media_player_;
832   cc::Layer* cc_layer_;
833
834   // These two fields must be carefully set and reset: the actual derived type
835   // of the attachment (same-thread vs cross-thread, for instance) must be the
836   // same semantic as the actual derived type of the tracer. Further, if there
837   // is no attachment, then there must be no tracer that's tracking an active
838   // attachment. Note that some kinds of attachments do not require a tracer;
839   // see MediaSourceAttachment::StartAttachingToMediaElement() for details.
840   scoped_refptr<MediaSourceAttachment> media_source_attachment_;
841   Member<MediaSourceTracer> media_source_tracer_;
842
843   // Stores "official playback position", updated periodically from "current
844   // playback position". Official playback position should not change while
845   // scripts are running. See setOfficialPlaybackPosition().
846   mutable double official_playback_position_;
847   mutable bool official_playback_position_needs_update_;
848
849   double fragment_end_time_;
850
851   typedef unsigned PendingActionFlags;
852   PendingActionFlags pending_action_flags_;
853
854   // FIXME: HTMLMediaElement has way too many state bits.
855   bool playing_ : 1;
856   bool should_delay_load_event_ : 1;
857   bool have_fired_loaded_data_ : 1;
858   bool can_autoplay_ : 1;
859   bool muted_ : 1;
860   bool paused_ : 1;
861   bool seeking_ : 1;
862   bool paused_by_context_paused_ : 1;
863   bool show_poster_flag_ : 1;
864
865   // data has not been loaded since sending a "stalled" event
866   bool sent_stalled_event_ : 1;
867
868   bool ignore_preload_none_ : 1;
869
870   bool text_tracks_visible_ : 1;
871   bool should_perform_automatic_track_selection_ : 1;
872
873   bool tracks_are_ready_ : 1;
874   bool processing_preference_change_ : 1;
875
876   bool was_always_muted_ : 1;
877
878 #if defined(TIZEN_MULTIMEDIA)
879   bool live_playback_complete_ : 1;
880 #endif
881
882 #if BUILDFLAG(IS_TIZEN_TV)
883   String content_mime_type_;
884   bool is_translated_url_ : 1;
885 #endif
886   // Set if the user has used the context menu to set the visibility of the
887   // controls.
888   absl::optional<bool> user_wants_controls_visible_;
889
890   // Whether or not |web_media_player_| should apply pitch adjustments at
891   // playback raters other than 1.0.
892   bool preserves_pitch_ = true;
893
894 #if BUILDFLAG(IS_TIZEN_TV)
895   bool is_deactivate_ : 1;
896 #endif
897
898 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
899   // This is to suppress stuff set to JS. Do not use it for other purposes.
900   bool suppress_events_ : 1;
901 #endif
902
903   // Whether the player disables the Remote Playback feature.
904   bool is_remote_playback_disabled_ = false;
905   // Whether the player is rendering remotely.
906   bool is_remote_rendering_ = false;
907   // Whether the media content is encrypted.
908   bool is_encrypted_media_ = false;
909   WebString remote_device_friendly_name_;
910   media::AudioCodec audio_codec_ = media::AudioCodec::kUnknown;
911   media::VideoCodec video_codec_ = media::VideoCodec::kUnknown;
912
913   Member<AudioTrackList> audio_tracks_;
914   Member<VideoTrackList> video_tracks_;
915   Member<TextTrackList> text_tracks_;
916   HeapVector<Member<TextTrack>> text_tracks_when_resource_selection_began_;
917
918   Member<CueTimeline> cue_timeline_;
919
920   HeapVector<Member<ScriptPromiseResolver>> play_promise_resolvers_;
921   TaskHandle play_promise_resolve_task_handle_;
922   TaskHandle play_promise_reject_task_handle_;
923   HeapVector<Member<ScriptPromiseResolver>> play_promise_resolve_list_;
924   HeapVector<Member<ScriptPromiseResolver>> play_promise_reject_list_;
925   PlayPromiseError play_promise_error_code_;
926
927   // HTMLMediaElement and its MediaElementAudioSourceNode in case it is provided
928   // die together.
929   Member<AudioSourceProviderClient> audio_source_node_;
930
931   // Controls browser vocalization within the media element (e.g. to speak cues,
932   // to pause utterance).
933   Member<SpeechSynthesisBase> speech_synthesis_;
934
935   // AudioClientImpl wraps an AudioSourceProviderClient.
936   // When the audio format is known, Chromium calls setFormat().
937   class AudioClientImpl final : public GarbageCollected<AudioClientImpl>,
938                                 public WebAudioSourceProviderClient {
939    public:
940     explicit AudioClientImpl(AudioSourceProviderClient* client)
941         : client_(client) {}
942
943     ~AudioClientImpl() override = default;
944
945     // WebAudioSourceProviderClient
946     void SetFormat(uint32_t number_of_channels, float sample_rate) override;
947
948     void Trace(Visitor*) const;
949
950    private:
951     Member<AudioSourceProviderClient> client_;
952   };
953
954   // AudioSourceProviderImpl wraps a WebAudioSourceProvider.
955   // provideInput() calls into Chromium to get a rendered audio stream.
956   class AudioSourceProviderImpl final : public AudioSourceProvider {
957     DISALLOW_NEW();
958
959    public:
960     AudioSourceProviderImpl() = default;
961     ~AudioSourceProviderImpl() override = default;
962
963     // Wraps the given WebAudioSourceProvider.
964     void Wrap(scoped_refptr<WebAudioSourceProviderImpl>);
965
966     // AudioSourceProvider
967     void SetClient(AudioSourceProviderClient*) override;
968     void ProvideInput(AudioBus*, int frames_to_process) override;
969
970     void Trace(Visitor*) const;
971
972    private:
973     base::Lock provide_input_lock;
974     scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_
975         GUARDED_BY(provide_input_lock);
976     Member<AudioClientImpl> client_;
977   };
978
979   AudioSourceProviderImpl audio_source_provider_;
980
981   // Notify HTMLMediaElement when a document's ExecutionContext is destroyed.
982   // It allows us to disconnect from a previous document's frame if we were
983   // using it to support our WebMediaPlayer rather than our current frame.
984   class OpenerContextObserver final
985       : public GarbageCollected<OpenerContextObserver>,
986         public ContextLifecycleObserver {
987    public:
988     // Notify `element` when our context is destroyed.
989     explicit OpenerContextObserver(HTMLMediaElement* element);
990     ~OpenerContextObserver() final;
991
992     void Trace(Visitor* visitor) const final;
993
994    protected:
995     void ContextDestroyed() final;
996
997     Member<HTMLMediaElement> element_;
998   };
999
1000   // Clean up things that are tied to any previous frame, including the player
1001   // and mojo interfaces, when we switch to a new frame.
1002   void AttachToNewFrame();
1003
1004   Member<Document> opener_document_;
1005   Member<OpenerContextObserver> opener_context_observer_;
1006
1007   friend class AutoplayPolicy;
1008   friend class AutoplayUmaHelperTest;
1009   friend class Internals;
1010   friend class TrackDisplayUpdateScope;
1011   friend class MediaControlsImplTest;
1012   friend class HTMLMediaElementTest;
1013   friend class HTMLMediaElementEventListenersTest;
1014   friend class HTMLVideoElement;
1015   friend class MediaControlInputElementTest;
1016   friend class MediaControlsOrientationLockDelegateTest;
1017   friend class MediaControlsRotateToFullscreenDelegateTest;
1018   friend class MediaControlLoadingPanelElementTest;
1019   friend class ContextMenuControllerTest;
1020   friend class HTMLVideoElementTest;
1021
1022   Member<AutoplayPolicy> autoplay_policy_;
1023
1024   WebRemotePlaybackClient* remote_playback_client_;
1025
1026   Member<MediaControls> media_controls_;
1027   Member<HTMLMediaElementControlsList> controls_list_;
1028
1029   Member<IntersectionObserver> lazy_load_intersection_observer_;
1030
1031   Member<DisallowNewWrapper<
1032       HeapMojoAssociatedRemote<media::mojom::blink::MediaPlayerHost>>>
1033       media_player_host_remote_;
1034
1035   // Note: There's only ever one entry in this set.
1036   Member<DisallowNewWrapper<
1037       HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>>>
1038       media_player_observer_remote_set_;
1039
1040   // A receiver set is needed here as there will be different objects in the
1041   // browser communicating with this object. This is done this way to avoid
1042   // routing everything through a single class (e.g. RFHI) and to keep this
1043   // logic contained inside MediaPlayer-related classes.
1044   Member<DisallowNewWrapper<
1045       HeapMojoAssociatedReceiverSet<media::mojom::blink::MediaPlayer,
1046                                     HTMLMediaElement>>>
1047       media_player_receiver_set_;
1048 };
1049
1050 template <>
1051 inline bool IsElementOfType<const HTMLMediaElement>(const Node& node) {
1052   return IsA<HTMLMediaElement>(node);
1053 }
1054 template <>
1055 struct DowncastTraits<HTMLMediaElement> {
1056   static bool AllowFrom(const Node& node) {
1057     auto* html_element = DynamicTo<HTMLElement>(node);
1058     return html_element && AllowFrom(*html_element);
1059   }
1060   static bool AllowFrom(const HTMLElement& html_element) {
1061     return IsA<HTMLAudioElement>(html_element) ||
1062            IsA<HTMLVideoElement>(html_element);
1063   }
1064 };
1065
1066 }  // namespace blink
1067
1068 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_