Bug 1072367 - Part 3: broadcast system message "cdma-info-rec-received" in MobileConnectionService. r=echen
authorBevis Tseng <btseng@mozilla.com>
Fri, 03 Oct 2014 14:23:41 +0800
changeset 210136 dcf3a8f45e6c63d43dbbb524528ccf361e43e154
parent 210135 80c3e34f21ff2a1b0a034b0fcea18a399cc3a6ac
child 210137 f926c956c3cdefda45099281ddce8ceb60cefe10
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersechen
bugs1072367
milestone35.0a1
Bug 1072367 - Part 3: broadcast system message "cdma-info-rec-received" in MobileConnectionService. r=echen
dom/mobileconnection/gonk/MobileConnectionService.js
dom/mobileconnection/gonk/nsIGonkMobileConnectionService.idl
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_worker.js
dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
--- a/dom/mobileconnection/gonk/MobileConnectionService.js
+++ b/dom/mobileconnection/gonk/MobileConnectionService.js
@@ -945,16 +945,21 @@ MobileConnectionService.prototype = {
 
   _updateDebugFlag: function() {
     try {
       DEBUG = RIL.DEBUG_RIL ||
               Services.prefs.getBoolPref(kPrefRilDebuggingEnabled);
     } catch (e) {}
   },
 
+  _broadcastCdmaInfoRecordSystemMessage: function(aMessage) {
+    // TODO: Bug 1072808, Broadcast System Message with proxy.
+    gSystemMessenger.broadcastMessage("cdma-info-rec-received", aMessage);
+  },
+
   /**
    * nsIMobileConnectionService interface.
    */
   get numItems() {
     return this._providers.length;
   },
 
   getItemByServiceId: function(aServiceId) {
@@ -1162,16 +1167,121 @@ MobileConnectionService.prototype = {
       debug("notifyCFStateChanged for " + aClientId);
     }
 
     let provider = this.getItemByServiceId(aClientId);
     provider.notifyCFStateChanged(aAction, aReason, aNumber, aTimeSeconds,
                                   aServiceClass);
   },
 
+  notifyCdmaInfoRecDisplay: function(aClientId, aDisplay) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      display: aDisplay
+    });
+  },
+
+  notifyCdmaInfoRecCalledPartyNumber: function(aClientId, aType, aPlan, aNumber,
+                                               aPi, aSi) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      calledNumber: {
+        type: aType,
+        plan: aPlan,
+        number: aNumber,
+        pi: aPi,
+        si: aSi
+      }
+    });
+  },
+
+  notifyCdmaInfoRecCallingPartyNumber: function(aClientId, aType, aPlan, aNumber,
+                                                aPi, aSi) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      callingNumber: {
+        type: aType,
+        plan: aPlan,
+        number: aNumber,
+        pi: aPi,
+        si: aSi
+      }
+    });
+  },
+
+  notifyCdmaInfoRecConnectedPartyNumber: function(aClientId, aType, aPlan, aNumber,
+                                                  aPi, aSi) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      connectedNumber: {
+        type: aType,
+        plan: aPlan,
+        number: aNumber,
+        pi: aPi,
+        si: aSi
+      }
+    });
+  },
+
+  notifyCdmaInfoRecSignal: function(aClientId, aType, aAlertPitch, aSignal){
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      signal: {
+        type: aType,
+        alertPitch: aAlertPitch,
+        signal: aSignal
+      }
+    });
+  },
+
+  notifyCdmaInfoRecRedirectingNumber: function(aClientId, aType, aPlan, aNumber,
+                                               aPi, aSi, aReason) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      redirect: {
+        type: aType,
+        plan: aPlan,
+        number: aNumber,
+        pi: aPi,
+        si: aSi,
+        reason: aReason
+      }
+    });
+  },
+
+  notifyCdmaInfoRecLineControl: function(aClientId, aPolarityIncluded, aToggle,
+                                         aReverse, aPowerDenial) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      lineControl: {
+        polarityIncluded: aPolarityIncluded,
+        toggle: aToggle,
+        reverse: aReverse,
+        powerDenial: aPowerDenial
+      }
+    });
+  },
+
+  notifyCdmaInfoRecClir: function(aClientId, aCause) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      clirCause: aCause
+    });
+  },
+
+  notifyCdmaInfoRecAudioControl: function(aClientId, aUplink, aDownLink) {
+    this._broadcastCdmaInfoRecordSystemMessage({
+      clientId: aClientId,
+      audioControl: {
+        upLink: aUplink,
+        downLink: aDownLink
+      }
+    });
+  },
+
   /**
    * nsIObserver interface.
    */
   observe: function(aSubject, aTopic, aData) {
     switch (aTopic) {
       case NS_NETWORK_ACTIVE_CHANGED_TOPIC_ID:
         for (let i = 0; i < this.numItems; i++) {
           let provider = this._providers[i];
--- a/dom/mobileconnection/gonk/nsIGonkMobileConnectionService.idl
+++ b/dom/mobileconnection/gonk/nsIGonkMobileConnectionService.idl
@@ -4,17 +4,17 @@
 
 #include "nsIMobileConnectionService.idl"
 
 %{C++
 #define GONK_MOBILECONNECTION_SERVICE_CONTRACTID \
         "@mozilla.org/mobileconnection/gonkmobileconnectionservice;1"
 %}
 
-[scriptable, uuid(b0310517-e7f6-4fa5-a52e-fa6ff35c8fc1)]
+[scriptable, uuid(2d574f0e-4a02-11e4-b1b3-cbc14b7608ce)]
 interface nsIGonkMobileConnectionService : nsIMobileConnectionService
 {
   void notifyNetworkInfoChanged(in unsigned long clientId, in jsval networkInfo);
 
   void notifyVoiceInfoChanged(in unsigned long clientId, in jsval voiceInfo);
 
   void notifyDataInfoChanged(in unsigned long clientId, in jsval dataInfo);
 
@@ -48,9 +48,210 @@ interface nsIGonkMobileConnectionService
                                     in DOMString network);
 
   void notifyCFStateChanged(in unsigned long clientId,
                             in unsigned short action,
                             in unsigned short reason,
                             in DOMString number,
                             in unsigned short timeSeconds,
                             in unsigned short serviceClass);
+
+  /**
+   * Notify Display Info from received Cdma-Info-Record.
+   * See 3.7.4.1 Display in 3GPP2 C.S0005-F.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param display
+            The string to be displayed.
+   */
+  void notifyCdmaInfoRecDisplay(in unsigned long clientId,
+                                in DOMString display);
+
+  /**
+   * Notify Called Party Number from received Cdma-Info-Record.
+   * See 3.7.4.2 Called Party Number in 3GPP2 C.S0005-F.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param type
+   *        The type of number. (3-bit binary)
+   *        See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+   * @param plan
+   *        The numbering plan. (4-bit binary)
+   *        See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+   * @param number
+   *        The string presentation of the number.
+   * @param pi (2-bit binary)
+   *        The Presentation indicator of the number.
+   *        See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+   * @param si (2-bit binary)
+   *        The Screening Indicator of the number.
+   *        See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+   */
+  void notifyCdmaInfoRecCalledPartyNumber(in unsigned long clientId,
+                                          in unsigned short type,
+                                          in unsigned short plan,
+                                          in DOMString number,
+                                          in unsigned short pi,
+                                          in unsigned short si);
+
+  /**
+   * Notify Calling Party Number from received Cdma-Info-Record.
+   * See 3.7.4.3 Calling Party Number in 3GPP2 C.S0005-F.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param type
+   *        The type of number. (3-bit binary)
+   *        See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+   * @param plan
+   *        The numbering plan. (4-bit binary)
+   *        See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+   * @param number
+   *        The string presentation of the number.
+   * @param pi (2-bit binary)
+   *        The Presentation indicator of the number.
+   *        See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+   * @param si (2-bit binary)
+   *        The Screening Indicator of the number.
+   *        See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+   */
+  void notifyCdmaInfoRecCallingPartyNumber(in unsigned long clientId,
+                                           in unsigned short type,
+                                           in unsigned short plan,
+                                           in DOMString number,
+                                           in unsigned short pi,
+                                           in unsigned short si);
+
+  /**
+   * Notify Connected Party Number from received Cdma-Info-Record.
+   * See 3.7.4.4 Connected Party Number in 3GPP2 C.S0005-F.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param type
+   *        The type of number. (3-bit binary)
+   *        See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+   * @param plan
+   *        The numbering plan. (4-bit binary)
+   *        See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+   * @param number
+   *        The string presentation of the number.
+   * @param pi (2-bit binary)
+   *        The Presentation indicator of the number.
+   *        See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+   * @param si (2-bit binary)
+   *        The Screening Indicator of the number.
+   *        See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+   */
+  void notifyCdmaInfoRecConnectedPartyNumber(in unsigned long clientId,
+                                             in unsigned short type,
+                                             in unsigned short plan,
+                                             in DOMString number,
+                                             in unsigned short pi,
+                                             in unsigned short si);
+
+  /**
+   * Notify Signal Info from received Cdma-Info-Record.
+   * See 3.7.4.5 Signal in 3GPP2 C.S0005-F.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param type
+   *        The signal type. (2-bit binary)
+   *        See Table 3.7.5.5-1 in 3GPP2 C.S0005-F.
+   * @param alertPitch
+   *        The pitch of the alerting signal. (2-bit binary)
+   *        See Table 3.7.5.5-2 in 3GPP2 C.S0005-F.
+   * @param signal
+   *        The signal code. (6-bit binary)
+   *        See Table 3.7.5.5-3, 3.7.5.5-4, 3.7.5.5-5 in 3GPP2 C.S0005-F.
+   */
+  void notifyCdmaInfoRecSignal(in unsigned long clientId,
+                               in unsigned short type,
+                               in unsigned short alertPitch,
+                               in unsigned short signal);
+
+  /**
+   * Notify Redirecting Number from received Cdma-Info-Record.
+   * See 3.7.4.11 Redirecting Number in 3GPP2 C.S0005-F.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param type
+   *        The type of number. (3-bit binary)
+   *        See Table 2.7.1.3.2.4-2 in 3GPP2 C.S0005-F.
+   * @param plan
+   *        The numbering plan. (4-bit binary)
+   *        See Table 2.7.1.3.2.4-3 in 3GPP2 C.S0005-F.
+   * @param number
+   *        The string presentation of the number.
+   * @param pi (2-bit binary)
+   *        The Presentation indicator of the number.
+   *        See Table 2.7.4.4-1 in 3GPP2 C.S0005-F.
+   * @param si (2-bit binary)
+   *        The Screening Indicator of the number.
+   *        See Table 2.7.4.4-2 in 3GPP2 C.S0005-F.
+   * @param reason (4-bit binary)
+   *        The redirection reason.
+   *        See Table 3.7.5.11-1 in 3GPP2 C.S0005-F.
+   */
+  void notifyCdmaInfoRecRedirectingNumber(in unsigned long clientId,
+                                          in unsigned short type,
+                                          in unsigned short plan,
+                                          in DOMString number,
+                                          in unsigned short pi,
+                                          in unsigned short si,
+                                          in unsigned short reason);
+
+  /**
+   * Notify Line Control from received Cdma-Info-Record.
+   * See 3.7.4.15 Line Control in 3GPP2 C.S0005-F.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param polarityIncluded (1-bit)
+   *        Polarity parameter included.
+   * @param toggle (1-bit)
+   *        Toggle mode.
+   * @param reverse (1-bit)
+   *        Reverse polarity.
+   * @param powerDenial (8-bit)
+   *        Power denial timeout.
+   */
+  void notifyCdmaInfoRecLineControl(in unsigned long clientId,
+                                    in unsigned short polarityIncluded,
+                                    in unsigned short toggle,
+                                    in unsigned short reverse,
+                                    in unsigned short powerDenial);
+
+  /**
+   * Notify CLIR from received Cdma-Info-Record.
+   * See 'ANNEX 1 Country-Specific Record Type for Japan' in T53.
+   * http://www.arib.or.jp/english/html/overview/doc/T53v6_5_pdf/5_ANNEX_v6_5.pdf
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param cause
+   *        Reason code. (8-bit binary)
+   *        See Table A 1.1-1 in T53.
+   */
+  void notifyCdmaInfoRecClir(in unsigned long clientId,
+                             in unsigned short cause);
+
+  /**
+   * Notify Audio Control from received Cdma-Info-Record.
+   *
+   * Note: No information from ARIB about Audio Control.
+   *       It seems obsolete according to ANNEX 1 in T53.
+   *       upLink/downLink are 'byte' value according to ril.h.
+   *       Treat them as 'signed short' to preserve the flexibility when needed.
+   *
+   * @param clientId
+   *        The ID of radioInterface where this info is notified from.
+   * @param upLink
+   * @param downLink
+   */
+  void notifyCdmaInfoRecAudioControl(in unsigned long clientId,
+                                     in short upLink,
+                                     in short downLink);
 };
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -391,23 +391,16 @@ XPCOMUtils.defineLazyGetter(this, "gMess
           this._resendQueuedTargetMessage();
           break;
         case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
           this._shutdown();
           break;
       }
     },
 
-    sendMobileConnectionMessage: function(message, clientId, data) {
-      this._sendTargetMessage("mobileconnection", message, {
-        clientId: clientId,
-        data: data
-      });
-    },
-
     sendIccMessage: function(message, clientId, data) {
       this._sendTargetMessage("icc", message, {
         clientId: clientId,
         data: data
       });
     }
   };
 });
@@ -2086,20 +2079,17 @@ RadioInterface.prototype = {
         break;
       case "stkcommand":
         this.handleStkProactiveCommand(message);
         break;
       case "stksessionend":
         gMessageManager.sendIccMessage("RIL:StkSessionEnd", this.clientId, null);
         break;
       case "cdma-info-rec-received":
-        if (DEBUG) this.debug("cdma-info-rec-received: " + JSON.stringify(message));
-        message.records.forEach(function(aRecord) {
-          gSystemMessenger.broadcastMessage("cdma-info-rec-received", aRecord);
-        });
+        this.handleCdmaInformationRecords(message.records);
         break;
       default:
         throw new Error("Don't know about this message type: " +
                         message.rilMessageType);
     }
   },
 
   /**
@@ -2917,16 +2907,109 @@ RadioInterface.prototype = {
                              hasEtwsInfo,
                              (hasEtwsInfo)
                                ? this._convertCbEtwsWarningType(etwsInfo.warningType)
                                : Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID,
                              hasEtwsInfo ? etwsInfo.emergencyUserAlert : false,
                              hasEtwsInfo ? etwsInfo.popup : false);
   },
 
+  handleCdmaInformationRecords: function(aRecords) {
+    if (DEBUG) this.debug("cdma-info-rec-received: " + JSON.stringify(aRecords));
+
+    let clientId = this.clientId;
+
+    aRecords.forEach(function(aRecord) {
+      if (aRecord.display) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecDisplay(clientId, aRecord.display);
+        return;
+      }
+
+      if (aRecord.calledNumber) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecCalledPartyNumber(clientId,
+                                              aRecord.calledNumber.type,
+                                              aRecord.calledNumber.plan,
+                                              aRecord.calledNumber.number,
+                                              aRecord.calledNumber.pi,
+                                              aRecord.calledNumber.si);
+        return;
+      }
+
+      if (aRecord.callingNumber) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecCallingPartyNumber(clientId,
+                                               aRecord.callingNumber.type,
+                                               aRecord.callingNumber.plan,
+                                               aRecord.callingNumber.number,
+                                               aRecord.callingNumber.pi,
+                                               aRecord.callingNumber.si);
+        return;
+      }
+
+      if (aRecord.connectedNumber) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecConnectedPartyNumber(clientId,
+                                                 aRecord.connectedNumber.type,
+                                                 aRecord.connectedNumber.plan,
+                                                 aRecord.connectedNumber.number,
+                                                 aRecord.connectedNumber.pi,
+                                                 aRecord.connectedNumber.si);
+        return;
+      }
+
+      if (aRecord.signal) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecSignal(clientId,
+                                   aRecord.signal.type,
+                                   aRecord.signal.alertPitch,
+                                   aRecord.signal.signal);
+        return;
+      }
+
+      if (aRecord.redirect) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecRedirectingNumber(clientId,
+                                              aRecord.redirect.type,
+                                              aRecord.redirect.plan,
+                                              aRecord.redirect.number,
+                                              aRecord.redirect.pi,
+                                              aRecord.redirect.si,
+                                              aRecord.redirect.reason);
+        return;
+      }
+
+      if (aRecord.lineControl) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecLineControl(clientId,
+                                        aRecord.lineControl.polarityIncluded,
+                                        aRecord.lineControl.toggle,
+                                        aRecord.lineControl.reverse,
+                                        aRecord.lineControl.powerDenial);
+        return;
+      }
+
+      if (aRecord.clirCause) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecClir(clientId,
+                                 aRecord.clirCause);
+        return;
+      }
+
+      if (aRecord.audioControl) {
+        gMobileConnectionService
+          .notifyCdmaInfoRecAudioControl(clientId,
+                                         aRecord.audioControl.upLink,
+                                         aRecord.audioControl.downLink);
+        return;
+      }
+    });
+  },
+
   // nsIObserver
 
   observe: function(subject, topic, data) {
     switch (topic) {
       case kMozSettingsChangedObserverTopic:
         if ("wrappedJSObject" in subject) {
           subject = subject.wrappedJSObject;
         }
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -10047,21 +10047,21 @@ CdmaPDUHelperObject.prototype = {
           record.redirect.pi = Buf.readInt32();
           record.redirect.si = Buf.readInt32();
           record.redirect.reason = Buf.readInt32();
           break;
         case PDU_CDMA_INFO_REC_TYPE_LINE_CONTROL:
           record.lineControl = {};
           record.lineControl.polarityIncluded = Buf.readInt32();
           record.lineControl.toggle = Buf.readInt32();
-          record.lineControl.recerse = Buf.readInt32();
+          record.lineControl.reverse = Buf.readInt32();
           record.lineControl.powerDenial = Buf.readInt32();
           break;
         case PDU_CDMA_INFO_REC_TYPE_T53_CLIR:
-          record.cause = Buf.readInt32();
+          record.clirCause = Buf.readInt32();
           break;
         case PDU_CDMA_INFO_REC_TYPE_T53_AUDIO_CONTROL:
           record.audioControl = {};
           record.audioControl.upLink = Buf.readInt32();
           record.audioControl.downLink = Buf.readInt32();
           break;
         case PDU_CDMA_INFO_REC_TYPE_T53_RELEASE:
           // Fall through
--- a/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
+++ b/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js
@@ -168,8 +168,67 @@ add_test(function test_signal_not_presen
   let context = worker.ContextPool._contexts[0];
   let helper = context.CdmaPDUHelper;
   let records = helper.decodeInformationRecord();
 
   do_check_eq(records.length, 0);
 
   run_next_test();
 });
+
+/**
+ * Verify decoder for Line Control
+ */
+add_test(function test_line_control() {
+  let worker = newWorkerWithParcel([
+                0x01,   // one inforemation record
+                0x06,   // type: line control
+                0x01,   // polarity included
+                0x00,   // not toggled
+                0x01,   // reversed
+                0xFF]); // Power denial timeout: 255 * 5 ms
+  let context = worker.ContextPool._contexts[0];
+  let helper = context.CdmaPDUHelper;
+  let records = helper.decodeInformationRecord();
+
+  do_check_eq(records[0].lineControl.polarityIncluded, 1);
+  do_check_eq(records[0].lineControl.toggle, 0);
+  do_check_eq(records[0].lineControl.reverse, 1);
+  do_check_eq(records[0].lineControl.powerDenial, 255);
+
+  run_next_test();
+});
+
+/**
+ * Verify decoder for CLIR Cause
+ */
+add_test(function test_clir() {
+  let worker = newWorkerWithParcel([
+                0x01,   // one inforemation record
+                0x08,   // type: clir
+                0x01]); // cause: Rejected by user
+  let context = worker.ContextPool._contexts[0];
+  let helper = context.CdmaPDUHelper;
+  let records = helper.decodeInformationRecord();
+
+  do_check_eq(records[0].clirCause, 1);
+
+  run_next_test();
+});
+
+/**
+ * Verify decoder for Audio Control
+ */
+add_test(function test_clir() {
+  let worker = newWorkerWithParcel([
+                0x01,   // one inforemation record
+                0x0A,   // type: audio control
+                0x01,   // uplink
+                0xFF]); // downlink
+  let context = worker.ContextPool._contexts[0];
+  let helper = context.CdmaPDUHelper;
+  let records = helper.decodeInformationRecord();
+
+  do_check_eq(records[0].audioControl.upLink, 1);
+  do_check_eq(records[0].audioControl.downLink, 255);
+
+  run_next_test();
+});