// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module media.mojom;

import "media/mojo/mojom/media_types.mojom";
import "mojo/public/mojom/base/time.mojom";
import "services/media_session/public/mojom/media_session.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";

[EnableIf=arkweb_video_assistant]
enum VideoAssistantDownloadButton {
  kDownloadPerPage,
  kDownloadForceShow,
  kDownloadForceHide,
};
 
[EnableIf=arkweb_video_assistant]
struct VideoAssistantConfig {
  bool video_assistant;
  bool playback_rate;
  VideoAssistantDownloadButton download_button;
};
 
[EnableIf=arkweb_video_assistant]
struct VideoAttributesForVAST {
  bool show_fullscreen_button;
  bool show_download_button;
  bool show_playback_rate_menu;
  double current_playback_rate;
  gfx.mojom.RectF rect;
 
  bool supports_save;
  double duration;
  bool visible;
};

[EnableIf=arkweb_video_assistant]
struct MediaInfoForVAST {
  string id;
  string title;
  double duration;
  double volume;
  double current_time;
  double playback_rate;
  int32 video_width;
  int32 video_height;
  int32 isMuted;
  bool isPlaying;
  bool isShowPlaybackSpeed;

  bool show_download_button;
  bool supports_save;
  bool fullscreen_overlay;
};

// Implemented by HTMLMediaElement in the renderer process to allow the
// browser to control media playback.
interface MediaPlayer {
  // Requests the media player to start or resume media playback.
  RequestPlay();

  // Suspend the html play.
  [EnableIf=is_arkweb]
  SetHtmlPlayEnabled(bool enabled);

  // Requests the media player to pause media playback.
  RequestPause(bool triggered_by_user);

  // Requests the media player to move forward the media playback position.
  RequestSeekForward(mojo_base.mojom.TimeDelta seek_time);

  // Requests the media player to move backward the media playback position.
  RequestSeekBackward(mojo_base.mojom.TimeDelta seek_time);

  // Requests the media player to move to a specific time.
  RequestSeekTo(mojo_base.mojom.TimeDelta seek_time);

  // Requests the media player to enter the Picture-in-Picture mode.
  RequestEnterPictureInPicture();

  // Requests the media player to mute or unmute.
  RequestMute(bool mute);

  // Set the volume multiplier to control audio ducking.
  // Output volume should be set to |player_volume| * |multiplier|. The range
  // of |multiplier| is [0, 1], where 1 indicates normal (non-ducked) playback.
  SetVolumeMultiplier(double multiplier);

  // Set the player as the persistent video. Persistent video should hide its
  // controls and go fullscreen.
  SetPersistentState(bool persistent);

  // Notify the player that it is now eligible to start recording power
  // measurements if |state| is true, else it is no longer eligible.
  SetPowerExperimentState(bool enabled);

  // Set the media player sink id to |sink_id|.
  SetAudioSinkId(string sink_id);

  // Suspends the media player when the host frame is closed.
  SuspendForFrameClosed();

  // Request the media player to start Media Remoting when there are available
  // sinks.
  RequestMediaRemoting();

  // Request the media player to check if it has a video that meets the
  // visibility threshold defined by |HTMLVideoElement| (kVisibilityThreshold).
  // The answer is computed by the |MediaVideoVisibilityTracker|.
  //
  // If this method is called multiple times in a row, the newest callback
  // always takes precedence. Previous ones are immediately run with `false`.
  RequestVisibility() => (bool has_sufficiently_visible_video);

  [EnableIf=arkweb_custom_video_player]
  RequestEnterFullscreen();

  [EnableIf=arkweb_custom_video_player]
  RequestExitFullscreen();

  [EnableIf=arkweb_video_assistant]
  SetPlaybackRate(double playback_rate);

  [EnableIf=arkweb_video_assistant]
  RequestDownloadUrl();

  [EnableIf=arkweb_video_assistant]
  HidePlaybackSpeedList();

  [EnableIf=arkweb_video_assistant]
  SetVideoSurface(int32 widget_id);

  [EnableIf=arkweb_pip]
  PipEnable(bool enable);

  [EnableIf=arkweb_pip]
  PipDown(bool enable);

  [EnableIf=arkweb_pip]
  RequestExitPictureInPicture();

  [EnableIf=arkweb_pip]
  NotifyPipResize();

  [EnableIf=arkweb_pip]
  PipRequestPlay();

  [EnableIf=arkweb_video_assistant]
  SetVolume(double volume);

  [Sync, EnableIf=arkweb_video_assistant]
  GetVolume() => (double volume);

  [EnableIf=arkweb_media_memory_pressure]
  NotifyMemoryLevel(int32 level);

  // Request the media player to record auto picture in picture related
  // information. This information helps identify why a request to enter
  // picture in picture automatically is denied/accepted.
  RecordAutoPictureInPictureInfo (AutoPipInfo auto_picture_in_picture_info);

  [EnableIf=arkweb_media_cast]
  PullUpCastBackGround(string device_name);

  [EnableIf=arkweb_media_cast]
  UpdateUiPlayState(bool is_playing);

  [EnableIf=arkweb_media_cast]
  UpdateUiPlayPosition(int64 position);

  [EnableIf=arkweb_media_cast]
  MediaCastStopped();

  [EnableIf=arkweb_media_cast]
  MediaCastStopByNavigation();

  [Sync, EnableIf=arkweb_media_cast]
  GetMediaCastCurrentTime() => (double time);

  [EnableIf=arkweb_media_cast]
  NotifyRemoteExitFullScreen();

  [EnableIf=arkweb_media_cast]
  NotifyCastControlShow(bool is_show);
};

// Implemented by the MediaWebContentsObserver. The remote lives in the renderer
// process and the receiver lives in the browser process.
interface MediaPlayerObserverClient {
  // Gets a flag indicating whether media has been played before.
  GetHasPlayedBefore() => (bool has_played_before);
};

// Implemented by MediaWebContentsObserver::MediaPlayerObserverHostImpl in the
// browser process.
interface MediaPlayerObserver {
  // Notifies that the media player started playing content.
  OnMediaPlaying();

  // Notifies that the media player stopped playing content,
  // indicating in |stream_ended| if playback has reached the end of the stream.
  OnMediaPaused(bool stream_ended);

  // Notifies that avsession is over.
  [EnableIf=arkweb_media_avsession]
  OnEndAVSession(bool is_hidden);

  // Notifies that the media player gone.
  [EnableIf=arkweb_activity_state]
  OnMediaPlayerGone();

  // Notifies that the muted status of the media player has changed.
  OnMutedStatusChanged(bool muted);

  // Notifies that the media metadata of the media player has changed, along
  // with the kind of tracks the media player has, and the type of content.
  OnMediaMetadataChanged(
      bool has_audio, bool has_video, MediaContentType content_type);

  // Notifies the browser process that the media playback position has changed,
  // and reports the new current position via |media_position|.
  OnMediaPositionStateChanged(media_session.mojom.MediaPosition media_position);

  // Notifies that the player has entered fullscreen.
  // This does not differentiate native controls fullscreen and custom controls
  // fullscreen. |status| is used by MediaWebContentsObserver to trigger
  // automatically Picture-in-Picture for fullscreen videos.
  OnMediaEffectivelyFullscreenChanged(FullscreenVideoStatus status);

  // Notifies that the size of the media player has changed.
  OnMediaSizeChanged(gfx.mojom.Size size);

  // Notifies the browser process of PictureinPicture playback's availability.
  OnPictureInPictureAvailabilityChanged(bool available);

  // Notifies that the audio output sink has changed.
  OnAudioOutputSinkChanged(string hashed_device_id);

  // Notifies that the playback starts/stops using AudioService.
  OnUseAudioServiceChanged(bool uses_audio_service);

  // Notifies the browser process that the ability to switch audio output
  // devices for the associated media player has been disabled.
  OnAudioOutputSinkChangingDisabled();

  // Notifies that the RemotePlayback metadata of the media player has changed.
  OnRemotePlaybackMetadataChange(media_session.mojom.RemotePlaybackMetadata
                             remote_playback_metadata);

  // Notifies that the video visibility has changed.
  OnVideoVisibilityChanged(bool meets_visibility_threshold);

  [EnableIf=arkweb_custom_video_player]
  UpdateLayerRect(gfx.mojom.Rect rect);

  [EnableIf=arkweb_custom_video_player]
  FullscreenChanged(bool is_fullscreen);

  [EnableIf=arkweb_video_assistant]
  OnVideoPlaying(VideoAttributesForVAST video_attributes);

  [EnableIf=arkweb_video_assistant]
  OnUpdateVideoAttributes(VideoAttributesForVAST video_attributes);

  [EnableIf=arkweb_video_assistant]
  OnVideoDestroyed();

  // Notifies that the title of playing content.
  [EnableIf=arkweb_media_avsession]
  OnGetMediaTitle(string data);

  // Notifies that the video poster of playing content.
  [EnableIf=arkweb_media_avsession]
  OnGetVideoPoster(string data);

  // Notifies that the title of playing content initialized.
  [EnableIf=arkweb_media_avsession]
  OnInitMediaTitle();

  // Notifies that the video poster of playing content initialized.
  [EnableIf=arkweb_media_avsession]
  OnInitVideoPoster();

  [EnableIf=arkweb_video_assistant]
  OnFullScreenOverlayEnter(MediaInfoForVAST media_info);

  [EnableIf=arkweb_video_assistant]
  UpdatePlayStateOverlay(uint32 playState);

  [EnableIf=arkweb_video_assistant]
  MutedChangedOverlay(bool muted);

  [EnableIf=arkweb_video_assistant]
  PlaybackRateChangedOverlay(double playback_rate);

  [EnableIf=arkweb_video_assistant]
  DurationChangedOverlay(double duration);

  [EnableIf=arkweb_video_assistant]
  TimeUpdateOverlay(double current_time);

  [EnableIf=arkweb_video_assistant]
  BufferedEndTimeChangedOverlay(double buffered_end_time);

  [EnableIf=arkweb_video_assistant]
  EndedOverlay();

  [EnableIf=arkweb_video_assistant]
  FullscreenChangedOverlay(bool fullscreen);

  [EnableIf=arkweb_video_assistant]
  SeekingOverlay();

  [EnableIf=arkweb_video_assistant]
  SeekingFinishedOverlay();

  [EnableIf=arkweb_video_assistant]
  ErrorOverlay(int32 error_code, string error_msg);

  [EnableIf=arkweb_video_assistant]
  VideoSizeChangedOverlay(int32 width, int32 height);

  [EnableIf=arkweb_video_assistant]
  FullscreenOverlayChanged(bool fullscreen_overlay, string decoder_name);

  [EnableIf=arkweb_video_assistant]
  OnVolumeChanged(double volume);

  [EnableIf=arkweb_pip]
  OnPictureInPictureStateChanged(uint32 state, int32 width, int32 height);

  [EnableIf=arkweb_media_cast]
  OnMediaCastEnter();
 
  [EnableIf=arkweb_media_cast]
  OnNotifyMeidaCastUri(string media_uri);
 
  [EnableIf=arkweb_media_cast]
  HandleStopMediaCast();
 
  [EnableIf=arkweb_media_cast]
  UpdateRemotePlayState(bool is_playing);
 
  [EnableIf=arkweb_media_cast]
  UpdateRemotePlayPosition(int64 position);
 
  [EnableIf=arkweb_media_cast]
  SetPauseByAvcast(bool pause_avcast);
};

// Implemented by MediaWebContentsObserver::MediaPlayerHostImpl in the browser
// process.
interface MediaPlayerHost {
  // Sends a message to the browser notifying the render frame associated to the
  // document owning the HTMLMediaElement that a new MediaPlayer is available,
  // passing a pending remote (i.e. `player_remote`) that will be used in the
  // browser process to establish a channel with the HTMLMediaElement.
  // `observer` starts observing the MediaPlayer as soon as the player is
  // created. `player_id` is an identifier for the player that is unique within
  // the scope of the RenderFrame.
  OnMediaPlayerAdded(pending_associated_remote<MediaPlayer> player_remote,
                     pending_associated_receiver<MediaPlayerObserver> observer,
                     int32 player_id);

  [EnableIf=arkweb_video_assistant]
  RequestVideoAssistantConfig() => (VideoAssistantConfig config);
};