зеркало из https://github.com/mozilla/gecko-dev.git
Bug 707629 - Part 1: Add call state handling and manipulation to the RIL worker. r=gal
This commit is contained in:
Родитель
d480bf7f68
Коммит
46378df6f5
|
@ -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.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче