WebAPI/WebTelephony

From MozillaWiki
Jump to navigation Jump to search

Goals

The aim of WebTelephony is to establish a DOM API, which allows web content to dial out and mediate calls, i.e. answer, reject, hold or resume a call.

Status

This has been implemented for B2G in the following bugs:

Implementation Specifics

Telephony call states

The diagram below shows the current design of B2G telephony call states.


 Some examples of state transition in detail:

  • Scenario #1: There is no other call on-line (current design)
    When a remote party dials, a new call is generated with its call index (no. 1), and the call state now is CALL_STATE_INCOMING.
    When user answers/hangs up the call, the call state is eventually pushed to CALL_STATE_CONNECTED/CALL_STATE_DISCONNECTED according to user's decision.
  • Scenario #2: There is already a call on-line
    When the third party dials, a new call is generated with the state of CALL_STATE_INCOMING. Since there is already a call on-line, the new call's index is no. 2.
    When user answers the new call (call no. 2), its state is going to be transferred to CALL_STATE_CONNECTED.
    In the meanwhile, the state of the originally connected call (call no. 1) should be forced to CALL_STATE_HELD.
    • Note: The served mobile subscriber can only have one call on hold at a time, according to 3GPP Specification "TS 22.083 section 2.2.1."
  • Scenario #3: User wants to hold a call when there's no waiting call
    User can |Hold()| to change the call state from CALL_STATE_CONNECTED to CALL_STATE_HELD.
    User can |Resume()| to make a call from CALL_STATE_HELD back to CALL_STATE_CONNECTED.


  B2G telephony call states

DOM API

We can access the phone functionality simply through navigator.mozTelephony. Once we have a reference to that object, we can start placing and recieving calls by the API below.

interface nsIDOMTelephony: nsIDOMEventTarget
{
  nsIDOMTelephonyCall dial(in DOMString number);

  attribute boolean muted;
  attribute boolean speakerEnabled;

  // The call that is "active", i.e. receives microphone input and tones
  // generated via startTone.
  readonly attribute jsval active;

  // Array of all calls that are currently connected.
  readonly attribute jsval calls;

  readonly attribute nsIDOMTelephonyCallGroup conferenceGroup;

  void startTone(in DOMString tone);
  void stopTone();

  attribute nsIDOMEventListener onincoming;
  attribute nsIDOMEventListener oncallschanged;
};

interface nsIDOMTelephonyCall: nsIDOMEventTarget
{
  readonly attribute DOMString number;

  // "dialing", "alerting", "busy", "connecting", "connected", "disconnecting", 
  // "disconnected", "incoming", "holding", "held", "resuming"
  readonly attribute DOMString state;

  readonly attribute nsIDOMTelephonyCallGroup group;

  // functions to mediate a call.
  void answer();  
  void hangUp();
  void hold(); 
  // Resuming a group automatically holds any other groups/calls
  void resume(); 

  attribute nsIDOMEventListener onstatechange;

  attribute nsIDOMEventListener ondialing;
  attribute nsIDOMEventListener onalerting;
  attribute nsIDOMEventListener onbusy;
  attribute nsIDOMEventListener onconnecting;
  attribute nsIDOMEventListener onconnected;
  attribute nsIDOMEventListener ondisconnecting;
  attribute nsIDOMEventListener ondisconnected;
  attribute nsIDOMEventListener onincoming;
  attribute nsIDOMEventListener onholding; 
  attribute nsIDOMEventListener onheld; 
  attribute nsIDOMEventListener onresuming; 

  // Fired whenever the .group attribute changes
  attribute nsIDOMEventListener ongroupchange;
};

interface nsIDOMTelephonyCallGroup : nsIDOMEventTarget
{
  // Array of all calls that are currently in this group. The length
  // of this array is never 1.
  readonly attribute jsval calls;

  // Add a call to the callgroup. call2 must not be specified if the
  // callgroup isn't empty.
  // If the callgroup is empty both call and call2 must be specified,
  // and one of them must be in 'held' state and the other in
  // 'connected' state.
  // Neither call or call2 can be in 'disconnected' state.
  void add(nsIDOMTelephonyCall call, optional nsIDOMTelephonyCall call2);

  // Removes a call from the callgroup. If this leaves the callgroup with
  // just one call, then that last call is also removed from the callgroup.
  void remove(nsIDOMTelephonyCall call);

  void hold();
  // Resuming a group automatically holds any other groups/calls
  void resume(); 

  // When this changes, the state of all contained calls changes at the same time
  readonly attribute DOMString state;

  attribute nsIDOMEventListener onstatechange;

  attribute nsIDOMEventListener onconnected;
  attribute nsIDOMEventListener onholding;
  attribute nsIDOMEventListener onheld;
  attribute nsIDOMEventListener onresuming;

  // Fires when the array in the 'calls' property changes.
  attribute nsIDOMEventListener oncallschanged;
};

Example

Here are few examples about how to use WebTelephony API.

Place a call

// First, obtain a telephony object.
var telephony = navigator.mozTelephony;

// Check if the speaker is enabled.
concole.log(telephony.speakerEnabled);
// Then, we dial out.
var outgoing = telephony.dial(phoneNumber);
// Event handlers for the call.
outgoing.onconnected = function onconnected(event) {
  /* Do something when the callee picks up the call. */
};

outgoing.ondisconnected = function ondisconnected(event) {
  /* Do something when the call finishes. */
};

// Hang up the call.
outgoing.hangUp();

Receive a call

// First, obtain a telephony object.
var telephony = navigator.mozTelephony;
// Receive an incoming call.
telephony.onincoming = function onincoming(event) {
  var incoming = event.call;
  
  // Answer the call. 
  incoming.answer();   
};

Links