Bug 787420: support set/get preferred network type, r=philikon
authorVicamo Yang <vyang@mozilla.com>
Sat, 22 Sep 2012 11:02:05 +0800
changeset 111383 a5ad096174ea38afbd8d61ac3d99ad351bd8b2bf
parent 111382 d3319e868a9275aba607378ab8df1399eee9d9a0
child 111384 7c8b8d36679ff71e4b01e49a65674dfdb3b58253
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphilikon
bugs787420
milestone18.0a1
Bug 787420: support set/get preferred network type, r=philikon
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_consts.js
dom/system/gonk/ril_worker.js
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -184,16 +184,19 @@ function RadioInterfaceLayer() {
 
   this.callWaitingStatus = null;
 
   // Read the 'ril.radio.disabled' setting in order to start with a known
   // value at boot time.
   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);
   lock.get("ril.data.passwd", this);
   lock.get("ril.data.httpProxyHost", this);
   lock.get("ril.data.httpProxyPort", this);
   lock.get("ril.data.roaming_enabled", this);
   lock.get("ril.data.enabled", this);
@@ -465,16 +468,19 @@ RadioInterfaceLayer.prototype = {
         this.handleCancelUSSD(message);
         break;
       case "stkcommand":
         this.handleStkProactiveCommand(message);
         break;
       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);
     }
   },
 
   _messageManagerByRequest: null,
   saveRequestTarget: function saveRequestTarget(msg) {
@@ -638,16 +644,49 @@ RadioInterfaceLayer.prototype = {
     }
 
     if (!newInfo.batch) {
       ppmm.broadcastAsyncMessage("RIL:DataInfoChanged", dataInfo);
     }
     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)
     if (voiceInfo.signalStrength != message.gsmDBM ||
         voiceInfo.relSignalStrength != message.gsmRelative) {
       voiceInfo.signalStrength = message.gsmDBM;
       voiceInfo.relSignalStrength = message.gsmRelative;
       ppmm.broadcastAsyncMessage("RIL:VoiceInfoChanged", voiceInfo);
@@ -699,16 +738,21 @@ RadioInterfaceLayer.prototype = {
   _ensureRadioState: function _ensureRadioState() {
     debug("Reported radio state is " + this.rilContext.radioState +
           ", desired radio enabled state is " + this._radioEnabled);
     if (this._radioEnabled == null) {
       // We haven't read the initial value from the settings DB yet.
       // 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.
       return;
     }
     if (this.rilContext.radioState == RIL.GECKO_RADIOSTATE_UNKNOWN) {
       // We haven't received a radio state notification from the RIL
       // yet. Wait for that.
@@ -1198,16 +1242,20 @@ RadioInterfaceLayer.prototype = {
 
   handle: function handle(aName, aResult) {
     switch(aName) {
       case "ril.radio.disabled":
         debug("'ril.radio.disabled' is now " + aResult);
         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!
       case "ril.data.roaming_enabled":
       case "ril.data.apn":
       case "ril.data.user":
       case "ril.data.passwd":
       case "ril.data.httpProxyHost":
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -330,28 +330,25 @@ const NETWORK_INFO_OPERATOR = "operator"
 const NETWORK_INFO_NETWORK_SELECTION_MODE = "networkSelectionMode";
 const NETWORK_INFO_MESSAGE_TYPES = [
   NETWORK_INFO_VOICE_REGISTRATION_STATE,
   NETWORK_INFO_DATA_REGISTRATION_STATE,
   NETWORK_INFO_OPERATOR,
   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;
 const NETWORK_CREG_STATE_REGISTERED_HOME = 1;
 const NETWORK_CREG_STATE_SEARCHING = 2;
 const NETWORK_CREG_STATE_DENIED = 3;
 const NETWORK_CREG_STATE_UNKNOWN = 4;
 const NETWORK_CREG_STATE_REGISTERED_ROAMING = 5;
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -599,16 +599,22 @@ let RIL = {
    */
   _receivedSmsSegmentsMap: {},
 
   /**
    * Outgoing messages waiting for SMS-STATUS-REPORT.
    */
   _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.
      */
     this.radioState = GECKO_RADIOSTATE_UNAVAILABLE;
     this._isInitialRadioState = true;
 
     /**
@@ -1676,26 +1682,43 @@ let RIL = {
 
   getOperator: function getOperator() {
     Buf.simpleRequest(REQUEST_OPERATOR);
   },
 
   /**
    * 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.
    */
   requestNetworkInfo: function requestNetworkInfo() {
     if (this._processingNetworkInfo) {
       if (DEBUG) debug("Network info requested, but we're already requesting network info.");
       return;
     }
 
@@ -3994,18 +4017,43 @@ RIL[REQUEST_DELETE_SMS_ON_SIM] = null;
 RIL[REQUEST_SET_BAND_MODE] = null;
 RIL[REQUEST_QUERY_AVAILABLE_BAND_MODE] = null;
 RIL[REQUEST_STK_GET_PROFILE] = null;
 RIL[REQUEST_STK_SET_PROFILE] = null;
 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;
 RIL[REQUEST_CDMA_SET_ROAMING_PREFERENCE] = null;
 RIL[REQUEST_CDMA_QUERY_ROAMING_PREFERENCE] = null;
 RIL[REQUEST_SET_TTY_MODE] = null;
 RIL[REQUEST_QUERY_TTY_MODE] = null;
 RIL[REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE] = null;
@@ -4228,16 +4276,18 @@ RIL[UNSOLICITED_RIL_CONNECTED] = functio
   let version = Buf.readUint32List()[0];
   RILQUIRKS_V5_LEGACY = (version < 5);
   if (DEBUG) {
     debug("Detected RIL version " + version);
     debug("RILQUIRKS_V5_LEGACY is " + RILQUIRKS_V5_LEGACY);
   }
 
   this.initRILState();
+
+  this.setPreferredNetworkType();
 };
 
 /**
  * This object exposes the functionality to parse and serialize PDU strings
  *
  * A PDU is a string containing a series of hexadecimally encoded octets
  * or nibble-swapped binary-coded decimals (BCDs). It contains not only the
  * message text but information about the sender, the SMS service center,