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

    AddDeviceByChannel(handle<channel> device_channel, string:256 device_name,
                       bool is_input);
};
