Bug 869778 - Part 3: RIL implementation for CDMA MIN. r=allstars.chh
authorEdgar Chen <echen@mozilla.com>
Mon, 12 Aug 2013 14:59:17 +0800
changeset 145436 2d4c400127af9d432cd3cefb874479784a9b5017
parent 145435 ff5b29debc08c6fb3823afa70e0cbe8db65e2e10
child 145437 65938897536e4f6a39568ebe442e5f2eafe49f08
push id713
push userechen@mozilla.com
push dateWed, 04 Sep 2013 15:04:28 +0000
treeherderb2g-inbound@9dcc96e41330 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersallstars
bugs869778
milestone26.0a1
Bug 869778 - Part 3: RIL implementation for CDMA MIN. r=allstars.chh
dom/system/gonk/RILContentHelper.js
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_consts.js
dom/system/gonk/ril_worker.js
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -40,18 +40,20 @@ if (DEBUG) {
     dump("-*- RILContentHelper: " + s + "\n");
   };
 } else {
   debug = function (s) {};
 }
 
 const RILCONTENTHELPER_CID =
   Components.ID("{472816e1-1fd6-4405-996c-806f9ea68174}");
-const ICCINFO_CID =
-  Components.ID("{fab2c0f0-d73a-11e2-8b8b-0800200c9a66}");
+const GSMICCINFO_CID =
+  Components.ID("{e0fa785b-ad3f-46ed-bc56-fcb0d6fe4fa8}");
+const CDMAICCINFO_CID =
+  Components.ID("{3d1f844f-9ec5-48fb-8907-aed2e5421709}");
 const MOBILECONNECTIONINFO_CID =
   Components.ID("{a35cfd39-2d93-4489-ac7d-396475dacb27}");
 const MOBILENETWORKINFO_CID =
   Components.ID("{a6c8416c-09b4-46d1-bf29-6520d677d085}");
 const MOBILECELLINFO_CID =
   Components.ID("{ae724dd4-ccaf-4006-98f1-6ce66a092464}");
 const VOICEMAILSTATUS_CID=
   Components.ID("{5467f2eb-e214-43ea-9b89-67711241ec8e}");
@@ -143,34 +145,60 @@ function MobileIccCardLockRetryCount(opt
 MobileIccCardLockRetryCount.prototype = {
   __exposedProps__ : {lockType: 'r',
                       retryCount: 'r',
                       success: 'r'}
 };
 
 function IccInfo() {}
 IccInfo.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozIccInfo]),
-  classID:        ICCINFO_CID,
-  classInfo:      XPCOMUtils.generateCI({
-    classID:          ICCINFO_CID,
-    classDescription: "IccInfo",
-    flags:            Ci.nsIClassInfo.DOM_OBJECT,
-    interfaces:       [Ci.nsIDOMMozIccInfo]
-  }),
-
-  // nsIDOMMozIccInfo
-
+  iccType: null,
   iccid: null,
   mcc: null,
   mnc: null,
   spn: null,
+  isDisplayNetworkNameRequired: null,
+  isDisplaySpnRequired: null
+};
+
+function GsmIccInfo() {}
+GsmIccInfo.prototype = {
+  __proto__: IccInfo.prototype,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozGsmIccInfo]),
+  classID: GSMICCINFO_CID,
+  classInfo: XPCOMUtils.generateCI({
+    classID:          GSMICCINFO_CID,
+    classDescription: "MozGsmIccInfo",
+    flags:            Ci.nsIClassInfo.DOM_OBJECT,
+    interfaces:       [Ci.nsIDOMMozGsmIccInfo]
+  }),
+
+  // nsIDOMMozGsmIccInfo
+
   msisdn: null
 };
 
+function CdmaIccInfo() {}
+CdmaIccInfo.prototype = {
+  __proto__: IccInfo.prototype,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozCdmaIccInfo]),
+  classID: CDMAICCINFO_CID,
+  classInfo: XPCOMUtils.generateCI({
+    classID:          CDMAICCINFO_CID,
+    classDescription: "MozCdmaIccInfo",
+    flags:            Ci.nsIClassInfo.DOM_OBJECT,
+    interfaces:       [Ci.nsIDOMMozCdmaIccInfo]
+  }),
+
+  // nsIDOMMozCdmaIccInfo
+
+  mdn: null,
+  min: null
+};
+
 function VoicemailInfo() {}
 VoicemailInfo.prototype = {
   number: null,
   displayName: null
 };
 
 function MobileConnectionInfo() {}
 MobileConnectionInfo.prototype = {
@@ -399,17 +427,17 @@ DOMMMIError.prototype = {
     this.additionalInformation = additionalInformation;
   },
 };
 
 function RILContentHelper() {
   this.rilContext = {
     cardState:            RIL.GECKO_CARDSTATE_UNKNOWN,
     networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
-    iccInfo:              new IccInfo(),
+    iccInfo:              null,
     voiceConnectionInfo:  new MobileConnectionInfo(),
     dataConnectionInfo:   new MobileConnectionInfo()
   };
   this.voicemailInfo = new VoicemailInfo();
 
   this.initDOMRequestHelper(/* aWindow */ null, RIL_IPC_MSG_NAMES);
   this._windowsMap = [];
   Services.obs.addObserver(this, "xpcom-shutdown", false);
@@ -467,17 +495,41 @@ RILContentHelper.prototype = {
     }
 
     let network = destInfo.network;
     if (!network) {
       network = destInfo.network = new MobileNetworkInfo();
     }
 
     this.updateInfo(srcNetwork, network);
- },
+  },
+
+  /**
+   * We need to consider below cases when update iccInfo:
+   * 1. Should clear iccInfo to null if there is no card detected.
+   * 2. Need to create corresponding object based on iccType.
+   */
+  updateIccInfo: function updateIccInfo(newInfo) {
+    // Card is not detected, clear iccInfo to null.
+    if (!newInfo || !newInfo.iccType) {
+      this.rilContext.iccInfo = null;
+      return;
+    }
+
+    // If iccInfo is null, new corresponding object based on iccType.
+    if (!this.rilContext.iccInfo) {
+      if (newInfo.iccType === "ruim" || newInfo.iccType === "csim") {
+        this.rilContext.iccInfo = new CdmaIccInfo();
+      } else {
+        this.rilContext.iccInfo = new GsmIccInfo();
+      }
+    }
+
+    this.updateInfo(newInfo, this.rilContext.iccInfo);
+  },
 
   _windowsMap: null,
 
   rilContext: null,
 
   getRilContext: function getRilContext() {
     // Update ril context by sending IPC message to chrome only when the first
     // time we require it. The information will be updated by following info
@@ -489,17 +541,17 @@ RILContentHelper.prototype = {
     let rilContext =
       cpmm.sendSyncMessage("RIL:GetRilContext", {clientId: 0})[0];
     if (!rilContext) {
       debug("Received null rilContext from chrome process.");
       return;
     }
     this.rilContext.cardState = rilContext.cardState;
     this.rilContext.networkSelectionMode = rilContext.networkSelectionMode;
-    this.updateInfo(rilContext.iccInfo, this.rilContext.iccInfo);
+    this.updateIccInfo(rilContext.iccInfo);
     this.updateConnectionInfo(rilContext.voice, this.rilContext.voiceConnectionInfo);
     this.updateConnectionInfo(rilContext.data, this.rilContext.dataConnectionInfo);
 
     return this.rilContext;
   },
 
   /**
    * nsIMobileConnectionProvider
@@ -1541,17 +1593,17 @@ RILContentHelper.prototype = {
           this.rilContext.cardState = data.cardState;
           this._deliverEvent("_iccListeners",
                              "notifyCardStateChanged",
                              null);
         }
         break;
       }
       case "RIL:IccInfoChanged":
-        this.updateInfo(msg.json.data, this.rilContext.iccInfo);
+        this.updateIccInfo(msg.json.data);
         this._deliverEvent("_iccListeners", "notifyIccInfoChanged", null);
         break;
       case "RIL:VoiceInfoChanged":
         this.updateConnectionInfo(msg.json.data,
                                   this.rilContext.voiceConnectionInfo);
         this._deliverEvent("_mobileConnectionListeners",
                            "notifyVoiceChanged",
                            null);
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -2217,31 +2217,24 @@ RadioInterface.prototype = {
     gMessageManager.sendVoicemailMessage("RIL:VoicemailInfoChanged",
                                          this.clientId, voicemailInfo);
   },
 
   handleIccInfoChange: function handleIccInfoChange(message) {
     let oldIccInfo = this.rilContext.iccInfo;
     this.rilContext.iccInfo = message;
 
-    let iccInfoChanged = !oldIccInfo ||
-                          oldIccInfo.iccid != message.iccid ||
-                          oldIccInfo.mcc != message.mcc ||
-                          oldIccInfo.mnc != message.mnc ||
-                          oldIccInfo.spn != message.spn ||
-                          oldIccInfo.isDisplayNetworkNameRequired != message.isDisplayNetworkNameRequired ||
-                          oldIccInfo.isDisplaySpnRequired != message.isDisplaySpnRequired ||
-                          oldIccInfo.msisdn != message.msisdn;
-    if (!iccInfoChanged) {
+    if (!this.isInfoChanged(message, oldIccInfo)) {
       return;
     }
     // RIL:IccInfoChanged corresponds to a DOM event that gets fired only
-    // when the MCC or MNC codes have changed.
+    // when iccInfo has changed.
     gMessageManager.sendIccMessage("RIL:IccInfoChanged",
-                                   this.clientId, message);
+                                   this.clientId,
+                                   message.iccType ? message : null);
 
     // Update lastKnownSimMcc.
     if (message.mcc) {
       try {
         Services.prefs.setCharPref("ril.lastKnownSimMcc",
                                    message.mcc.toString());
       } catch (e) {}
     }
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -365,16 +365,25 @@ this.CARD_APPTYPE_UNKNOWN = 0;
 this.CARD_APPTYPE_SIM = 1;
 this.CARD_APPTYPE_USIM = 2;
 this.CARD_APPTYPE_RUIM = 3;
 this.CARD_APPTYPE_CSIM = 4;
 this.CARD_APPTYPE_ISIM = 5;
 
 this.CARD_MAX_APPS = 8;
 
+this.GECKO_CARD_TYPE = [
+  null,
+  "sim",
+  "usim",
+  "ruim",
+  "csim",
+  "isim"
+];
+
 this.NETWORK_STATE_UNKNOWN = "unknown";
 this.NETWORK_STATE_AVAILABLE = "available";
 this.NETWORK_STATE_CONNECTED = "connected";
 this.NETWORK_STATE_FORBIDDEN = "forbidden";
 
 this.NETWORK_SELECTION_MODE_AUTOMATIC = 0;
 this.NETWORK_SELECTION_MODE_MANUAL = 1;
 
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -1309,16 +1309,20 @@ let RIL = {
   getBasebandVersion: function getBasebandVersion() {
     Buf.simpleRequest(REQUEST_BASEBAND_VERSION);
   },
 
   sendExitEmergencyCbModeRequest: function sendExitEmergencyCbModeRequest(options) {
     Buf.simpleRequest(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, options);
   },
 
+  getCdmaSubscription: function getCdmaSubscription() {
+    Buf.simpleRequest(REQUEST_CDMA_SUBSCRIPTION);
+  },
+
   exitEmergencyCbMode: function exitEmergencyCbMode(options) {
     // The function could be called by an API from RadioInterfaceLayer or by
     // ril_worker itself. From ril_worker, we won't pass the parameter
     // 'options'. In this case, it is marked as internal.
     if (!options) {
       options = {internal: true};
     }
     this._cancelEmergencyCbModeTimeout();
@@ -2924,16 +2928,19 @@ let RIL = {
             debug("ICC absent");
           }
           newCardState = GECKO_CARDSTATE_ABSENT;
           break;
       }
       if (newCardState == this.cardState) {
         return;
       }
+      this.iccInfo = {iccType: null};
+      ICCUtilsHelper.handleICCInfoChange();
+
       this.cardState = newCardState;
       this.sendChromeMessage({rilMessageType: "cardstatechange",
                               cardState: this.cardState});
       return;
     }
 
     let index = this._isCdma ? iccStatus.cdmaSubscriptionAppIndex :
                                iccStatus.gsmUmtsSubscriptionAppIndex;
@@ -2975,16 +2982,18 @@ let RIL = {
 
     if (this.cardState == newCardState) {
       return;
     }
 
     // This was moved down from CARD_APPSTATE_READY
     this.requestNetworkInfo();
     if (newCardState == GECKO_CARDSTATE_READY) {
+      this.iccInfo.iccType = GECKO_CARD_TYPE[this.appType];
+
       // For type SIM, we need to check EF_phase first.
       // Other types of ICC we can send Terminal_Profile immediately.
       if (this.appType == CARD_APPTYPE_SIM) {
         ICCRecordHelper.readICCPhase();
         ICCRecordHelper.fetchICCRecords();
       } else if (this.appType == CARD_APPTYPE_USIM) {
         this.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
         ICCRecordHelper.fetchICCRecords();
@@ -5758,17 +5767,31 @@ RIL[REQUEST_GSM_SET_BROADCAST_SMS_CONFIG
   if (options.rilRequestError == ERROR_SUCCESS) {
     this.setSmsBroadcastActivation(true);
   }
 };
 RIL[REQUEST_GSM_SMS_BROADCAST_ACTIVATION] = null;
 RIL[REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG] = null;
 RIL[REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG] = null;
 RIL[REQUEST_CDMA_SMS_BROADCAST_ACTIVATION] = null;
-RIL[REQUEST_CDMA_SUBSCRIPTION] = null;
+RIL[REQUEST_CDMA_SUBSCRIPTION] = function REQUEST_CDMA_SUBSCRIPTION(length, options) {
+  if (options.rilRequestError) {
+    return;
+  }
+
+  let result = Buf.readStringList();
+
+  this.iccInfo.mdn = result[0];
+  // The result[1] is Home SID. (Already be handled in readCDMAHome())
+  // The result[2] is Home NID. (Already be handled in readCDMAHome())
+  this.iccInfo.min = result[3];
+  // The result[4] is PRL version.
+
+  ICCUtilsHelper.handleICCInfoChange();
+};
 RIL[REQUEST_CDMA_WRITE_SMS_TO_RUIM] = null;
 RIL[REQUEST_CDMA_DELETE_SMS_ON_RUIM] = null;
 RIL[REQUEST_DEVICE_IDENTITY] = function REQUEST_DEVICE_IDENTITY(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   let result = Buf.readStringList();
@@ -12755,16 +12778,17 @@ let ICCContactHelper = {
 };
 
 let RuimRecordHelper = {
   fetchRuimRecords: function fetchRuimRecords() {
     ICCRecordHelper.readICCID();
     RIL.getIMSI();
     this.readCST();
     this.readCDMAHome();
+    RIL.getCdmaSubscription();
   },
 
   /**
    * Read CDMAHOME for CSIM.
    * See 3GPP2 C.S0023 Sec. 3.4.8.
    */
   readCDMAHome: function readCDMAHome() {
     function callback(options) {