// Copyright 2018 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.bluetooth.avrcp;

using fuchsia.bluetooth as bt;
using zx;

@discoverable
protocol PeerManager {
    /// Returns a browse controller client to a remote target (TG) service at
    /// the peer specified by `peer_id`.
    GetBrowseControllerForTarget(resource struct {
        peer_id bt.PeerId;
        client server_end:BrowseController;
    }) -> (struct {}) error zx.status;

    /// Returns a controller client to a remote target (TG) service at the peer specified by
    /// `peer_id`.
    GetControllerForTarget(resource struct {
        peer_id bt.PeerId;
        client server_end:Controller;
    }) -> (struct {}) error zx.status;

    /// Set the absolute volume handler.  Only one handler may be set  at at time.
    /// If a second handler is registered it will be dropped and an error will
    /// be returned.
    SetAbsoluteVolumeHandler(resource struct {
        handler client_end:AbsoluteVolumeHandler;
    }) -> (struct {}) error zx.status;

    /// Sets an implementation of target handler that will vend delegates for each incoming
    /// remote TG -> local CT connections to handle the commands being sent by the remote TG.
    RegisterTargetHandler(resource struct {
        handler client_end:TargetHandler;
    }) -> (struct {}) error zx.status;
};

/// Handler for absolute volume requests from a remote peer. See AVRCP v 1.6.2 section 6.13.2.
/// Absolute volume is represented as a percentage using one byte with the most significant bit
/// reserved. 0% is represented as 0x0 and 100% as 0x7f. Volume should scaled between the
/// two values.
protocol AbsoluteVolumeHandler {
    /// Requests that the absolute volume of the player be changed.
    /// `requested_volume` is the requested volume by the peer.
    /// Returns the actual volume set locally by the handler.
    SetVolume(struct {
        requested_volume uint8;
    }) -> (struct {
        set_volume uint8;
    });

    /// Returns latest volume of the handler to the AVRCP service. This function should return
    /// immediately on the first call and if the volume has changed since the last call to this
    /// function, otherwise it should only return when the volume has been changed.
    /// Multiple outstanding `OnVolumeChanged` requests can be made - all outstanding calls will
    /// return when the volume has been changed.
    // TODO(fxbug.dev/54002): Update docs when addressed.
    OnVolumeChanged() -> (struct {
        new_volume uint8;
    });

    /// Returns the current volume immediately.
    GetCurrentVolume() -> (struct {
        volume uint8;
    });
};

/// Client wrapper for local controller (CT) -> remote target (TG) AVCTP
/// connections between devices for browse related commands.
///
/// NOTE: a client is high level construct and does not represent a connection
/// with a device. Connections are internally managed and may be shared by
/// multiple clients. The actual connection may be opened on-demand after any
/// command here is called.
protocol BrowseController {
    /// Used for GetFolderItems(MediaPlayerList).
    /// Gets the list of media players. End index is inclusive.
    GetMediaPlayerItems(struct {
        start_index uint32;
        end_index uint32;
    }) -> (struct {
        items vector<MediaPlayerItem>:MAX_MEDIA_PLAYER_ITEMS;
    }) error BrowseControllerError;

    /// Used for GetFolderItems(NowPlayingList).
    /// Gets the list of items from the now playing list aka the queue of the
    /// addressed media player.
    /// + request `end_index` is inclusive.
    GetNowPlayingItems(struct {
        start_index uint32;
        end_index uint32;
        attribute_option AttributeRequestOption;
    }) -> (struct {
        items vector<MediaElementItem>:MAX_NOW_PLAYING_ITEMS;
    }) error BrowseControllerError;

    /// Used for GetFolderItems(MediaPlayerVirtualFilesystem).
    /// Gets the list of folder item/media element item.
    /// + request `end_index` is inclusive.
    GetFileSystemItems(struct {
        start_index uint32;
        end_index uint32;
        attribute_option AttributeRequestOption;
    }) -> (struct {
        items vector<FileSystemItem>:MAX_FILESYSTEM_ITEMS;
    }) error BrowseControllerError;

    /// Used for ChangePath browse command.
    /// + request `path` dictates whether or not the direction will be Move Up
    ///   or Move down. If `path.parent` is set, direction will be Move Up. If
    ///   `path.child_folder_uid` is set, direction will be Move Down.
    ChangePath(struct {
        path Path;
    }) -> (struct {
        num_items uint32;
    }) error BrowseControllerError;

    ///  Used for PlayItem(FileSystem).
    PlayFileSystemItem(struct {
        /// UID of folder or media element.
        uid uint64;
    }) -> (struct {}) error BrowseControllerError;

    ///  Used for PlayItem(NowPlayingList). Plays the specified item from the now playing
    /// list aka the queue of the addressed media player.
    PlayNowPlayingItem(struct {
        uid uint64;
    }) -> (struct {}) error BrowseControllerError;

    /// Changes the addressed `player_id` on the target when multiple are supported.
    SetBrowsedPlayer(struct {
        player_id uint16;
    }) -> (struct {}) error BrowseControllerError;
};

/// Client wrapper for local controller (CT) -> remote target (TG) AVCTP
/// connections between devices for AV/C commands.
///
/// See `BrowseController` protocol note for more detailed explanation on
/// the purpose of this protocol.
protocol Controller {
    /// Returns currently set player application setting values for the `attribute_ids`.
    /// If no `attribute_ids` are provided, this method will query the TG for all valid
    /// attribute ID's, and return the currently set player application setting values.
    GetPlayerApplicationSettings(struct {
        attribute_ids vector<PlayerApplicationSettingAttributeId>:MAX_ATTRIBUTES;
    }) -> (struct {
        current_settings PlayerApplicationSettings;
    }) error ControllerError;

    /// Sets the player application settings specified by `requested_settings`. Only
    /// settings specified in the input `requested_settings` will be overwritten.
    /// Returns the actual settings that were set.
    /// Settings provided in the `requested_settings` that are unsupported or unknown
    /// will not be set; the returned `set_settings` will include only the settings
    /// that were successfully set on the remote target.
    SetPlayerApplicationSettings(struct {
        requested_settings PlayerApplicationSettings;
    }) -> (struct {
        set_settings PlayerApplicationSettings;
    }) error ControllerError;

    /// Returns the currently playing media attributes.
    /// May send either the GetElementAttributes or GetItemAttributes command depending on what
    /// is supported.
    GetMediaAttributes() -> (struct {
        attributes MediaAttributes;
    }) error ControllerError;

    /// Returns the status of the currently playing media.
    GetPlayStatus() -> (struct {
        play_status PlayStatus;
    }) error ControllerError;

    /// Request the absolute volume on the peer be changed. Returns the actual volume set by the
    /// peer. Values can range from 0x00 to 0x7F (with 100% volume being 0x7F). You may not get a
    /// volume changed notification event from the remote peer as result of changing this.
    SetAbsoluteVolume(struct {
        requested_volume uint8;
    }) -> (struct {
        set_volume uint8;
    }) error ControllerError;

    /// Inform target of the controller's battery level.
    InformBatteryStatus(struct {
        battery_status BatteryStatus;
    }) -> (struct {}) error ControllerError;

    /// Filters notifications that will be received with [`OnNotification`]. Not all notifications
    /// are supported by all peers. Resetting the notification filter may trigger all requested
    /// notification types to post their current value to [`OnNotification`] immediately.
    ///
    /// The `position_change_interval` argument is used to set the interval in seconds that the
    /// controller client would like to be notified of `TRACK_POS_CHANGED` events.
    /// `position_change_interval` is ignored if `TRACK_POS` is not set. The position change interval
    /// is best effort and not a guarantee and events may arrive more frequently or less frequently
    /// than requested.
    SetNotificationFilter(struct {
        notifications Notifications;
        position_change_interval uint32;
    });

    /// Incoming notification events from the target peer. `timestamp` is monotonic wall time
    /// of when the event was received by the peer.
    /// You must call [`NotifyNotificationHandled`] after receving a notification event to
    /// acknowledge delivery. Multiple non-discrete events may be combined into a single
    /// notification if acknowledged after a new event arrives from a peer.
    /// Call [`SetNotificationFilter`] to set the notifications that are requested of the peer.
    /// All notifications are discrete state changes except volume change and position change
    /// notifications.
    -> OnNotification(struct {
        timestamp zx.time;
        notification Notification;
    });

    /// Call to acknowledge handling of a notification from [`OnNotification`].
    NotifyNotificationHandled();

    /// Changes the addressed `player_id` on the target when multiple are supported.
    SetAddressedPlayer(struct {
        player_id uint16;
    }) -> (struct {}) error ControllerError;

    /// Send an AV\C passthrough key command. Sends both a key down and key up event.
    SendCommand(struct {
        command AvcPanelCommand;
    }) -> (struct {}) error ControllerError;
};
