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

/// Client wrapper for the local target.
/// A client is a high level construct and does not represent a connection with a device.
closed protocol TargetHandler {
    /// Returns the event notification ids that are supported by the TG.
    strict GetEventsSupported() -> (struct {
        notification_ids vector<NotificationEvent>:MAX_NOTIFICATIONS;
    }) error TargetAvcError;

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

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

    /// Send an AV\C passthrough key command.
    /// If `key_pressed`, then the AV\C passthrough command shall be interpreted as a key
    /// press down event. Otherwise, the command shall be interpreted as a key release event.
    strict SendCommand(struct {
        command AvcPanelCommand;
        pressed bool;
    }) -> () error TargetPassthroughError;

    /// Request the target device to provide all the target supported player application
    /// setting attributes.
    strict ListPlayerApplicationSettingAttributes() -> (struct {
        attributes vector<PlayerApplicationSettingAttributeId>:MAX_ATTRIBUTES;
    }) error TargetAvcError;

    /// 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.
    strict GetPlayerApplicationSettings(struct {
        attribute_ids vector<PlayerApplicationSettingAttributeId>:MAX_ATTRIBUTES;
    }) -> (struct {
        current_settings PlayerApplicationSettings;
    }) error TargetAvcError;

    /// 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; and `SetPlayerApplicationSettings` will not return an error.
    /// Instead, the returned `set_settings` will include only the settings that were
    /// successfully set on the remote target.
    strict SetPlayerApplicationSettings(struct {
        requested_settings PlayerApplicationSettings;
    }) -> (struct {
        set_settings PlayerApplicationSettings;
    }) error TargetAvcError;

    /// Returns the current value for the notification specified by `event_id`.
    strict GetNotification(struct {
        event_id NotificationEvent;
    }) -> (struct {
        current_value Notification;
    }) error TargetAvcError;

    /// Returns the changed value of the notification specified by 'event_id'.
    /// A changed value refers to any value that is different than the input parameter
    /// `current` Notification value.
    /// `WatchNotification` will not respond until the Notification value associated
    /// with `event_id` has changed from the `current` Notification.
    strict WatchNotification(struct {
        event_id NotificationEvent;
        current Notification;
        pos_change_interval uint32;
    }) -> (struct {
        new_value Notification;
    }) error TargetAvcError;

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

    /// Returns a list of media player information about the players on the target.
    strict GetMediaPlayerItems() -> (struct {
        items vector<MediaPlayerItem>:MAX_MEDIA_PLAYER_ITEMS;
    }) error TargetAvcError;
};
