/*
 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_

#include <memory>

#include "base/optional.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "media/mojo/mojom/media_player.mojom-blink.h"
#include "third_party/blink/public/common/media/display_type.h"
#include "third_party/blink/public/platform/web_media_player_client.h"
#include "third_party/blink/public/platform/webaudiosourceprovider_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/html/media/media_controls.h"
#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h"
#include "third_party/blink/renderer/platform/audio/audio_source_provider.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_set.h"
#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"

namespace cc {
class Layer;
}

namespace media {
enum class MediaContentType;
}  // namespace media

namespace blink {

class AudioSourceProviderClient;
class AudioTrack;
class AudioTrackList;
class AutoplayPolicy;
class ContentType;
class CueTimeline;
class Event;
class EventQueue;
class ExceptionState;
class HTMLMediaElementControlsList;
class HTMLSourceElement;
class HTMLTrackElement;
class MediaError;
class MediaSourceAttachment;
class MediaSourceTracer;
class MediaStreamDescriptor;
class ScriptPromiseResolver;
class ScriptState;
class TextTrack;
class TextTrackContainer;
class TextTrackList;
class TimeRanges;
class VideoTrack;
class VideoTrackList;
class WebInbandTextTrack;
class WebRemotePlaybackClient;

class CORE_EXPORT HTMLMediaElement
    : public HTMLElement,
      public Supplementable<HTMLMediaElement>,
      public ActiveScriptWrappable<HTMLMediaElement>,
      public ExecutionContextLifecycleStateObserver,
      public media::mojom::blink::MediaPlayer,
      private WebMediaPlayerClient {
  DEFINE_WRAPPERTYPEINFO();
  USING_PRE_FINALIZER(HTMLMediaElement, Dispose);

 public:
  // Limits the range of media playback rate.
  static constexpr double kMinPlaybackRate = 0.0625;
  static constexpr double kMaxPlaybackRate = 16.0;

  bool IsMediaElement() const override { return true; }

  static MIMETypeRegistry::SupportsType GetSupportsType(const ContentType&);

  enum class RecordMetricsBehavior { kDoNotRecord, kDoRecord };

  static bool IsHLSURL(const KURL&);

  // If HTMLMediaElement is using MediaTracks (either placeholder or provided
  // by the page).
  static bool MediaTracksEnabledInternally();

  // Notify the HTMLMediaElement that the media controls settings have changed
  // for the given document.
  static void OnMediaControlsEnabledChange(Document*);

  // Binds |pending_receiver| and adds it to |media_player_receiver_set_|. Also
  // called from other Blink classes (e.g. PictureInPictureControllerImpl).
  void BindMediaPlayerReceiver(
      mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayer>
          pending_receiver);

  void Trace(Visitor*) const override;

  WebMediaPlayer* GetWebMediaPlayer() const { return web_media_player_.get(); }

  // Returns true if the loaded media has a video track.
  // Note that even an audio element can have video track in cases such as
  // <audio src="video.webm">, in which case this function will return true.
  bool HasVideo() const;
  // Returns true if loaded media has an audio track.
  bool HasAudio() const;

  bool SupportsSave() const;

  bool SupportsLoop() const;

  cc::Layer* CcLayer() const;

  enum DelayedActionType {
    kLoadMediaResource = 1 << 0,
    kLoadTextTrackResource = 1 << 1
  };
  void ScheduleTextTrackResourceLoad();

  bool HasRemoteRoutes() const;

  // error state
  MediaError* error() const;

  // network state
  void SetSrc(const AtomicString&);
  const KURL& currentSrc() const { return current_src_; }

  // Return the URL to be used for downloading the media.
  const KURL& downloadURL() const {
    // If we didn't get a redirected URL from the player, then use the original.
    if (current_src_after_redirects_.IsNull() ||
        current_src_after_redirects_.IsEmpty()) {
      return currentSrc();
    }
    return current_src_after_redirects_;
  }

  void SetSrcObject(MediaStreamDescriptor*);
  MediaStreamDescriptor* GetSrcObject() const { return src_object_.Get(); }

  enum NetworkState {
    kNetworkEmpty,
    kNetworkIdle,
    kNetworkLoading,
    kNetworkNoSource
  };
  NetworkState getNetworkState() const;

  String preload() const;
  void setPreload(const AtomicString&);
  WebMediaPlayer::Preload PreloadType() const;
  String EffectivePreload() const;
  WebMediaPlayer::Preload EffectivePreloadType() const;

  WebTimeRanges BufferedInternal() const;
  TimeRanges* buffered() const;
  void load();
  String canPlayType(ExecutionContext* context, const String& mime_type) const;

  // ready state
  enum ReadyState {
    kHaveNothing,
    kHaveMetadata,
    kHaveCurrentData,
    kHaveFutureData,
    kHaveEnoughData
  };
  ReadyState getReadyState() const;
  bool seeking() const;

  // playback state
  double currentTime() const;
  void setCurrentTime(double);
  double duration() const;
  bool paused() const;
  double defaultPlaybackRate() const;
  void setDefaultPlaybackRate(double);
  double playbackRate() const;
  void setPlaybackRate(double, ExceptionState& = ASSERT_NO_EXCEPTION);
  TimeRanges* played();
  WebTimeRanges SeekableInternal() const;
  TimeRanges* seekable() const;
  bool ended() const;
  bool Autoplay() const;
  bool Loop() const;
  void SetLoop(bool);
  ScriptPromise playForBindings(ScriptState*);
  base::Optional<DOMExceptionCode> Play();
  void pause();
  double latencyHint() const;
  void setLatencyHint(double);
  bool preservesPitch() const;
  void setPreservesPitch(bool);
  void FlingingStarted();
  void FlingingStopped();

  // statistics
  uint64_t webkitAudioDecodedByteCount() const;
  uint64_t webkitVideoDecodedByteCount() const;

  // media source extensions
  void CloseMediaSource();
  void DurationChanged(double duration, bool request_seek);

  // controls
  bool ShouldShowControls(
      const RecordMetricsBehavior = RecordMetricsBehavior::kDoNotRecord) const;
  DOMTokenList* controlsList() const;
  HTMLMediaElementControlsList* ControlsListInternal() const;
  double volume() const;
  void setVolume(double, ExceptionState& = ASSERT_NO_EXCEPTION);
  bool muted() const;
  void setMuted(bool);
  virtual bool SupportsPictureInPicture() const { return false; }

  void TogglePlayState();

  AudioTrackList& audioTracks();
  void AudioTrackChanged(AudioTrack*);

  VideoTrackList& videoTracks();
  void SelectedVideoTrackChanged(VideoTrack*);

  TextTrack* addTextTrack(const AtomicString& kind,
                          const AtomicString& label,
                          const AtomicString& language,
                          ExceptionState&);

  TextTrackList* textTracks();
  CueTimeline& GetCueTimeline();

  // Implements the "forget the media element's media-resource-specific tracks"
  // algorithm in the HTML5 spec.
  void ForgetResourceSpecificTracks();

  void DidAddTrackElement(HTMLTrackElement*);
  void DidRemoveTrackElement(HTMLTrackElement*);

  void HonorUserPreferencesForAutomaticTextTrackSelection();

  bool TextTracksAreReady() const;
  void ConfigureTextTrackDisplay();
  void UpdateTextTrackDisplay();
  double LastSeekTime() const { return last_seek_time_; }
  void TextTrackReadyStateChanged(TextTrack*);

  void TextTrackModeChanged(TextTrack*);
  void DisableAutomaticTextTrackSelection();

  // EventTarget function.
  // Both Node (via HTMLElement) and ExecutionContextLifecycleStateObserver
  // define this method, which causes an ambiguity error at compile time. This
  // class's constructor ensures that both implementations return document, so
  // return the result of one of them here.
  using HTMLElement::GetExecutionContext;

  bool IsFullscreen() const;
  virtual bool UsesOverlayFullscreenVideo() const { return false; }

  bool HasClosedCaptions() const;
  bool TextTracksVisible() const;

  static void SetTextTrackKindUserPreferenceForAllMediaElements(Document*);
  void AutomaticTrackSelectionForUpdatedUserPreference();

  // Returns the MediaControls, or null if they have not been added yet.
  // Note that this can be non-null even if there is no controls attribute.
  MediaControls* GetMediaControls() const;

  // Notifies the media element that the media controls became visible, so
  // that text track layout may be updated to avoid overlapping them.
  void MediaControlsDidBecomeVisible();

  void SourceWasRemoved(HTMLSourceElement*);
  void SourceWasAdded(HTMLSourceElement*);

  // ScriptWrappable functions.
  bool HasPendingActivity() const override;

  AudioSourceProviderClient* AudioSourceNode() { return audio_source_node_; }
  void SetAudioSourceNode(AudioSourceProviderClient*);

  AudioSourceProvider& GetAudioSourceProvider() {
    return audio_source_provider_;
  }

  enum InvalidURLAction { kDoNothing, kComplain };
  bool IsSafeToLoadURL(const KURL&, InvalidURLAction);

  // Checks to see if current media data is CORS-same-origin.
  bool IsMediaDataCorsSameOrigin() const;

  void ScheduleEvent(Event*);

  // Returns the "effective media volume" value as specified in the HTML5 spec.
  double EffectiveMediaVolume() const;

  // Predicates also used when dispatching wrapper creation (cf.
  // [SpecialWrapFor] IDL attribute usage.)
  virtual bool IsHTMLAudioElement() const { return false; }
  virtual bool IsHTMLVideoElement() const { return false; }

  void VideoWillBeDrawnToCanvas() const;

  const WebRemotePlaybackClient* RemotePlaybackClient() const {
    return remote_playback_client_;
  }

  const AutoplayPolicy& GetAutoplayPolicy() const { return *autoplay_policy_; }

  WebMediaPlayer::LoadType GetLoadType() const;

  bool HasMediaSource() const { return media_source_attachment_.get(); }

  // Return true if element is paused and won't resume automatically if it
  // becomes visible again.
  bool PausedWhenVisible() const;

  void DidAudioOutputSinkChanged(const String& hashed_device_id);

  void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); }

  // Required by tests set mock receivers to check that messages are delivered.
  void AddMediaPlayerObserverForTesting(
      mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver>
          observer);

  bool IsShowPosterFlagSet() const { return show_poster_flag_; }

 protected:
  // Assert the correct order of the children in shadow dom when DCHECK is on.
  static void AssertShadowRootChildren(ShadowRoot&);

  HTMLMediaElement(const QualifiedName&, Document&);
  ~HTMLMediaElement() override;
  void Dispose();

  // Returns a constant reference to the HeapMojoAssociatedRemoteSet holding all
  // the bound remotes for the media::mojom::blink::MediaPlayerObserver
  // interface. Needed to allow sending messages directly from
  // HTMLMediaElement's subclasses.
  const HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>&
  GetMediaPlayerObserverRemoteSet() {
    return media_player_observer_remote_set_;
  }

  void ParseAttribute(const AttributeModificationParams&) override;
  void FinishParsingChildren() final;
  bool IsURLAttribute(const Attribute&) const override;
  void AttachLayoutTree(AttachContext&) override;
  void ParserDidSetAttributes() override;
  void CloneNonAttributePropertiesFrom(const Element&,
                                       CloneChildrenFlag) override;

  InsertionNotificationRequest InsertedInto(ContainerNode&) override;
  void RemovedFrom(ContainerNode&) override;

  // Return true if media is cross origin from the current document
  // and has not passed a cors check, meaning that we should return
  // as little information as possible about it.
  bool MediaShouldBeOpaque() const;

  void DidMoveToNewDocument(Document& old_document) override;
  virtual KURL PosterImageURL() const { return KURL(); }

  // Called after the creation of |web_media_player_|.
  virtual void OnWebMediaPlayerCreated() {}
  virtual void OnWebMediaPlayerCleared() {}

  void UpdateLayoutObject();

 private:
  // Friend class for testing.
  friend class ContextMenuControllerTest;
  friend class HTMLMediaElementTest;
  friend class PictureInPictureControllerTest;
  friend class VideoWakeLockTest;

  bool HasPendingActivityInternal() const;

  void ResetMediaPlayerAndMediaSource();

  bool AlwaysCreateUserAgentShadowRoot() const final { return true; }
  bool AreAuthorShadowsAllowed() const final { return false; }

  bool SupportsFocus() const final;
  bool IsMouseFocusable() const final;
  bool LayoutObjectIsNeeded(const ComputedStyle&) const override;
  LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
  void DidNotifySubtreeInsertionsToDocument() override;
  void DidRecalcStyle(const StyleRecalcChange) final;

  bool CanStartSelection() const override { return false; }

  bool IsInteractiveContent() const final;

  // ExecutionContextLifecycleStateObserver functions.
  void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override;
  void ContextDestroyed() override;

  virtual void OnPlay() {}
  virtual void OnLoadStarted() {}
  virtual void OnLoadFinished() {}

  void SetShowPosterFlag(bool value);

  void SetReadyState(ReadyState);
  void SetNetworkState(WebMediaPlayer::NetworkState);

  // WebMediaPlayerClient implementation.
  void NetworkStateChanged() final;
  void ReadyStateChanged() final;
  void TimeChanged() final;
  void Repaint() final;
  void DurationChanged() final;
  void SizeChanged() final;

  void SetCcLayer(cc::Layer*) final;
  WebMediaPlayer::TrackId AddAudioTrack(const WebString&,
                                        WebMediaPlayerClient::AudioTrackKind,
                                        const WebString&,
                                        const WebString&,
                                        bool) final;
  void RemoveAudioTrack(WebMediaPlayer::TrackId) final;
  WebMediaPlayer::TrackId AddVideoTrack(const WebString&,
                                        WebMediaPlayerClient::VideoTrackKind,
                                        const WebString&,
                                        const WebString&,
                                        bool) final;
  void RemoveVideoTrack(WebMediaPlayer::TrackId) final;
  void AddTextTrack(WebInbandTextTrack*) final;
  void RemoveTextTrack(WebInbandTextTrack*) final;
  void MediaSourceOpened(WebMediaSource*) final;
  void RemotePlaybackCompatibilityChanged(const WebURL&,
                                          bool is_compatible) final;
  void OnBecamePersistentVideo(bool) override {}
  bool HasSelectedVideoTrack() final;
  WebMediaPlayer::TrackId GetSelectedVideoTrackId() final;
  bool WasAlwaysMuted() final;
  bool HasNativeControls() final;
  bool IsAudioElement() final;
  DisplayType GetDisplayType() const override;
  WebRemotePlaybackClient* RemotePlaybackClient() final {
    return remote_playback_client_;
  }
  std::vector<TextTrackMetadata> GetTextTrackMetadata() override;
  gfx::ColorSpace TargetColorSpace() override;
  bool WasAutoplayInitiated() override;
  bool IsInAutoPIP() const override { return false; }
  void ResumePlayback() final;
  void PausePlayback() final;
  void DidPlayerStartPlaying() override;
  void DidPlayerPaused(bool stream_ended) override;
  void DidPlayerMutedStatusChange(bool muted) override;
  void DidMediaMetadataChange(
      bool has_audio,
      bool has_video,
      media::MediaContentType media_content_type) override;
  void DidPlayerMediaPositionStateChange(double playback_rate,
                                         base::TimeDelta duration,
                                         base::TimeDelta position) override;
  void DidDisableAudioOutputSinkChanges() override;
  void DidPlayerSizeChange(const gfx::Size& size) override;
  void DidBufferUnderflow() override;
  void DidSeek() override;

  // Returns a reference to the mojo remote for the MediaPlayerHost interface,
  // requesting it first from the BrowserInterfaceBroker if needed. It is an
  // error to call this method before having access to the document's frame.
  media::mojom::blink::MediaPlayerHost& GetMediaPlayerHostRemote();

  // media::mojom::MediaPlayer  implementation.
  void AddMediaPlayerObserver(
      mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver>
          observer) override;
  void RequestPlay() override;
  void RequestPause(bool triggered_by_user) override;
  void RequestSeekForward(base::TimeDelta seek_time) override;
  void RequestSeekBackward(base::TimeDelta seek_time) override;
  void RequestEnterPictureInPicture() override {}
  void RequestExitPictureInPicture() override {}
  void SetAudioSinkId(const String&) override;

  void LoadTimerFired(TimerBase*);
  void ProgressEventTimerFired(TimerBase*);
  void PlaybackProgressTimerFired(TimerBase*);
  void ScheduleTimeupdateEvent(bool periodic_event);
  void StartPlaybackProgressTimer();
  void StartProgressEventTimer();
  void StopPeriodicTimers();

  void Seek(double time);
  void FinishSeek();
  void AddPlayedRange(double start, double end);

  // FIXME: Rename to scheduleNamedEvent for clarity.
  void ScheduleEvent(const AtomicString& event_name);

  // loading
  void InvokeLoadAlgorithm();
  void InvokeResourceSelectionAlgorithm();
  void LoadInternal();
  void SelectMediaResource();
  void LoadResource(const WebMediaPlayerSource&, const String& content_type);
  void StartPlayerLoad();
  void SetPlayerPreload();
  void ScheduleNextSourceChild();
  void LoadSourceFromObject();
  void LoadSourceFromAttribute();
  void LoadNextSourceChild();
  void ClearMediaPlayer();
  void ClearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
  bool HavePotentialSourceChild();
  void NoneSupported(const String&);
  void MediaEngineError(MediaError*);
  void CancelPendingEventsAndCallbacks();
  void WaitForSourceChange();
  void SetIgnorePreloadNone();

  KURL SelectNextSourceChild(String* content_type, InvalidURLAction);

  void MediaLoadingFailed(WebMediaPlayer::NetworkState, const String&);

  // deferred loading (preload=none)
  bool LoadIsDeferred() const;
  void DeferLoad();
  void CancelDeferredLoad();
  void StartDeferredLoad();
  void ExecuteDeferredLoad();
  void DeferredLoadTimerFired(TimerBase*);

  void MarkCaptionAndSubtitleTracksAsUnconfigured();

  // This does not check user gesture restrictions.
  void PlayInternal();

  // This does not stop autoplay visibility observation.
  void PauseInternal();

  void UpdatePlayState();
  bool PotentiallyPlaying() const;
  bool StoppedDueToErrors() const;
  bool CouldPlayIfEnoughData() const override;

  // Generally the presence of the loop attribute should be considered to mean
  // playback has not "ended", as "ended" and "looping" are mutually exclusive.
  // See
  // https://html.spec.whatwg.org/C/#ended-playback
  enum class LoopCondition { kIncluded, kIgnored };
  bool EndedPlayback(LoopCondition = LoopCondition::kIncluded) const;

  void SetShouldDelayLoadEvent(bool);

  double EarliestPossiblePosition() const;
  double CurrentPlaybackPosition() const;
  double OfficialPlaybackPosition() const;
  void SetOfficialPlaybackPosition(double) const;
  void RequireOfficialPlaybackPositionUpdate() const;

  void EnsureMediaControls();
  void UpdateControlsVisibility();

  TextTrackContainer& EnsureTextTrackContainer();

  void ChangeNetworkStateFromLoadingToIdle();

  WebMediaPlayer::CorsMode CorsMode() const;

  // Returns the "direction of playback" value as specified in the HTML5 spec.
  enum DirectionOfPlayback { kBackward, kForward };
  DirectionOfPlayback GetDirectionOfPlayback() const;

  // Creates placeholder AudioTrack and/or VideoTrack objects when
  // WebMediaPlayer objects advertise they have audio and/or video, but don't
  // explicitly signal them via addAudioTrack() and addVideoTrack().
  // FIXME: Remove this once all WebMediaPlayer implementations properly report
  // their track info.
  void CreatePlaceholderTracksIfNecessary();

  void SetNetworkState(NetworkState);

  void AudioTracksTimerFired(TimerBase*);

  void ScheduleResolvePlayPromises();
  void ScheduleRejectPlayPromises(DOMExceptionCode);
  void ScheduleNotifyPlaying();
  void ResolveScheduledPlayPromises();
  void RejectScheduledPlayPromises();
  void RejectPlayPromises(DOMExceptionCode, const String&);
  void RejectPlayPromisesInternal(DOMExceptionCode, const String&);

  void OnRemovedFromDocumentTimerFired(TimerBase*);

  void SetError(MediaError* error);
  void ReportCurrentTimeToMediaSource();

  Features GetFeatures() override;

  HeapTaskRunnerTimer<HTMLMediaElement> load_timer_;
  HeapTaskRunnerTimer<HTMLMediaElement> progress_event_timer_;
  HeapTaskRunnerTimer<HTMLMediaElement> playback_progress_timer_;
  HeapTaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_;
  HeapTaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_;

  Member<TimeRanges> played_time_ranges_;
  Member<EventQueue> async_event_queue_;

  double playback_rate_;
  double default_playback_rate_;
  NetworkState network_state_;
  ReadyState ready_state_;
  ReadyState ready_state_maximum_;
  KURL current_src_;
  KURL current_src_after_redirects_;
  Member<MediaStreamDescriptor> src_object_;

  // To prevent potential regression when extended by the MSE API, do not set
  // |error_| outside of constructor and SetError().
  Member<MediaError> error_;

  double volume_;
  double last_seek_time_;

  base::Optional<base::ElapsedTimer> previous_progress_time_;

  // Cached duration to suppress duplicate events if duration unchanged.
  double duration_;

  // The last time a timeupdate event was sent in movie time.
  double last_time_update_event_media_time_;

  // The default playback start position.
  double default_playback_start_position_;

  // Loading state.
  enum LoadState {
    kWaitingForSource,
    kLoadingFromSrcObject,
    kLoadingFromSrcAttr,
    kLoadingFromSourceElement
  };
  LoadState load_state_;
  Member<HTMLSourceElement> current_source_node_;
  Member<Node> next_child_node_to_consider_;

  // "Deferred loading" state (for preload=none).
  enum DeferredLoadState {
    // The load is not deferred.
    kNotDeferred,
    // The load is deferred, and waiting for the task to set the
    // delaying-the-load-event flag (to false).
    kWaitingForStopDelayingLoadEventTask,
    // The load is the deferred, and waiting for a triggering event.
    kWaitingForTrigger,
    // The load is deferred, and waiting for the task to set the
    // delaying-the-load-event flag, after which the load will be executed.
    kExecuteOnStopDelayingLoadEventTask
  };
  DeferredLoadState deferred_load_state_;
  HeapTaskRunnerTimer<HTMLMediaElement> deferred_load_timer_;

  std::unique_ptr<WebMediaPlayer> web_media_player_;
  cc::Layer* cc_layer_;

  // These two fields must be carefully set and reset: the actual derived type
  // of the attachment (same-thread vs cross-thread, for instance) must be the
  // same semantic as the actual derived type of the tracer. Further, if there
  // is no attachment, then there must be no tracer that's tracking an active
  // attachment. Note that some kinds of attachments do not require a tracer;
  // see MediaSourceAttachment::StartAttachingToMediaElement() for details.
  scoped_refptr<MediaSourceAttachment> media_source_attachment_;
  Member<MediaSourceTracer> media_source_tracer_;

  // Stores "official playback position", updated periodically from "current
  // playback position". Official playback position should not change while
  // scripts are running. See setOfficialPlaybackPosition().
  mutable double official_playback_position_;
  mutable bool official_playback_position_needs_update_;

  double fragment_end_time_;

  typedef unsigned PendingActionFlags;
  PendingActionFlags pending_action_flags_;

  // FIXME: HTMLMediaElement has way too many state bits.
  bool playing_ : 1;
  bool should_delay_load_event_ : 1;
  bool have_fired_loaded_data_ : 1;
  bool can_autoplay_ : 1;
  bool muted_ : 1;
  bool paused_ : 1;
  bool seeking_ : 1;
  bool paused_by_context_paused_ : 1;
  bool show_poster_flag_ : 1;

  // data has not been loaded since sending a "stalled" event
  bool sent_stalled_event_ : 1;

  bool ignore_preload_none_ : 1;

  bool text_tracks_visible_ : 1;
  bool should_perform_automatic_track_selection_ : 1;

  bool tracks_are_ready_ : 1;
  bool processing_preference_change_ : 1;

  bool was_always_muted_ : 1;

  // Whether or not |web_media_player_| should apply pitch adjustments at
  // playback raters other than 1.0.
  bool preserves_pitch_ = true;

  // Keeps track of when the player seek event was sent to the browser process.
  base::TimeTicks last_seek_update_time_;

  Member<AudioTrackList> audio_tracks_;
  Member<VideoTrackList> video_tracks_;
  Member<TextTrackList> text_tracks_;
  HeapVector<Member<TextTrack>> text_tracks_when_resource_selection_began_;

  Member<CueTimeline> cue_timeline_;

  HeapVector<Member<ScriptPromiseResolver>> play_promise_resolvers_;
  TaskHandle play_promise_resolve_task_handle_;
  TaskHandle play_promise_reject_task_handle_;
  HeapVector<Member<ScriptPromiseResolver>> play_promise_resolve_list_;
  HeapVector<Member<ScriptPromiseResolver>> play_promise_reject_list_;
  DOMExceptionCode play_promise_error_code_;

  // HTMLMediaElement and its MediaElementAudioSourceNode in case it is provided
  // die together.
  Member<AudioSourceProviderClient> audio_source_node_;

  // AudioClientImpl wraps an AudioSourceProviderClient.
  // When the audio format is known, Chromium calls setFormat().
  class AudioClientImpl final : public GarbageCollected<AudioClientImpl>,
                                public WebAudioSourceProviderClient {
   public:
    explicit AudioClientImpl(AudioSourceProviderClient* client)
        : client_(client) {}

    ~AudioClientImpl() override = default;

    // WebAudioSourceProviderClient
    void SetFormat(uint32_t number_of_channels, float sample_rate) override;

    void Trace(Visitor*) const;

   private:
    Member<AudioSourceProviderClient> client_;
  };

  // AudioSourceProviderImpl wraps a WebAudioSourceProvider.
  // provideInput() calls into Chromium to get a rendered audio stream.
  class AudioSourceProviderImpl final : public AudioSourceProvider {
    DISALLOW_NEW();

   public:
    AudioSourceProviderImpl() = default;
    ~AudioSourceProviderImpl() override = default;

    // Wraps the given WebAudioSourceProvider.
    void Wrap(scoped_refptr<WebAudioSourceProviderImpl>);

    // AudioSourceProvider
    void SetClient(AudioSourceProviderClient*) override;
    void ProvideInput(AudioBus*, uint32_t frames_to_process) override;

    void Trace(Visitor*) const;

   private:
    scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_;
    Member<AudioClientImpl> client_;
    Mutex provide_input_lock;
  };

  AudioSourceProviderImpl audio_source_provider_;

  friend class AutoplayPolicy;
  friend class AutoplayUmaHelperTest;
  friend class Internals;
  friend class TrackDisplayUpdateScope;
  friend class MediaControlsImplTest;
  friend class HTMLMediaElementTest;
  friend class HTMLMediaElementEventListenersTest;
  friend class HTMLVideoElement;
  friend class MediaControlInputElementTest;
  friend class MediaControlsOrientationLockDelegateTest;
  friend class MediaControlsRotateToFullscreenDelegateTest;
  friend class MediaControlLoadingPanelElementTest;
  friend class ContextMenuControllerTest;
  friend class HTMLVideoElementTest;

  Member<AutoplayPolicy> autoplay_policy_;

  WebRemotePlaybackClient* remote_playback_client_;

  Member<MediaControls> media_controls_;
  Member<HTMLMediaElementControlsList> controls_list_;

  Member<IntersectionObserver> lazy_load_intersection_observer_;

  HeapMojoAssociatedRemote<media::mojom::blink::MediaPlayerHost>
      media_player_host_remote_;

  // Multiple objects outside of the renderer process can register as observers,
  // so we need to store the remotes in a set here.
  HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>
      media_player_observer_remote_set_;

  // A receiver set is needed here as there will be different objects in the
  // browser communicating with this object. This is done this way to avoid
  // routing everything through a single class (e.g. RFHI) and to keep this
  // logic contained inside MediaPlayer-related classes.
  HeapMojoAssociatedReceiverSet<media::mojom::blink::MediaPlayer,
                                HTMLMediaElement>
      media_player_receiver_set_;
};

template <>
inline bool IsElementOfType<const HTMLMediaElement>(const Node& node) {
  return IsA<HTMLMediaElement>(node);
}
template <>
struct DowncastTraits<HTMLMediaElement> {
  static bool AllowFrom(const Node& node) {
    auto* html_element = DynamicTo<HTMLElement>(node);
    return html_element && AllowFrom(*html_element);
  }
  static bool AllowFrom(const HTMLElement& html_element) {
    return IsA<HTMLAudioElement>(html_element) ||
           IsA<HTMLVideoElement>(html_element);
  }
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_ELEMENT_H_
