Bug 814625 - Part 6: Telephony provider and IDL: Add multisim support. r=hsinyi

This commit is contained in:
Szu-Yu Chen [:aknow] 2013-10-31 08:05:51 -04:00
Родитель ee0ff1ecd5
Коммит 0576683f0f
3 изменённых файлов: 130 добавлений и 81 удалений

Просмотреть файл

@ -9,6 +9,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
var RIL = {};
Cu.import("resource://gre/modules/ril_consts.js", RIL);
@ -64,6 +65,10 @@ XPCOMUtils.defineLazyGetter(this, "gAudioManager", function getAudioManager() {
}
});
XPCOMUtils.defineLazyServiceGetter(this, "gRadioInterfaceLayer",
"@mozilla.org/ril;1",
"nsIRadioInterfaceLayer");
XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
"@mozilla.org/power/powermanagerservice;1",
"nsIPowerManagerService");
@ -72,12 +77,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
"@mozilla.org/system-message-internal;1",
"nsISystemMessagesInternal");
XPCOMUtils.defineLazyGetter(this, "gRadioInterface", function () {
let ril = Cc["@mozilla.org/ril;1"].getService(Ci["nsIRadioInterfaceLayer"]);
// TODO: Bug 854326 - B2G Multi-SIM: support multiple SIM cards for SMS/MMS
return ril.getRadioInterface(0);
});
XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function () {
let ns = {};
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns);
@ -85,8 +84,8 @@ XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function () {
});
function TelephonyProvider() {
this._numClients = gRadioInterfaceLayer.numRadioInterfaces;
this._listeners = [];
this._updateDebugFlag();
this.defaultServiceId = this._getDefaultServiceId();
@ -140,6 +139,10 @@ TelephonyProvider.prototype = {
}
},
_getClient: function _getClient(aClientId) {
return gRadioInterfaceLayer.getRadioInterface(aClientId);
},
// An array of nsITelephonyListener instances.
_listeners: null,
_notifyAllListeners: function _notifyAllListeners(aMethodName, aArgs) {
@ -159,6 +162,16 @@ TelephonyProvider.prototype = {
}
},
_matchActiveCall: function _matchActiveCall(aCall) {
if (this._activeCall &&
this._activeCall.callIndex == aCall.callIndex &&
this._activeCall.clientId == aCall.clientId) {
return true;
}
return false;
},
/**
* Track the active call and update the audio system as its state changes.
*/
@ -186,7 +199,7 @@ TelephonyProvider.prototype = {
}
if (aCall.isConference) {
if (this._activeCall && this._activeCall.callIndex == aCall.callIndex) {
if (this._matchActiveCall(aCall)) {
this._activeCall = null;
}
return;
@ -225,8 +238,7 @@ TelephonyProvider.prototype = {
case nsITelephonyProvider.CALL_STATE_HELD: // Fall through...
case nsITelephonyProvider.CALL_STATE_DISCONNECTED:
aCall.isActive = false;
if (this._activeCall &&
this._activeCall.callIndex == aCall.callIndex) {
if (this._matchActiveCall(aCall)) {
// Previously active call is not active now.
this._activeCall = null;
}
@ -332,26 +344,45 @@ TelephonyProvider.prototype = {
this._listeners.splice(index, 1);
},
enumerateCalls: function(aListener) {
if (DEBUG) debug("Requesting enumeration of calls for callback");
gRadioInterface.sendWorkerMessage("enumerateCalls", null,
(function(response) {
for (let call of response.calls) {
call.state = this._convertRILCallState(call.state);
call.isActive = this._activeCall ?
(call.callIndex == this._activeCall.callIndex) : false;
_enumerateCallsForClient: function _enumerateCallsForClient(aClientId,
aListener) {
if (DEBUG) debug("Enumeration of calls for client " + aClientId);
aListener.enumerateCallState(call.callIndex, call.state, call.number,
let deferred = Promise.defer();
this._getClient(aClientId).sendWorkerMessage("enumerateCalls", null,
(function(response) {
for (let call of response.calls) {
call.clienId = aClientId;
call.state = this._convertRILCallState(call.state);
call.isActive = this._matchActiveCall(call);
aListener.enumerateCallState(call.clientId, call.callIndex,
call.state, call.number,
call.isActive, call.isOutgoing,
call.isEmergency, call.isConference);
}
aListener.enumerateCallStateComplete();
deferred.resolve();
return false;
}).bind(this));
return deferred.promise;
},
dial: function(aNumber, aIsEmergency) {
enumerateCalls: function(aListener) {
if (DEBUG) debug("Requesting enumeration of calls for callback");
let promise = Promise.resolve();
for (let i = 0; i < this._numClients; ++i) {
promise = promise.then(this._enumerateCallsForClient.bind(this, i, aListener));
}
promise.then(function() {
aListener.enumerateCallStateComplete();
});
},
dial: function(aClientId, aNumber, aIsEmergency) {
if (DEBUG) debug("Dialing " + (aIsEmergency ? "emergency " : "") + aNumber);
// we don't try to be too clever here, as the phone is probably in the
// locked state. Let's just check if it's a number without normalizing
@ -359,53 +390,55 @@ TelephonyProvider.prototype = {
aNumber = gPhoneNumberUtils.normalize(aNumber);
}
if (this._validateNumber(aNumber)) {
gRadioInterface.sendWorkerMessage("dial", { number: aNumber,
isDialEmergency: aIsEmergency });
this._getClient(aClientId).sendWorkerMessage("dial", {
number: aNumber,
isDialEmergency: aIsEmergency
});
}
},
hangUp: function(aCallIndex) {
gRadioInterface.sendWorkerMessage("hangUp", { callIndex: aCallIndex });
hangUp: function(aClientId, aCallIndex) {
this._getClient(aClientId).sendWorkerMessage("hangUp", { callIndex: aCallIndex });
},
startTone: function(aDtmfChar) {
gRadioInterface.sendWorkerMessage("startTone", { dtmfChar: aDtmfChar });
startTone: function(aClientId, aDtmfChar) {
this._getClient(aClientId).sendWorkerMessage("startTone", { dtmfChar: aDtmfChar });
},
stopTone: function() {
gRadioInterface.sendWorkerMessage("stopTone");
stopTone: function(aClientId) {
this._getClient(aClientId).sendWorkerMessage("stopTone");
},
answerCall: function(aCallIndex) {
gRadioInterface.sendWorkerMessage("answerCall", { callIndex: aCallIndex });
answerCall: function(aClientId, aCallIndex) {
this._getClient(aClientId).sendWorkerMessage("answerCall", { callIndex: aCallIndex });
},
rejectCall: function(aCallIndex) {
gRadioInterface.sendWorkerMessage("rejectCall", { callIndex: aCallIndex });
rejectCall: function(aClientId, aCallIndex) {
this._getClient(aClientId).sendWorkerMessage("rejectCall", { callIndex: aCallIndex });
},
holdCall: function(aCallIndex) {
gRadioInterface.sendWorkerMessage("holdCall", { callIndex: aCallIndex });
holdCall: function(aClientId, aCallIndex) {
this._getClient(aClientId).sendWorkerMessage("holdCall", { callIndex: aCallIndex });
},
resumeCall: function(aCallIndex) {
gRadioInterface.sendWorkerMessage("resumeCall", { callIndex: aCallIndex });
resumeCall: function(aClientId, aCallIndex) {
this._getClient(aClientId).sendWorkerMessage("resumeCall", { callIndex: aCallIndex });
},
conferenceCall: function conferenceCall() {
gRadioInterface.sendWorkerMessage("conferenceCall");
conferenceCall: function conferenceCall(aClientId) {
this._getClient(aClientId).sendWorkerMessage("conferenceCall");
},
separateCall: function separateCall(aCallIndex) {
gRadioInterface.sendWorkerMessage("separateCall", { callIndex: aCallIndex });
separateCall: function separateCall(aClientId, aCallIndex) {
this._getClient(aClientId).sendWorkerMessage("separateCall", { callIndex: aCallIndex });
},
holdConference: function holdConference() {
gRadioInterface.sendWorkerMessage("holdConference");
holdConference: function holdConference(aClientId) {
this._getClient(aClientId).sendWorkerMessage("holdConference");
},
resumeConference: function resumeConference() {
gRadioInterface.sendWorkerMessage("resumeConference");
resumeConference: function resumeConference(aClientId) {
this._getClient(aClientId).sendWorkerMessage("resumeConference");
},
get microphoneMuted() {
@ -448,7 +481,7 @@ TelephonyProvider.prototype = {
/**
* Handle call disconnects by updating our current state and the audio system.
*/
notifyCallDisconnected: function notifyCallDisconnected(aCall) {
notifyCallDisconnected: function notifyCallDisconnected(aClientId, aCall) {
if (DEBUG) debug("handleCallDisconnected: " + JSON.stringify(aCall));
aCall.state = nsITelephonyProvider.CALL_STATE_DISCONNECTED;
@ -463,7 +496,8 @@ TelephonyProvider.prototype = {
this._updateCallAudioState(aCall, null);
this._notifyAllListeners("callStateChanged", [aCall.callIndex,
this._notifyAllListeners("callStateChanged", [aClientId,
aCall.callIndex,
aCall.state,
aCall.number,
aCall.isActive,
@ -475,8 +509,8 @@ TelephonyProvider.prototype = {
/**
* Handle call error.
*/
notifyCallError: function notifyCallError(aCallIndex, aErrorMsg) {
this._notifyAllListeners("notifyError", [aCallIndex, aErrorMsg]);
notifyCallError: function notifyCallError(aClientId, aCallIndex, aErrorMsg) {
this._notifyAllListeners("notifyError", [aClientId, aCallIndex, aErrorMsg]);
},
/**
@ -497,7 +531,7 @@ TelephonyProvider.prototype = {
* Handle call state changes by updating our current state and the audio
* system.
*/
notifyCallStateChanged: function notifyCallStateChanged(aCall) {
notifyCallStateChanged: function notifyCallStateChanged(aClientId, aCall) {
if (DEBUG) debug("handleCallStateChange: " + JSON.stringify(aCall));
aCall.state = this._convertRILCallState(aCall.state);
@ -507,7 +541,8 @@ TelephonyProvider.prototype = {
this._updateCallAudioState(aCall, null);
this._notifyAllListeners("callStateChanged", [aCall.callIndex,
this._notifyAllListeners("callStateChanged", [aClientId,
aCall.callIndex,
aCall.state,
aCall.number,
aCall.isActive,
@ -516,19 +551,19 @@ TelephonyProvider.prototype = {
aCall.isConference]);
},
notifyCdmaCallWaiting: function notifyCdmaCallWaiting(aNumber) {
notifyCdmaCallWaiting: function notifyCdmaCallWaiting(aClientId, aNumber) {
// We need to acquire a CPU wake lock to avoid the system falling into
// the sleep mode when the RIL handles the incoming call.
this._acquireCallRingWakeLock();
this._notifyAllListeners("notifyCdmaCallWaiting", [aNumber]);
this._notifyAllListeners("notifyCdmaCallWaiting", [aClientId, aNumber]);
},
notifySupplementaryService: function notifySupplementaryService(aCallIndex,
aNotification) {
notifySupplementaryService:
function notifySupplementaryService(aClientId, aCallIndex, aNotification) {
let notification = this._convertRILSuppSvcNotification(aNotification);
this._notifyAllListeners("supplementaryServiceNotification",
[aCallIndex, notification]);
[aClientId, aCallIndex, notification]);
},
notifyConferenceCallStateChanged: function notifyConferenceCallStateChanged(aState) {

Просмотреть файл

@ -10,21 +10,21 @@
"@mozilla.org/telephony/gonktelephonyprovider;1"
%}
[scriptable, uuid(f072f334-e4ea-4754-9929-533da30444a8)]
[scriptable, uuid(fe113e67-5a15-49e6-a555-7f41409f611a)]
interface nsIGonkTelephonyProvider : nsITelephonyProvider
{
void notifyCallDisconnected(in jsval call);
void notifyCallDisconnected(in unsigned long clientId, in jsval call);
void notifyCallError(in long callIndex,
void notifyCallError(in unsigned long clientId, in long callIndex,
in AString error);
void notifyCallRing();
void notifyCallStateChanged(in jsval call);
void notifyCallStateChanged(in unsigned long clientId, in jsval call);
void notifyCdmaCallWaiting(in AString number);
void notifyCdmaCallWaiting(in unsigned long clientId, in AString number);
void notifySupplementaryService(in long callIndex,
void notifySupplementaryService(in unsigned long clientId, in long callIndex,
in AString notification);
void notifyConferenceCallStateChanged(in short state);

Просмотреть файл

@ -4,12 +4,14 @@
#include "nsISupports.idl"
[scriptable, uuid(3aa42e77-7c2b-43a1-b105-7be094b0817a)]
[scriptable, uuid(707c4c43-a0d7-4093-af52-d4d6a3a333c3)]
interface nsITelephonyListener : nsISupports
{
/**
* Notified when a telephony call changes state.
*
* @param clientId
Indicate the RIL client, 0 ~ (number of client - 1).
* @param callIndex
* Call identifier assigned by the RIL.
* @param callState
@ -25,7 +27,8 @@ interface nsITelephonyListener : nsISupports
* @param isConference
* Indicates whether this call is a conference call.
*/
void callStateChanged(in unsigned long callIndex,
void callStateChanged(in unsigned long clientId,
in unsigned long callIndex,
in unsigned short callState,
in AString number,
in boolean isActive,
@ -55,6 +58,8 @@ interface nsITelephonyListener : nsISupports
* telephony call state (nsITelephonyProvider::enumerateCalls). This is
* called once per call that is currently managed by the RIL.
*
* @param clientId
Indicate the RIL client, 0 ~ (number of client - 1).
* @param callIndex
* Call identifier assigned by the RIL.
* @param callState
@ -68,7 +73,8 @@ interface nsITelephonyListener : nsISupports
* @param isConference
* Indicates whether this call is a conference call.
*/
void enumerateCallState(in unsigned long callIndex,
void enumerateCallState(in unsigned long clientId,
in unsigned long callIndex,
in unsigned short callState,
in AString number,
in boolean isActive,
@ -79,32 +85,40 @@ interface nsITelephonyListener : nsISupports
/**
* 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 nsITelephonyProvider::NOTIFICATION_* values.
*/
void supplementaryServiceNotification(in long callIndex,
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 long callIndex,
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.
*/
void notifyCdmaCallWaiting(in AString number);
void notifyCdmaCallWaiting(in unsigned long clientId, in AString number);
};
%{C++
@ -118,7 +132,7 @@ interface nsITelephonyListener : nsISupports
* XPCOM component (in the content process) that provides the telephony
* information.
*/
[scriptable, uuid(f7680b82-53fc-42a7-9adf-bc0f2726425c)]
[scriptable, uuid(4ff3ecb7-b024-4752-9dd6-c3623c6e6b8a)]
interface nsITelephonyProvider : nsISupports
{
const unsigned short CALL_STATE_UNKNOWN = 0;
@ -155,22 +169,22 @@ interface nsITelephonyProvider : nsISupports
/**
* Functionality for making and managing phone calls.
*/
void dial(in DOMString number,
void dial(in unsigned long clientId, in DOMString number,
in boolean isEmergency);
void hangUp(in unsigned long callIndex);
void hangUp(in unsigned long clientId, in unsigned long callIndex);
void startTone(in DOMString dtmfChar);
void stopTone();
void startTone(in unsigned long clientId, in DOMString dtmfChar);
void stopTone(in unsigned long clientId);
void answerCall(in unsigned long callIndex);
void rejectCall(in unsigned long callIndex);
void holdCall(in unsigned long callIndex);
void resumeCall(in unsigned long callIndex);
void answerCall(in unsigned long clientId, in unsigned long callIndex);
void rejectCall(in unsigned long clientId, in unsigned long callIndex);
void holdCall(in unsigned long clientId, in unsigned long callIndex);
void resumeCall(in unsigned long clientId, in unsigned long callIndex);
void conferenceCall();
void separateCall(in unsigned long callIndex);
void holdConference();
void resumeConference();
void conferenceCall(in unsigned long clientId);
void separateCall(in unsigned long clientId, in unsigned long callIndex);
void holdConference(in unsigned long clientId);
void resumeConference(in unsigned long clientId);
attribute bool microphoneMuted;
attribute bool speakerEnabled;