Bug 734145 - B2G RIL: Support USSD codes. Part 2: RIL. r=philikon
authorFernando Jiménez <ferjmoreno@gmail.com>
Sat, 09 Jun 2012 17:07:18 -0400
changeset 101090 6a82222e6d5b00b2a3f258eb1509f17c607254a4
parent 101089 c9491fa6ac54d92cbaae5e9854324930debeefb4
child 101091 fed1cc9763919b56e5d91615ca102fc6fedc3b32
push id1316
push userakeybl@mozilla.com
push dateMon, 27 Aug 2012 22:37:00 +0000
treeherdermozilla-beta@db4b09302ee2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphilikon
bugs734145
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 734145 - B2G RIL: Support USSD codes. Part 2: RIL. r=philikon
dom/system/gonk/RILContentHelper.js
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_worker.js
--- a/dom/system/gonk/RILContentHelper.js
+++ b/dom/system/gonk/RILContentHelper.js
@@ -31,21 +31,27 @@ const RIL_IPC_MSG_NAMES = [
   "RIL:CallStateChanged",
   "RIL:CallError",
   "RIL:GetCardLock:Return:OK",
   "RIL:GetCardLock:Return:KO",
   "RIL:SetCardLock:Return:OK",
   "RIL:SetCardLock:Return:KO",
   "RIL:UnlockCardLock:Return:OK",
   "RIL:UnlockCardLock:Return:KO",
+  "RIL:UssdReceived",
+  "RIL:SendUssd:Return:OK",
+  "RIL:SendUssd:Return:KO",
+  "RIL:CancelUssd:Return:OK",
+  "RIL:CancelUssd:Return:KO"
 ];
 
 const kVoiceChangedTopic     = "mobile-connection-voice-changed";
 const kDataChangedTopic      = "mobile-connection-data-changed";
 const kCardStateChangedTopic = "mobile-connection-cardstate-changed";
+const kUssdReceivedTopic     = "mobile-connection-ussd-received";
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsIFrameMessageManager");
 
 function MobileConnectionInfo() {}
 MobileConnectionInfo.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMMozMobileConnectionInfo]),
@@ -170,16 +176,40 @@ RILContentHelper.prototype = {
                                   Cr.NS_ERROR_UNEXPECTED);
     }
     let request = Services.DOMRequest.createRequest(window);
     info.requestId = this.getRequestId(request);
     cpmm.sendAsyncMessage("RIL:SetCardLock", info);
     return request;
   },
 
+  sendUSSD: function sendUSSD(window, ussd) {
+    debug("Sending USSD " + ussd);
+    if (!window) {
+      throw Components.Exception("Can't get window object",
+                                 Cr.NS_ERROR_EXPECTED);
+    }
+    let request = Services.DOMRequest.createRequest(window);
+    let requestId = this.getRequestId(request);
+    cpmm.sendAsyncMessage("RIL:SendUSSD", {ussd: ussd, requestId: requestId});
+    return request;
+  },
+
+  cancelUSSD: function cancelUSSD(window) {
+    debug("Cancel USSD");
+    if (!window) {
+      throw Components.Exception("Can't get window object",
+                                 Cr.NS_ERROR_UNEXPECTED);
+    }
+    let request = Services.DOMRequest.createRequest(window);
+    let requestId = this.getRequestId(request);
+    cpmm.sendAsyncMessage("RIL:CancelUSSD", {requestId: requestId});
+    return request;
+  },
+
   _telephonyCallbacks: null,
   _enumerationTelephonyCallbacks: null,
 
   registerTelephonyCallback: function registerTelephonyCallback(callback) {
     if (this._telephonyCallbacks) {
       if (this._telephonyCallbacks.indexOf(callback) != -1) {
         throw new Error("Already registered this callback!");
       }
@@ -323,16 +353,34 @@ RILContentHelper.prototype = {
       case "RIL:GetCardLock:Return:KO":
       case "RIL:SetCardLock:Return:KO":
       case "RIL:UnlockCardLock:Return:KO":
         request = this.takeRequest(msg.json.requestId);
         if (request) {
           Services.DOMRequest.fireError(request, msg.json.errorMsg);
         }
         break;
+      case "RIL:UssdReceived":
+        Services.obs.notifyObservers(null, kUssdReceivedTopic,
+                                     msg.json.message);
+        break;
+      case "RIL:SendUssd:Return:OK":
+      case "RIL:CancelUssd:Return:OK":
+        request = this.takeRequest(msg.json.requestId);
+        if (request) {
+          Services.DOMRequest.fireSuccess(request, msg.json);
+        }
+        break;
+      case "RIL:SendUssd:Return:KO":
+      case "RIL:CancelUssd:Return:KO":
+        request = this.takeRequest(msg.json.requestId);
+        if (request) {
+          Services.DOMRequest.fireError(request, msg.json.errorMsg);
+        }
+        break;
     }
   },
 
   handleEnumerateCalls: function handleEnumerateCalls(calls) {
     debug("handleEnumerateCalls: " + JSON.stringify(calls));
     let callback = this._enumerationTelephonyCallbacks.shift();
     for (let i in calls) {
       let call = calls[i];
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -42,17 +42,19 @@ const RIL_IPC_MSG_NAMES = [
   "RIL:HangUp",
   "RIL:AnswerCall",
   "RIL:RejectCall",
   "RIL:HoldCall",
   "RIL:ResumeCall",
   "RIL:GetAvailableNetworks",
   "RIL:GetCardLock",
   "RIL:UnlockCardLock",
-  "RIL:SetCardLock"
+  "RIL:SetCardLock",
+  "RIL:SendUSSD",
+  "RIL:CancelUSSD"
 ];
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSmsService",
                                    "@mozilla.org/sms/smsservice;1",
                                    "nsISmsService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSmsRequestManager",
                                    "@mozilla.org/sms/smsrequestmanager;1",
@@ -251,16 +253,22 @@ RadioInterfaceLayer.prototype = {
         this.getCardLock(msg.json);
         break;
       case "RIL:UnlockCardLock":
         this.unlockCardLock(msg.json);
         break;
       case "RIL:SetCardLock":
         this.setCardLock(msg.json);
         break;
+      case "RIL:SendUSSD":
+        this.sendUSSD(msg.json);
+        break;
+      case "RIL:CancelUSSD":
+        this.cancelUSSD(msg.json);
+        break;
     }
   },
 
   onerror: function onerror(event) {
     debug("Got an error: " + event.filename + ":" +
           event.lineno + ": " + event.message + "\n");
     event.preventDefault();
   },
@@ -370,16 +378,26 @@ RadioInterfaceLayer.prototype = {
         if (callback) {
           delete this._contactsCallbacks[message.requestId];
           callback.receiveContactsList(message.contactType, message.contacts);
         }
         break;
       case "celllocationchanged":
         this.radioState.cell = message;
         break;
+      case "ussdreceived":
+        debug("ussdreceived " + JSON.stringify(message));
+        this.handleUSSDReceived(message);
+        break;
+      case "sendussd":
+        this.handleSendUSSD(message);
+        break;
+      case "cancelussd":
+        this.handleCancelUSSD(message);
+        break;
       default:
         throw new Error("Don't know about this message type: " + message.type);
     }
   },
 
   updateVoiceConnection: function updateVoiceConnection(state) {
     let voiceInfo = this.radioState.voice;
     voiceInfo.type = "gsm"; //TODO see bug 726098.
@@ -785,16 +803,35 @@ RadioInterfaceLayer.prototype = {
   handleICCSetCardLock: function handleICCSetCardLock(message) {
     ppmm.sendAsyncMessage("RIL:SetCardLock:Return:OK", message);
   },
 
   handleICCUnlockCardLock: function handleICCUnlockCardLock(message) {
     ppmm.sendAsyncMessage("RIL:UnlockCardLock:Return:OK", message);
   },
 
+  handleUSSDReceived: function handleUSSDReceived(ussd) {
+    debug("handleUSSDReceived " + JSON.stringify(ussd));
+    ppmm.sendAsyncMessage("RIL:UssdReceived", ussd);
+  },
+
+  handleSendUSSD: function handleSendUSSD(message) {
+    debug("handleSendUSSD " + JSON.stringify(message));
+    let messageType = message.success ? "RIL:SendUssd:Return:OK" :
+                                        "RIL:SendUssd:Return:KO";
+    ppmm.sendAsyncMessage(messageType, message);
+  },
+
+  handleCancelUSSD: function handleCancelUSSD(message) {
+    debug("handleCancelUSSD " + JSON.stringify(message));
+    let messageType = message.success ? "RIL:CancelUssd:Return:OK" :
+                                        "RIL:CancelUssd:Return:KO";
+    ppmm.sendAsyncMessage(messageType, message);
+  },
+
   // nsIObserver
 
   observe: function observe(subject, topic, data) {
     switch (topic) {
       case kMozSettingsChangedObserverTopic:
         let setting = JSON.parse(data);
         this.handleMozSettingsChanged(setting);
         break;
@@ -886,16 +923,28 @@ RadioInterfaceLayer.prototype = {
   resumeCall: function resumeCall(callIndex) {
     this.worker.postMessage({type: "resumeCall", callIndex: callIndex});
   },
 
   getAvailableNetworks: function getAvailableNetworks(requestId) {
     this.worker.postMessage({type: "getAvailableNetworks", requestId: requestId});
   },
 
+  sendUSSD: function sendUSSD(message) {
+    debug("SendUSSD " + JSON.stringify(message));
+    message.type = "sendUSSD";
+    this.worker.postMessage(message);
+  },
+
+  cancelUSSD: function cancelUSSD(message) {
+    debug("Cancel pending USSD");
+    message.type = "cancelUSSD";
+    this.worker.postMessage(message);
+  },
+
   get microphoneMuted() {
     return gAudioManager.microphoneMuted;
   },
   set microphoneMuted(value) {
     if (value == this.microphoneMuted) {
       return;
     }
     gAudioManager.phoneState = value ?
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -1753,16 +1753,36 @@ let RIL = {
   /**
    * Get failure casue code for the most recently failed PDP context.
    */
   getFailCauseCode: function getFailCauseCode(options) {
     Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE, options);
   },
 
   /**
+   * Send USSD.
+   *
+   * @param ussd
+   *        String containing the USSD code.
+   *
+   */
+   sendUSSD: function sendUSSD(options) {
+     Buf.newParcel(REQUEST_SEND_USSD, options);
+     Buf.writeString(options.ussd);
+     Buf.sendParcel();
+   },
+
+  /**
+   * Cancel pending USSD.
+   */
+   cancelUSSD: function cancelUSSD(options) {
+     Buf.simpleRequest(REQUEST_CANCEL_USSD, options);
+   },
+
+  /**
    * Check a given number against the list of emergency numbers provided by the RIL.
    *
    * @param number
    *        The number to look up.
    */
    _isEmergencyNumber: function _isEmergencyNumber(number) {
      // Check read-write ecclist property first.
      let numbers = libcutils.property_get("ril.ecclist");
@@ -2938,18 +2958,32 @@ RIL[REQUEST_SIM_IO] = function REQUEST_S
       debug("ICC I/O Error EF id = " + options.fileId.toString(16) +
             " command = " + options.command.toString(16) +
             "(" + sw1.toString(16) + "/" + sw2.toString(16) + ")");
     }
     return;
   }
   this._processICCIO(options);
 };
-RIL[REQUEST_SEND_USSD] = null;
-RIL[REQUEST_CANCEL_USSD] = null;
+RIL[REQUEST_SEND_USSD] = function REQUEST_SEND_USSD(length, options) {
+  if (DEBUG) {
+    debug("REQUEST_SEND_USSD " + JSON.stringify(options)); 
+  }
+  options.type = "sendussd";
+  options.success = options.rilRequestError == 0 ? true : false;
+  this.sendDOMMessage(options);
+};
+RIL[REQUEST_CANCEL_USSD] = function REQUEST_CANCEL_USSD(length, options) {
+  if (DEBUG) {
+    debug("REQUEST_CANCEL_USSD" + JSON.stringify(options));
+  }
+  options.type = "cancelussd";
+  options.success = options.rilRequestError == 0 ? true : false;
+  this.sendDOMMessage(options);
+};
 RIL[REQUEST_GET_CLIR] = null;
 RIL[REQUEST_SET_CLIR] = null;
 RIL[REQUEST_QUERY_CALL_FORWARD_STATUS] = null;
 RIL[REQUEST_SET_CALL_FORWARD] = null;
 RIL[REQUEST_QUERY_CALL_WAITING] = null;
 RIL[REQUEST_SET_CALL_WAITING] = null;
 RIL[REQUEST_SMS_ACKNOWLEDGE] = null;
 RIL[REQUEST_GET_IMEI] = function REQUEST_GET_IMEI(length, options) {
@@ -3229,19 +3263,28 @@ RIL[UNSOLICITED_RESPONSE_NEW_SMS] = func
 RIL[UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT] = function UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT(length) {
   let result = this._processSmsStatusReport(length);
   this.acknowledgeSMS(result == PDU_FCS_OK, result);
 };
 RIL[UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM] = function UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM(length) {
   let info = Buf.readUint32List();
   //TODO
 };
-RIL[UNSOLICITED_ON_USSD] = null;
-RIL[UNSOLICITED_ON_USSD_REQUEST] = null;
-
+RIL[UNSOLICITED_ON_USSD] = function UNSOLICITED_ON_USSD() {
+  let [typeCode, message] = Buf.readStringList();
+  if (DEBUG) {
+    debug("On USSD. Type Code: " + typeCode + " Message: " + message);
+  }
+  // Empty message should not be progressed to the DOM.
+  if (!message || message == "") {
+    return;
+  }
+  this.sendDOMMessage({type: "ussdreceived",
+                       message: message});
+};
 RIL[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED() {
   let dateString = Buf.readString();
 
   // The data contained in the NITZ message is
   // in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
   // for example: 12/02/16,03:36:08-20,00,310410
 
   // Always print the NITZ info so we can collection what different providers