// 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.media;

using fuchsia.hardware.audio;

type AudioGainInfoFlags = strict bits : uint32 {
    MUTE = 0x01;
    AGC_SUPPORTED = 0x02;
    AGC_ENABLED = 0x04;
};

type AudioGainInfo = struct {
    gain_db float32;
    flags AudioGainInfoFlags;
};

type AudioDeviceInfo = struct {
    name string;
    unique_id string;
    token_id uint64;
    is_input bool;

    // We include these during device enumeration to reduce server round-trip
    // calls, and to simplify a user's state machine when determining current
    // device state during initial enumeration.
    gain_info AudioGainInfo;
    is_default bool;
};

type AudioGainValidFlags = strict bits : uint32 {
    GAIN_VALID = 0x01;
    MUTE_VALID = 0x02;
    AGC_VALID = 0x04;
};

@discoverable
closed protocol AudioDeviceEnumerator {
    /// Obtain the list of currently active audio devices.
    strict GetDevices() -> (struct {
        devices vector<AudioDeviceInfo>;
    });

    /// Events sent when devices are added or removed, or when properties of a
    /// device change.
    //
    // TODO(mpuryear): Should we have a set of filters which control which of
    // these events a user receives?
    //
    // Pro: Having filters like this removes the need for the server to send
    // messages to clients who don't care. In particular, it seems likely that a
    // client who just called SetDeviceGain will not care about the
    // OnDeviceGainChanged event being fired.
    //
    // Con: Having filters like this means that the server needs to maintain a
    // bit more per-client state.
    strict -> OnDeviceAdded(struct {
        device AudioDeviceInfo;
    });
    strict -> OnDeviceRemoved(struct {
        device_token uint64;
    });
    strict -> OnDeviceGainChanged(struct {
        device_token uint64;
        gain_info AudioGainInfo;
    });
    @deprecated
    strict -> OnDefaultDeviceChanged(struct {
        old_default_token uint64;
        new_default_token uint64;
    });

    /// Gain/Mute/AGC control
    ///
    /// Note that each of these operations requires a device_token in order to
    /// target the proper input/output.
    ///
    /// The Get command returns the device_token of the device whose gain is
    /// being reported, or `ZX_KOID_INVALID` in the case that the requested
    /// device_token was invalid or the device had been removed from the system
    /// before the Get command could be processed.
    ///
    /// Set commands which are given an invalid device token are ignored and
    /// have no effect on the system. In addition, users do not need to control
    /// all of the gain settings for an audio device with each call. Only the
    /// settings with a corresponding flag set in the set_flags parameter will
    /// be affected. For example, passing SetAudioGainFlag_MuteValid will cause
    /// a SetDeviceGain call to care only about the mute setting in the
    /// gain_info structure, while passing (SetAudioGainFlag_GainValid |
    /// SetAudioGainFlag_MuteValid) will cause both the mute and the gain
    /// status to be changed simultaneously.
    strict GetDeviceGain(struct {
        device_token uint64;
    }) -> (struct {
        device_token uint64;
        gain_info AudioGainInfo;
    });
    strict SetDeviceGain(struct {
        device_token uint64;
        gain_info AudioGainInfo;
        valid_flags AudioGainValidFlags;
    });

    //
    // TODO(mpuryear): solidify the concept of "default" device. Right now, it
    // basically means the device which would be chosen as the destination of an
    // AudioRenderer stream (or the source for an AudioCapturer stream), in the
    // absence of...
    //
    // 1) Any manual routing configuration imposed by the user.
    // 2) Any property based routing decision made by the audio service.
    //
    // Currently, this translates to "the default inputs/output will be the last
    // plugged input/output". As the human level logic which drives the audio
    // routing policy evolves and becomes more complicated, this will probably
    // change.
    /// Default Device
    ///
    /// Fetch the device ID of the current default input or output device, or
    /// `ZX_KOID_INVALID` if no such device exists.
    @deprecated
    @available(removed=15)
    strict GetDefaultInputDevice() -> (struct {
        device_token uint64;
    });
    @deprecated
    @available(removed=15)
    strict GetDefaultOutputDevice() -> (struct {
        device_token uint64;
    });

    /// # Deprecation
    ///
    /// StreamConfig is not supported anymore, instead use an
    /// [Audio Composite](https://fuchsia.dev/fuchsia-src/development/audio/drivers/composite)
    /// , see
    /// [Audio Drivers Architecture](https://fuchsia.dev/fuchsia-src/development/audio/drivers/architecture)
    @available(deprecated=20)
    strict AddDeviceByChannel(resource struct {
        device_name string:256;
        is_input bool;
        channel client_end:fuchsia.hardware.audio.StreamConfig;
    });
};
