diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index a3dfa8279e8..8d24c066ffd 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -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] = diff --git a/dom/system/gonk/tests/test_ril_worker_mmi_cf.js b/dom/system/gonk/tests/test_ril_worker_mmi_cf.js deleted file mode 100644 index 1362b313ef0..00000000000 --- a/dom/system/gonk/tests/test_ril_worker_mmi_cf.js +++ /dev/null @@ -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(); -}); diff --git a/dom/system/gonk/tests/xpcshell.ini b/dom/system/gonk/tests/xpcshell.ini index 97acee85db8..661dd16d196 100644 --- a/dom/system/gonk/tests/xpcshell.ini +++ b/dom/system/gonk/tests/xpcshell.ini @@ -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] diff --git a/dom/telephony/gonk/TelephonyService.js b/dom/telephony/gonk/TelephonyService.js index bb3b6d9cf98..d49c2b98e31 100644 --- a/dom/telephony/gonk/TelephonyService.js +++ b/dom/telephony/gonk/TelephonyService.js @@ -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. *