diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index e7f2af5754b..08f5bfa9b8c 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -189,6 +189,9 @@ function RadioInterfaceLayer() { let lock = gSettingsService.createLock(); lock.get("ril.radio.disabled", this); + // Read preferred network type from the setting DB. + lock.get("ril.radio.preferredNetworkType", this); + // Read the APN data form the setting DB. lock.get("ril.data.apn", this); lock.get("ril.data.user", this); @@ -470,6 +473,9 @@ RadioInterfaceLayer.prototype = { case "stksessionend": ppmm.broadcastAsyncMessage("RIL:StkSessionEnd", null); break; + case "setPreferredNetworkType": + this.handleSetPreferredNetworkType(message); + break; default: throw new Error("Don't know about this message type: " + message.rilMessageType); @@ -643,6 +649,39 @@ RadioInterfaceLayer.prototype = { this.updateRILNetworkInterface(); }, + _preferredNetworkType: null, + setPreferredNetworkType: function setPreferredNetworkType(value) { + let networkType = RIL.RIL_PREFERRED_NETWORK_TYPE_TO_GECKO.indexOf(value); + if (networkType < 0) { + gSettingsService.createLock().set("ril.radio.preferredNetworkType", + this._preferredNetworkType || RIL.GECKO_PREFERRED_NETWORK_TYPE_DEFAULT, + false); + return; + } + + if (networkType == this._preferredNetworkType) { + return; + } + + this.worker.postMessage({rilMessageType: "setPreferredNetworkType", + networkType: networkType}); + + this._ensureRadioState(); + }, + + handleSetPreferredNetworkType: function handleSetPreferredNetworkType(message) { + if ((this._preferredNetworkType != null) && !message.success) { + gSettingsService.createLock().set("ril.radio.preferredNetworkType", + this._preferredNetworkType, + false); + return; + } + + this._preferredNetworkType = message.networkType; + debug("_preferredNetworkType is now " + + RIL.RIL_PREFERRED_NETWORK_TYPE_TO_GECKO[this._preferredNetworkType]); + }, + handleSignalStrengthChange: function handleSignalStrengthChange(message) { let voiceInfo = this.rilContext.voice; // TODO CDMA, EVDO, LTE, etc. (see bug 726098) @@ -704,6 +743,11 @@ RadioInterfaceLayer.prototype = { // Wait for that. return; } + if (this._preferredNetworkType == null) { + // We haven't read the initial value from the settings DB yet. + // Wait for that. + return; + } if (!this._sysMsgListenerReady) { // The UI's system app isn't ready yet for us to receive any // events (e.g. incoming SMS, etc.). Wait for that. @@ -1203,6 +1247,10 @@ RadioInterfaceLayer.prototype = { this._radioEnabled = !aResult; this._ensureRadioState(); break; + case "ril.radio.preferredNetworkType": + debug("'ril.radio.preferredNetworkType' is now " + aResult); + this.setPreferredNetworkType(aResult); + break; case "ril.data.enabled": this._oldRilDataEnabledState = this.dataCallSettings["enabled"]; // Fall through! diff --git a/dom/system/gonk/ril_consts.js b/dom/system/gonk/ril_consts.js index 776041e5c68..47c4a5f54cf 100644 --- a/dom/system/gonk/ril_consts.js +++ b/dom/system/gonk/ril_consts.js @@ -335,18 +335,15 @@ const NETWORK_INFO_MESSAGE_TYPES = [ NETWORK_INFO_NETWORK_SELECTION_MODE ]; -const PREFERRED_NETWORK_TYPE_GSM_WCDMA = 0; -const PREFERRED_NETWORK_TYPE_GSM_ONLY = 1; -const PREFERRED_NETWORK_TYPE_WCDMA = 2; -const PREFERRED_NETWORK_TYPE_GSM_WCDMA_AUTO = 3; -const PREFERRED_NETWORK_TYPE_CDMA_EVDO_AUTO = 4; -const PREFERRED_NETWORK_TYPE_CDMA_ONLY = 5; -const PREFERRED_NETWORK_TYPE_EVDO_ONLY = 6; -const PREFERRED_NETWORK_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7; -const PREFERRED_NETWORK_TYPE_LTE_CDMA_EVDO = 8; -const PREFERRED_NETWORK_TYPE_LTE_GSM_WCDMA = 9; -const PREFERRED_NETWORK_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10; -const PREFERRED_NETWORK_TYPE_LTE_ONLY = 11; +const GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM = "wcdma/gsm"; +const GECKO_PREFERRED_NETWORK_TYPE_GSM_ONLY = "gsm"; +const GECKO_PREFERRED_NETWORK_TYPE_WCDMA_ONLY = "wcdma"; +const GECKO_PREFERRED_NETWORK_TYPE_DEFAULT = GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM; +const RIL_PREFERRED_NETWORK_TYPE_TO_GECKO = [ + GECKO_PREFERRED_NETWORK_TYPE_WCDMA_GSM, + GECKO_PREFERRED_NETWORK_TYPE_GSM_ONLY, + GECKO_PREFERRED_NETWORK_TYPE_WCDMA_ONLY +]; // Network registration states. See TS 27.007 7.2 const NETWORK_CREG_STATE_NOT_SEARCHING = 0; diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index a5e1b206606..a1a1ffb864f 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -604,6 +604,12 @@ let RIL = { */ _pendingSentSmsMap: {}, + /** + * Index of the RIL_PREFERRED_NETWORK_TYPE_TO_GECKO. Its value should be + * preserved over rild reset. + */ + preferredNetworkType: null, + initRILState: function initRILState() { /** * One of the RADIO_STATE_* constants. @@ -1681,15 +1687,32 @@ let RIL = { /** * Set the preferred network type. * - * @param network_type - * The network type. One of the PREFERRED_NETWORK_TYPE_* constants. + * @param options An object contains a valid index of + * RIL_PREFERRED_NETWORK_TYPE_TO_GECKO as its `networkType` + * attribute, or undefined to set current preferred network + * type. */ - setPreferredNetworkType: function setPreferredNetworkType(network_type) { - Buf.newParcel(REQUEST_SET_PREFERRED_NETWORK_TYPE); - Buf.writeUint32(network_type); + setPreferredNetworkType: function setPreferredNetworkType(options) { + if (options) { + this.preferredNetworkType = options.networkType; + } + if (this.preferredNetworkType == null) { + return; + } + + Buf.newParcel(REQUEST_SET_PREFERRED_NETWORK_TYPE, options); + Buf.writeUint32(1); + Buf.writeUint32(this.preferredNetworkType); Buf.sendParcel(); }, + /** + * Get the preferred network type. + */ + getPreferredNetworkType: function getPreferredNetworkType() { + Buf.simpleRequest(REQUEST_GET_PREFERRED_NETWORK_TYPE); + }, + /** * Request various states about the network. */ @@ -3999,8 +4022,33 @@ RIL[REQUEST_STK_SEND_ENVELOPE_COMMAND] = null; RIL[REQUEST_STK_SEND_TERMINAL_RESPONSE] = null; RIL[REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM] = null; RIL[REQUEST_EXPLICIT_CALL_TRANSFER] = null; -RIL[REQUEST_SET_PREFERRED_NETWORK_TYPE] = null; -RIL[REQUEST_GET_PREFERRED_NETWORK_TYPE] = null; +RIL[REQUEST_SET_PREFERRED_NETWORK_TYPE] = function REQUEST_SET_PREFERRED_NETWORK_TYPE(length, options) { + if (options.networkType == null) { + // The request was made by ril_worker itself automatically. Don't report. + return; + } + + this.sendDOMMessage({ + rilMessageType: "setPreferredNetworkType", + networkType: options.networkType, + success: options.rilRequestError == ERROR_SUCCESS + }); +}; +RIL[REQUEST_GET_PREFERRED_NETWORK_TYPE] = function REQUEST_GET_PREFERRED_NETWORK_TYPE(length, options) { + let networkType; + if (!options.rilRequestError) { + networkType = RIL_PREFERRED_NETWORK_TYPE_TO_GECKO.indexOf(GECKO_PREFERRED_NETWORK_TYPE_DEFAULT); + if (Buf.readUint32()) { + this.preferredNetworkType = networkType = Buf.readUint32(); + } + } + + this.sendDOMMessage({ + rilMessageType: "getPreferredNetworkType", + networkType: networkType, + success: options.rilRequestError == ERROR_SUCCESS + }); +}; RIL[REQUEST_GET_NEIGHBORING_CELL_IDS] = null; RIL[REQUEST_SET_LOCATION_UPDATES] = null; RIL[REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE] = null; @@ -4233,6 +4281,8 @@ RIL[UNSOLICITED_RIL_CONNECTED] = function UNSOLICITED_RIL_CONNECTED(length) { } this.initRILState(); + + this.setPreferredNetworkType(); }; /**