WebAPI/WebTelephony
< WebAPI
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:
- WebTelephony meta bug: bug 674726
- B2G telephony meta bug: bug 699235
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.
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 Telephony : EventTarget {
/**
* There are multiple telephony services in multi-sim architecture. We use
* |serviceId| to indicate the target telephony service. If not specified,
* the implementation MUST use the default service.
*
* Possible values of |serviceId| are 0 ~ (number of services - 1), which is
* simply the index of a service. Get number of services by acquiring
* |navigator.mozMobileConnections.length|.
*/
// Promise<TelephonyCall>
Promise dial(DOMString number, optional unsigned long serviceId);
// Promise<TelephonyCall>
Promise dialEmergency(DOMString number, optional unsigned long serviceId);
[Throws]
void startTone(DOMString tone, optional unsigned long serviceId);
[Throws]
void stopTone(optional unsigned long serviceId);
[Throws]
attribute boolean muted;
[Throws]
attribute boolean speakerEnabled;
readonly attribute (TelephonyCall or TelephonyCallGroup)? active;
// A call is contained either in Telephony or in TelephonyCallGroup.
readonly attribute CallsList calls;
readonly attribute TelephonyCallGroup conferenceGroup;
attribute EventHandler onincoming;
attribute EventHandler oncallschanged;
attribute EventHandler onremoteheld;
attribute EventHandler onremoteresumed;
};
interface TelephonyCall : EventTarget {
// Indicate which service the call comes from.
readonly attribute unsigned long serviceId;
readonly attribute DOMString number;
// In CDMA networks, the 2nd waiting call shares the connection with the 1st
// call. We need an additional attribute for the 2nd number.
readonly attribute DOMString? secondNumber;
readonly attribute DOMString state;
// The property "emergency" indicates whether the call number is an emergency
// number. Only the outgoing call could have a value with true and it is
// available after dialing state.
readonly attribute boolean emergency;
// Indicate whether the call state can be switched between "connected" and
// "held".
readonly attribute boolean switchable;
// Indicate whether the call can be added into TelephonyCallGroup.
readonly attribute boolean mergeable;
readonly attribute DOMError? error;
readonly attribute TelephonyCallGroup? group;
[Throws]
void answer();
[Throws]
void hangUp();
[Throws]
void hold();
[Throws]
void resume();
attribute EventHandler onstatechange;
attribute EventHandler ondialing;
attribute EventHandler onalerting;
attribute EventHandler onconnecting;
attribute EventHandler onconnected;
attribute EventHandler ondisconnecting;
attribute EventHandler ondisconnected;
attribute EventHandler onholding;
attribute EventHandler onheld;
attribute EventHandler onresuming;
attribute EventHandler onerror;
// Fired whenever the group attribute changes.
attribute EventHandler ongroupchange;
};
interface TelephonyCallGroup : EventTarget {
readonly attribute CallsList calls;
[Throws]
void add(TelephonyCall call);
[Throws]
void add(TelephonyCall call, TelephonyCall secondCall);
[Throws]
void remove(TelephonyCall call);
[Throws]
void hold();
[Throws]
void resume();
readonly attribute DOMString state;
attribute EventHandler onstatechange;
attribute EventHandler onconnected;
attribute EventHandler onholding;
attribute EventHandler onheld;
attribute EventHandler onresuming;
attribute EventHandler oncallschanged;
attribute EventHandler onerror;
};
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
- Source code: http://mxr.mozilla.org/mozilla-central/source/dom/telephony/
- Security discussion: WebTelephony security discussion MozillaWiki/WebTelephony Security