Bug 1159591 - Part 10: Move MMI logic from ril_worker to telephonyService (USSD). r=aknow

This commit is contained in:
Edgar Chen 2015-04-30 22:45:40 +08:00
parent 325672a649
commit 84fc95b7b8
4 changed files with 70 additions and 252 deletions

View File

@ -244,16 +244,6 @@ RilObject.prototype = {
*/
this._pendingNetworkInfo = {rilMessageType: "networkinfochanged"};
/**
* USSD session flag.
* Only one USSD session may exist at a time, and the session is assumed
* to exist until:
* a) There's a call to cancelUSSD()
* b) The implementation sends a UNSOLICITED_ON_USSD with a type code
* of "0" (USSD-Notify/no further action) or "2" (session terminated)
*/
this._ussdSession = null;
/**
* Cell Broadcast Search Lists.
*/
@ -1845,67 +1835,13 @@ RilObject.prototype = {
this.context.Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE, options);
},
sendMMI: function(options) {
if (DEBUG) {
this.context.debug("SendMMI " + JSON.stringify(options));
}
let _sendMMIError = (function(errorMsg) {
options.errorMsg = errorMsg;
this.sendChromeMessage(options);
}).bind(this);
// It's neither a valid mmi code nor an ongoing ussd.
let mmi = options.mmi;
if (!mmi && !this._ussdSession) {
_sendMMIError(MMI_ERROR_KS_ERROR);
return;
}
let _isRadioAvailable = (function() {
if (this.radioState !== GECKO_RADIOSTATE_ENABLED) {
_sendMMIError(GECKO_ERROR_RADIO_NOT_AVAILABLE);
return false;
}
return true;
}).bind(this);
// If the MMI code is not a known code, it is treated as an ussd.
if (!_isRadioAvailable()) {
return;
}
options.ussd = mmi.fullMMI;
if (this._ussdSession) {
if (DEBUG) this.context.debug("Cancel existing ussd session.");
this.cachedUSSDRequest = options;
this.cancelUSSD({});
return;
}
this.sendUSSD(options, false);
},
/**
* Cache the request for send out a new ussd when there is an existing
* session. We should do cancelUSSD first.
*/
cachedUSSDRequest : null,
/**
* Send USSD.
*
* @param ussd
* String containing the USSD code.
*/
sendUSSD: function(options, checkSession = true) {
if (checkSession && !this._ussdSession) {
options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
this.sendChromeMessage(options);
return;
}
sendUSSD: function(options) {
let Buf = this.context.Buf;
Buf.newParcel(REQUEST_SEND_USSD, options);
Buf.writeString(options.ussd);
@ -4360,24 +4296,12 @@ RilObject.prototype[REQUEST_SEND_USSD] = function REQUEST_SEND_USSD(length, opti
if (DEBUG) {
this.context.debug("REQUEST_SEND_USSD " + JSON.stringify(options));
}
this._ussdSession = !options.errorMsg;
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_CANCEL_USSD] = function REQUEST_CANCEL_USSD(length, options) {
if (DEBUG) {
this.context.debug("REQUEST_CANCEL_USSD" + JSON.stringify(options));
}
this._ussdSession = !!options.errorMsg;
// The cancelUSSD is triggered by ril_worker itself.
if (this.cachedUSSDRequest) {
if (DEBUG) this.context.debug("Send out the cached ussd request");
this.sendUSSD(this.cachedUSSDRequest);
this.cachedUSSDRequest = null;
return;
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_GET_CLIR] = function REQUEST_GET_CLIR(length, options) {
@ -5166,18 +5090,12 @@ RilObject.prototype[UNSOLICITED_ON_USSD] = function UNSOLICITED_ON_USSD() {
this.context.debug("On USSD. Type Code: " + typeCode + " Message: " + message);
}
let oldSession = this._ussdSession;
// Per ril.h the USSD session is assumed to persist if the type code is "1".
this._ussdSession = typeCode == "1";
if (!oldSession && !this._ussdSession && !message) {
return;
}
this.sendChromeMessage({rilMessageType: "ussdreceived",
message: message,
sessionEnded: !this._ussdSession});
// Per ril.h the USSD session is assumed to persist if
// the type code is "1", otherwise the current session
// (if any) is assumed to have terminated.
sessionEnded: typeCode !== "1"});
};
RilObject.prototype[UNSOLICITED_ON_USSD_REQUEST] = null;
RilObject.prototype[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED() {

View File

@ -1,118 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
function run_test() {
run_next_test();
}
function createMMIOptions(procedure, serviceCode, sia, sib, sic) {
let mmi = {
fullMMI: Array.slice(arguments).join("*") + "#",
procedure: procedure,
serviceCode: serviceCode,
sia: sia,
sib: sib,
sic: sic
};
return mmi;
}
function testSendMMI(mmi, error) {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
do_print("worker.postMessage " + worker.postMessage);
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({rilMessageType: "sendMMI", mmi: mmi});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.rilMessageType, "sendMMI");
equal(postedMessage.errorMsg, error);
}
/**
* sendMMI tests.
*/
add_test(function test_sendMMI_null() {
testSendMMI(null, MMI_ERROR_KS_ERROR);
run_next_test();
});
add_test(function test_sendMMI_short_code() {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
let ussdOptions;
context.RIL.sendUSSD = function fakeSendUSSD(options){
ussdOptions = options;
context.RIL[REQUEST_SEND_USSD](0, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: {fullMMI: "**"}});
let postedMessage = workerhelper.postedMessage;
equal(ussdOptions.ussd, "**");
equal(postedMessage.errorMsg, undefined);
ok(context.RIL._ussdSession);
run_next_test();
});
add_test(function test_sendMMI_USSD() {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
let ussdOptions;
context.RIL.sendUSSD = function fakeSendUSSD(options) {
ussdOptions = options;
context.RIL[REQUEST_SEND_USSD](0, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*", "123")});
let postedMessage = workerhelper.postedMessage;
equal(ussdOptions.ussd, "**123#");
equal(postedMessage.errorMsg, undefined);
ok(context.RIL._ussdSession);
run_next_test();
});
add_test(function test_sendMMI_USSD_error() {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
let ussdOptions;
context.RIL.sendUSSD = function fakeSendUSSD(options){
ussdOptions = options;
context.RIL[REQUEST_SEND_USSD](0, {
errorMsg: GECKO_ERROR_GENERIC_FAILURE
});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*", "123")});
let postedMessage = workerhelper.postedMessage;
equal(ussdOptions.ussd, "**123#");
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
ok(!context.RIL._ussdSession);
run_next_test();
});

View File

@ -23,7 +23,6 @@ skip-if = true
[test_ril_worker_sms_gsmpduhelper.js]
[test_ril_worker_sms_segment_info.js]
[test_ril_worker_smsc_address.js]
[test_ril_worker_mmi.js]
[test_ril_worker_cf.js]
[test_ril_worker_cellbroadcast_config.js]
[test_ril_worker_cellbroadcast.js]

View File

@ -230,6 +230,7 @@ function TelephonyService() {
this._currentCalls = {};
this._currentConferenceState = nsITelephonyService.CALL_STATE_UNKNOWN;
this._audioStates = [];
this._ussdSessions = [];
this._cdmaCallWaitingNumber = null;
@ -243,6 +244,7 @@ function TelephonyService() {
for (let i = 0; i < this._numClients; ++i) {
this._audioStates[i] = nsITelephonyAudioService.PHONE_STATE_NORMAL;
this._ussdSessions[i] = false;
this._currentCalls[i] = {};
this._enumerateCallsForClient(i);
}
@ -265,6 +267,15 @@ TelephonyService.prototype = {
_callRingWakeLock: null,
_callRingWakeLockTimer: null,
/**
* USSD session flags.
* Only one USSD session may exist at a time, and the session is assumed
* to exist until:
* a) There's a call to cancelUSSD()
* b) Receiving a session end unsolicited event.
*/
_ussdSessions: null,
_acquireCallRingWakeLock: function() {
if (!this._callRingWakeLock) {
if (DEBUG) debug("Acquiring a CPU wake lock for handling incoming call.");
@ -916,53 +927,25 @@ TelephonyService.prototype = {
this._callWaitingMMI(aClientId, aMmi, aCallback);
break;
// Fall back to "sendMMI".
// Handle unknown MMI code as USSD.
default:
this._sendMMI(aClientId, aMmi, aCallback);
if (!this._isRadioOn(aClientId)) {
aCallback.notifyDialMMIError(RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE);
return;
}
this._sendUSSDInternal(aClientId, aMmi.fullMMI, aResponse => {
if (aResponse.errorMsg) {
aCallback.notifyDialMMIError(aResponse.errorMsg);
return;
}
aCallback.notifyDialMMISuccess("");
});
break;
}
},
_sendMMI: function(aClientId, aMmi, aCallback) {
this._sendToRilWorker(aClientId, "sendMMI",
{ mmi: aMmi }, response => {
if (DEBUG) debug("MMI response: " + JSON.stringify(response));
if (response.errorMsg) {
if (response.additionalInformation != null) {
aCallback.notifyDialMMIErrorWithInfo(response.errorMsg,
response.additionalInformation);
} else {
aCallback.notifyDialMMIError(response.errorMsg);
}
return;
}
// No additional information
if (response.additionalInformation === undefined) {
aCallback.notifyDialMMISuccess(response.statusMessage);
return;
}
// Additional information is an integer.
if (!isNaN(parseInt(response.additionalInformation, 10))) {
aCallback.notifyDialMMISuccessWithInteger(
response.statusMessage, response.additionalInformation);
return;
}
// Additional information is an array of strings.
let array = response.additionalInformation;
if (Array.isArray(array) && array.length > 0 && typeof array[0] === "string") {
aCallback.notifyDialMMISuccessWithStrings(response.statusMessage,
array.length, array);
return;
}
aCallback.notifyDialMMISuccess(response.statusMessage);
});
},
/**
* Handle call forwarding MMI code.
*
@ -2015,13 +1998,42 @@ TelephonyService.prototype = {
},
sendUSSD: function(aClientId, aUssd, aCallback) {
this._sendToRilWorker(aClientId, "sendUSSD", { ussd: aUssd },
this._defaultCallbackHandler.bind(this, aCallback));
this._sendUSSDInternal(aClientId, aUssd,
this._defaultCallbackHandler.bind(this, aCallback));
},
_sendUSSDInternal: function(aClientId, aUssd, aCallback) {
if (!this._ussdSessions[aClientId]) {
this._sendToRilWorker(aClientId, "sendUSSD", { ussd: aUssd }, aResponse => {
this._ussdSessions[aClientId] = !aResponse.errorMsg;
aCallback(aResponse);
});
return;
}
// Cancel the previous ussd session first.
this._cancelUSSDInternal(aClientId, aResponse => {
// Fail to cancel ussd session, report error instead of sending ussd
// request.
if (aResponse.errorMsg) {
aCallback(aResponse);
return;
}
this._sendUSSDInternal(aClientId, aUssd, aCallback);
});
},
cancelUSSD: function(aClientId, aCallback) {
this._sendToRilWorker(aClientId, "cancelUSSD", {},
this._defaultCallbackHandler.bind(this, aCallback));
this._cancelUSSDInternal(aClientId,
this._defaultCallbackHandler.bind(this, aCallback));
},
_cancelUSSDInternal: function(aClientId, aCallback) {
this._sendToRilWorker(aClientId, "cancelUSSD", {}, aResponse => {
this._ussdSessions[aClientId] = !!aResponse.errorMsg;
aCallback(aResponse);
});
},
get microphoneMuted() {
@ -2289,6 +2301,13 @@ TelephonyService.prototype = {
aMessage + " (sessionEnded : " + aSessionEnded + ")");
}
let oldSession = this._ussdSessions[aClientId];
this._ussdSessions[aClientId] = !aSessionEnded;
if (!oldSession && !this._ussdSessions[aClientId] && !aMessage) {
return;
}
gTelephonyMessenger.notifyUssdReceived(aClientId, aMessage, aSessionEnded);
},