Bug 1159591 - Part 2: Move MMI logic from ril_worker to telephonyService (Call Forwarding). r=aknow

This commit is contained in:
Edgar Chen 2015-04-29 15:05:06 +08:00
parent f03ba744fe
commit ac9b3a68e6
4 changed files with 116 additions and 263 deletions

View File

@ -1977,34 +1977,6 @@ RilObject.prototype = {
// trigger the appropriate RIL request if possible.
let sc = mmi.serviceCode;
switch (sc) {
// Call forwarding
case MMI_SC_CFU:
case MMI_SC_CF_BUSY:
case MMI_SC_CF_NO_REPLY:
case MMI_SC_CF_NOT_REACHABLE:
case MMI_SC_CF_ALL:
case MMI_SC_CF_ALL_CONDITIONAL:
if (!_isRadioAvailable()) {
return;
}
// Call forwarding requires at least an action, given by the MMI
// procedure, and a reason, given by the MMI service code, but there
// is no way that we get this far without a valid procedure or service
// code.
options.action = MMI_PROC_TO_CF_ACTION[mmi.procedure];
options.reason = MMI_SC_TO_CF_REASON[sc];
options.number = mmi.sia;
options.serviceClass = this._siToServiceClass(mmi.sib);
if (options.action == CALL_FORWARD_ACTION_QUERY_STATUS) {
this.queryCallForwardStatus(options);
return;
}
options.isSetCallForward = true;
options.timeSeconds = mmi.sic;
this.setCallForward(options);
return;
// Change the current ICC PIN number.
case MMI_SC_PIN:
// As defined in TS.122.030 6.6.2 to change the ICC PIN we should expect
@ -3614,7 +3586,7 @@ RilObject.prototype = {
case 25:
return ICC_SERVICE_CLASS_DATA_ASYNC;
case 26:
return ICC_SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE;
return ICC_SERVICE_CLASS_DATA_SYNC + ICC_SERVICE_CLASS_VOICE;
case 99:
return ICC_SERVICE_CLASS_PACKET;
default:
@ -4891,33 +4863,10 @@ RilObject.prototype[REQUEST_QUERY_CALL_FORWARD_STATUS] =
rules[i] = rule;
}
options.rules = rules;
if (options.rilMessageType === "sendMMI") {
options.statusMessage = MMI_SM_KS_SERVICE_INTERROGATED;
// MMI query call forwarding options request returns a set of rules that
// will be exposed in the form of an array of MozCallForwardingOptions
// instances.
options.additionalInformation = rules;
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_SET_CALL_FORWARD] =
function REQUEST_SET_CALL_FORWARD(length, options) {
if (!options.errorMsg && options.rilMessageType === "sendMMI") {
switch (options.action) {
case CALL_FORWARD_ACTION_ENABLE:
options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
break;
case CALL_FORWARD_ACTION_DISABLE:
options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
break;
case CALL_FORWARD_ACTION_REGISTRATION:
options.statusMessage = MMI_SM_KS_SERVICE_REGISTERED;
break;
case CALL_FORWARD_ACTION_ERASURE:
options.statusMessage = MMI_SM_KS_SERVICE_ERASED;
break;
}
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_QUERY_CALL_WAITING] =

View File

@ -1,156 +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 setCallForwardSuccess(procedure, serviceCode, sia, sib, sic) {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
context.RIL.setCallForward = function fakeSetCallForward(options) {
context.RIL[REQUEST_SET_CALL_FORWARD](0, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions(procedure, serviceCode, sia, sib,
sic)});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
}
add_test(function test_sendMMI_call_forwarding_activation() {
setCallForwardSuccess("*", "21", "12345", "99", "10");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_deactivation() {
setCallForwardSuccess("#", "21", "12345", "99", "10");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_interrogation() {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
context.Buf.readInt32 = function fakeReadUint32() {
return context.Buf.int32Array.pop();
};
context.Buf.readString = function fakeReadString() {
return "+34666222333";
};
context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) {
context.Buf.int32Array = [
0, // rules.timeSeconds
145, // rules.toa
49, // rules.serviceClass
CALL_FORWARD_REASON_UNCONDITIONAL, // rules.reason
1, // rules.active
1 // rulesLength
];
context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*#", "21")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, undefined);
ok(Array.isArray(postedMessage.rules));
equal(postedMessage.rules.length, 1);
ok(postedMessage.rules[0].active);
equal(postedMessage.rules[0].reason, CALL_FORWARD_REASON_UNCONDITIONAL);
equal(postedMessage.rules[0].number, "+34666222333");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_interrogation_no_rules() {
let workerhelper = newInterceptWorker();
let worker = workerhelper.worker;
let context = worker.ContextPool._contexts[0];
context.Buf.readInt32 = function fakeReadUint32() {
return 0;
};
context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) {
context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, {});
};
context.RIL.radioState = GECKO_RADIOSTATE_ENABLED;
context.RIL.sendMMI({mmi: createMMIOptions("*#", "21")});
let postedMessage = workerhelper.postedMessage;
equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE);
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_registration() {
setCallForwardSuccess("**", "21", "12345", "99", "10");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_erasure() {
setCallForwardSuccess("##", "21", "12345", "99");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_CFB() {
setCallForwardSuccess("*", "67", "12345", "99", "10");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_CFNRy() {
setCallForwardSuccess("*", "61", "12345", "99", "10");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_CFNRc() {
setCallForwardSuccess("*", "62", "12345", "99", "10");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_CFAll() {
setCallForwardSuccess("*", "004", "12345", "99", "10");
run_next_test();
});
add_test(function test_sendMMI_call_forwarding_CFAllConditional() {
setCallForwardSuccess("*", "002", "12345", "99", "10");
run_next_test();
});

View File

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

View File

@ -23,8 +23,6 @@ const GONK_TELEPHONYSERVICE_CONTRACTID =
const GONK_TELEPHONYSERVICE_CID =
Components.ID("{67d26434-d063-4d28-9f48-5b3189788155}");
const MOBILECALLFORWARDINGOPTIONS_CID =
Components.ID("{79b5988b-9436-48d8-a652-88fa033f146c}");
const TELEPHONYCALLINFO_CID =
Components.ID("{d9e8b358-a02c-4cf3-9fc7-816c2e8d46e4}");
@ -54,6 +52,13 @@ const DIAL_ERROR_RADIO_NOT_AVAILABLE = RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE;
const TONES_GAP_DURATION = 70;
// Consts for MMI.
const CF_ACTION_TO_STATUS_MESSAGE = {};
CF_ACTION_TO_STATUS_MESSAGE[Ci.nsIMobileConnection.CALL_FORWARD_ACTION_ENABLE] = RIL.MMI_SM_KS_SERVICE_ENABLED;
CF_ACTION_TO_STATUS_MESSAGE[Ci.nsIMobileConnection.CALL_FORWARD_ACTION_DISABLE] = RIL.MMI_SM_KS_SERVICE_DISABLED;
CF_ACTION_TO_STATUS_MESSAGE[Ci.nsIMobileConnection.CALL_FORWARD_ACTION_REGISTRATION] = RIL.MMI_SM_KS_SERVICE_REGISTERED;
CF_ACTION_TO_STATUS_MESSAGE[Ci.nsIMobileConnection.CALL_FORWARD_ACTION_ERASURE] = RIL.MMI_SM_KS_SERVICE_ERASED;
let DEBUG;
function debug(s) {
dump("TelephonyService: " + s + "\n");
@ -96,30 +101,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PhoneNumberUtils",
XPCOMUtils.defineLazyModuleGetter(this, "DialNumberUtils",
"resource://gre/modules/DialNumberUtils.jsm");
function MobileCallForwardingOptions(aOptions) {
for (let key in aOptions) {
this[key] = aOptions[key];
}
}
MobileCallForwardingOptions.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileCallForwardingOptions]),
classID: MOBILECALLFORWARDINGOPTIONS_CID,
classInfo: XPCOMUtils.generateCI({
classID: MOBILECALLFORWARDINGOPTIONS_CID,
classDescription: "MobileCallForwardingOptions",
interfaces: [Ci.nsIMobileCallForwardingOptions]
}),
// nsIMobileForwardingOptions
active: false,
action: nsIMobileConnection.CALL_FORWARD_ACTION_UNKNOWN,
reason: nsIMobileConnection.CALL_FORWARD_REASON_UNKNOWN,
number: null,
timeSeconds: -1,
serviceClass: nsIMobileConnection.ICC_SERVICE_CLASS_NONE
};
function TelephonyCallInfo(aCall) {
this.clientId = aCall.clientId;
this.callIndex = aCall.callIndex;
@ -403,10 +384,6 @@ TelephonyService.prototype = {
}
},
_rulesToCallForwardingOptions: function(aRules) {
return aRules.map(rule => new MobileCallForwardingOptions(rule));
},
_updateDebugFlag: function() {
try {
DEBUG = RIL.DEBUG_RIL ||
@ -844,8 +821,6 @@ TelephonyService.prototype = {
* Parsed MMI structure.
* @param aCallback
* A nsITelephonyDialCallback object.
* @param aStartNewSession
* True to start a new session for ussd request.
*/
_dialMMI: function(aClientId, aMmi, aCallback) {
let mmiServiceCode = aMmi ?
@ -853,6 +828,22 @@ TelephonyService.prototype = {
aCallback.notifyDialMMI(mmiServiceCode);
// We check if the MMI service code is supported and in that case we
// trigger the appropriate RIL request if possible.
switch (mmiServiceCode) {
// Call Forwarding
case RIL.MMI_KS_SC_CALL_FORWARDING:
this._callForwardingMMI(aClientId, aMmi, aCallback);
break;
// Fall back to "sendMMI".
default:
this._sendMMI(aClientId, aMmi, aCallback);
break;
}
},
_sendMMI: function(aClientId, aMmi, aCallback) {
this._sendToRilWorker(aClientId, "sendMMI",
{ mmi: aMmi }, response => {
if (DEBUG) debug("MMI response: " + JSON.stringify(response));
@ -876,28 +867,6 @@ TelephonyService.prototype = {
return;
}
// MMI query call forwarding options request returns a set of rules that
// will be exposed in the form of an array of MozCallForwardingOptions
// instances.
if (mmiServiceCode === RIL.MMI_KS_SC_CALL_FORWARDING) {
if (response.isSetCallForward) {
gGonkMobileConnectionService.notifyCFStateChanged(aClientId,
response.action,
response.reason,
response.number,
response.timeSeconds,
response.serviceClass);
}
if (response.additionalInformation != null) {
let callForwardingOptions =
this._rulesToCallForwardingOptions(response.additionalInformation);
aCallback.notifyDialMMISuccessWithCallForwardingOptions(
response.statusMessage, callForwardingOptions.length, callForwardingOptions);
return;
}
}
// No additional information
if (response.additionalInformation === undefined) {
aCallback.notifyDialMMISuccess(response.statusMessage);
@ -923,6 +892,54 @@ TelephonyService.prototype = {
});
},
/**
* Handle call forwarding MMI code.
*
* @param aClientId
* Client id.
* @param aMmi
* Parsed MMI structure.
* @param aCallback
* A nsITelephonyDialCallback object.
*/
_callForwardingMMI: function(aClientId, aMmi, aCallback) {
if (!this._isRadioOn(aClientId)) {
aCallback.notifyDialMMIError(RIL.GECKO_ERROR_RADIO_NOT_AVAILABLE);
return;
}
let connection = gGonkMobileConnectionService.getItemByServiceId(aClientId);
let action = RIL.MMI_PROC_TO_CF_ACTION[aMmi.procedure];
let reason = RIL.MMI_SC_TO_CF_REASON[aMmi.serviceCode];
if (action === Ci.nsIMobileConnection.CALL_FORWARD_ACTION_QUERY_STATUS) {
connection.getCallForwarding(reason, {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionCallback]),
notifyGetCallForwardingSuccess: function(aCount, aResults) {
aCallback.notifyDialMMISuccessWithCallForwardingOptions(
RIL.MMI_SM_KS_SERVICE_INTERROGATED, aCount, aResults);
},
notifyError: function(aErrorMsg) {
aCallback.notifyDialMMIError(aErrorMsg);
},
});
} else {
let number = aMmi.sia;
let serviceClass = this._siToServiceClass(aMmi.sib);
let timeSeconds = aMmi.sic;
connection.setCallForwarding(action, reason, number, timeSeconds,
serviceClass, {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionCallback]),
notifySuccess: function() {
aCallback.notifyDialMMISuccess(CF_ACTION_TO_STATUS_MESSAGE[action]);
},
notifyError: function(aErrorMsg) {
aCallback.notifyDialMMIError(aErrorMsg);
},
});
}
},
_serviceCodeToKeyString: function(aServiceCode) {
switch (aServiceCode) {
case RIL.MMI_SC_CFU:
@ -964,6 +981,50 @@ TelephonyService.prototype = {
}
},
/**
* Helper for translating basic service group to service class parameter.
*/
_siToServiceClass: function(aSi) {
if (!aSi) {
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_NONE;
}
let serviceCode = parseInt(aSi, 10);
switch (serviceCode) {
case 10:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_SMS +
Ci.nsIMobileConnection.ICC_SERVICE_CLASS_FAX +
Ci.nsIMobileConnection.ICC_SERVICE_CLASS_VOICE;
case 11:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_VOICE;
case 12:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_SMS +
Ci.nsIMobileConnection.ICC_SERVICE_CLASS_FAX;
case 13:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_FAX;
case 16:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_SMS;
case 19:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_FAX +
Ci.nsIMobileConnection.ICC_SERVICE_CLASS_VOICE;
case 21:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_PAD +
Ci.nsIMobileConnection.ICC_SERVICE_CLASS_DATA_ASYNC;
case 22:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_PACKET +
Ci.nsIMobileConnection.ICC_SERVICE_CLASS_DATA_SYNC;
case 25:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_DATA_ASYNC;
case 26:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_DATA_SYNC +
Ci.nsIMobileConnection.ICC_SERVICE_CLASS_VOICE;
case 99:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_PACKET;
default:
return Ci.nsIMobileConnection.ICC_SERVICE_CLASS_NONE;
}
},
/**
* The default callback handler for call operations.
*