// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.media.sessions2;

using zx;
using fuchsia.media.audio;
using fuchsia.media;

using SessionId = uint64;

/// SessionInfoDelta holds a description of a media session.
table SessionInfoDelta {
    /// The domain on which the session takes place. A domain identifies a set of
    /// mutually compatible media targets and sessions; sessions on a domain may
    /// be played back on targets of the same domain.
    ///
    /// This field is always present.
    1: Domain domain;
    /// Whether the source of the media playback is on this device.
    ///
    /// This field is present only if known.
    2: bool is_local;
    /// If this is `true`, the playback is taking place local to the device.
    /// Playing on the device speaker is local, playing on a remote speaker
    /// is not. This is only set when the session is playing back; a paused
    /// session is not active.
    ///
    /// This field is always present.
    3: bool is_locally_active;
    /// The status of the player.
    ///
    /// This field is always present.
    4: PlayerStatus player_status;
    /// Metadata describing the media session.
    ///
    /// This field is always present.
    5: fuchsia.media.Metadata metadata;
    /// Images associated with the media or its source.
    ///
    /// This field is always present.
    6: vector<MediaImage> media_images;
    /// The capabilities the player of the media implements.
    ///
    /// This field is always present.
    7: PlayerCapabilities player_capabilities;
};

/// Controls a media session and views its status.
///
/// The channel will close if the media session is stopped.
protocol SessionControl {
    /// Plays media.
    Play();
    /// Pauses playback and retains position in media
    Pause();
    /// Stops playback. The session should close.
    Stop();
    /// Seeks to a specific position in media. Implementations are free to
    /// enter an error state if the position is out of bounds. `position`
    /// is an offset from the beginning of the media.
    Seek(zx.duration position);
    /// Skips forward in media by the player's default skip amount.
    SkipForward();
    /// Skips in reverse in media by the player's default skip amount.
    SkipReverse();
    /// Changes media to the next item (e.g. next song in playlist).
    NextItem();
    /// Changes media to the previous item.
    PrevItem();
    /// Sets the playback rate of the media. This will not change the
    /// playback mode.
    SetPlaybackRate(float32 playback_rate);
    /// Sets repeat mode to any of the supported repeat modes.
    SetRepeatMode(RepeatMode repeat_mode);
    /// Sets shuffle mode.
    SetShuffleMode(bool shuffle_on);
    /// Binds to the session's volume control for control and notifications.
    BindVolumeControl(
        request<fuchsia.media.audio.VolumeControl> volume_control_request);
    /// Watches the session status. Leave a request hanging to receive a reply when
    /// the session status changes. The first request will be answered immediately with
    /// the current state.
    WatchStatus() -> (SessionInfoDelta session_info_delta);
};

/// Views a media session's status.
///
/// The channel will close if the media session is stopped.
protocol SessionObserver {
    /// Watches the session status. Leave a request hanging to receive a reply when
    /// the session status changes. The first request will be answered immediately with
    /// the current state.
    WatchStatus() -> (SessionInfoDelta session_info_delta);
};

/// Options that specify which sessions are watched when watching the collection.
///
/// The watched set is the set of sessions which satisfies all options.
table WatchOptions {
    /// Watch only the active session. Watches all if not set.
    1: bool only_active;
    /// Watch only sessions with these allowlisted ids. Watches all if not set.
    2: vector<SessionId>:1000 allowed_sessions;
};

/// `SessionsWatcher` watches the collection of published sessions.
protocol SessionsWatcher {
    /// Called by the registry service when a session is updated. On first connection,
    /// this will be called as many times as needed to communicate the state of the
    /// world.
    ///
    /// `SessionsWatcher` must reply to acknowledge receipt of the session info delta.
    /// Delinquent watchers who do not reply will eventually be disconnected.
    SessionUpdated(SessionId session_id, SessionInfoDelta session_info_delta) -> ();

    /// Called by the registry service when a session is removed from the registered
    /// collection.
    ///
    /// `SessionsWatcher` must reply to acknlowledge receipt of the session removal.
    /// Delinquent watchers who do not reply will eventually be disconnected.
    SessionRemoved(SessionId session_id) -> ();
};

/// `Discovery` observes the collection of published media sessions
/// and connects clients to them.
[Discoverable]
protocol Discovery {
    /// Connects a session watcher configured with the given options.
    WatchSessions(
        WatchOptions watch_options,
        SessionsWatcher session_watcher);

    /// Connects to a `SessionControl` for `session_id` if present. Drops the
    /// given channel otherwise.
    ConnectToSession(SessionId session_id,
                     request<SessionControl> session_control_request);
};

/// `ObserverDiscovery` observes the collection of published media sessions
/// and connects clients to them for observation without playback controls.
[Discoverable]
protocol ObserverDiscovery {
    /// Connects a session watcher configured with the given options.
    WatchSessions(WatchOptions watch_options,
                  SessionsWatcher sessions_watcher);

    /// Connects to a `SessionObserver` for `session_id` if present. Drops the
    /// given channel otherwise.
    ConnectToSession(SessionId session_id,
                     request<SessionObserver> session_request);
};

/// A protocol for watching the current active media session on the device.
///
/// The currently active media session is the most recent existing media session
/// to announce a "Playing" state on the local device, even if it is now paused.
[Discoverable]
protocol ActiveSession {
    /// Watches the active session. The first request will be answered immediately
    /// with the current active session. Always leave a request hanging to receive
    /// a reply when the active session changes.
    WatchActiveSession() -> (SessionControl? session);
};
