/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsISupports.idl"

interface nsIDOMWindow;

[uuid(5fe83b24-38b9-4901-a4a1-d1bd57d3fe18)]
interface nsIAudioChannelAgentCallback : nsISupports
{
  /**
   * Notified when the window volume/mute is changed
   */
  void windowVolumeChanged(in float aVolume, in bool aMuted);

  /**
   * Notified when the capture state is changed.
   */
  void windowAudioCaptureChanged();
};

/**
 * This interface provides an agent for gecko components to participate
 * in the audio channel service. Gecko components are responsible for
 *   1. Indicating what channel type they are using (via the init() member
 *      function).
 *   2. Before playing, checking the playable status of the channel.
 *   3. Notifying the agent when they start/stop using this channel.
 *   4. Notifying the agent of changes to the visibility of the component using
 *      this channel.
 *
 * The agent will invoke a callback to notify Gecko components of
 *   1. Changes to the playable status of this channel.
 */

[uuid(18222148-1b32-463d-b050-b741f43a07ba)]
interface nsIAudioChannelAgent : nsISupports
{
  const long AUDIO_AGENT_CHANNEL_NORMAL             = 0;
  const long AUDIO_AGENT_CHANNEL_CONTENT            = 1;
  const long AUDIO_AGENT_CHANNEL_NOTIFICATION       = 2;
  const long AUDIO_AGENT_CHANNEL_ALARM              = 3;
  const long AUDIO_AGENT_CHANNEL_TELEPHONY          = 4;
  const long AUDIO_AGENT_CHANNEL_RINGER             = 5;
  const long AUDIO_AGENT_CHANNEL_PUBLICNOTIFICATION = 6;
  const long AUDIO_AGENT_CHANNEL_SYSTEM             = 7;

  const long AUDIO_AGENT_CHANNEL_ERROR              = 1000;

  const long AUDIO_AGENT_STATE_NORMAL               = 0;
  const long AUDIO_AGENT_STATE_MUTED                = 1;
  const long AUDIO_AGENT_STATE_FADED                = 2;

  const long AUDIO_AGENT_DONT_NOTIFY                = 0;
  const long AUDIO_AGENT_NOTIFY                     = 1;

  /**
   * Before init() is called, this returns AUDIO_AGENT_CHANNEL_ERROR.
   */
  readonly attribute long audioChannelType;

  %{C++
  inline int32_t AudioChannelType() {
    int32_t channel;
    return NS_SUCCEEDED(GetAudioChannelType(&channel)) ? channel : AUDIO_AGENT_CHANNEL_ERROR;
  }
  %}

  /**
   * Initialize the agent with a channel type.
   * Note: This function should only be called once.
   *
   * @param window
   *    The window
   * @param channelType
   *    Audio Channel Type listed as above
   * @param callback
   *    1. Once the playable status changes, agent uses this callback function
   *       to notify Gecko component.
   *    2. The callback is allowed to be null. Ex: telephony doesn't need to
   *       listen change of the playable status.
   *    3. The AudioChannelAgent keeps a strong reference to the callback
   *       object.
   */
  void init(in nsIDOMWindow window, in long channelType,
            in nsIAudioChannelAgentCallback callback);

  /**
   * This method is just like init(), except the audio channel agent keeps a
   * weak reference to the callback object.
   *
   * In order for this to work, |callback| must implement
   * nsISupportsWeakReference.
   */
  void initWithWeakCallback(in nsIDOMWindow window, in long channelType,
                            in nsIAudioChannelAgentCallback callback);

  /**
   * Notify the agent that we want to start playing.
   * Note: Gecko component SHOULD call this function first then start to
   *          play audio stream only when return value is true.
   *
   * @param notifyPlaying
   *   Whether to send audio-playback notifications, one of AUDIO_CHANNEL_NOTIFY
   *   or AUDIO_CHANNEL_DONT_NOTIFY.
   *
   * @return
   *    normal state: the agent has registered with audio channel service and
   *          the component should start playback.
   *    muted state: the agent has registered with audio channel service but
   *          the component should not start playback.
   *    faded state: the agent has registered with audio channel service the
   *          component should start playback as well as reducing the volume.
   */
  void notifyStartedPlaying(in unsigned long notifyPlayback, out float volume, out bool muted);

  /**
   * Notify the agent we no longer want to play.
   *
   * Note : even if notifyStartedPlaying() returned false, the agent would
   * still be registered with the audio channel service and receive callbacks
   * for status changes. So notifyStoppedPlaying must still eventually be
   * called to unregister the agent with the channel service.
   */
  void notifyStoppedPlaying();
};
