/* 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 nsIMobileCallForwardingOptions;
interface nsITelephonyCallInfo;

[scriptable, uuid(37fb45bb-ae10-4cfd-b24e-d656a9787a0a)]
interface nsITelephonyListener : nsISupports
{
  /**
   * Called when enumeration asked by nsITelephonyService::enumerateCalls
   * is completed.
   */
  void enumerateCallStateComplete();

  /**
   * Called when nsITelephonyService is asked to enumerate the current
   * telephony call state (nsITelephonyService::enumerateCalls). This is
   * called once per call that is currently managed by the RIL.
   */
  void enumerateCallState(in nsITelephonyCallInfo info);

  /**
   * Notified when a telephony call changes state.
   */
  void callStateChanged(in unsigned long length,
                        [array, size_is(length)] in nsITelephonyCallInfo allInfo);

  /**
   * Called when participants of a conference call have been updated, and the
   * conference call state changes.
   *
   * @param callState
   *        Possible values are: nsITelephonyService::CALL_STATE_UNKNOWN,
   *        nsITelephonyService::CALL_STATE_HELD,
   *        nsITelephonyService::CALL_STATE_CONNECTED.
   */
  void conferenceCallStateChanged(in unsigned short callState);

  /**
   * Notify when RIL receives supplementary service notification.
   *
   * @param clientId
            Indicate the RIL client, 0 ~ (number of client - 1).
   * @param callIndex
   *        Call identifier assigned by the RIL. -1 if not specified
   * @param notification
   *        One of the nsITelephonyService::NOTIFICATION_* values.
   */
  void supplementaryServiceNotification(in unsigned long clientId,
                                        in long callIndex,
                                        in unsigned short notification);

  /**
   * Called when RIL error occurs.
   *
   * @param clientId
            Indicate the RIL client, 0 ~ (number of client - 1).
   * @param callIndex
   *        Call identifier assigned by the RIL. -1 if no connection
   * @param error
   *        Error from RIL.
   */
  void notifyError(in unsigned long clientId,
                   in long callIndex,
                   in AString error);

  /**
   * Called when a waiting call comes in CDMA networks.
   *
   * @param clientId
            Indicate the RIL client, 0 ~ (number of client - 1).
   * @param number
   *        Number of the other party.
   * @param numberPresentation
   *        Presentation of the call number.
   *        One of the nsITelephonyProvider::CALL_PRESENTATION_* values.
   * @param name
   *        Name of the other party.
   * @param namePresentation
   *        Presentation of the call name.
   *        One of the nsITelephonyProvider::CALL_PRESENTATION_* values.
   */
  void notifyCdmaCallWaiting(in unsigned long clientId,
                             in AString number,
                             in unsigned short numberPresentation,
                             in AString name,
                             in unsigned short namePresentation);

  /**
   * Called when RIL error occurs to creating or separating a conference call.
   *
   * @param name
   *        Error name. Possible values are addError and removeError.
   * @param message
   *        Detailed error message from RIL.
   */
  void notifyConferenceError(in AString name,
                             in AString message);
};

/**
 * A callback interface for handling asynchronous response.
 */
[scriptable, uuid(cffc3f9d-2c88-4a14-8ebc-f216caf0cc1d)]
interface nsITelephonyCallback : nsISupports
{
  void notifySuccess();
  void notifyError(in AString error);
};

/**
 * A callback interface for handling asynchronous response for telephony.dial.
 */
[scriptable, uuid(e16c6e6f-93c6-4e1e-99bf-592b98f67e15)]
interface nsITelephonyDialCallback : nsITelephonyCallback
{
  /**
   * Called when a dial request is treated as an MMI code and it is about to
   * process the request.
   *
   * @param serviceCode
   *        MMI service code key string that defined in MMI_KS_SC_*
   */
  void notifyDialMMI(in AString serviceCode);

  /**
   * Called when a dial request is treated as a call setup and the result
   * succeeds.
   *
   * @param clientId
            Indicate the RIL client, 0 ~ (number of client - 1).
   * @param callIndex
   *        Call index from RIL.
   * @param number
   *        Dialed out phone number (ex: Temporary CLIR prefix will be removed)
   */
  void notifyDialCallSuccess(in unsigned long cliendId,
                             in unsigned long callIndex,
                             in AString number);

  /**
   * Called when a MMI code request succeeds.
   * The function should only be called after notifyDialMMI.
   */
  void notifyDialMMISuccess(in AString statusMessage);
  void notifyDialMMISuccessWithInteger(in AString statusMessage,
                                       in unsigned short aAdditionalInformation);
  void notifyDialMMISuccessWithStrings(in AString statusMessage,
                                       in unsigned long aLength,
                                       [array, size_is(aLength)] in wstring aAdditionalInformation);
  void notifyDialMMISuccessWithCallForwardingOptions(in AString statusMessage,
                                                     in unsigned long aLength,
                                                     [array, size_is(aLength)] in nsIMobileCallForwardingOptions aAdditionalInformation);

  /**
   * Called when a MMI code request fails.
   * The function should only be called after notifyDialMMI.
   */
  void notifyDialMMIError(in AString error);
  void notifyDialMMIErrorWithInfo(in AString error, in unsigned short info);
};

%{C++
#define TELEPHONY_SERVICE_CID \
  { 0x9cf8aa52, 0x7c1c, 0x4cde, { 0x97, 0x4e, 0xed, 0x2a, 0xa0, 0xe7, 0x35, 0xfa } }
#define TELEPHONY_SERVICE_CONTRACTID \
  "@mozilla.org/telephony/telephonyservice;1"
%}

/**
 * XPCOM component (in the content process) that provides the telephony
 * information.
 */
[scriptable, uuid(2b7b3fe7-f1d9-48be-8fd6-aaf890fa73af)]
interface nsITelephonyService : nsISupports
{
  const unsigned short CALL_STATE_UNKNOWN = 0;
  const unsigned short CALL_STATE_DIALING = 1;
  const unsigned short CALL_STATE_ALERTING = 2;
  const unsigned short CALL_STATE_CONNECTING = 3;
  const unsigned short CALL_STATE_CONNECTED = 4;
  const unsigned short CALL_STATE_HOLDING = 5;
  const unsigned short CALL_STATE_HELD = 6;
  const unsigned short CALL_STATE_RESUMING = 7;
  const unsigned short CALL_STATE_DISCONNECTING = 8;
  const unsigned short CALL_STATE_DISCONNECTED = 9;
  const unsigned short CALL_STATE_INCOMING = 10;

  const unsigned short NOTIFICATION_REMOTE_HELD = 0;
  const unsigned short NOTIFICATION_REMOTE_RESUMED = 1;

  const unsigned short CALL_PRESENTATION_ALLOWED = 0;
  const unsigned short CALL_PRESENTATION_RESTRICTED = 1;
  const unsigned short CALL_PRESENTATION_UNKNOWN = 2;
  const unsigned short CALL_PRESENTATION_PAYPHONE = 3;

  readonly attribute unsigned long defaultServiceId;

  /**
   * Called when a content process registers receiving unsolicited messages from
   * RadioInterfaceLayer in the chrome process. Only a content process that has
   * the 'telephony' permission is allowed to register.
   */
  void registerListener(in nsITelephonyListener listener);
  void unregisterListener(in nsITelephonyListener listener);

  /**
   * Will continue calling listener.enumerateCallState until the listener
   * returns false.
   */
  void enumerateCalls(in nsITelephonyListener listener);

  /**
   * Functionality for making and managing phone calls.
   */
  void dial(in unsigned long clientId, in DOMString number,
            in boolean isEmergency, in nsITelephonyDialCallback callback);

  void sendTones(in unsigned long clientId, in DOMString dtmfChars,
                 in unsigned long pauseDuration, in unsigned long toneDuration,
                 in nsITelephonyCallback callback);

  void startTone(in unsigned long clientId, in DOMString dtmfChar);
  void stopTone(in unsigned long clientId);

  void answerCall(in unsigned long clientId,
                  in unsigned long callIndex,
                  in nsITelephonyCallback callback);
  void rejectCall(in unsigned long clientId,
                  in unsigned long callIndex,
                  in nsITelephonyCallback callback);
  void hangUpCall(in unsigned long clientId,
                  in unsigned long callIndex,
                  in nsITelephonyCallback callback);
  void holdCall(in unsigned long clientId,
                in unsigned long callIndex,
                in nsITelephonyCallback callback);
  void resumeCall(in unsigned long clientId,
                  in unsigned long callIndex,
                  in nsITelephonyCallback callback);

  void conferenceCall(in unsigned long clientId,
                      in nsITelephonyCallback callback);
  void separateCall(in unsigned long clientId, in unsigned long callIndex,
                    in nsITelephonyCallback callback);
  void hangUpConference(in unsigned long clientId,
                        in nsITelephonyCallback callback);
  void holdConference(in unsigned long clientId,
                      in nsITelephonyCallback callback);
  void resumeConference(in unsigned long clientId,
                        in nsITelephonyCallback callback);

  /**
   * Send an USSD on existing session. It results in error if the session is
   * not existed.
   *
   * If successful, callback.notifySuccess() will be called.
   * Otherwise, callback.notifyError() will be called.
   */
  void sendUSSD(in unsigned long clientId, in DOMString ussd,
                in nsITelephonyCallback callback);

  /**
   * Cancel an existing USSD session.
   *
   * If successful, callback.notifySuccess() will be called.
   * Otherwise, callback.notifyError() will be called.
   */
  void cancelUSSD(in unsigned long cliendId, in nsITelephonyCallback callback);

  attribute bool microphoneMuted;
  attribute bool speakerEnabled;
};

%{C++
template<typename T> struct already_AddRefed;

already_AddRefed<nsITelephonyService>
NS_CreateTelephonyService();
%}
