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

Basic functionality is done with some work remaining.

For details about the development, refer to

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.
  • 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 conferanceGroup;

  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