Bug 707629 - Part 1: Add call state handling and manipulation to the RIL worker. r=gal

This commit is contained in:
Philipp von Weitershausen 2011-12-07 14:57:05 +08:00
Родитель d480bf7f68
Коммит 46378df6f5
2 изменённых файлов: 241 добавлений и 44 удалений

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

@ -36,19 +36,6 @@
*
* ***** END LICENSE BLOCK ***** */
const CARD_MAX_APPS = 8;
const RADIO_STATE_OFF = 0;
const RADIO_STATE_UNAVAILABLE = 1;
const RADIO_STATE_SIM_NOT_READY = 2;
const RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3;
const RADIO_STATE_SIM_READY = 4;
const RADIO_STATE_RUIM_NOT_READY = 5;
const RADIO_STATE_RUIM_READY = 6;
const RADIO_STATE_RUIM_LOCKED_OR_ABSENT = 7;
const RADIO_STATE_NV_NOT_READY = 8;
const RADIO_STATE_NV_READY = 9;
const REQUEST_GET_SIM_STATUS = 1;
const REQUEST_ENTER_SIM_PIN = 2;
const REQUEST_ENTER_SIM_PUK = 3;
@ -154,6 +141,9 @@ const REQUEST_SET_SMSC_ADDRESS = 101;
const REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
const REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
const RESPONSE_TYPE_SOLICITED = 0;
const RESPONSE_TYPE_UNSOLICITED = 1;
const UNSOLICITED_RESPONSE_BASE = 1000;
const UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED = 1000;
const UNSOLICITED_RESPONSE_CALL_STATE_CHANGED = 1001;
@ -187,3 +177,67 @@ const UNSOLICITED_OEM_HOOK_RAW = 1028;
const UNSOLICITED_RINGBACK_TONE = 1029;
const UNSOLICITED_RESEND_INCALL_MUTE = 1030;
const RADIO_STATE_OFF = 0;
const RADIO_STATE_UNAVAILABLE = 1;
const RADIO_STATE_SIM_NOT_READY = 2;
const RADIO_STATE_SIM_LOCKED_OR_ABSENT = 3;
const RADIO_STATE_SIM_READY = 4;
const RADIO_STATE_RUIM_NOT_READY = 5;
const RADIO_STATE_RUIM_READY = 6;
const RADIO_STATE_RUIM_LOCKED_OR_ABSENT = 7;
const RADIO_STATE_NV_NOT_READY = 8;
const RADIO_STATE_NV_READY = 9;
const CARD_MAX_APPS = 8;
const CALL_STATE_ACTIVE = 0;
const CALL_STATE_HOLDING = 1;
const CALL_STATE_DIALING = 2;
const CALL_STATE_ALERTING = 3;
const CALL_STATE_INCOMING = 4;
const CALL_STATE_WAITING = 5;
const TOA_INTERNATIONAL = 0x91;
const TOA_UNKNOWN = 0x81;
const CALL_PRESENTATION_ALLOWED = 0;
const CALL_PRESENTATION_RESTRICTED = 1;
const CALL_PRESENTATION_UNKNOWN = 2;
const CALL_PRESENTATION_PAYPHONE = 3;
/**
* DOM constants
*/
const DOM_RADIOSTATE_UNAVAILABLE = "unavailable";
const DOM_RADIOSTATE_OFF = "off";
const DOM_RADIOSTATE_READY = "ready";
const DOM_CARDSTATE_UNAVAILABLE = "unavailable";
const DOM_CARDSTATE_ABSENT = "absent";
const DOM_CARDSTATE_PIN_REQUIRED = "pin_required";
const DOM_CARDSTATE_PUK_REQUIRED = "puk_required";
const DOM_CARDSTATE_NETWORK_LOCKED = "network_locked";
const DOM_CARDSTATE_NOT_READY = "not_ready";
const DOM_CARDSTATE_READY = "ready";
const DOM_CALL_READYSTATE_DIALING = "dialing";
const DOM_CALL_READYSTATE_RINGING = "ringing";
const DOM_CALL_READYSTATE_BUSY = "busy";
const DOM_CALL_READYSTATE_CONNECTING = "connecting";
const DOM_CALL_READYSTATE_CONNECTED = "connected";
const DOM_CALL_READYSTATE_DISCONNECTING = "disconnecting";
const DOM_CALL_READYSTATE_DISCONNECTED = "disconnected";
const DOM_CALL_READYSTATE_INCOMING = "incoming";
const DOM_CALL_READYSTATE_HOLDING = "holding";
const DOM_CALL_READYSTATE_HELD = "held";
const RIL_TO_DOM_CALL_STATE = [
DOM_CALL_READYSTATE_CONNECTED, // CALL_READYSTATE_ACTIVE
DOM_CALL_READYSTATE_HELD, // CALL_READYSTATE_HOLDING
DOM_CALL_READYSTATE_DIALING, // CALL_READYSTATE_DIALING
DOM_CALL_READYSTATE_RINGING, // CALL_READYSTATE_ALERTING
DOM_CALL_READYSTATE_INCOMING, // CALL_READYSTATE_INCOMING
DOM_CALL_READYSTATE_HELD // CALL_READYSTATE_WAITING (XXX is this right?)
];

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

@ -71,9 +71,6 @@ const UINT16_SIZE = 2;
const UINT32_SIZE = 4;
const PARCEL_SIZE_SIZE = UINT32_SIZE;
const RESPONSE_TYPE_SOLICITED = 0;
const RESPONSE_TYPE_UNSOLICITED = 1;
/**
* This object contains helpers buffering incoming data & deconstructing it
* into parcels as well as buffering outgoing data & constructing parcels.
@ -434,12 +431,13 @@ let Buf = {
processParcel: function processParcel() {
let response_type = this.readUint32();
let length = this.readIncoming - 2 * UINT32_SIZE;
let length = this.readIncoming - UINT32_SIZE;
let request_type;
if (response_type == RESPONSE_TYPE_SOLICITED) {
let token = this.readUint32();
let error = this.readUint32();
length -= 2 * UINT32_SIZE;
request_type = this.tokenRequestMap[token];
if (error) {
//TODO
@ -452,6 +450,7 @@ let Buf = {
delete this.tokenRequestMap[token];
} else if (response_type == RESPONSE_TYPE_UNSOLICITED) {
request_type = this.readUint32();
length -= UINT32_SIZE;
debug("Unsolicited response for request type " + request_type);
} else {
debug("Unknown response type: " + response_type);
@ -625,6 +624,33 @@ let RIL = {
Buf.sendParcel();
},
/**
* Hang up the phone.
*
* @param index
* Call index (1-based) as reported by REQUEST_GET_CURRENT_CALLS.
*/
hangUp: function hangUp(index) {
Buf.newParcel(REQUEST_HANGUP);
Buf.writeUint32(1);
Buf.writeUint32(index);
Buf.sendParcel();
},
/**
* Answer an incoming call.
*/
answerCall: function answerCall() {
Buf.simpleRequest(REQUEST_ANSWER);
},
/**
* Reject an incoming call.
*/
rejectCall: function rejectCall() {
Buf.simpleRequest(REQUEST_UDUB);
},
/**
* Send an SMS.
*
@ -698,14 +724,23 @@ RIL[REQUEST_ENTER_SIM_PUK2] = null;
RIL[REQUEST_CHANGE_SIM_PIN] = null;
RIL[REQUEST_CHANGE_SIM_PIN2] = null;
RIL[REQUEST_ENTER_NETWORK_DEPERSONALIZATION] = null;
RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS() {
let calls = [];
let calls_length = Buf.readUint32();
RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length) {
let calls_length = 0;
// The RIL won't even send us the length integer if there are no active calls.
// So only read this integer if the parcel actually has it.
if (length) {
calls_length = Buf.readUint32();
}
if (!calls_length) {
Phone.onCurrentCalls(null);
return;
}
let calls = {};
for (let i = 0; i < calls_length; i++) {
let dc = {
state: Buf.readUint32(), // CALLSTATE_* constants
index: Buf.readUint32(),
let call = {
state: Buf.readUint32(), // CALL_STATE_*
index: Buf.readUint32(), // GSM index (1-based)
toa: Buf.readUint32(),
isMpty: Boolean(Buf.readUint32()),
isMT: Boolean(Buf.readUint32()),
@ -714,41 +749,48 @@ RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS() {
isVoicePrivacy: Boolean(Buf.readUint32()),
somethingOrOther: Buf.readUint32(), //XXX TODO whatziz? not in ril.h, but it's in the output...
number: Buf.readString(), //TODO munge with TOA
numberPresentation: Buf.readUint32(), // Connection.PRESENTATION XXX TODO
numberPresentation: Buf.readUint32(), // CALL_PRESENTATION_*
name: Buf.readString(),
namePresentation: Buf.readUint32(),
uusInfo: null
};
let uusInfoPresent = Buf.readUint32();
if (uusInfoPresent == 1) {
dc.uusInfo = {
call.uusInfo = {
type: Buf.readUint32(),
dcs: Buf.readUint32(),
userData: null //XXX TODO byte array?!?
};
}
calls.push(dc);
calls[call.index] = call;
}
Phone.onCurrentCalls(calls);
};
RIL[REQUEST_DIAL] = null;
RIL[REQUEST_DIAL] = function REQUEST_DIAL(length) {
Phone.onDial();
};
RIL[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length) {
let imsi = Buf.readString(length);
let imsi = Buf.readString();
Phone.onIMSI(imsi);
};
RIL[REQUEST_HANGUP] = null;
RIL[REQUEST_HANGUP] = function REQUEST_HANGUP(length) {
Phone.onHangUp();
};
RIL[REQUEST_HANGUP_WAITING_OR_BACKGROUND] = null;
RIL[REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND] = null;
RIL[REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE] = null;
RIL[REQUEST_SWITCH_HOLDING_AND_ACTIVE] = null;
RIL[REQUEST_CONFERENCE] = null;
RIL[REQUEST_UDUB] = null;
RIL[REQUEST_UDUB] = function REQUEST_UDUB(length) {
Phone.onRejectCall();
};
RIL[REQUEST_LAST_CALL_FAIL_CAUSE] = null;
RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH() {
let strength = {
// Valid values are (0-31, 99) as defined in TS 27.007 8.5.
gsmSignalStrength: Buf.readUint32(),
// For some reason we're getting int32s like [99, 4, 0, 0] and [99, 3, 0, 0]
// here, so let's strip of anything beyond the first byte.
gsmSignalStrength: Buf.readUint32() & 0xff,
// GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5.
gsmBitErrorRate: Buf.readUint32(),
// The CDMA RSSI value.
@ -804,7 +846,9 @@ RIL[REQUEST_GET_IMEISV] = function REQUEST_GET_IMEISV() {
let imeiSV = Buf.readString();
Phone.onIMEISV(imeiSV);
};
RIL[REQUEST_ANSWER] = null;
RIL[REQUEST_ANSWER] = function REQUEST_ANSWER(length) {
Phone.onAnswerCall();
};
RIL[REQUEST_DEACTIVATE_DATA_CALL] = null;
RIL[REQUEST_QUERY_FACILITY_LOCK] = null;
RIL[REQUEST_SET_FACILITY_LOCK] = null;
@ -901,7 +945,15 @@ RIL[UNSOLICITED_STK_EVENT_NOTIFY] = null;
RIL[UNSOLICITED_STK_CALL_SETUP] = null;
RIL[UNSOLICITED_SIM_SMS_STORAGE_FULL] = null;
RIL[UNSOLICITED_SIM_REFRESH] = null;
RIL[UNSOLICITED_CALL_RING] = null;
RIL[UNSOLICITED_CALL_RING] = function UNSOLICITED_CALL_RING() {
let info = {
isPresent: Buf.readUint32(),
signalType: Buf.readUint32(),
alertPitch: Buf.readUint32(),
signal: Buf.readUint32()
};
Phone.onCallRing(info);
};
RIL[UNSOLICITED_RESPONSE_SIM_STATUS_CHANGED] = null;
RIL[UNSOLICITED_RESPONSE_CDMA_NEW_SMS] = null;
RIL[UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS] = null;
@ -961,7 +1013,7 @@ let Phone = {
/**
* Active calls
*/
calls: null,
currentCalls: {},
/**
* Handlers for messages from the RIL. They all begin with on* and are called
@ -1001,7 +1053,8 @@ let Phone = {
RIL.setScreenState(true);
this.sendDOMMessage({
type: "radiostatechange",
radioState: (newState == RADIO_STATE_OFF) ? "off" : "ready"
radioState: (newState == RADIO_STATE_OFF) ?
DOM_RADIOSTATE_OFF : DOM_RADIOSTATE_READY
});
//XXX TODO For now, just turn the radio on if it's off. for the real
@ -1018,7 +1071,7 @@ let Phone = {
//TODO do that
this.sendDOMMessage({type: "radiostatechange",
radioState: "unavailable"});
radioState: DOM_RADIOSTATE_UNAVAILABLE});
}
if (newState == RADIO_STATE_SIM_READY ||
@ -1029,13 +1082,13 @@ let Phone = {
this.requestNetworkInfo();
RIL.getSignalStrength();
this.sendDOMMessage({type: "cardstatechange",
cardState: "ready"});
cardState: DOM_CARDSTATE_READY});
}
if (newState == RADIO_STATE_SIM_LOCKED_OR_ABSENT ||
newState == RADIO_STATE_RUIM_LOCKED_OR_ABSENT) {
RIL.getICCStatus();
this.sendDOMMessage({type: "cardstatechange",
cardState: "unavailable"});
cardState: DOM_CARDSTATE_UNAVAILABLE});
}
let wasOn = this.radioState != RADIO_STATE_OFF &&
@ -1052,17 +1105,69 @@ let Phone = {
this.radioState = newState;
},
onCurrentCalls: function onCurrentCalls(calls) {
debug("onCurrentCalls");
debug(calls);
//TODO
this.sendDOMMessage({type: "callstatechange", callState: calls});
onCurrentCalls: function onCurrentCalls(newCalls) {
// Go through the calls we currently have on file and see if any of them
// changed state. Remove them from the newCalls map as we deal with them
// so that only new calls remain in the map after we're done.
for each (let currentCall in this.currentCalls) {
let callIndex = currentCall.index;
let newCall;
if (newCalls) {
newCall = newCalls[callIndex];
delete newCalls[callIndex];
}
if (!newCall) {
// Call is no longer reported by the radio. Send disconnected
// state change.
this.sendDOMMessage({type: "callstatechange",
callState: DOM_CALL_READYSTATE_DISCONNECTED,
callIndex: callIndex,
number: currentCall.number,
name: currentCall.name});
delete this.currentCalls[currentCall];
continue;
}
if (newCall.state == currentCall.state) {
continue;
}
this._handleChangedCallState(newCall);
}
// Go through any remaining calls that are new to us.
for each (let newCall in newCalls) {
if (newCall.isVoice) {
this._handleChangedCallState(newCall);
}
}
},
_handleChangedCallState: function handleChangedCallState(newCall) {
// Format international numbers appropriately.
if (newCall.number &&
newCall.toa == TOA_INTERNATIONAL &&
newCall.number[0] != "+") {
newCall.number = "+" + newCall.number;
}
this.currentCalls[newCall.index] = newCall;
this.sendDOMMessage({type: "callstatechange",
callState: RIL_TO_DOM_CALL_STATE[newCall.state],
callIndex: newCall.index,
number: newCall.number,
name: newCall.name});
},
onCallStateChanged: function onCallStateChanged() {
RIL.getCurrentCalls();
},
onCallRing: function onCallRing(info) {
debug("onCallRing " + JSON.stringify(info)); //DEBUG
RIL.getCurrentCalls();
},
onNetworkStateChanged: function onNetworkStateChanged() {
debug("Network state changed, re-requesting phone state.");
this.requestNetworkInfo();
@ -1131,6 +1236,18 @@ let Phone = {
signalStrength: strength});
},
onDial: function onDial() {
},
onHangUp: function onHangUp() {
},
onAnswerCall: function onAnswerCall() {
},
onRejectCall: function onRejectCall() {
},
onSendSMS: function onSendSMS(messageRef, ackPDU, errorCode) {
//TODO
},
@ -1170,6 +1287,32 @@ let Phone = {
RIL.dial(options.number, 0, 0);
},
/**
* Hang up a call.
*
* @param callIndex
* Call index of the call to hang up.
*/
hangUp: function hangUp(options) {
//TODO need to check whether call is holding/waiting/background
// and then use REQUEST_HANGUP_WAITING_OR_BACKGROUND
RIL.hangUp(options.callIndex);
},
/**
* Answer an incoming call.
*/
answerCall: function answerCall() {
RIL.answerCall();
},
/**
* Reject an incoming call.
*/
rejectCall: function rejectCall() {
RIL.rejectCall();
},
/**
* Send an SMS.
*