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

const uint32 AudioGainInfoFlag_Mute = 0x01;
const uint32 AudioGainInfoFlag_AgcSupported = 0x02;
const uint32 AudioGainInfoFlag_AgcEnabled = 0x04;

struct AudioGainInfo {
    float32 gain_db;
    uint32 flags;
};

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

    // 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.
    AudioGainInfo gain_info;
    bool is_default;
};

const uint32 SetAudioGainFlag_GainValid = 0x01;
const uint32 SetAudioGainFlag_MuteValid = 0x02;
const uint32 SetAudioGainFlag_AgcValid = 0x04;

[Discoverable]
protocol AudioDeviceEnumerator {
    /// Obtain the list of currently active audio devices.
    GetDevices() -> (vector<AudioDeviceInfo> devices);

    /// 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.
    -> OnDeviceAdded(AudioDeviceInfo device);
    -> OnDeviceRemoved(uint64 device_token);
    -> OnDeviceGainChanged(uint64 device_token, AudioGainInfo gain_info);
    -> OnDefaultDeviceChanged(uint64 old_default_token,
                              uint64 new_default_token);

    /// 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.
    GetDeviceGain(uint64 device_token)
        -> (uint64 device_token, AudioGainInfo gain_info);
    SetDeviceGain(uint64 device_token,
                  AudioGainInfo gain_info,
                  uint32 set_flags);

    /// Default Device
    ///
    /// Fetch the device ID of the current default input or output device, or
    /// ZX_KOID_INVALID if no such device exists.
    //
    // 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.
    GetDefaultInputDevice() -> (uint64 device_token);
    GetDefaultOutputDevice() -> (uint64 device_token);
};
