45db0e500cb5e433ce0935c1ea76fa1684ca4e12
[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   bool HasMediaSource() const { return media_source_attachment_.get(); }
393
394   // Return true if element is paused and won't resume automatically if it
395   // becomes visible again.
396   bool PausedWhenVisible() const;
397
398   void DidAudioOutputSinkChanged(const String& hashed_device_id);
399
400   void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); }
401
402   // This should be called directly after creation.
403   void SetMediaPlayerHostForTesting(
404       mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerHost> host);
405
406   bool IsShowPosterFlagSet() const { return show_poster_flag_; }
407
408   // What LocalFrame should own our player?  Normally, players are tied to their
409   // HTMLMediaElement's LocalFrame for metrics, network fetch, etc.  This has
410   // the side-effect of requiring that a player is destroyed when the element's
411   // frame changes.  That causes playback to be user-visibly interrupted,
412   // potentially for multiple seconds.
413   //
414   // In some very restricted cases, related to picture-in-picture playback, it
415   // is okay to keep the player even when the element is moved to a new
416   // document.  It requires that everything is same-origin, and that lifetimes
417   // are looked after carefully so that the player does not outlive the frame
418   // that owns it.  However, it permits seamless playback when transitioning to
419   // picture in picture.  In this case, this function will return a different
420   // frame than our own.
421   //
422   // Note that new players can be created in this frame as well, so that a
423   // transfer back to the original opener frame when picture in picture is
424   // closed can be seamless too, even if the player was recreated for some
425   // reason while in picture in picture mode.
426   LocalFrame* LocalFrameForPlayer();
427
428  protected:
429   // Assert the correct order of the children in shadow dom when DCHECK is on.
430   static void AssertShadowRootChildren(ShadowRoot&);
431
432   HTMLMediaElement(const QualifiedName&, Document&);
433   ~HTMLMediaElement() override;
434   void Dispose();
435
436   // Returns a constant reference to the HeapMojoAssociatedRemoteSet holding all
437   // the bound remotes for the media::mojom::blink::MediaPlayerObserver
438   // interface. Needed to allow sending messages directly from
439   // HTMLMediaElement's subclasses.
440   const HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>&
441   GetMediaPlayerObserverRemoteSet() {
442     return media_player_observer_remote_set_->Value();
443   }
444
445   void ParseAttribute(const AttributeModificationParams&) override;
446   void FinishParsingChildren() final;
447   bool IsURLAttribute(const Attribute&) const override;
448   void AttachLayoutTree(AttachContext&) override;
449   void ParserDidSetAttributes() override;
450   void CloneNonAttributePropertiesFrom(const Element&,
451                                        NodeCloningData&) override;
452
453   InsertionNotificationRequest InsertedInto(ContainerNode&) override;
454   void RemovedFrom(ContainerNode&) override;
455
456   // Return true if media is cross origin from the current document
457   // and has not passed a cors check, meaning that we should return
458   // as little information as possible about it.
459   bool MediaShouldBeOpaque() const;
460
461   void DidMoveToNewDocument(Document& old_document) override;
462   virtual KURL PosterImageURL() const { return KURL(); }
463
464   // Called after the creation of |web_media_player_|.
465   virtual void OnWebMediaPlayerCreated() {}
466   virtual void OnWebMediaPlayerCleared() {}
467
468   void UpdateLayoutObject();
469
470  private:
471   // Friend class for testing.
472   friend class ContextMenuControllerTest;
473   friend class HTMLMediaElementTest;
474   friend class PictureInPictureControllerTestWithWidget;
475   friend class VideoWakeLockTest;
476
477   class SourceMetadata {
478     DISALLOW_NEW();
479
480    public:
481     enum class SourceVisibility { kVisibleToApp, kInvisibleToApp };
482     SourceMetadata() = default;
483     void SetSource(const KURL& src, SourceVisibility visibility) {
484       src_ = src;
485       invisible_to_app_ = visibility == SourceVisibility::kInvisibleToApp;
486     }
487     const KURL& GetSourceIfVisible() const {
488       return invisible_to_app_ ? NullURL() : src_;
489     }
490     const KURL& GetSource() const { return src_; }
491
492    private:
493     KURL src_;
494
495     // If true, then |current_src| is used only for internal loading and safety
496     // checks, and for logging that is not visible to apps, either. For example,
497     // when loading from a MediaSourceHandle as srcObject, this would be true.
498     bool invisible_to_app_ = false;
499   };
500
501   bool HasPendingActivityInternal() const;
502
503   void ResetMediaPlayerAndMediaSource();
504
505   bool AlwaysCreateUserAgentShadowRoot() const final { return true; }
506   bool AreAuthorShadowsAllowed() const final { return false; }
507
508   bool SupportsFocus() const final;
509   bool IsFocusable(
510       bool disallow_layout_updates_for_accessibility_only = false) const final;
511   bool IsKeyboardFocusable() const final;
512   int DefaultTabIndex() const final;
513   bool LayoutObjectIsNeeded(const DisplayStyle&) const override;
514   LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
515   void DidNotifySubtreeInsertionsToDocument() override;
516   void DidRecalcStyle(const StyleRecalcChange) final;
517
518   bool CanStartSelection() const override { return false; }
519
520   bool IsInteractiveContent() const final;
521
522   // ExecutionContextLifecycleStateObserver functions.
523   void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
524   void ContextDestroyed() override;
525
526   virtual void OnPlay() {}
527   virtual void OnLoadStarted() {}
528   virtual void OnLoadFinished() {}
529
530   // Handles playing of media element when audio descriptions are finished
531   // speaking.
532   void OnSpeakingCompleted();
533
534   void SetShowPosterFlag(bool value);
535
536   void SetReadyState(ReadyState);
537   void SetNetworkState(WebMediaPlayer::NetworkState);
538
539   // WebMediaPlayerClient implementation.
540   void NetworkStateChanged() final;
541   void ReadyStateChanged() final;
542   void TimeChanged() final;
543   void Repaint() final;
544   void DurationChanged() final;
545   void SizeChanged() final;
546   void OnFirstFrame(base::TimeTicks frame_time,
547                     size_t bytes_to_first_frame) override {}
548
549   void SetCcLayer(cc::Layer*) final;
550   WebMediaPlayer::TrackId AddAudioTrack(const WebString&,
551                                         WebMediaPlayerClient::AudioTrackKind,
552                                         const WebString&,
553                                         const WebString&,
554                                         bool) final;
555   void RemoveAudioTrack(WebMediaPlayer::TrackId) final;
556   WebMediaPlayer::TrackId AddVideoTrack(const WebString&,
557                                         WebMediaPlayerClient::VideoTrackKind,
558                                         const WebString&,
559                                         const WebString&,
560                                         bool) final;
561   void RemoveVideoTrack(WebMediaPlayer::TrackId) final;
562   void MediaSourceOpened(WebMediaSource*) final;
563   void RemotePlaybackCompatibilityChanged(const WebURL&,
564                                           bool is_compatible) final;
565   bool HasSelectedVideoTrack() final;
566   WebMediaPlayer::TrackId GetSelectedVideoTrackId() final;
567   bool WasAlwaysMuted() final;
568   bool HasNativeControls() final;
569   bool IsAudioElement() final;
570   DisplayType GetDisplayType() const override;
571   WebRemotePlaybackClient* RemotePlaybackClient() final {
572     return remote_playback_client_;
573   }
574   gfx::ColorSpace TargetColorSpace() override;
575   bool WasAutoplayInitiated() override;
576   bool IsInAutoPIP() const override { return false; }
577   void ResumePlayback() final;
578   void PausePlayback(PauseReason) final;
579   void DidPlayerStartPlaying() override;
580   void DidPlayerPaused(bool stream_ended) override;
581   void DidPlayerMutedStatusChange(bool muted) override;
582   void DidMediaMetadataChange(bool has_audio,
583                               bool has_video,
584                               media::AudioCodec audio_codec,
585                               media::VideoCodec video_codec,
586                               media::MediaContentType media_content_type,
587                               bool is_encrypted_media) override;
588   void DidPlayerMediaPositionStateChange(double playback_rate,
589                                          base::TimeDelta duration,
590                                          base::TimeDelta position,
591                                          bool end_of_media) override;
592   void DidDisableAudioOutputSinkChanges() override;
593   void DidUseAudioServiceChange(bool uses_audio_service) override;
594   void DidPlayerSizeChange(const gfx::Size& size) override;
595   void OnRemotePlaybackDisabled(bool disabled) override;
596 #if defined(TIZEN_MULTIMEDIA)
597   void SuspendPlayer() override;
598 #endif
599
600   // Returns a reference to the mojo remote for the MediaPlayerHost interface,
601   // requesting it first from the BrowserInterfaceBroker if needed. It is an
602   // error to call this method before having access to the document's frame.
603   media::mojom::blink::MediaPlayerHost& GetMediaPlayerHostRemote();
604
605   // media::mojom::MediaPlayer  implementation.
606   void RequestPlay() override;
607   void RequestPause(bool triggered_by_user) override;
608   void RequestSeekForward(base::TimeDelta seek_time) override;
609   void RequestSeekBackward(base::TimeDelta seek_time) override;
610   void RequestSeekTo(base::TimeDelta seek_time) override;
611   void RequestEnterPictureInPicture() override {}
612   void RequestMute(bool mute) override;
613   void SetVolumeMultiplier(double multiplier) override;
614   void SetPersistentState(bool persistent) override {}
615   void SetPowerExperimentState(bool enabled) override;
616   void SetAudioSinkId(const String&) override;
617   void SuspendForFrameClosed() override;
618   void RequestMediaRemoting() override {}
619
620 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
621   void MediaPlayerHidden() final;
622   void MediaPlayerShown() final;
623   void Suspend();
624   void Resume();
625   void NotifyPlayingUrl();
626 #endif
627
628   void LoadTimerFired(TimerBase*);
629   void ProgressEventTimerFired();
630   void PlaybackProgressTimerFired();
631   void ScheduleTimeupdateEvent(bool periodic_event);
632   void StartPlaybackProgressTimer();
633   void StartProgressEventTimer();
634   void StopPeriodicTimers();
635
636   void Seek(double time);
637   void FinishSeek();
638   void AddPlayedRange(double start, double end);
639
640   // FIXME: Rename to scheduleNamedEvent for clarity.
641   void ScheduleEvent(const AtomicString& event_name);
642
643   // loading
644   void InvokeLoadAlgorithm();
645   void InvokeResourceSelectionAlgorithm();
646   void LoadInternal();
647   void SelectMediaResource();
648   void LoadResource(const WebMediaPlayerSource&, const String& content_type);
649   void StartPlayerLoad();
650   void SetPlayerPreload();
651   void ScheduleNextSourceChild();
652   void LoadSourceFromObject();
653   void LoadSourceFromAttribute();
654   void LoadNextSourceChild();
655   void ClearMediaPlayer();
656   void ClearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
657   bool HavePotentialSourceChild();
658   void NoneSupported(const String&);
659   void MediaEngineError(MediaError*);
660   void CancelPendingEventsAndCallbacks();
661   void WaitForSourceChange();
662   void SetIgnorePreloadNone();
663
664   KURL SelectNextSourceChild(String* content_type, InvalidURLAction);
665
666   void MediaLoadingFailed(WebMediaPlayer::NetworkState, const String&);
667
668   // deferred loading (preload=none)
669   bool LoadIsDeferred() const;
670   void DeferLoad();
671   void CancelDeferredLoad();
672   void StartDeferredLoad();
673   void ExecuteDeferredLoad();
674   void DeferredLoadTimerFired(TimerBase*);
675
676   void MarkCaptionAndSubtitleTracksAsUnconfigured();
677
678   // This does not check user gesture restrictions.
679   void PlayInternal();
680
681   // This does not stop autoplay visibility observation.
682   // By default, will pause the video and speech.
683   void PauseInternal(PlayPromiseError code, bool pause_speech = true);
684
685   // By default, will pause the video and speech.
686   void UpdatePlayState(bool pause_speech = true);
687
688   bool PotentiallyPlaying() const;
689   bool StoppedDueToErrors() const;
690   bool CouldPlayIfEnoughData() const override;
691
692   // Generally the presence of the loop attribute should be considered to mean
693   // playback has not "ended", as "ended" and "looping" are mutually exclusive.
694   // See
695   // https://html.spec.whatwg.org/C/#ended-playback
696   enum class LoopCondition { kIncluded, kIgnored };
697   bool EndedPlayback(LoopCondition = LoopCondition::kIncluded) const;
698
699   void SetShouldDelayLoadEvent(bool);
700
701   double EarliestPossiblePosition() const;
702   double CurrentPlaybackPosition() const;
703   double OfficialPlaybackPosition() const;
704   void SetOfficialPlaybackPosition(double) const;
705   void RequireOfficialPlaybackPositionUpdate() const;
706
707   void EnsureMediaControls();
708   void UpdateControlsVisibility();
709
710   TextTrackContainer& EnsureTextTrackContainer();
711
712   void ChangeNetworkStateFromLoadingToIdle();
713
714   WebMediaPlayer::CorsMode CorsMode() const;
715
716   // Returns the "direction of playback" value as specified in the HTML5 spec.
717   enum DirectionOfPlayback { kBackward, kForward };
718   DirectionOfPlayback GetDirectionOfPlayback() const;
719
720   // Creates placeholder AudioTrack and/or VideoTrack objects when
721   // WebMediaPlayer objects advertise they have audio and/or video, but don't
722   // explicitly signal them via addAudioTrack() and addVideoTrack().
723   // FIXME: Remove this once all WebMediaPlayer implementations properly report
724   // their track info.
725   void CreatePlaceholderTracksIfNecessary();
726
727   void SetNetworkState(NetworkState, bool update_media_controls = true);
728
729   void AudioTracksTimerFired(TimerBase*);
730
731   void ScheduleResolvePlayPromises();
732   void ScheduleRejectPlayPromises(PlayPromiseError);
733   void ScheduleNotifyPlaying();
734   void ResolveScheduledPlayPromises();
735   void RejectScheduledPlayPromises();
736   void RejectPlayPromises(DOMExceptionCode, const String&);
737   void RejectPlayPromisesInternal(DOMExceptionCode, const String&);
738
739   void OnRemovedFromDocumentTimerFired(TimerBase*);
740
741   void SetError(MediaError* error);
742   void ReportCurrentTimeToMediaSource();
743
744   void ResetMojoState();
745   void OnRemotePlaybackMetadataChange();
746
747   // Determine if we should reuse the player when moving the element from
748   // |old_document| to |new_document|
749   bool ShouldReusePlayer(Document& old_document, Document& new_document) const;
750
751   // Adds a new MediaPlayerObserver remote that will be notified about media
752   // player events and returns a receiver that an observer implementation can
753   // bind to.
754   mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayerObserver>
755   AddMediaPlayerObserverAndPassReceiver();
756
757   // Timers used to schedule one-shot tasks with no delay.
758   HeapTaskRunnerTimer<HTMLMediaElement> load_timer_;
759   HeapTaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_;
760   HeapTaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_;
761   // Use a low precision timer for repeating tasks to avoid excessive Idle Wake
762   // Up frequency, especially when WebRTC is used and the page contains many
763   // HTMLMediaElements.
764   LowPrecisionTimer progress_event_timer_;
765   LowPrecisionTimer playback_progress_timer_;
766
767   Member<TimeRanges> played_time_ranges_;
768   Member<EventQueue> async_event_queue_;
769
770   double playback_rate_;
771   double default_playback_rate_;
772   NetworkState network_state_;
773   ReadyState ready_state_;
774   ReadyState ready_state_maximum_;
775
776   SourceMetadata current_src_;
777   KURL current_src_after_redirects_;
778
779   Member<MediaStreamDescriptor> src_object_stream_descriptor_;
780   Member<MediaSourceHandle> src_object_media_source_handle_;
781
782   // To prevent potential regression when extended by the MSE API, do not set
783   // |error_| outside of constructor and SetError().
784   Member<MediaError> error_;
785
786   double volume_;
787   double last_seek_time_;
788
789   absl::optional<base::ElapsedTimer> previous_progress_time_;
790
791   // Cached duration to suppress duplicate events if duration unchanged.
792   double duration_;
793
794   // The last time a timeupdate event was sent in movie time.
795   double last_time_update_event_media_time_;
796
797   // The default playback start position.
798   double default_playback_start_position_;
799
800   // Loading state.
801   enum LoadState {
802     kWaitingForSource,
803     kLoadingFromSrcObject,
804     kLoadingFromSrcAttr,
805     kLoadingFromSourceElement
806   };
807   LoadState load_state_;
808   Member<HTMLSourceElement> current_source_node_;
809   Member<Node> next_child_node_to_consider_;
810
811   // "Deferred loading" state (for preload=none).
812   enum DeferredLoadState {
813     // The load is not deferred.
814     kNotDeferred,
815     // The load is deferred, and waiting for the task to set the
816     // delaying-the-load-event flag (to false).
817     kWaitingForStopDelayingLoadEventTask,
818     // The load is the deferred, and waiting for a triggering event.
819     kWaitingForTrigger,
820     // The load is deferred, and waiting for the task to set the
821     // delaying-the-load-event flag, after which the load will be executed.
822     kExecuteOnStopDelayingLoadEventTask
823   };
824   DeferredLoadState deferred_load_state_;
825   HeapTaskRunnerTimer<HTMLMediaElement> deferred_load_timer_;
826
827   std::unique_ptr<WebMediaPlayer> web_media_player_;
828   cc::Layer* cc_layer_;
829
830   // These two fields must be carefully set and reset: the actual derived type
831   // of the attachment (same-thread vs cross-thread, for instance) must be the
832   // same semantic as the actual derived type of the tracer. Further, if there
833   // is no attachment, then there must be no tracer that's tracking an active
834   // attachment. Note that some kinds of attachments do not require a tracer;
835   // see MediaSourceAttachment::StartAttachingToMediaElement() for details.
836   scoped_refptr<MediaSourceAttachment> media_source_attachment_;
837   Member<MediaSourceTracer> media_source_tracer_;
838
839   // Stores "official playback position", updated periodically from "current
840   // playback position". Official playback position should not change while
841   // scripts are running. See setOfficialPlaybackPosition().
842   mutable double official_playback_position_;
843   mutable bool official_playback_position_needs_update_;
844
845   double fragment_end_time_;
846
847   typedef unsigned PendingActionFlags;
848   PendingActionFlags pending_action_flags_;
849
850   // FIXME: HTMLMediaElement has way too many state bits.
851   bool playing_ : 1;
852   bool should_delay_load_event_ : 1;
853   bool have_fired_loaded_data_ : 1;
854   bool can_autoplay_ : 1;
855   bool muted_ : 1;
856   bool paused_ : 1;
857   bool seeking_ : 1;
858   bool paused_by_context_paused_ : 1;
859   bool show_poster_flag_ : 1;
860
861   // data has not been loaded since sending a "stalled" event
862   bool sent_stalled_event_ : 1;
863
864   bool ignore_preload_none_ : 1;
865
866   bool text_tracks_visible_ : 1;
867   bool should_perform_automatic_track_selection_ : 1;
868
869   bool tracks_are_ready_ : 1;
870   bool processing_preference_change_ : 1;
871
872   bool was_always_muted_ : 1;
873
874 #if defined(TIZEN_MULTIMEDIA)
875   bool live_playback_complete_ : 1;
876 #endif
877
878 #if BUILDFLAG(IS_TIZEN_TV)
879   String content_mime_type_;
880   bool is_translated_url_ : 1;
881 #endif
882   // Set if the user has used the context menu to set the visibility of the
883   // controls.
884   absl::optional<bool> user_wants_controls_visible_;
885
886   // Whether or not |web_media_player_| should apply pitch adjustments at
887   // playback raters other than 1.0.
888   bool preserves_pitch_ = true;
889
890 #if BUILDFLAG(IS_TIZEN_TV)
891   bool is_deactivate_ : 1;
892 #endif
893
894 #if defined(TIZEN_MULTIMEDIA_SUPPORT)
895   // This is to suppress stuff set to JS. Do not use it for other purposes.
896   bool suppress_events_ : 1;
897 #endif
898
899   // Whether the player disables the Remote Playback feature.
900   bool is_remote_playback_disabled_ = false;
901   // Whether the player is rendering remotely.
902   bool is_remote_rendering_ = false;
903   // Whether the media content is encrypted.
904   bool is_encrypted_media_ = false;
905   WebString remote_device_friendly_name_;
906   media::AudioCodec audio_codec_ = media::AudioCodec::kUnknown;
907   media::VideoCodec video_codec_ = media::VideoCodec::kUnknown;
908
909   Member<AudioTrackList> audio_tracks_;
910   Member<VideoTrackList> video_tracks_;
911   Member<TextTrackList> text_tracks_;
912   HeapVector<Member<TextTrack>> text_tracks_when_resource_selection_began_;
913
914   Member<CueTimeline> cue_timeline_;
915
916   HeapVector<Member<ScriptPromiseResolver>> play_promise_resolvers_;
917   TaskHandle play_promise_resolve_task_handle_;
918   TaskHandle play_promise_reject_task_handle_;
919   HeapVector<Member<ScriptPromiseResolver>> play_promise_resolve_list_;
920   HeapVector<Member<ScriptPromiseResolver>> play_promise_reject_list_;
921   PlayPromiseError play_promise_error_code_;
922
923   // HTMLMediaElement and its MediaElementAudioSourceNode in case it is provided
924   // die together.
925   Member<AudioSourceProviderClient> audio_source_node_;
926
927   // Controls browser vocalization within the media element (e.g. to speak cues,
928   // to pause utterance).
929   Member<SpeechSynthesisBase> speech_synthesis_;
930
931   // AudioClientImpl wraps an AudioSourceProviderClient.
932   // When the audio format is known, Chromium calls setFormat().
933   class AudioClientImpl final : public GarbageCollected<AudioClientImpl>,
934                                 public WebAudioSourceProviderClient {
935    public:
936     explicit AudioClientImpl(AudioSourceProviderClient* client)
937         : client_(client) {}
938
939     ~AudioClientImpl() override = default;
940
941     // WebAudioSourceProviderClient
942     void SetFormat(uint32_t number_of_channels, float sample_rate) override;
943
944     void Trace(Visitor*) const;
945
946    private:
947     Member<AudioSourceProviderClient> client_;
948   };
949
950   // AudioSourceProviderImpl wraps a WebAudioSourceProvider.
951   // provideInput() calls into Chromium to get a rendered audio stream.
952   class AudioSourceProviderImpl final : public AudioSourceProvider {
953     DISALLOW_NEW();
954
955    public:
956     AudioSourceProviderImpl() = default;
957     ~AudioSourceProviderImpl() override = default;
958
959     // Wraps the given WebAudioSourceProvider.
960     void Wrap(scoped_refptr<WebAudioSourceProviderImpl>);
961
962     // AudioSourceProvider
963     void SetClient(AudioSourceProviderClient*) override;
964     void ProvideInput(AudioBus*, int frames_to_process) override;
965
966     void Trace(Visitor*) const;
967
968    private:
969     base::Lock provide_input_lock;
970     scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_
971         GUARDED_BY(provide_input_lock);
972     Member<AudioClientImpl> client_;
973   };
974
975   AudioSourceProviderImpl audio_source_provider_;
976
977   // Notify HTMLMediaElement when a document's ExecutionContext is destroyed.
978   // It allows us to disconnect from a previous document's frame if we were
979   // using it to support our WebMediaPlayer rather than our current frame.
980   class OpenerContextObserver final
981       : public GarbageCollected<OpenerContextObserver>,
982         public ContextLifecycleObserver {
983    public:
984     // Notify `element` when our context is destroyed.
985     explicit OpenerContextObserver(HTMLMediaElement* element);
986     ~OpenerContextObserver() final;
987
988     void Trace(Visitor* visitor) const final;
989
990    protected:
991     void ContextDestroyed() final;
992
993     Member<HTMLMediaElement> element_;
994   };
995
996   // Clean up things that are tied to any previous frame, including the player
997   // and mojo interfaces, when we switch to a new frame.
998   void AttachToNewFrame();
999
1000   Member<Document> opener_document_;
1001   Member<OpenerContextObserver> opener_context_observer_;
1002
1003   friend class AutoplayPolicy;
1004   friend class AutoplayUmaHelperTest;
1005   friend class Internals;
1006   friend class TrackDisplayUpdateScope;
1007   friend class MediaControlsImplTest;
1008   friend class HTMLMediaElementTest;
1009   friend class HTMLMediaElementEventListenersTest;
1010   friend class HTMLVideoElement;
1011   friend class MediaControlInputElementTest;
1012   friend class MediaControlsOrientationLockDelegateTest;
1013   friend class MediaControlsRotateToFullscreenDelegateTest;
1014   friend class MediaControlLoadingPanelElementTest;
1015   friend class ContextMenuControllerTest;
1016   friend class HTMLVideoElementTest;
1017
1018   Member<AutoplayPolicy> autoplay_policy_;
1019
1020   WebRemotePlaybackClient* remote_playback_client_;
1021
1022   Member<MediaControls> media_controls_;
1023   Member<HTMLMediaElementControlsList> controls_list_;
1024
1025   Member<IntersectionObserver> lazy_load_intersection_observer_;
1026
1027   Member<DisallowNewWrapper<
1028       HeapMojoAssociatedRemote<media::mojom::blink::MediaPlayerHost>>>
1029       media_player_host_remote_;
1030
1031   // Note: There's only ever one entry in this set.
1032   Member<DisallowNewWrapper<
1033       HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>>>
1034       media_player_observer_remote_set_;
1035
1036   // A receiver set is needed here as there will be different objects in the
1037   // browser communicating with this object. This is done this way to avoid
1038   // routing everything through a single class (e.g. RFHI) and to keep this
1039   // logic contained inside MediaPlayer-related classes.
1040   Member<DisallowNewWrapper<
1041       HeapMojoAssociatedReceiverSet<media::mojom::blink::MediaPlayer,
1042                                     HTMLMediaElement>>>
1043       media_player_receiver_set_;
1044 };
1045
1046 template <>
1047 inline bool IsElementOfType<const HTMLMediaElement>(const Node& node) {
1048   return IsA<HTMLMediaElement>(node);
1049 }
1050 template <>
1051 struct DowncastTraits<HTMLMediaElement> {
1052   static bool AllowFrom(const Node& node) {
1053     auto* html_element = DynamicTo<HTMLElement>(node);
1054     return html_element && AllowFrom(*html_element);
1055   }
1056   static bool AllowFrom(const HTMLElement& html_element) {
1057     return IsA<HTMLAudioElement>(html_element) ||
1058            IsA<HTMLVideoElement>(html_element);
1059   }
1060 };
1061
1062 }  // namespace blink
1063
1064 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_